From 106f7ee6163974efa86106cccc20d4f375a66d8b Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Mon, 22 Jul 2024 20:58:45 +0300 Subject: [PATCH 001/245] AsyncAPI version choosing interface --- faststream/app.py | 4 +- faststream/asyncapi/generate.py | 219 +++----------------------------- faststream/constants.py | 5 + 3 files changed, 23 insertions(+), 205 deletions(-) diff --git a/faststream/app.py b/faststream/app.py index 0669812829..4c201ad9f9 100644 --- a/faststream/app.py +++ b/faststream/app.py @@ -1,4 +1,3 @@ -import logging import logging.config from typing import ( TYPE_CHECKING, @@ -19,6 +18,7 @@ from faststream._compat import ExceptionGroup from faststream.asyncapi.proto import AsyncAPIApplication from faststream.cli.supervisors.utils import set_exit +from faststream.constants import AsyncAPIVersion from faststream.exceptions import ValidationError from faststream.log.logging import logger from faststream.utils import apply_types, context @@ -68,6 +68,7 @@ def __init__( title: str = "FastStream", version: str = "0.1.0", description: str = "", + asyncapi_version: AsyncAPIVersion = AsyncAPIVersion.v2_6, terms_of_service: Optional["AnyHttpUrl"] = None, license: Optional[Union["License", "LicenseDict", "AnyDict"]] = None, contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] = None, @@ -87,6 +88,7 @@ def __init__( self.broker = broker self.logger = logger self.context = context + self.asyncapi_version = asyncapi_version self._on_startup_calling = [apply_types(to_async(x)) for x in on_startup] self._after_startup_calling = [apply_types(to_async(x)) for x in after_startup] diff --git a/faststream/asyncapi/generate.py b/faststream/asyncapi/generate.py index daec95ec00..7ff32b4ea4 100644 --- a/faststream/asyncapi/generate.py +++ b/faststream/asyncapi/generate.py @@ -1,212 +1,23 @@ -from typing import TYPE_CHECKING, Any, Dict, List +from typing import TYPE_CHECKING, Any, Union -from faststream._compat import DEF_KEY -from faststream.asyncapi.schema import ( - Channel, - Components, - Info, - Message, - Reference, - Schema, - Server, -) -from faststream.constants import ContentTypes +from faststream.asyncapi.base import BaseSchema +from faststream.asyncapi.v2_6_0.generate import get_app_schema as get_app_schema_v2_6 +from faststream.asyncapi.v3_0_0.generate import get_app_schema as get_app_schema_v3 +from faststream.asyncapi.version import AsyncAPIVersion if TYPE_CHECKING: - from faststream.asyncapi.proto import AsyncAPIApplication - from faststream.broker.core.usecase import BrokerUsecase - from faststream.broker.types import ConnectionType, MsgType + from faststream._compat import HAS_FASTAPI + from faststream.app import FastStream + if HAS_FASTAPI: + from faststream.broker.fastapi.router import StreamRouter -def get_app_schema(app: "AsyncAPIApplication") -> Schema: - """Get the application schema.""" - broker = app.broker - if broker is None: # pragma: no cover - raise RuntimeError() - broker.setup() - servers = get_broker_server(broker) - channels = get_broker_channels(broker) +def get_app_schema(app: "AsyncAPIApplication") -> BaseSchema: + if app.asyncapi_version == AsyncAPIVersion.v3_0: + return get_app_schema_v3(app) - messages: Dict[str, Message] = {} - payloads: Dict[str, Dict[str, Any]] = {} - for channel_name, ch in channels.items(): - ch.servers = list(servers.keys()) + if app.asyncapi_version == AsyncAPIVersion.v2_6: + return get_app_schema_v2_6(app) - if ch.subscribe is not None: - m = ch.subscribe.message - - if isinstance(m, Message): # pragma: no branch - ch.subscribe.message = _resolve_msg_payloads( - m, - channel_name, - payloads, - messages, - ) - - if ch.publish is not None: - m = ch.publish.message - - if isinstance(m, Message): # pragma: no branch - ch.publish.message = _resolve_msg_payloads( - m, - channel_name, - payloads, - messages, - ) - schema = Schema( - info=Info( - title=app.title, - version=app.version, - description=app.description, - termsOfService=app.terms_of_service, - contact=app.contact, - license=app.license, - ), - defaultContentType=ContentTypes.json.value, - id=app.identifier, - tags=list(app.asyncapi_tags) if app.asyncapi_tags else None, - externalDocs=app.external_docs, - servers=servers, - channels=channels, - components=Components( - messages=messages, - schemas=payloads, - securitySchemes=None - if broker.security is None - else broker.security.get_schema(), - ), - ) - return schema - - -def get_broker_server( - broker: "BrokerUsecase[MsgType, ConnectionType]", -) -> Dict[str, Server]: - """Get the broker server for an application.""" - servers = {} - - broker_meta: Dict[str, Any] = { - "protocol": broker.protocol, - "protocolVersion": broker.protocol_version, - "description": broker.description, - "tags": broker.tags, - # TODO - # "variables": "", - # "bindings": "", - } - - if broker.security is not None: - broker_meta["security"] = broker.security.get_requirement() - - if isinstance(broker.url, str): - servers["development"] = Server( - url=broker.url, - **broker_meta, - ) - - elif len(broker.url) == 1: - servers["development"] = Server( - url=broker.url[0], - **broker_meta, - ) - - else: - for i, url in enumerate(broker.url, 1): - servers[f"Server{i}"] = Server( - url=url, - **broker_meta, - ) - - return servers - - -def get_broker_channels( - broker: "BrokerUsecase[MsgType, ConnectionType]", -) -> Dict[str, Channel]: - """Get the broker channels for an application.""" - channels = {} - - for h in broker._subscribers.values(): - channels.update(h.schema()) - - for p in broker._publishers.values(): - channels.update(p.schema()) - - return channels - - -def _resolve_msg_payloads( - m: Message, - channel_name: str, - payloads: Dict[str, Any], - messages: Dict[str, Any], -) -> Reference: - """Replace message payload by reference and normalize payloads. - - Payloads and messages are editable dicts to store schemas for reference in AsyncAPI. - """ - one_of_list: List[Reference] = [] - m.payload = _move_pydantic_refs(m.payload, DEF_KEY) - - if DEF_KEY in m.payload: - payloads.update(m.payload.pop(DEF_KEY)) - - one_of = m.payload.get("oneOf") - if isinstance(one_of, dict): - for p_title, p in one_of.items(): - payloads.update(p.pop(DEF_KEY, {})) - if p_title not in payloads: - payloads[p_title] = p - one_of_list.append(Reference(**{"$ref": f"#/components/schemas/{p_title}"})) - - elif one_of is not None: - for p in one_of: - p_title = next(iter(p.values())).split("/")[-1] - if p_title not in payloads: - payloads[p_title] = p - one_of_list.append(Reference(**{"$ref": f"#/components/schemas/{p_title}"})) - - if not one_of_list: - payloads.update(m.payload.pop(DEF_KEY, {})) - p_title = m.payload.get("title", f"{channel_name}Payload") - if p_title not in payloads: - payloads[p_title] = m.payload - m.payload = {"$ref": f"#/components/schemas/{p_title}"} - - else: - m.payload["oneOf"] = one_of_list - - assert m.title # nosec B101 - messages[m.title] = m - return Reference(**{"$ref": f"#/components/messages/{m.title}"}) - - -def _move_pydantic_refs( - original: Any, - key: str, -) -> Any: - """Remove pydantic references and replacem them by real schemas.""" - if not isinstance(original, Dict): - return original - - data = original.copy() - - for k in data: - item = data[k] - - if isinstance(item, str): - if key in item: - data[k] = data[k].replace(key, "components/schemas") - - elif isinstance(item, dict): - data[k] = _move_pydantic_refs(data[k], key) - - elif isinstance(item, List): - for i in range(len(data[k])): - data[k][i] = _move_pydantic_refs(item[i], key) - - if isinstance(desciminator := data.get("discriminator"), dict): - data["discriminator"] = desciminator["propertyName"] - - return data + raise NotImplementedError(f"Async API version not supported: {app.asyncapi_version}") diff --git a/faststream/constants.py b/faststream/constants.py index d3f7c3e25d..2d2dadffa5 100644 --- a/faststream/constants.py +++ b/faststream/constants.py @@ -8,3 +8,8 @@ class ContentTypes(str, Enum): text = "text/plain" json = "application/json" + + +class AsyncAPIVersion(str, Enum): + v3_0 = "3.0" + v2_6 = "2.6" From 1dab719089ae60c150993f0b996ca854a4210ee2 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Mon, 22 Jul 2024 21:57:49 +0300 Subject: [PATCH 002/245] Schema v3 and info v3 --- faststream/app.py | 2 +- faststream/asyncapi/generate.py | 9 ++- faststream/asyncapi/schema/__init__.py | 22 ++++-- faststream/asyncapi/schema/info.py | 72 +++++++++++++++-- faststream/asyncapi/schema/main.py | 105 ++++++++++++++++++++++++- faststream/asyncapi/site.py | 8 +- faststream/asyncapi/version.py | 6 ++ faststream/broker/fastapi/router.py | 4 +- faststream/cli/docs/app.py | 5 +- faststream/constants.py | 5 -- 10 files changed, 204 insertions(+), 34 deletions(-) create mode 100644 faststream/asyncapi/version.py diff --git a/faststream/app.py b/faststream/app.py index 4c201ad9f9..950b3f1164 100644 --- a/faststream/app.py +++ b/faststream/app.py @@ -17,8 +17,8 @@ from faststream._compat import ExceptionGroup from faststream.asyncapi.proto import AsyncAPIApplication +from faststream.asyncapi.version import AsyncAPIVersion from faststream.cli.supervisors.utils import set_exit -from faststream.constants import AsyncAPIVersion from faststream.exceptions import ValidationError from faststream.log.logging import logger from faststream.utils import apply_types, context diff --git a/faststream/asyncapi/generate.py b/faststream/asyncapi/generate.py index 7ff32b4ea4..39cba02fcc 100644 --- a/faststream/asyncapi/generate.py +++ b/faststream/asyncapi/generate.py @@ -1,16 +1,19 @@ -from typing import TYPE_CHECKING, Any, Union +from typing import TYPE_CHECKING +from faststream._compat import HAS_FASTAPI from faststream.asyncapi.base import BaseSchema +from faststream.asyncapi.schema import ( + BaseSchema, +) from faststream.asyncapi.v2_6_0.generate import get_app_schema as get_app_schema_v2_6 from faststream.asyncapi.v3_0_0.generate import get_app_schema as get_app_schema_v3 from faststream.asyncapi.version import AsyncAPIVersion if TYPE_CHECKING: from faststream._compat import HAS_FASTAPI - from faststream.app import FastStream if HAS_FASTAPI: - from faststream.broker.fastapi.router import StreamRouter + pass def get_app_schema(app: "AsyncAPIApplication") -> BaseSchema: diff --git a/faststream/asyncapi/schema/__init__.py b/faststream/asyncapi/schema/__init__.py index e6881e1873..67bb38e49b 100644 --- a/faststream/asyncapi/schema/__init__.py +++ b/faststream/asyncapi/schema/__init__.py @@ -7,13 +7,20 @@ ) from faststream.asyncapi.schema.channels import Channel from faststream.asyncapi.schema.info import ( + BaseInfo, Contact, ContactDict, - Info, + InfoV2_6, + InfoV3_0, License, LicenseDict, ) -from faststream.asyncapi.schema.main import ASYNC_API_VERSION, Components, Schema +from faststream.asyncapi.schema.main import ( + BaseSchema, + Components, + SchemaV2_6, + SchemaV3_0, +) from faststream.asyncapi.schema.message import CorrelationId, Message from faststream.asyncapi.schema.operations import Operation from faststream.asyncapi.schema.security import SecuritySchemaComponent @@ -25,14 +32,19 @@ Tag, TagDict, ) +from faststream.asyncapi.version import AsyncAPIVersion __all__ = ( # main - "ASYNC_API_VERSION", - "Schema", + "AsyncAPIVersion", + "BaseSchema", + "SchemaV2_6", + "SchemaV3_0", "Components", # info - "Info", + "BaseInfo", + "InfoV2_6", + "InfoV3_0", "Contact", "ContactDict", "License", diff --git a/faststream/asyncapi/schema/info.py b/faststream/asyncapi/schema/info.py index 1e5a1a2d6f..575b552331 100644 --- a/faststream/asyncapi/schema/info.py +++ b/faststream/asyncapi/schema/info.py @@ -1,4 +1,14 @@ -from typing import Any, Callable, Dict, Iterable, Optional, Type, Union +from typing import ( + TYPE_CHECKING, + Any, + Callable, + Dict, + Iterable, + List, + Optional, + Type, + Union, +) from pydantic import AnyHttpUrl, BaseModel from typing_extensions import Required, TypedDict @@ -12,6 +22,17 @@ ) from faststream.log import logger +if TYPE_CHECKING: + from faststream.asyncapi.schema import ( + ExternalDocs, + ExternalDocsDict, + Tag, + TagDict, + ) + from faststream.types import ( + AnyDict, + ) + try: import email_validator @@ -156,25 +177,19 @@ class Config: extra = "allow" -class Info(BaseModel): +class BaseInfo(BaseModel): """A class to represent information. Attributes: title : title of the information version : version of the information (default: "1.0.0") description : description of the information (default: "") - termsOfService : terms of service for the information (default: None) - contact : contact information for the information (default: None) - license : license information for the information (default: None) """ title: str version: str = "1.0.0" description: str = "" - termsOfService: Optional[AnyHttpUrl] = None - contact: Optional[Union[Contact, ContactDict, Dict[str, Any]]] = None - license: Optional[Union[License, LicenseDict, Dict[str, Any]]] = None if PYDANTIC_V2: model_config = {"extra": "allow"} @@ -183,3 +198,44 @@ class Info(BaseModel): class Config: extra = "allow" + + + +class InfoV2_6(BaseInfo): # noqa: N801 + """A class to represent information. + + Attributes: + title : title of the information + version : version of the information (default: "1.0.0") + description : description of the information (default: "") + termsOfService : terms of service for the information (default: None) + contact : contact information for the information (default: None) + license : license information for the information (default: None) + + """ + + termsOfService: Optional[AnyHttpUrl] = None + contact: Optional[Union[Contact, ContactDict, Dict[str, Any]]] = None + license: Optional[Union[License, LicenseDict, Dict[str, Any]]] = None + + +class InfoV3_0(BaseInfo): # noqa: N801 + """A class to represent information. + + Attributes: + termsOfService : terms of service for the information (default: None) + contact : contact information for the information (default: None) + license : license information for the information (default: None) + tags : optional list of tags + externalDocs : optional external documentation + + """ + + termsOfService: Optional[AnyHttpUrl] = None + contact: Optional[Union[Contact, ContactDict, Dict[str, Any]]] = None + license: Optional[Union[License, LicenseDict, Dict[str, Any]]] = None + tags: Optional[List[Union["Tag", "TagDict", "AnyDict"]]] = None + externalDocs: Optional[ + Union["ExternalDocs", "ExternalDocsDict", "AnyDict"] + ] = None + diff --git a/faststream/asyncapi/schema/main.py b/faststream/asyncapi/schema/main.py index acceca985d..acdc29917e 100644 --- a/faststream/asyncapi/schema/main.py +++ b/faststream/asyncapi/schema/main.py @@ -4,7 +4,7 @@ from faststream._compat import PYDANTIC_V2, model_to_json, model_to_jsonable from faststream.asyncapi.schema.channels import Channel -from faststream.asyncapi.schema.info import Info +from faststream.asyncapi.schema.info import BaseInfo, InfoV2_6, InfoV3_0 from faststream.asyncapi.schema.message import Message from faststream.asyncapi.schema.servers import Server from faststream.asyncapi.schema.utils import ( @@ -13,6 +13,7 @@ Tag, TagDict, ) +from faststream.asyncapi.version import AsyncAPIVersion ASYNC_API_VERSION = "2.6.0" @@ -66,7 +67,49 @@ class Config: extra = "allow" -class Schema(BaseModel): +class BaseSchema(BaseModel): + """A class to represent a schema. + + Attributes: + info : information about the schema + + Methods: + to_jsonable() -> Any: Convert the schema to a JSON-serializable object. + to_json() -> str: Convert the schema to a JSON string. + to_yaml() -> str: Convert the schema to a YAML string. + + """ + + info: BaseInfo + + def to_jsonable(self) -> Any: + """Convert the schema to a JSON-serializable object.""" + return model_to_jsonable( + self, + by_alias=True, + exclude_none=True, + ) + + def to_json(self) -> str: + """Convert the schema to a JSON string.""" + return model_to_json( + self, + by_alias=True, + exclude_none=True, + ) + + def to_yaml(self) -> str: + """Convert the schema to a YAML string.""" + from io import StringIO + + import yaml + + io = StringIO(initial_value="", newline="\n") + yaml.dump(self.to_jsonable(), io, sort_keys=False) + return io.getvalue() + + +class SchemaV2_6(BaseSchema): # noqa: N801 """A class to represent a schema. Attributes: @@ -87,10 +130,10 @@ class Schema(BaseModel): """ - asyncapi: str = ASYNC_API_VERSION + asyncapi: AsyncAPIVersion = AsyncAPIVersion.v2_6 id: Optional[str] = None defaultContentType: Optional[str] = None - info: Info + info: InfoV2_6 servers: Optional[Dict[str, Server]] = None channels: Dict[str, Channel] components: Optional[Components] = None @@ -122,3 +165,57 @@ def to_yaml(self) -> str: io = StringIO(initial_value="", newline="\n") yaml.dump(self.to_jsonable(), io, sort_keys=False) return io.getvalue() + + +class SchemaV3_0(BaseSchema): # noqa: N801 + """A class to represent a schema. + + Attributes: + asyncapi : version of the async API + id : optional ID + defaultContentType : optional default content type + info : information about the schema + servers : optional dictionary of servers + channels : dictionary of channels + components : optional components of the schema + + Methods: + to_jsonable() -> Any: Convert the schema to a JSON-serializable object. + to_json() -> str: Convert the schema to a JSON string. + to_yaml() -> str: Convert the schema to a YAML string. + + """ + + asyncapi: AsyncAPIVersion = AsyncAPIVersion.v3_0 + id: Optional[str] = None + defaultContentType: Optional[str] = None + info: InfoV3_0 + servers: Optional[Dict[str, Server]] = None + channels: Dict[str, Channel] + components: Optional[Components] = None + + def to_jsonable(self) -> Any: + """Convert the schema to a JSON-serializable object.""" + return model_to_jsonable( + self, + by_alias=True, + exclude_none=True, + ) + + def to_json(self) -> str: + """Convert the schema to a JSON string.""" + return model_to_json( + self, + by_alias=True, + exclude_none=True, + ) + + def to_yaml(self) -> str: + """Convert the schema to a YAML string.""" + from io import StringIO + + import yaml + + io = StringIO(initial_value="", newline="\n") + yaml.dump(self.to_jsonable(), io, sort_keys=False) + return io.getvalue() diff --git a/faststream/asyncapi/site.py b/faststream/asyncapi/site.py index 9b11565c6a..8afaedbd9c 100644 --- a/faststream/asyncapi/site.py +++ b/faststream/asyncapi/site.py @@ -7,7 +7,7 @@ from faststream.log import logger if TYPE_CHECKING: - from faststream.asyncapi.schema import Schema + from faststream.asyncapi.schema import BaseSchema ASYNCAPI_JS_DEFAULT_URL = "https://unpkg.com/@asyncapi/react-component@1.0.0-next.54/browser/standalone/index.js" @@ -18,7 +18,7 @@ def get_asyncapi_html( - schema: "Schema", + schema: "BaseSchema", sidebar: bool = True, info: bool = True, servers: bool = True, @@ -103,7 +103,7 @@ def get_asyncapi_html( def serve_app( - schema: "Schema", + schema: "BaseSchema", host: str, port: int, ) -> None: @@ -121,7 +121,7 @@ class _Handler(server.BaseHTTPRequestHandler): def __init__( self, *args: Any, - schema: "Schema", + schema: "BaseSchema", **kwargs: Any, ) -> None: self.schema = schema diff --git a/faststream/asyncapi/version.py b/faststream/asyncapi/version.py new file mode 100644 index 0000000000..ed41bdd0ce --- /dev/null +++ b/faststream/asyncapi/version.py @@ -0,0 +1,6 @@ +from enum import Enum + + +class AsyncAPIVersion(str, Enum): + v3_0 = "3.0" + v2_6 = "2.6" diff --git a/faststream/broker/fastapi/router.py b/faststream/broker/fastapi/router.py index baf7ceff53..559e59abac 100644 --- a/faststream/broker/fastapi/router.py +++ b/faststream/broker/fastapi/router.py @@ -53,7 +53,7 @@ from starlette.types import ASGIApp, AppType, Lifespan from faststream.asyncapi import schema as asyncapi - from faststream.asyncapi.schema import Schema + from faststream.asyncapi.schema import BaseSchema from faststream.broker.core.usecase import BrokerUsecase from faststream.broker.message import StreamMessage from faststream.broker.publisher.proto import PublisherProto @@ -93,7 +93,7 @@ class StreamRouter( docs_router: Optional[APIRouter] _after_startup_hooks: List[Callable[[Any], Awaitable[Optional[Mapping[str, Any]]]]] _on_shutdown_hooks: List[Callable[[Any], Awaitable[None]]] - schema: Optional["Schema"] + schema: Optional["BaseSchema"] title: str description: str diff --git a/faststream/cli/docs/app.py b/faststream/cli/docs/app.py index 648390cf46..a1b436fc9f 100644 --- a/faststream/cli/docs/app.py +++ b/faststream/cli/docs/app.py @@ -8,7 +8,7 @@ from faststream._compat import json_dumps, model_parse from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.schema import Schema +from faststream.asyncapi.schema import SchemaV2_6 from faststream.asyncapi.site import serve_app from faststream.cli.utils.imports import import_from_string from faststream.exceptions import INSTALL_WATCHFILES, INSTALL_YAML @@ -183,6 +183,7 @@ def _parse_and_serve( f"Unknown extension given - {app}; Please provide app in format [python_module:FastStream] or [asyncapi.yaml/.json] - path to your application or documentation" ) - raw_schema = model_parse(Schema, data) + # TODO: add schema choosing based on FastStream.asyncapi_version + raw_schema = model_parse(SchemaV2_6, data) serve_app(raw_schema, host, port) diff --git a/faststream/constants.py b/faststream/constants.py index 2d2dadffa5..d3f7c3e25d 100644 --- a/faststream/constants.py +++ b/faststream/constants.py @@ -8,8 +8,3 @@ class ContentTypes(str, Enum): text = "text/plain" json = "application/json" - - -class AsyncAPIVersion(str, Enum): - v3_0 = "3.0" - v2_6 = "2.6" From 40189c872048399eb93ef7d9512decf6238c43f5 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Mon, 22 Jul 2024 22:07:31 +0300 Subject: [PATCH 003/245] StreamRouter asyncapi_version choosing support --- faststream/broker/fastapi/router.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/faststream/broker/fastapi/router.py b/faststream/broker/fastapi/router.py index 559e59abac..e8ae3b8347 100644 --- a/faststream/broker/fastapi/router.py +++ b/faststream/broker/fastapi/router.py @@ -32,6 +32,7 @@ from faststream.asyncapi.proto import AsyncAPIApplication from faststream.asyncapi.site import get_asyncapi_html +from faststream.asyncapi.version import AsyncAPIVersion from faststream.broker.fastapi.get_dependant import get_fastapi_dependant from faststream.broker.fastapi.route import wrap_callable_to_fastapi_compatible from faststream.broker.middlewares import BaseMiddleware @@ -126,6 +127,7 @@ def __init__( generate_unique_id ), # AsyncAPI information + asyncapi_version: AsyncAPIVersion = AsyncAPIVersion.v2_6, asyncapi_tags: Optional[ Iterable[Union["asyncapi.Tag", "asyncapi.TagDict"]] ] = None, @@ -163,6 +165,7 @@ def __init__( self.description = "" self.license = None self.contact = None + self.asyncapi_version = asyncapi_version self.schema = None From d5184b8b732bdb0210279b6008cbe9f5a90e2b1e Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 27 Jul 2024 11:02:56 +0300 Subject: [PATCH 004/245] channels and operations v3 --- faststream/asyncapi/generate.py | 8 +-- faststream/asyncapi/schema/__init__.py | 2 + faststream/asyncapi/schema/info.py | 21 +++--- faststream/asyncapi/schema/main.py | 57 +++++++++++++++- faststream/asyncapi/schema/v3/__init__.py | 0 faststream/asyncapi/schema/v3/channels.py | 40 +++++++++++ faststream/asyncapi/schema/v3/operations.py | 54 +++++++++++++++ faststream/asyncapi/schema/v3/servers.py | 76 +++++++++++++++++++++ 8 files changed, 237 insertions(+), 21 deletions(-) create mode 100644 faststream/asyncapi/schema/v3/__init__.py create mode 100644 faststream/asyncapi/schema/v3/channels.py create mode 100644 faststream/asyncapi/schema/v3/operations.py create mode 100644 faststream/asyncapi/schema/v3/servers.py diff --git a/faststream/asyncapi/generate.py b/faststream/asyncapi/generate.py index 39cba02fcc..9210e223ce 100644 --- a/faststream/asyncapi/generate.py +++ b/faststream/asyncapi/generate.py @@ -1,20 +1,14 @@ from typing import TYPE_CHECKING -from faststream._compat import HAS_FASTAPI from faststream.asyncapi.base import BaseSchema from faststream.asyncapi.schema import ( BaseSchema, + ) from faststream.asyncapi.v2_6_0.generate import get_app_schema as get_app_schema_v2_6 from faststream.asyncapi.v3_0_0.generate import get_app_schema as get_app_schema_v3 from faststream.asyncapi.version import AsyncAPIVersion -if TYPE_CHECKING: - from faststream._compat import HAS_FASTAPI - - if HAS_FASTAPI: - pass - def get_app_schema(app: "AsyncAPIApplication") -> BaseSchema: if app.asyncapi_version == AsyncAPIVersion.v3_0: diff --git a/faststream/asyncapi/schema/__init__.py b/faststream/asyncapi/schema/__init__.py index 67bb38e49b..2605adde91 100644 --- a/faststream/asyncapi/schema/__init__.py +++ b/faststream/asyncapi/schema/__init__.py @@ -32,6 +32,7 @@ Tag, TagDict, ) +from faststream.asyncapi.schema.v3.operations import OperationV3_0 from faststream.asyncapi.version import AsyncAPIVersion __all__ = ( @@ -70,4 +71,5 @@ "SecuritySchemaComponent", # subscription "Operation", + "OperationV3_0", ) diff --git a/faststream/asyncapi/schema/info.py b/faststream/asyncapi/schema/info.py index 575b552331..970e7c019d 100644 --- a/faststream/asyncapi/schema/info.py +++ b/faststream/asyncapi/schema/info.py @@ -1,5 +1,4 @@ from typing import ( - TYPE_CHECKING, Any, Callable, Dict, @@ -20,18 +19,16 @@ JsonSchemaValue, with_info_plain_validator_function, ) +from faststream.asyncapi.schema.utils import ( # noqa: TCH001 + ExternalDocs, + ExternalDocsDict, + Tag, + TagDict, +) from faststream.log import logger - -if TYPE_CHECKING: - from faststream.asyncapi.schema import ( - ExternalDocs, - ExternalDocsDict, - Tag, - TagDict, - ) - from faststream.types import ( - AnyDict, - ) +from faststream.types import ( # noqa: TCH001 + AnyDict, +) try: import email_validator diff --git a/faststream/asyncapi/schema/main.py b/faststream/asyncapi/schema/main.py index acdc29917e..b230eabcd0 100644 --- a/faststream/asyncapi/schema/main.py +++ b/faststream/asyncapi/schema/main.py @@ -13,6 +13,9 @@ Tag, TagDict, ) +from faststream.asyncapi.schema.v3.channels import ChannelV3_0 +from faststream.asyncapi.schema.v3.operations import OperationV3_0 +from faststream.asyncapi.schema.v3.servers import ServerV3_0 from faststream.asyncapi.version import AsyncAPIVersion ASYNC_API_VERSION = "2.6.0" @@ -67,6 +70,55 @@ class Config: extra = "allow" +class ComponentsV3_0(BaseModel): + # TODO + # servers + # serverVariables + # channels + """A class to represent components in a system. + + Attributes: + messages : Optional dictionary of messages + schemas : Optional dictionary of schemas + + Note: + The following attributes are not implemented yet: + - servers + - serverVariables + - channels + - securitySchemes + - parameters + - correlationIds + - operationTraits + - messageTraits + - serverBindings + - channelBindings + - operationBindings + - messageBindings + + """ + + messages: Optional[Dict[str, Message]] = None + schemas: Optional[Dict[str, Dict[str, Any]]] = None + securitySchemes: Optional[Dict[str, Dict[str, Any]]] = None + # parameters + # correlationIds + # operationTraits + # messageTraits + # serverBindings + # channelBindings + # operationBindings + # messageBindings + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" + + class BaseSchema(BaseModel): """A class to represent a schema. @@ -190,8 +242,9 @@ class SchemaV3_0(BaseSchema): # noqa: N801 id: Optional[str] = None defaultContentType: Optional[str] = None info: InfoV3_0 - servers: Optional[Dict[str, Server]] = None - channels: Dict[str, Channel] + servers: Optional[Dict[str, ServerV3_0]] = None + channels: Dict[str, ChannelV3_0] + operations: Dict[str, OperationV3_0] components: Optional[Components] = None def to_jsonable(self) -> Any: diff --git a/faststream/asyncapi/schema/v3/__init__.py b/faststream/asyncapi/schema/v3/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/faststream/asyncapi/schema/v3/channels.py b/faststream/asyncapi/schema/v3/channels.py new file mode 100644 index 0000000000..7d4803b2b3 --- /dev/null +++ b/faststream/asyncapi/schema/v3/channels.py @@ -0,0 +1,40 @@ +from typing import Dict, List, Optional, Union + +from pydantic import BaseModel + +from faststream._compat import PYDANTIC_V2 +from faststream.asyncapi.schema.bindings import ChannelBinding +from faststream.asyncapi.schema.message import Message +from faststream.asyncapi.schema.utils import Parameter, Reference + + +class ChannelV3_0(BaseModel): + """A class to represent a channel. + + Attributes: + address: A string representation of this channel's address. + description : optional description of the channel + servers : optional list of servers associated with the channel + bindings : optional channel binding + parameters : optional parameters associated with the channel + + Configurations: + model_config : configuration for the model (only applicable for Pydantic version 2) + Config : configuration for the class (only applicable for Pydantic version 1) + + """ + + address: str + description: Optional[str] = None + servers: Optional[List[str]] = None + messages: Dict[str, Union[Message, Reference]] + bindings: Optional[ChannelBinding] = None + parameters: Optional[Parameter] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" diff --git a/faststream/asyncapi/schema/v3/operations.py b/faststream/asyncapi/schema/v3/operations.py new file mode 100644 index 0000000000..3da166c1c3 --- /dev/null +++ b/faststream/asyncapi/schema/v3/operations.py @@ -0,0 +1,54 @@ +from typing import Any, Dict, List, Literal, Optional, Union + +from pydantic import BaseModel + +from faststream._compat import PYDANTIC_V2 +from faststream.asyncapi.schema.bindings import OperationBinding +from faststream.asyncapi.schema.utils import ( + ExternalDocs, + ExternalDocsDict, + Reference, + Tag, + TagDict, +) +from faststream.asyncapi.schema.v3.channels import ChannelV3_0 + + +class OperationV3_0(BaseModel): + """A class to represent an operation. + + Attributes: + operationId : ID of the operation + summary : summary of the operation + description : description of the operation + bindings : bindings of the operation + message : message of the operation + security : security details of the operation + tags : tags associated with the operation + externalDocs : external documentation for the operation + + """ + action: Literal["send", "receive"] + summary: Optional[str] = None + description: Optional[str] = None + + bindings: Optional[OperationBinding] = None + + messages: List[Reference] + channel: Union[ChannelV3_0, Reference] + + security: Optional[Dict[str, List[str]]] = None + + # TODO + # traits + + tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = None + externalDocs: Optional[Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" diff --git a/faststream/asyncapi/schema/v3/servers.py b/faststream/asyncapi/schema/v3/servers.py new file mode 100644 index 0000000000..537e08992f --- /dev/null +++ b/faststream/asyncapi/schema/v3/servers.py @@ -0,0 +1,76 @@ +from typing import Any, Dict, List, Optional, Union + +from pydantic import BaseModel + +from faststream._compat import PYDANTIC_V2 +from faststream.asyncapi.schema.bindings import ServerBinding +from faststream.asyncapi.schema.utils import Reference, Tag, TagDict + +SecurityRequirement = List[Dict[str, List[str]]] + + +class ServerVariable(BaseModel): + """A class to represent a server variable. + + Attributes: + enum : list of possible values for the server variable (optional) + default : default value for the server variable (optional) + description : description of the server variable (optional) + examples : list of example values for the server variable (optional) + + """ + + enum: Optional[List[str]] = None + default: Optional[str] = None + description: Optional[str] = None + examples: Optional[List[str]] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" + + +class ServerV3_0(BaseModel): + """A class to represent a server. + + Attributes: + host : host of the server + pathname : pathname of the server + protocol : protocol used by the server + description : optional description of the server + protocolVersion : optional version of the protocol used by the server + tags : optional list of tags associated with the server + security : optional security requirement for the server + variables : optional dictionary of server variables + bindings : optional server binding + + Note: + The attributes `description`, `protocolVersion`, `tags`, `security`, `variables`, and `bindings` are all optional. + + Configurations: + If `PYDANTIC_V2` is True, the model configuration is set to allow extra attributes. + Otherwise, the `Config` class is defined with the `extra` attribute set to "allow". + + """ + + host: str + pathname: str + protocol: str + description: Optional[str] = None + protocolVersion: Optional[str] = None + tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = None + security: Optional[SecurityRequirement] = None + variables: Optional[Dict[str, Union[ServerVariable, Reference]]] = None + bindings: Optional[Union[ServerBinding, Reference]] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" From 3d77fb7520ac039a7f0ab8fdc29308da9b2f2537 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 27 Jul 2024 21:28:08 +0300 Subject: [PATCH 005/245] explicit server reference and naming fix --- faststream/asyncapi/generate.py | 3 --- faststream/asyncapi/version.py | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/faststream/asyncapi/generate.py b/faststream/asyncapi/generate.py index 9210e223ce..398ee3b290 100644 --- a/faststream/asyncapi/generate.py +++ b/faststream/asyncapi/generate.py @@ -1,6 +1,3 @@ -from typing import TYPE_CHECKING - -from faststream.asyncapi.base import BaseSchema from faststream.asyncapi.schema import ( BaseSchema, diff --git a/faststream/asyncapi/version.py b/faststream/asyncapi/version.py index ed41bdd0ce..dd5ae828f3 100644 --- a/faststream/asyncapi/version.py +++ b/faststream/asyncapi/version.py @@ -2,5 +2,5 @@ class AsyncAPIVersion(str, Enum): - v3_0 = "3.0" - v2_6 = "2.6" + v3_0 = "3.0.0" + v2_6 = "2.6.0" From 52260407501c2f8ce5ce6305c7dc4fa1adcfab0e Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 28 Jul 2024 22:18:42 +0300 Subject: [PATCH 006/245] AsyncAPI rabbit naming test --- tests/asyncapi/base/v3_0_0/__init__.py | 0 tests/asyncapi/base/v3_0_0/naming.py | 399 ++++++++++++++++++ tests/asyncapi/rabbit/v2_6_0/__init__.py | 3 + .../rabbit/{ => v2_6_0}/test_arguments.py | 0 .../rabbit/{ => v2_6_0}/test_connection.py | 0 .../rabbit/{ => v2_6_0}/test_fastapi.py | 0 .../rabbit/{ => v2_6_0}/test_naming.py | 0 .../rabbit/{ => v2_6_0}/test_publisher.py | 0 .../rabbit/{ => v2_6_0}/test_router.py | 0 .../rabbit/{ => v2_6_0}/test_security.py | 0 tests/asyncapi/rabbit/v3_0_0/__init__.py | 3 + tests/asyncapi/rabbit/v3_0_0/test_naming.py | 107 +++++ 12 files changed, 512 insertions(+) create mode 100644 tests/asyncapi/base/v3_0_0/__init__.py create mode 100644 tests/asyncapi/base/v3_0_0/naming.py create mode 100644 tests/asyncapi/rabbit/v2_6_0/__init__.py rename tests/asyncapi/rabbit/{ => v2_6_0}/test_arguments.py (100%) rename tests/asyncapi/rabbit/{ => v2_6_0}/test_connection.py (100%) rename tests/asyncapi/rabbit/{ => v2_6_0}/test_fastapi.py (100%) rename tests/asyncapi/rabbit/{ => v2_6_0}/test_naming.py (100%) rename tests/asyncapi/rabbit/{ => v2_6_0}/test_publisher.py (100%) rename tests/asyncapi/rabbit/{ => v2_6_0}/test_router.py (100%) rename tests/asyncapi/rabbit/{ => v2_6_0}/test_security.py (100%) create mode 100644 tests/asyncapi/rabbit/v3_0_0/__init__.py create mode 100644 tests/asyncapi/rabbit/v3_0_0/test_naming.py diff --git a/tests/asyncapi/base/v3_0_0/__init__.py b/tests/asyncapi/base/v3_0_0/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/asyncapi/base/v3_0_0/naming.py b/tests/asyncapi/base/v3_0_0/naming.py new file mode 100644 index 0000000000..105ba45e0a --- /dev/null +++ b/tests/asyncapi/base/v3_0_0/naming.py @@ -0,0 +1,399 @@ +from typing import Any, Type + +from dirty_equals import Contains, IsStr +from pydantic import create_model + +from faststream import FastStream +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.broker.core.usecase import BrokerUsecase + + +class BaseNaming: + broker_class: Type[BrokerUsecase[Any, Any]] + + +class SubscriberNaming(BaseNaming): + def test_subscriber_naming(self): + broker = self.broker_class() + + @broker.subscriber("test") + async def handle_user_created(msg: str): ... + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert list(schema["channels"].keys()) == [ + IsStr(regex=r"test[\w:]*:HandleUserCreated") + ] + + assert list(schema["components"]["messages"].keys()) == [ + IsStr(regex=r"test[\w:]*:HandleUserCreated:Message") + ] + + assert list(schema["components"]["schemas"].keys()) == [ + "HandleUserCreated:Message:Payload" + ] + + def test_pydantic_subscriber_naming(self): + broker = self.broker_class() + + @broker.subscriber("test") + async def handle_user_created(msg: create_model("SimpleModel")): ... + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert list(schema["channels"].keys()) == [ + IsStr(regex=r"test[\w:]*:HandleUserCreated") + ] + + assert list(schema["components"]["messages"].keys()) == [ + IsStr(regex=r"test[\w:]*:HandleUserCreated:Message") + ] + + assert list(schema["components"]["schemas"].keys()) == ["SimpleModel"] + + def test_multi_subscribers_naming(self): + broker = self.broker_class() + + @broker.subscriber("test") + @broker.subscriber("test2") + async def handle_user_created(msg: str): ... + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert list(schema["channels"].keys()) == [ + IsStr(regex=r"test[\w:]*:HandleUserCreated"), + IsStr(regex=r"test2[\w:]*:HandleUserCreated"), + ] + + assert list(schema["components"]["messages"].keys()) == [ + IsStr(regex=r"test[\w:]*:HandleUserCreated:Message"), + IsStr(regex=r"test2[\w:]*:HandleUserCreated:Message"), + ] + + assert list(schema["components"]["schemas"].keys()) == [ + "HandleUserCreated:Message:Payload" + ] + + def test_subscriber_naming_manual(self): + broker = self.broker_class() + + @broker.subscriber("test", title="custom") + async def handle_user_created(msg: str): ... + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert list(schema["channels"].keys()) == ["custom"] + + assert list(schema["components"]["messages"].keys()) == ["custom:Message"] + + assert list(schema["components"]["schemas"].keys()) == [ + "custom:Message:Payload" + ] + + def test_subscriber_naming_default(self): + broker = self.broker_class() + + broker.subscriber("test") + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert list(schema["channels"].keys()) == [ + IsStr(regex=r"test[\w:]*:Subscriber") + ] + + assert list(schema["components"]["messages"].keys()) == [ + IsStr(regex=r"test[\w:]*:Subscriber:Message") + ] + + for key, v in schema["components"]["schemas"].items(): + assert key == "Subscriber:Message:Payload" + assert v == {"title": key} + + def test_subscriber_naming_default_with_title(self): + broker = self.broker_class() + + broker.subscriber("test", title="custom") + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert list(schema["channels"].keys()) == ["custom"] + + assert list(schema["components"]["messages"].keys()) == ["custom:Message"] + + assert list(schema["components"]["schemas"].keys()) == [ + "custom:Message:Payload" + ] + + assert schema["components"]["schemas"]["custom:Message:Payload"] == { + "title": "custom:Message:Payload" + } + + def test_multi_subscribers_naming_default(self): + broker = self.broker_class() + + @broker.subscriber("test") + async def handle_user_created(msg: str): ... + + broker.subscriber("test2") + broker.subscriber("test3") + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert list(schema["channels"].keys()) == [ + IsStr(regex=r"test[\w:]*:HandleUserCreated"), + IsStr(regex=r"test2[\w:]*:Subscriber"), + IsStr(regex=r"test3[\w:]*:Subscriber"), + ] + + assert list(schema["components"]["messages"].keys()) == [ + IsStr(regex=r"test[\w:]*:HandleUserCreated:Message"), + IsStr(regex=r"test2[\w:]*:Subscriber:Message"), + IsStr(regex=r"test3[\w:]*:Subscriber:Message"), + ] + + assert list(schema["components"]["schemas"].keys()) == [ + "HandleUserCreated:Message:Payload", + "Subscriber:Message:Payload", + ] + + assert schema["components"]["schemas"]["Subscriber:Message:Payload"] == { + "title": "Subscriber:Message:Payload" + } + + +class FilterNaming(BaseNaming): + def test_subscriber_filter_base(self): + broker = self.broker_class() + + @broker.subscriber("test") + async def handle_user_created(msg: str): ... + + @broker.subscriber("test") + async def handle_user_id(msg: int): ... + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert list(schema["channels"].keys()) == [ + IsStr(regex=r"test[\w:]*:HandleUserCreated") + ] + + assert list(schema["components"]["messages"].keys()) == [ + IsStr(regex=r"test[\w:]*:HandleUserCreated:Message") + ] + + assert list(schema["components"]["schemas"].keys()) == [ + "HandleUserCreated:Message:Payload", + "HandleUserId:Message:Payload", + ] + + def test_subscriber_filter_pydantic(self): + broker = self.broker_class() + + @broker.subscriber("test") + async def handle_user_created(msg: create_model("SimpleModel")): ... + + @broker.subscriber("test") + async def handle_user_id(msg: int): ... + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert list(schema["channels"].keys()) == [ + IsStr(regex=r"test[\w:]*:HandleUserCreated") + ] + + assert list(schema["components"]["messages"].keys()) == [ + IsStr(regex=r"test[\w:]*:HandleUserCreated:Message") + ] + + assert list(schema["components"]["schemas"].keys()) == [ + "SimpleModel", + "HandleUserId:Message:Payload", + ] + + def test_subscriber_filter_with_title(self): + broker = self.broker_class() + + @broker.subscriber("test", title="custom") + async def handle_user_created(msg: str): ... + + @broker.subscriber("test", title="custom") + async def handle_user_id(msg: int): ... + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert list(schema["channels"].keys()) == ["custom"] + + assert list(schema["components"]["messages"].keys()) == ["custom:Message"] + + assert list(schema["components"]["schemas"].keys()) == [ + "HandleUserCreated:Message:Payload", + "HandleUserId:Message:Payload", + ] + + +class PublisherNaming(BaseNaming): + def test_publisher_naming_base(self): + broker = self.broker_class() + + @broker.publisher("test") + async def handle_user_created() -> str: ... + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] + + assert list(schema["components"]["messages"].keys()) == [ + IsStr(regex=r"test[\w:]*:Publisher:Message") + ] + + assert list(schema["components"]["schemas"].keys()) == [ + IsStr(regex=r"test[\w:]*:Publisher:Message:Payload") + ] + + def test_publisher_naming_pydantic(self): + broker = self.broker_class() + + @broker.publisher("test") + async def handle_user_created() -> create_model("SimpleModel"): ... + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] + + assert list(schema["components"]["messages"].keys()) == [ + IsStr(regex=r"test[\w:]*:Publisher:Message") + ] + + assert list(schema["components"]["schemas"].keys()) == [ + "SimpleModel", + ] + + def test_publisher_manual_naming(self): + broker = self.broker_class() + + @broker.publisher("test", title="custom") + async def handle_user_created() -> str: ... + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert list(schema["channels"].keys()) == ["custom"] + + assert list(schema["components"]["messages"].keys()) == ["custom:Message"] + + assert list(schema["components"]["schemas"].keys()) == [ + "custom:Message:Payload" + ] + + def test_publisher_with_schema_naming(self): + broker = self.broker_class() + + @broker.publisher("test", schema=str) + async def handle_user_created(): ... + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] + + assert list(schema["components"]["messages"].keys()) == [ + IsStr(regex=r"test[\w:]*:Publisher:Message") + ] + + assert list(schema["components"]["schemas"].keys()) == [ + IsStr(regex=r"test[\w:]*:Publisher:Message:Payload") + ] + + def test_publisher_manual_naming_with_schema(self): + broker = self.broker_class() + + @broker.publisher("test", title="custom", schema=str) + async def handle_user_created(): ... + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert list(schema["channels"].keys()) == ["custom"] + + assert list(schema["components"]["messages"].keys()) == ["custom:Message"] + + assert list(schema["components"]["schemas"].keys()) == [ + "custom:Message:Payload" + ] + + def test_multi_publishers_naming(self): + broker = self.broker_class() + + @broker.publisher("test") + @broker.publisher("test2") + async def handle_user_created() -> str: ... + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + names = list(schema["channels"].keys()) + assert names == Contains( + IsStr(regex=r"test2[\w:]*:Publisher"), + IsStr(regex=r"test[\w:]*:Publisher"), + ), names + + messages = list(schema["components"]["messages"].keys()) + assert messages == Contains( + IsStr(regex=r"test2[\w:]*:Publisher:Message"), + IsStr(regex=r"test[\w:]*:Publisher:Message"), + ), messages + + payloads = list(schema["components"]["schemas"].keys()) + assert payloads == Contains( + IsStr(regex=r"test2[\w:]*:Publisher:Message:Payload"), + IsStr(regex=r"test[\w:]*:Publisher:Message:Payload"), + ), payloads + + def test_multi_publisher_usages(self): + broker = self.broker_class() + + pub = broker.publisher("test") + + @pub + async def handle_user_created() -> str: ... + + @pub + async def handle() -> int: ... + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert list(schema["channels"].keys()) == [ + IsStr(regex=r"test[\w:]*:Publisher"), + ] + + assert list(schema["components"]["messages"].keys()) == [ + IsStr(regex=r"test[\w:]*:Publisher:Message"), + ] + + assert list(schema["components"]["schemas"].keys()) == [ + "HandleUserCreated:Publisher:Message:Payload", + "Handle:Publisher:Message:Payload", + ], list(schema["components"]["schemas"].keys()) + + def test_multi_publisher_usages_with_custom(self): + broker = self.broker_class() + + pub = broker.publisher("test", title="custom") + + @pub + async def handle_user_created() -> str: ... + + @pub + async def handle() -> int: ... + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert list(schema["channels"].keys()) == ["custom"] + + assert list(schema["components"]["messages"].keys()) == ["custom:Message"] + + assert list(schema["components"]["schemas"].keys()) == [ + "HandleUserCreated:Publisher:Message:Payload", + "Handle:Publisher:Message:Payload", + ] + + +class NamingTestCase(SubscriberNaming, FilterNaming, PublisherNaming): + pass diff --git a/tests/asyncapi/rabbit/v2_6_0/__init__.py b/tests/asyncapi/rabbit/v2_6_0/__init__.py new file mode 100644 index 0000000000..ebec43fcd5 --- /dev/null +++ b/tests/asyncapi/rabbit/v2_6_0/__init__.py @@ -0,0 +1,3 @@ +import pytest + +pytest.importorskip("aio_pika") diff --git a/tests/asyncapi/rabbit/test_arguments.py b/tests/asyncapi/rabbit/v2_6_0/test_arguments.py similarity index 100% rename from tests/asyncapi/rabbit/test_arguments.py rename to tests/asyncapi/rabbit/v2_6_0/test_arguments.py diff --git a/tests/asyncapi/rabbit/test_connection.py b/tests/asyncapi/rabbit/v2_6_0/test_connection.py similarity index 100% rename from tests/asyncapi/rabbit/test_connection.py rename to tests/asyncapi/rabbit/v2_6_0/test_connection.py diff --git a/tests/asyncapi/rabbit/test_fastapi.py b/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py similarity index 100% rename from tests/asyncapi/rabbit/test_fastapi.py rename to tests/asyncapi/rabbit/v2_6_0/test_fastapi.py diff --git a/tests/asyncapi/rabbit/test_naming.py b/tests/asyncapi/rabbit/v2_6_0/test_naming.py similarity index 100% rename from tests/asyncapi/rabbit/test_naming.py rename to tests/asyncapi/rabbit/v2_6_0/test_naming.py diff --git a/tests/asyncapi/rabbit/test_publisher.py b/tests/asyncapi/rabbit/v2_6_0/test_publisher.py similarity index 100% rename from tests/asyncapi/rabbit/test_publisher.py rename to tests/asyncapi/rabbit/v2_6_0/test_publisher.py diff --git a/tests/asyncapi/rabbit/test_router.py b/tests/asyncapi/rabbit/v2_6_0/test_router.py similarity index 100% rename from tests/asyncapi/rabbit/test_router.py rename to tests/asyncapi/rabbit/v2_6_0/test_router.py diff --git a/tests/asyncapi/rabbit/test_security.py b/tests/asyncapi/rabbit/v2_6_0/test_security.py similarity index 100% rename from tests/asyncapi/rabbit/test_security.py rename to tests/asyncapi/rabbit/v2_6_0/test_security.py diff --git a/tests/asyncapi/rabbit/v3_0_0/__init__.py b/tests/asyncapi/rabbit/v3_0_0/__init__.py new file mode 100644 index 0000000000..ebec43fcd5 --- /dev/null +++ b/tests/asyncapi/rabbit/v3_0_0/__init__.py @@ -0,0 +1,3 @@ +import pytest + +pytest.importorskip("aio_pika") diff --git a/tests/asyncapi/rabbit/v3_0_0/test_naming.py b/tests/asyncapi/rabbit/v3_0_0/test_naming.py new file mode 100644 index 0000000000..8ae42a4cfd --- /dev/null +++ b/tests/asyncapi/rabbit/v3_0_0/test_naming.py @@ -0,0 +1,107 @@ +from typing import Type + +from faststream import FastStream +from faststream.asyncapi.generate import get_app_schema +from faststream.rabbit import RabbitBroker +from tests.asyncapi.base.v3_0_0.naming import NamingTestCase + + +class TestNaming(NamingTestCase): + broker_class: Type[RabbitBroker] = RabbitBroker + + def test_subscriber_with_exchange(self): + broker = self.broker_class() + + @broker.subscriber("test", "exchange") + async def handle(): ... + + schema = get_app_schema(FastStream(broker)).to_jsonable() + + assert list(schema["channels"].keys()) == ["test:exchange:Handle"] + + assert list(schema["components"]["messages"].keys()) == [ + "test:exchange:Handle:Message" + ] + + def test_publisher_with_exchange(self): + broker = self.broker_class() + + @broker.publisher("test", "exchange") + async def handle(): ... + + schema = get_app_schema(FastStream(broker)).to_jsonable() + + assert list(schema["channels"].keys()) == ["test:exchange:Publisher"] + + assert list(schema["components"]["messages"].keys()) == [ + "test:exchange:Publisher:Message" + ] + + def test_base(self): + broker = self.broker_class() + + @broker.subscriber("test") + async def handle(): ... + + schema = get_app_schema(FastStream(broker)).to_jsonable() + + assert ( + schema + == { + "asyncapi": "2.6.0", + "defaultContentType": "application/json", + "info": {"title": "FastStream", "version": "0.1.0", "description": ""}, + "servers": { + "development": { + "url": "amqp://guest:guest@localhost:5672/", # pragma: allowlist secret + "protocol": "amqp", + "protocolVersion": "0.9.1", + } + }, + "channels": { + "test:_:Handle": { + "servers": ["development"], + "bindings": { + "amqp": { + "is": "routingKey", + "bindingVersion": "0.2.0", + "queue": { + "name": "test", + "durable": False, + "exclusive": False, + "autoDelete": False, + "vhost": "/", + }, + "exchange": {"type": "default", "vhost": "/"}, + } + }, + "subscribe": { + "bindings": { + "amqp": { + "cc": "test", + "ack": True, + "bindingVersion": "0.2.0", + } + }, + "message": { + "$ref": "#/components/messages/test:_:Handle:Message" + }, + }, + } + }, + "components": { + "messages": { + "test:_:Handle:Message": { + "title": "test:_:Handle:Message", + "correlationId": { + "location": "$message.header#/correlation_id" + }, + "payload": {"$ref": "#/components/schemas/EmptyPayload"}, + } + }, + "schemas": { + "EmptyPayload": {"title": "EmptyPayload", "type": "null"} + }, + }, + } + ) From c969e354155f1825586ec3e4d04808578fbb8f29 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 28 Jul 2024 22:30:47 +0300 Subject: [PATCH 007/245] asyncapi generation typo fix --- faststream/asyncapi/generate.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/faststream/asyncapi/generate.py b/faststream/asyncapi/generate.py index 398ee3b290..4962f8c82c 100644 --- a/faststream/asyncapi/generate.py +++ b/faststream/asyncapi/generate.py @@ -13,5 +13,3 @@ def get_app_schema(app: "AsyncAPIApplication") -> BaseSchema: if app.asyncapi_version == AsyncAPIVersion.v2_6: return get_app_schema_v2_6(app) - - raise NotImplementedError(f"Async API version not supported: {app.asyncapi_version}") From 1912c40df30a2ebb8e5eddbc464e2eb020c6e370 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 28 Jul 2024 22:31:51 +0300 Subject: [PATCH 008/245] AsyncAPI RabbitMQ specific naming tests fix --- tests/asyncapi/rabbit/v3_0_0/test_naming.py | 124 ++++++++++++-------- 1 file changed, 72 insertions(+), 52 deletions(-) diff --git a/tests/asyncapi/rabbit/v3_0_0/test_naming.py b/tests/asyncapi/rabbit/v3_0_0/test_naming.py index 8ae42a4cfd..611359df71 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_naming.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_naming.py @@ -2,6 +2,7 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.version import AsyncAPIVersion from faststream.rabbit import RabbitBroker from tests.asyncapi.base.v3_0_0.naming import NamingTestCase @@ -15,7 +16,7 @@ def test_subscriber_with_exchange(self): @broker.subscriber("test", "exchange") async def handle(): ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() assert list(schema["channels"].keys()) == ["test:exchange:Handle"] @@ -29,7 +30,7 @@ def test_publisher_with_exchange(self): @broker.publisher("test", "exchange") async def handle(): ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() assert list(schema["channels"].keys()) == ["test:exchange:Publisher"] @@ -43,65 +44,84 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() assert ( - schema - == { - "asyncapi": "2.6.0", - "defaultContentType": "application/json", - "info": {"title": "FastStream", "version": "0.1.0", "description": ""}, - "servers": { - "development": { - "url": "amqp://guest:guest@localhost:5672/", # pragma: allowlist secret - "protocol": "amqp", - "protocolVersion": "0.9.1", - } - }, - "channels": { - "test:_:Handle": { - "servers": ["development"], - "bindings": { - "amqp": { - "is": "routingKey", - "bindingVersion": "0.2.0", - "queue": { - "name": "test", - "durable": False, - "exclusive": False, - "autoDelete": False, - "vhost": "/", - }, - "exchange": {"type": "default", "vhost": "/"}, - } - }, - "subscribe": { + schema + == { + "asyncapi": "3.0.0", + "defaultContentType": "application/json", + "info": {"title": "FastStream", "version": "0.1.0", "description": ""}, + "servers": { + "development": { + "host": "guest:guest@localhost:5672", # pragma: allowlist secret + "pathname": "/", + "protocol": "amqp", + "protocolVersion": "0.9.1", + } + }, + "channels": { + "test:_:Handle": { + "address": "test:_:Handle", + "servers": [ + { + "$ref": "#/servers/development", + } + ], "bindings": { "amqp": { - "cc": "test", - "ack": True, + "is": "routingKey", "bindingVersion": "0.2.0", + "queue": { + "name": "test", + "durable": False, + "exclusive": False, + "autoDelete": False, + "vhost": "/", + }, + "exchange": {"type": "default", "vhost": "/"}, } }, - "message": { - "$ref": "#/components/messages/test:_:Handle:Message" - }, - }, - } - }, - "components": { - "messages": { - "test:_:Handle:Message": { - "title": "test:_:Handle:Message", - "correlationId": { - "location": "$message.header#/correlation_id" + "messages": { + "SubscribeMessage": { + "$ref": "#/components/messages/test:_:Handle:SubscribeMessage" + } }, - "payload": {"$ref": "#/components/schemas/EmptyPayload"}, } }, - "schemas": { - "EmptyPayload": {"title": "EmptyPayload", "type": "null"} + 'operations': { + 'test:_:HandleSubscribe': { + 'action': 'receive', + 'bindings': { + 'amqp': { + 'ack': True, + 'bindingVersion': '0.2.0', + 'cc': 'test', + }, + }, + 'channel': { + '$ref': '#/channels/test:_:Handle', + }, + 'messages': [ + { + '$ref': '#/channels/test:_:Handle/messages/SubscribeMessage', + }, + ], + }, + }, + "components": { + "messages": { + "test:_:Handle:Message": { + "title": "test:_:Handle:Message", + "correlationId": { + "location": "$message.header#/correlation_id" + }, + "payload": {"$ref": "#/components/schemas/EmptyPayload"}, + } + }, + "schemas": { + "EmptyPayload": {"title": "EmptyPayload", "type": "null"} + }, }, - }, - } + } ) From e2d5a28bf096715ad093d516b94f70d52559e9cd Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Tue, 30 Jul 2024 19:17:01 +0300 Subject: [PATCH 009/245] AsyncAPI Kafka specific naming tests fix --- tests/asyncapi/kafka/v3_0_0/__init__.py | 0 tests/asyncapi/kafka/v3_0_0/test_naming.py | 72 ++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 tests/asyncapi/kafka/v3_0_0/__init__.py create mode 100644 tests/asyncapi/kafka/v3_0_0/test_naming.py diff --git a/tests/asyncapi/kafka/v3_0_0/__init__.py b/tests/asyncapi/kafka/v3_0_0/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/asyncapi/kafka/v3_0_0/test_naming.py b/tests/asyncapi/kafka/v3_0_0/test_naming.py new file mode 100644 index 0000000000..7ba238de44 --- /dev/null +++ b/tests/asyncapi/kafka/v3_0_0/test_naming.py @@ -0,0 +1,72 @@ +from faststream import FastStream +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.kafka import KafkaBroker +from tests.asyncapi.base.naming import NamingTestCase + + +class TestNaming(NamingTestCase): + broker_class = KafkaBroker + + def test_base(self): + broker = self.broker_class() + + @broker.subscriber("test") + async def handle(): ... + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert schema == { + "asyncapi": "3.0.0", + "defaultContentType": "application/json", + "info": {"title": "FastStream", "version": "0.1.0", "description": ""}, + "servers": { + "development": { + "host": "localhost", + "pathname": "", + "protocol": "kafka", + "protocolVersion": "auto", + } + }, + "channels": { + "address": "test:Handle", + "test:Handle": { + "servers": [ + { + "$ref": "#/servers/development", + } + ], + "bindings": {"kafka": {"topic": "test", "bindingVersion": "0.4.0"}}, + "messages": { + "SubscribeMessage": { + "$ref": "#/components/messages/test:Handle:SubscribeMessage", + }, + }, + } + }, + "operations": { + "test:HandleSubscribe": { + "action": "receive", + "channel": { + "$ref": "#/channels/test:Handle", + }, + "messages": [ + { + "$ref": "#/channels/test:Handle/messages/SubscribeMessage", + } + ], + } + }, + "components": { + "messages": { + "test:Handle:Message": { + "title": "test:Handle:Message", + "correlationId": { + "location": "$message.header#/correlation_id" + }, + "payload": {"$ref": "#/components/schemas/EmptyPayload"}, + } + }, + "schemas": {"EmptyPayload": {"title": "EmptyPayload", "type": "null"}}, + }, + } From 87251eb7fafafd9a0495197d9877c32ce5726548 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Tue, 30 Jul 2024 20:35:03 +0300 Subject: [PATCH 010/245] AsyncAPI 3.0.0 Redis specific naming tests --- tests/asyncapi/kafka/v3_0_0/test_naming.py | 2 +- tests/asyncapi/redis/v3_0_0/__init__.py | 0 tests/asyncapi/redis/v3_0_0/test_naming.py | 112 +++++++++++++++++++++ 3 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 tests/asyncapi/redis/v3_0_0/__init__.py create mode 100644 tests/asyncapi/redis/v3_0_0/test_naming.py diff --git a/tests/asyncapi/kafka/v3_0_0/test_naming.py b/tests/asyncapi/kafka/v3_0_0/test_naming.py index 7ba238de44..7a94bbcd25 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_naming.py +++ b/tests/asyncapi/kafka/v3_0_0/test_naming.py @@ -29,8 +29,8 @@ async def handle(): ... } }, "channels": { - "address": "test:Handle", "test:Handle": { + "address": "test:Handle", "servers": [ { "$ref": "#/servers/development", diff --git a/tests/asyncapi/redis/v3_0_0/__init__.py b/tests/asyncapi/redis/v3_0_0/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/asyncapi/redis/v3_0_0/test_naming.py b/tests/asyncapi/redis/v3_0_0/test_naming.py new file mode 100644 index 0000000000..e33db75211 --- /dev/null +++ b/tests/asyncapi/redis/v3_0_0/test_naming.py @@ -0,0 +1,112 @@ +import pytest + +from faststream import FastStream +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.redis import RedisBroker +from tests.asyncapi.base.naming import NamingTestCase + + +class TestNaming(NamingTestCase): + broker_class = RedisBroker + + def test_base(self): + broker = self.broker_class() + + @broker.subscriber("test") + async def handle(): ... + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert schema == { + "asyncapi": "3.0.0", + "channels": { + "test:Handle": { + "address": "test:Handle", + "bindings": { + "redis": { + "bindingVersion": "custom", + "channel": "test", + "method": "subscribe", + } + }, + "servers": [ + { + "$ref": "#/servers/development" + } + ], + "messages": { + "SubscribeMessage": {"$ref": "#/components/messages/test:Handle:SubscribeMessage"} + }, + } + }, + "operations": { + "test:HandleSubscribe": { + "action": "receive", + "channel": { + "$ref": "#/channels/test:Handle", + }, + "messages": [ + { + "$ref": "#/channels/test:Handle/messages/SubscribeMessage" + } + ] + } + }, + "components": { + "messages": { + "test:Handle:Message": { + "correlationId": { + "location": "$message.header#/correlation_id" + }, + "payload": {"$ref": "#/components/schemas/EmptyPayload"}, + "title": "test:Handle:Message", + } + }, + "schemas": {"EmptyPayload": {"title": "EmptyPayload", "type": "null"}}, + }, + "defaultContentType": "application/json", + "info": {"description": "", "title": "FastStream", "version": "0.1.0"}, + "servers": { + "development": { + "protocol": "redis", + "protocolVersion": "custom", + "host": "localhost:6379", + "pathname": "", + } + }, + }, schema + + @pytest.mark.parametrize( + "args", + ( # noqa: PT007 + pytest.param({"channel": "test"}, id="channel"), + pytest.param({"list": "test"}, id="list"), + pytest.param({"stream": "test"}, id="stream"), + ), + ) + def test_subscribers_variations(self, args): + broker = self.broker_class() + + @broker.subscriber(**args) + async def handle(): ... + + schema = get_app_schema(FastStream(broker)) + assert list(schema.channels.keys()) == ["test:Handle"] + + @pytest.mark.parametrize( + "args", + ( # noqa: PT007 + pytest.param({"channel": "test"}, id="channel"), + pytest.param({"list": "test"}, id="list"), + pytest.param({"stream": "test"}, id="stream"), + ), + ) + def test_publisher_variations(self, args): + broker = self.broker_class() + + @broker.publisher(**args) + async def handle(): ... + + schema = get_app_schema(FastStream(broker)) + assert list(schema.channels.keys()) == ["test:Publisher"] From 6f858a228445b38fe93334ea950b2c973ac33391 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Tue, 30 Jul 2024 20:55:09 +0300 Subject: [PATCH 011/245] AsyncAPI 3.0.0 Nats naming tests --- tests/asyncapi/nats/v3_0_0/__init__.py | 0 tests/asyncapi/nats/v3_0_0/test_naming.py | 74 +++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 tests/asyncapi/nats/v3_0_0/__init__.py create mode 100644 tests/asyncapi/nats/v3_0_0/test_naming.py diff --git a/tests/asyncapi/nats/v3_0_0/__init__.py b/tests/asyncapi/nats/v3_0_0/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/asyncapi/nats/v3_0_0/test_naming.py b/tests/asyncapi/nats/v3_0_0/test_naming.py new file mode 100644 index 0000000000..0f0266af9c --- /dev/null +++ b/tests/asyncapi/nats/v3_0_0/test_naming.py @@ -0,0 +1,74 @@ +from faststream import FastStream +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.nats import NatsBroker +from tests.asyncapi.base.naming import NamingTestCase + + +class TestNaming(NamingTestCase): + broker_class = NatsBroker + + def test_base(self): + broker = self.broker_class() + + @broker.subscriber("test") + async def handle(): ... + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert schema == { + "asyncapi": "3.0.0", + "defaultContentType": "application/json", + "info": {"title": "FastStream", "version": "0.1.0", "description": ""}, + "servers": { + "development": { + "host": "localhost:4222", + "pathname": "", + "protocol": "nats", + "protocolVersion": "custom", + } + }, + "channels": { + "test:Handle": { + "address": "test:Handle", + "servers": [ + { + "$ref": "#/servers/development", + } + ], + "bindings": { + "nats": {"subject": "test", "bindingVersion": "custom"} + }, + "messages": { + "SubscribeMessage": { + "$ref": "#/components/messages/test:Handle:SubscribeMessage", + }, + }, + } + }, + "operations": { + "test:HandleSubscribe": { + "action": "receive", + "channel": { + "$ref": "#/channels/test:Handle", + }, + "messages": [ + { + "$ref": "#/channels/test:Handle/messages/SubscribeMessage", + } + ], + } + }, + "components": { + "messages": { + "test:Handle:Message": { + "title": "test:Handle:Message", + "correlationId": { + "location": "$message.header#/correlation_id" + }, + "payload": {"$ref": "#/components/schemas/EmptyPayload"}, + } + }, + "schemas": {"EmptyPayload": {"title": "EmptyPayload", "type": "null"}}, + }, + } From 5eb290c8a9124a0ae69badb0759b16eae3cc3b69 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Tue, 30 Jul 2024 21:06:59 +0300 Subject: [PATCH 012/245] AsyncAPI 3.0.0 Confluent naming tests --- tests/asyncapi/confluent/v3_0_0/__init__.py | 0 .../asyncapi/confluent/v3_0_0/test_naming.py | 72 +++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 tests/asyncapi/confluent/v3_0_0/__init__.py create mode 100644 tests/asyncapi/confluent/v3_0_0/test_naming.py diff --git a/tests/asyncapi/confluent/v3_0_0/__init__.py b/tests/asyncapi/confluent/v3_0_0/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/asyncapi/confluent/v3_0_0/test_naming.py b/tests/asyncapi/confluent/v3_0_0/test_naming.py new file mode 100644 index 0000000000..4747d69be1 --- /dev/null +++ b/tests/asyncapi/confluent/v3_0_0/test_naming.py @@ -0,0 +1,72 @@ +from faststream import FastStream +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.confluent import KafkaBroker +from tests.asyncapi.base.naming import NamingTestCase + + +class TestNaming(NamingTestCase): + broker_class = KafkaBroker + + def test_base(self): + broker = self.broker_class() + + @broker.subscriber("test") + async def handle(): ... + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert schema == { + "asyncapi": "3.0.0", + "defaultContentType": "application/json", + "info": {"title": "FastStream", "version": "0.1.0", "description": ""}, + "servers": { + "development": { + "host": "localhost", + "pathname": "", + "protocol": "kafka", + "protocolVersion": "auto", + } + }, + "channels": { + "test:Handle": { + "address": "test:Handle", + "servers": [ + { + "$ref": "#/servers/development", + } + ], + "bindings": {"kafka": {"topic": "test", "bindingVersion": "0.4.0"}}, + "messages": { + "SubscribeMessage": { + "$ref": "#/components/messages/test:Handle:SubscribeMessage", + }, + }, + } + }, + "operations": { + "test:HandleSubscribe": { + "action": "receive", + "channel": { + "$ref": "#/channels/test:Handle", + }, + "messages": [ + { + "$ref": "#/channels/test:Handle/messages/SubscribeMessage", + } + ], + } + }, + "components": { + "messages": { + "test:Handle:Message": { + "title": "test:Handle:Message", + "correlationId": { + "location": "$message.header#/correlation_id" + }, + "payload": {"$ref": "#/components/schemas/EmptyPayload"}, + } + }, + "schemas": {"EmptyPayload": {"title": "EmptyPayload", "type": "null"}}, + }, + } From 769d2dcbc8be34a983c34018e5803c6def0dd944 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Tue, 30 Jul 2024 22:26:35 +0300 Subject: [PATCH 013/245] AsyncAPI 3.0.0 naming tests fix --- tests/asyncapi/confluent/v3_0_0/test_naming.py | 2 +- tests/asyncapi/kafka/v3_0_0/test_naming.py | 2 +- tests/asyncapi/nats/v3_0_0/test_naming.py | 2 +- tests/asyncapi/redis/v3_0_0/test_naming.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/asyncapi/confluent/v3_0_0/test_naming.py b/tests/asyncapi/confluent/v3_0_0/test_naming.py index 4747d69be1..5a05a36058 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_naming.py +++ b/tests/asyncapi/confluent/v3_0_0/test_naming.py @@ -2,7 +2,7 @@ from faststream.asyncapi.generate import get_app_schema from faststream.asyncapi.version import AsyncAPIVersion from faststream.confluent import KafkaBroker -from tests.asyncapi.base.naming import NamingTestCase +from tests.asyncapi.base.v3_0_0.naming import NamingTestCase class TestNaming(NamingTestCase): diff --git a/tests/asyncapi/kafka/v3_0_0/test_naming.py b/tests/asyncapi/kafka/v3_0_0/test_naming.py index 7a94bbcd25..7c7ccb6dc8 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_naming.py +++ b/tests/asyncapi/kafka/v3_0_0/test_naming.py @@ -2,7 +2,7 @@ from faststream.asyncapi.generate import get_app_schema from faststream.asyncapi.version import AsyncAPIVersion from faststream.kafka import KafkaBroker -from tests.asyncapi.base.naming import NamingTestCase +from tests.asyncapi.base.v3_0_0.naming import NamingTestCase class TestNaming(NamingTestCase): diff --git a/tests/asyncapi/nats/v3_0_0/test_naming.py b/tests/asyncapi/nats/v3_0_0/test_naming.py index 0f0266af9c..87d44e5d32 100644 --- a/tests/asyncapi/nats/v3_0_0/test_naming.py +++ b/tests/asyncapi/nats/v3_0_0/test_naming.py @@ -2,7 +2,7 @@ from faststream.asyncapi.generate import get_app_schema from faststream.asyncapi.version import AsyncAPIVersion from faststream.nats import NatsBroker -from tests.asyncapi.base.naming import NamingTestCase +from tests.asyncapi.base.v3_0_0.naming import NamingTestCase class TestNaming(NamingTestCase): diff --git a/tests/asyncapi/redis/v3_0_0/test_naming.py b/tests/asyncapi/redis/v3_0_0/test_naming.py index e33db75211..373a3c82c2 100644 --- a/tests/asyncapi/redis/v3_0_0/test_naming.py +++ b/tests/asyncapi/redis/v3_0_0/test_naming.py @@ -4,7 +4,7 @@ from faststream.asyncapi.generate import get_app_schema from faststream.asyncapi.version import AsyncAPIVersion from faststream.redis import RedisBroker -from tests.asyncapi.base.naming import NamingTestCase +from tests.asyncapi.base.v3_0_0.naming import NamingTestCase class TestNaming(NamingTestCase): From eb42a338fedbe18973c2f0fcb9df7e91146f99d5 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Wed, 31 Jul 2024 10:25:37 +0300 Subject: [PATCH 014/245] AsyncAPI 3.0.0 publisher message rename --- faststream/asyncapi/generate.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/faststream/asyncapi/generate.py b/faststream/asyncapi/generate.py index 4962f8c82c..c0b79442ca 100644 --- a/faststream/asyncapi/generate.py +++ b/faststream/asyncapi/generate.py @@ -13,3 +13,5 @@ def get_app_schema(app: "AsyncAPIApplication") -> BaseSchema: if app.asyncapi_version == AsyncAPIVersion.v2_6: return get_app_schema_v2_6(app) + + raise NotImplementedError From 37bcb3bba2c9fcbc0f9f9f8d15e45ad3ac72d9ad Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Wed, 31 Jul 2024 11:09:42 +0300 Subject: [PATCH 015/245] AsyncAPI 3.0.0 RabbitMQ publisher tests --- tests/asyncapi/base/v3_0_0/naming.py | 2 +- tests/asyncapi/base/v3_0_0/publisher.py | 129 +++++++++ .../asyncapi/rabbit/v3_0_0/test_publisher.py | 262 ++++++++++++++++++ 3 files changed, 392 insertions(+), 1 deletion(-) create mode 100644 tests/asyncapi/base/v3_0_0/publisher.py create mode 100644 tests/asyncapi/rabbit/v3_0_0/test_publisher.py diff --git a/tests/asyncapi/base/v3_0_0/naming.py b/tests/asyncapi/base/v3_0_0/naming.py index 105ba45e0a..106dd61309 100644 --- a/tests/asyncapi/base/v3_0_0/naming.py +++ b/tests/asyncapi/base/v3_0_0/naming.py @@ -267,7 +267,7 @@ async def handle_user_created() -> create_model("SimpleModel"): ... assert list(schema["components"]["schemas"].keys()) == [ "SimpleModel", - ] + ], list(schema["components"]["schemas"].keys()) def test_publisher_manual_naming(self): broker = self.broker_class() diff --git a/tests/asyncapi/base/v3_0_0/publisher.py b/tests/asyncapi/base/v3_0_0/publisher.py new file mode 100644 index 0000000000..9dc1df1b76 --- /dev/null +++ b/tests/asyncapi/base/v3_0_0/publisher.py @@ -0,0 +1,129 @@ +from typing import Type + +import pydantic + +from faststream import FastStream +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.broker.core.usecase import BrokerUsecase + + +class PublisherTestcase: + broker_class: Type[BrokerUsecase] + + def build_app(self, broker): + """Patch it to test FastAPI scheme generation too.""" + return FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0) + + def test_publisher_with_description(self): + broker = self.broker_class() + + @broker.publisher("test", description="test description") + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + key = tuple(schema["channels"].keys())[0] # noqa: RUF015 + assert schema["channels"][key]["description"] == "test description" + + def test_basic_publisher(self): + broker = self.broker_class() + + @broker.publisher("test") + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + key = tuple(schema["channels"].keys())[0] # noqa: RUF015 + assert schema["channels"][key].get("description") is None + assert schema["operations"][key] is not None + + payload = schema["components"]["schemas"] + for v in payload.values(): + assert v == {} + + def test_none_publisher(self): + broker = self.broker_class() + + @broker.publisher("test") + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + payload = schema["components"]["schemas"] + for v in payload.values(): + assert v == {} + + def test_typed_publisher(self): + broker = self.broker_class() + + @broker.publisher("test") + async def handle(msg) -> int: ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + payload = schema["components"]["schemas"] + for v in payload.values(): + assert v["type"] == "integer" + + def test_pydantic_model_publisher(self): + class User(pydantic.BaseModel): + name: str = "" + id: int + + broker = self.broker_class() + + @broker.publisher("test") + async def handle(msg) -> User: ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + payload = schema["components"]["schemas"] + + for key, v in payload.items(): + assert v == { + "properties": { + "id": {"title": "Id", "type": "integer"}, + "name": {"default": "", "title": "Name", "type": "string"}, + }, + "required": ["id"], + "title": key, + "type": "object", + } + + def test_delayed(self): + broker = self.broker_class() + + pub = broker.publisher("test") + + @pub + async def handle(msg) -> int: ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + payload = schema["components"]["schemas"] + for v in payload.values(): + assert v["type"] == "integer" + + def test_with_schema(self): + broker = self.broker_class() + + broker.publisher("test", title="Custom", schema=int) + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + payload = schema["components"]["schemas"] + for v in payload.values(): + assert v["type"] == "integer" + + def test_not_include(self): + broker = self.broker_class() + + @broker.publisher("test", include_in_schema=False) + @broker.subscriber("in-test", include_in_schema=False) + async def handler(msg: str): + pass + + schema = get_app_schema(self.build_app(broker)) + + assert schema.channels == {}, schema.channels diff --git a/tests/asyncapi/rabbit/v3_0_0/test_publisher.py b/tests/asyncapi/rabbit/v3_0_0/test_publisher.py new file mode 100644 index 0000000000..b5e4011591 --- /dev/null +++ b/tests/asyncapi/rabbit/v3_0_0/test_publisher.py @@ -0,0 +1,262 @@ +from faststream.asyncapi.generate import get_app_schema +from faststream.rabbit import ExchangeType, RabbitBroker, RabbitExchange, RabbitQueue +from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase + + +class TestArguments(PublisherTestcase): + broker_class = RabbitBroker + + def test_just_exchange(self): + broker = self.broker_class("amqp://guest:guest@localhost:5672/vhost") + + @broker.publisher(exchange="test-ex") + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + assert schema["channels"] == { + "_:test-ex:Publisher": { + "address": "_:test-ex:Publisher", + "bindings": { + "amqp": { + "bindingVersion": "0.2.0", + "exchange": { + "autoDelete": False, + "durable": False, + "name": "test-ex", + "type": "direct", + "vhost": "/vhost", + }, + "is": "routingKey", + } + }, + "servers": [ + { + "$ref": "#/servers/development", + } + ], + "messages": { + "Message": { + "$ref": "#/components/messages/_:test-ex:Publisher:Message", + }, + }, + } + }, schema["channels"] + + assert schema["operations"] == { + "_:test-ex:Publisher": { + "action": "send", + "bindings": { + "amqp": { + "ack": True, + "bindingVersion": "0.2.0", + "deliveryMode": 1, + "mandatory": True, + } + }, + "channel": { + "$ref": "#/channels/_:test-ex:Publisher", + }, + "messages": [ + { + "$ref": "#/channels/_:test-ex:Publisher/messages/Message", + }, + ], + }, + } + + def test_publisher_bindings(self): + broker = self.broker_class() + + @broker.publisher( + RabbitQueue("test", auto_delete=True), + RabbitExchange("test-ex", type=ExchangeType.TOPIC), + ) + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + key = tuple(schema["channels"].keys())[0] # noqa: RUF015 + + assert schema["channels"][key]["bindings"] == { + "amqp": { + "bindingVersion": "0.2.0", + "exchange": { + "autoDelete": False, + "durable": False, + "name": "test-ex", + "type": "topic", + "vhost": "/", + }, + "is": "routingKey", + "queue": { + "autoDelete": True, + "durable": False, + "exclusive": False, + "name": "test", + "vhost": "/", + }, + } + } + + def test_useless_queue_bindings(self): + broker = self.broker_class() + + @broker.publisher( + RabbitQueue("test", auto_delete=True), + RabbitExchange("test-ex", type=ExchangeType.FANOUT), + ) + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + assert schema["channels"] == { + "_:test-ex:Publisher": { + "address": "_:test-ex:Publisher", + "bindings": { + "amqp": { + "bindingVersion": "0.2.0", + "exchange": { + "autoDelete": False, + "durable": False, + "name": "test-ex", + "type": "fanout", + "vhost": "/", + }, + "is": "routingKey", + } + }, + "messages": { + "Message": { + "$ref": "#/components/messages/_:test-ex:Publisher:Message" + } + }, + "servers": [ + { + "$ref": "#/servers/development", + } + ], + } + } + + assert schema["operations"] == { + "_:test-ex:Publisher": { + "action": "send", + "channel": { + "$ref": "#/channels/_:test-ex:Publisher", + }, + "messages": [ + { + "$ref": "#/channels/_:test-ex:Publisher/messages/Message" + } + ], + } + } + + def test_reusable_exchange(self): + broker = self.broker_class("amqp://guest:guest@localhost:5672/vhost") + + @broker.publisher(exchange="test-ex", routing_key="key1") + @broker.publisher(exchange="test-ex", routing_key="key2", priority=10) + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + assert schema["channels"] == { + "key1:test-ex:Publisher": { + "address": "key1:test-ex:Publisher", + "bindings": { + "amqp": { + "bindingVersion": "0.2.0", + "exchange": { + "autoDelete": False, + "durable": False, + "name": "test-ex", + "type": "direct", + "vhost": "/vhost", + }, + "is": "routingKey", + } + }, + "servers": [ + { + "$ref": "#/servers/development", + } + ], + 'messages': { + 'Message': { + '$ref': '#/components/messages/key1:test-ex:Publisher:Message', + }, + }, + + }, + "key2:test-ex:Publisher": { + "address": "key2:test-ex:Publisher", + "bindings": { + "amqp": { + "bindingVersion": "0.2.0", + "exchange": { + "autoDelete": False, + "durable": False, + "name": "test-ex", + "type": "direct", + "vhost": "/vhost", + }, + "is": "routingKey", + } + }, + "servers": [ + { + "$ref": "#/servers/development", + } + ], + 'messages': { + 'Message': { + '$ref': '#/components/messages/key2:test-ex:Publisher:Message', + }, + }, + }, + } + + assert schema["operations"] == { + "key1:test-ex:Publisher": { + "action": "send", + "channel": { + "$ref": "#/channels/key1:test-ex:Publisher", + }, + "bindings": { + "amqp": { + "ack": True, + "bindingVersion": "0.2.0", + "cc": "key1", + "deliveryMode": 1, + "mandatory": True, + } + }, + "messages": [ + { + "$ref": "#/channels/key1:test-ex:Publisher/messages/Message" + } + ], + }, + "key2:test-ex:Publisher": { + "action": "send", + "channel": { + "$ref": "#/channels/key2:test-ex:Publisher", + }, + "bindings": { + "amqp": { + "ack": True, + "bindingVersion": "0.2.0", + "cc": "key2", + "deliveryMode": 1, + "priority": 10, + "mandatory": True, + } + }, + "messages": [ + { + "$ref": "#/channels/key2:test-ex:Publisher/messages/Message" + } + ], + }, + } From bb7d2a81819ed2bcf4c8497d9078c467109c3937 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Wed, 31 Jul 2024 20:16:33 +0300 Subject: [PATCH 016/245] AsyncAPI 3.0.0 Kafka publisher tests --- tests/asyncapi/kafka/v3_0_0/test_publisher.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tests/asyncapi/kafka/v3_0_0/test_publisher.py diff --git a/tests/asyncapi/kafka/v3_0_0/test_publisher.py b/tests/asyncapi/kafka/v3_0_0/test_publisher.py new file mode 100644 index 0000000000..f86395b016 --- /dev/null +++ b/tests/asyncapi/kafka/v3_0_0/test_publisher.py @@ -0,0 +1,20 @@ +from faststream.asyncapi.generate import get_app_schema +from faststream.kafka import KafkaBroker +from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase + + +class TestArguments(PublisherTestcase): + broker_class = KafkaBroker + + def test_publisher_bindings(self): + broker = self.broker_class() + + @broker.publisher("test") + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + key = tuple(schema["channels"].keys())[0] # noqa: RUF015 + + assert schema["channels"][key]["bindings"] == { + "kafka": {"bindingVersion": "0.4.0", "topic": "test"} + } From 22715fd57eb30d1819563e2b9dfa9d69e03b89cc Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Wed, 31 Jul 2024 20:18:12 +0300 Subject: [PATCH 017/245] AsyncAPI 3.0.0 Confluent publisher tests --- .../confluent/v3_0_0/test_publisher.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tests/asyncapi/confluent/v3_0_0/test_publisher.py diff --git a/tests/asyncapi/confluent/v3_0_0/test_publisher.py b/tests/asyncapi/confluent/v3_0_0/test_publisher.py new file mode 100644 index 0000000000..7cc53143e0 --- /dev/null +++ b/tests/asyncapi/confluent/v3_0_0/test_publisher.py @@ -0,0 +1,20 @@ +from faststream.asyncapi.generate import get_app_schema +from faststream.confluent import KafkaBroker +from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase + + +class TestArguments(PublisherTestcase): + broker_class = KafkaBroker + + def test_publisher_bindings(self): + broker = self.broker_class() + + @broker.publisher("test") + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + key = tuple(schema["channels"].keys())[0] # noqa: RUF015 + + assert schema["channels"][key]["bindings"] == { + "kafka": {"bindingVersion": "0.4.0", "topic": "test"} + } From 713727afa8906fd0ab4376ba0f6755d11fec2ae4 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Wed, 31 Jul 2024 20:18:59 +0300 Subject: [PATCH 018/245] AsyncAPI 3.0.0 Nats publisher tests --- tests/asyncapi/nats/v3_0_0/test_publisher.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tests/asyncapi/nats/v3_0_0/test_publisher.py diff --git a/tests/asyncapi/nats/v3_0_0/test_publisher.py b/tests/asyncapi/nats/v3_0_0/test_publisher.py new file mode 100644 index 0000000000..7851fce715 --- /dev/null +++ b/tests/asyncapi/nats/v3_0_0/test_publisher.py @@ -0,0 +1,20 @@ +from faststream.asyncapi.generate import get_app_schema +from faststream.nats import NatsBroker +from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase + + +class TestArguments(PublisherTestcase): + broker_class = NatsBroker + + def test_publisher_bindings(self): + broker = self.broker_class() + + @broker.publisher("test") + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + key = tuple(schema["channels"].keys())[0] # noqa: RUF015 + + assert schema["channels"][key]["bindings"] == { + "nats": {"bindingVersion": "custom", "subject": "test"} + }, schema["channels"][key]["bindings"] From f74068fa35a08688d523b53fa66f0220e5ea5b8d Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Wed, 31 Jul 2024 20:19:42 +0300 Subject: [PATCH 019/245] AsyncAPI 3.0.0 Redis publisher tests --- tests/asyncapi/redis/v3_0_0/test_publisher.py | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 tests/asyncapi/redis/v3_0_0/test_publisher.py diff --git a/tests/asyncapi/redis/v3_0_0/test_publisher.py b/tests/asyncapi/redis/v3_0_0/test_publisher.py new file mode 100644 index 0000000000..de7cead72a --- /dev/null +++ b/tests/asyncapi/redis/v3_0_0/test_publisher.py @@ -0,0 +1,50 @@ +from faststream.asyncapi.generate import get_app_schema +from faststream.redis import RedisBroker +from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase + + +class TestArguments(PublisherTestcase): + broker_class = RedisBroker + + def test_channel_publisher(self): + broker = self.broker_class() + + @broker.publisher("test") + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + key = tuple(schema["channels"].keys())[0] # noqa: RUF015 + + assert schema["channels"][key]["bindings"] == { + "redis": { + "bindingVersion": "custom", + "channel": "test", + "method": "publish", + } + } + + def test_list_publisher(self): + broker = self.broker_class() + + @broker.publisher(list="test") + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + key = tuple(schema["channels"].keys())[0] # noqa: RUF015 + + assert schema["channels"][key]["bindings"] == { + "redis": {"bindingVersion": "custom", "channel": "test", "method": "rpush"} + } + + def test_stream_publisher(self): + broker = self.broker_class() + + @broker.publisher(stream="test") + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + key = tuple(schema["channels"].keys())[0] # noqa: RUF015 + + assert schema["channels"][key]["bindings"] == { + "redis": {"bindingVersion": "custom", "channel": "test", "method": "xadd"} + } From 9188743aeaa35d6a568aa93a77778859f6ad880c Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Wed, 31 Jul 2024 22:07:26 +0300 Subject: [PATCH 020/245] pydantic refs support --- faststream/asyncapi/generate.py | 2 +- tests/asyncapi/base/v3_0_0/arguments.py | 0 tests/asyncapi/rabbit/v3_0_0/test_arguments.py | 0 3 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 tests/asyncapi/base/v3_0_0/arguments.py create mode 100644 tests/asyncapi/rabbit/v3_0_0/test_arguments.py diff --git a/faststream/asyncapi/generate.py b/faststream/asyncapi/generate.py index c0b79442ca..78f3549c4b 100644 --- a/faststream/asyncapi/generate.py +++ b/faststream/asyncapi/generate.py @@ -14,4 +14,4 @@ def get_app_schema(app: "AsyncAPIApplication") -> BaseSchema: if app.asyncapi_version == AsyncAPIVersion.v2_6: return get_app_schema_v2_6(app) - raise NotImplementedError + raise NotImplementedError(f"AsyncAPI version not supported: {app.asyncapi_version}") diff --git a/tests/asyncapi/base/v3_0_0/arguments.py b/tests/asyncapi/base/v3_0_0/arguments.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/asyncapi/rabbit/v3_0_0/test_arguments.py b/tests/asyncapi/rabbit/v3_0_0/test_arguments.py new file mode 100644 index 0000000000..e69de29bb2 From 633969c7853498704878948b09c3cb9490bdd035 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Wed, 31 Jul 2024 22:07:46 +0300 Subject: [PATCH 021/245] AsyncAPI 3.0.0 RabbitMQ arguments tests --- tests/asyncapi/base/v3_0_0/arguments.py | 656 ++++++++++++++++++ .../asyncapi/rabbit/v3_0_0/test_arguments.py | 66 ++ 2 files changed, 722 insertions(+) diff --git a/tests/asyncapi/base/v3_0_0/arguments.py b/tests/asyncapi/base/v3_0_0/arguments.py index e69de29bb2..5c4bf1e2b3 100644 --- a/tests/asyncapi/base/v3_0_0/arguments.py +++ b/tests/asyncapi/base/v3_0_0/arguments.py @@ -0,0 +1,656 @@ +import json +import pprint +from dataclasses import dataclass +from enum import Enum +from typing import Optional, Type, Union + +import pydantic +from dirty_equals import IsDict, IsPartialDict, IsStr +from fast_depends import Depends +from fastapi import Depends as APIDepends +from typing_extensions import Annotated, Literal + +from faststream import Context, FastStream +from faststream._compat import PYDANTIC_V2 +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.broker.core.usecase import BrokerUsecase +from tests.marks import pydantic_v2 + + +class FastAPICompatible: + broker_class: Type[BrokerUsecase] + dependency_builder = staticmethod(APIDepends) + + def build_app(self, broker): + """Patch it to test FastAPI scheme generation too.""" + return FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0) + + def test_custom_naming(self): + broker = self.broker_class() + + @broker.subscriber("test", title="custom_name", description="test description") + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + key = tuple(schema["channels"].keys())[0] # noqa: RUF015 + + assert key == "custom_name" + assert schema["channels"][key]["description"] == "test description" + + def test_docstring_description(self): + broker = self.broker_class() + + @broker.subscriber("test", title="custom_name") + async def handle(msg): + """Test description.""" + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + key = tuple(schema["channels"].keys())[0] # noqa: RUF015 + + assert key == "custom_name" + assert schema["channels"][key]["description"] == "Test description.", schema[ + "channels" + ][key]["description"] + + def test_empty(self): + broker = self.broker_class() + + @broker.subscriber("test") + async def handle(): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + payload = schema["components"]["schemas"] + + for key, v in payload.items(): + assert key == "EmptyPayload" + assert v == { + "title": key, + "type": "null", + } + + def test_no_type(self): + broker = self.broker_class() + + @broker.subscriber("test") + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + payload = schema["components"]["schemas"] + + for key, v in payload.items(): + assert key == "Handle:Message:Payload" + assert v == {"title": key} + + def test_simple_type(self): + broker = self.broker_class() + + @broker.subscriber("test") + async def handle(msg: int): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + payload = schema["components"]["schemas"] + assert next(iter(schema["channels"].values())).get("description") is None + + for key, v in payload.items(): + assert key == "Handle:Message:Payload" + assert v == {"title": key, "type": "integer"} + + def test_simple_optional_type(self): + broker = self.broker_class() + + @broker.subscriber("test") + async def handle(msg: Optional[int]): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + payload = schema["components"]["schemas"] + + for key, v in payload.items(): + assert key == "Handle:Message:Payload" + assert v == IsDict( + { + "anyOf": [{"type": "integer"}, {"type": "null"}], + "title": key, + } + ) | IsDict( + { # TODO: remove when deprecating PydanticV1 + "title": key, + "type": "integer", + } + ), v + + def test_simple_type_with_default(self): + broker = self.broker_class() + + @broker.subscriber("test") + async def handle(msg: int = 1): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + payload = schema["components"]["schemas"] + + for key, v in payload.items(): + assert key == "Handle:Message:Payload" + assert v == { + "default": 1, + "title": key, + "type": "integer", + } + + def test_multi_args_no_type(self): + broker = self.broker_class() + + @broker.subscriber("test") + async def handle(msg, another): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + payload = schema["components"]["schemas"] + + for key, v in payload.items(): + assert key == "Handle:Message:Payload" + assert v == { + "properties": { + "another": {"title": "Another"}, + "msg": {"title": "Msg"}, + }, + "required": ["msg", "another"], + "title": key, + "type": "object", + } + + def test_multi_args_with_type(self): + broker = self.broker_class() + + @broker.subscriber("test") + async def handle(msg: str, another: int): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + payload = schema["components"]["schemas"] + + for key, v in payload.items(): + assert key == "Handle:Message:Payload" + assert v == { + "properties": { + "another": {"title": "Another", "type": "integer"}, + "msg": {"title": "Msg", "type": "string"}, + }, + "required": ["msg", "another"], + "title": key, + "type": "object", + } + + def test_multi_args_with_default(self): + broker = self.broker_class() + + @broker.subscriber("test") + async def handle(msg: str, another: Optional[int] = None): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + payload = schema["components"]["schemas"] + + for key, v in payload.items(): + assert key == "Handle:Message:Payload" + + assert v == { + "properties": { + "another": IsDict( + { + "anyOf": [{"type": "integer"}, {"type": "null"}], + "default": None, + "title": "Another", + } + ) + | IsDict( + { # TODO: remove when deprecating PydanticV1 + "title": "Another", + "type": "integer", + } + ), + "msg": {"title": "Msg", "type": "string"}, + }, + "required": ["msg"], + "title": key, + "type": "object", + } + + def test_dataclass(self): + @dataclass + class User: + id: int + name: str = "" + + broker = self.broker_class() + + @broker.subscriber("test") + async def handle(user: User): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + payload = schema["components"]["schemas"] + + for key, v in payload.items(): + assert key == "User" + assert v == { + "properties": { + "id": {"title": "Id", "type": "integer"}, + "name": {"default": "", "title": "Name", "type": "string"}, + }, + "required": ["id"], + "title": key, + "type": "object", + } + + def test_pydantic_model(self): + class User(pydantic.BaseModel): + name: str = "" + id: int + + broker = self.broker_class() + + @broker.subscriber("test") + async def handle(user: User): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + payload = schema["components"]["schemas"] + + for key, v in payload.items(): + assert key == "User" + assert v == { + "properties": { + "id": {"title": "Id", "type": "integer"}, + "name": {"default": "", "title": "Name", "type": "string"}, + }, + "required": ["id"], + "title": key, + "type": "object", + } + + def test_pydantic_model_with_enum(self): + class Status(str, Enum): + registered = "registered" + banned = "banned" + + class User(pydantic.BaseModel): + name: str = "" + id: int + status: Status + + broker = self.broker_class() + + @broker.subscriber("test") + async def handle(user: User): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + payload = schema["components"]["schemas"] + + assert payload == { + "Status": IsPartialDict( + { + "enum": ["registered", "banned"], + "title": "Status", + "type": "string", + } + ), + "User": { + "properties": { + "id": {"title": "Id", "type": "integer"}, + "name": {"default": "", "title": "Name", "type": "string"}, + "status": {"$ref": "#/components/schemas/Status"}, + }, + "required": ["id", "status"], + "title": "User", + "type": "object", + }, + }, payload + + def test_pydantic_model_mixed_regular(self): + class Email(pydantic.BaseModel): + addr: str + + class User(pydantic.BaseModel): + name: str = "" + id: int + email: Email + + broker = self.broker_class() + + @broker.subscriber("test") + async def handle(user: User, description: str = ""): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + payload = schema["components"]["schemas"] + + assert payload == { + "Email": { + "title": "Email", + "type": "object", + "properties": {"addr": {"title": "Addr", "type": "string"}}, + "required": ["addr"], + }, + "User": { + "title": "User", + "type": "object", + "properties": { + "name": {"title": "Name", "default": "", "type": "string"}, + "id": {"title": "Id", "type": "integer"}, + "email": {"$ref": "#/components/schemas/Email"}, + }, + "required": ["id", "email"], + }, + "Handle:Message:Payload": { + "title": "Handle:Message:Payload", + "type": "object", + "properties": { + "user": {"$ref": "#/components/schemas/User"}, + "description": { + "title": "Description", + "default": "", + "type": "string", + }, + }, + "required": ["user"], + }, + } + + def test_pydantic_model_with_example(self): + class User(pydantic.BaseModel): + name: str = "" + id: int + + if PYDANTIC_V2: + model_config = { + "json_schema_extra": {"examples": [{"name": "john", "id": 1}]} + } + + else: + + class Config: + schema_extra = {"examples": [{"name": "john", "id": 1}]} # noqa: RUF012 + + broker = self.broker_class() + + @broker.subscriber("test") + async def handle(user: User): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + payload = schema["components"]["schemas"] + + for key, v in payload.items(): + assert key == "User" + assert v == { + "examples": [{"id": 1, "name": "john"}], + "properties": { + "id": {"title": "Id", "type": "integer"}, + "name": {"default": "", "title": "Name", "type": "string"}, + }, + "required": ["id"], + "title": "User", + "type": "object", + } + + def test_with_filter(self): + class User(pydantic.BaseModel): + name: str = "" + id: int + + broker = self.broker_class() + + @broker.subscriber( # pragma: no branch + "test", + filter=lambda m: m.content_type == "application/json", + ) + async def handle(id: int): ... + + @broker.subscriber("test") + async def handle_default(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + assert ( + len( + next(iter(schema["components"]["messages"].values()))["payload"][ + "oneOf" + ] + ) + == 2 + ) + + payload = schema["components"]["schemas"] + + assert "Handle:Message:Payload" in list(payload.keys()) + assert "HandleDefault:Message:Payload" in list(payload.keys()) + + def test_ignores_depends(self): + broker = self.broker_class() + + def dep(name: str = ""): + return name + + def dep2(name2: str): + return name2 + + dependencies = (self.dependency_builder(dep2),) + message = self.dependency_builder(dep) + + @broker.subscriber("test", dependencies=dependencies) + async def handle(id: int, message=message): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + payload = schema["components"]["schemas"] + + for key, v in payload.items(): + assert key == "Handle:Message:Payload" + assert v == { + "properties": { + "id": {"title": "Id", "type": "integer"}, + "name": {"default": "", "title": "Name", "type": "string"}, + "name2": {"title": "Name2", "type": "string"}, + }, + "required": ["id", "name2"], + "title": key, + "type": "object", + }, v + + @pydantic_v2 + def test_descriminator(self): + class Sub2(pydantic.BaseModel): + type: Literal["sub2"] + + class Sub(pydantic.BaseModel): + type: Literal["sub"] + + descriminator = Annotated[ + Union[Sub2, Sub], pydantic.Field(discriminator="type") + ] + + broker = self.broker_class() + + @broker.subscriber("test") + async def handle(user: descriminator): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + key = next(iter(schema["components"]["messages"].keys())) + assert key == IsStr(regex=r"test[\w:]*:Handle:Message") + + assert schema["components"] == { + "messages": { + key: { + "title": key, + "correlationId": {"location": "$message.header#/correlation_id"}, + "payload": { + "$ref": "#/components/schemas/Handle:Message:Payload" + }, + } + }, + "schemas": { + "Sub": { + "properties": { + "type": IsPartialDict({"const": "sub", "title": "Type"}) + }, + "required": ["type"], + "title": "Sub", + "type": "object", + }, + "Sub2": { + "properties": { + "type": IsPartialDict({"const": "sub2", "title": "Type"}) + }, + "required": ["type"], + "title": "Sub2", + "type": "object", + }, + "Handle:Message:Payload": { + "discriminator": "type", + "oneOf": [ + {"$ref": "#/components/schemas/Sub2"}, + {"$ref": "#/components/schemas/Sub"}, + ], + "title": "Handle:Message:Payload", + }, + }, + }, schema["components"] + + @pydantic_v2 + def test_nested_descriminator(self): + class Sub2(pydantic.BaseModel): + type: Literal["sub2"] + + class Sub(pydantic.BaseModel): + type: Literal["sub"] + + class Model(pydantic.BaseModel): + msg: Union[Sub2, Sub] = pydantic.Field(..., discriminator="type") + + broker = self.broker_class() + + @broker.subscriber("test") + async def handle(user: Model): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + key = next(iter(schema["components"]["messages"].keys())) + assert key == IsStr(regex=r"test[\w:]*:Handle:Message") + assert schema["components"] == { + "messages": { + key: { + "title": key, + "correlationId": {"location": "$message.header#/correlation_id"}, + "payload": {"$ref": "#/components/schemas/Model"}, + } + }, + "schemas": { + "Sub": { + "properties": { + "type": IsPartialDict({"const": "sub", "title": "Type"}) + }, + "required": ["type"], + "title": "Sub", + "type": "object", + }, + "Sub2": { + "properties": { + "type": IsPartialDict({"const": "sub2", "title": "Type"}) + }, + "required": ["type"], + "title": "Sub2", + "type": "object", + }, + "Model": { + "properties": { + "msg": { + "discriminator": "type", + "oneOf": [ + {"$ref": "#/components/schemas/Sub2"}, + {"$ref": "#/components/schemas/Sub"}, + ], + "title": "Msg", + } + }, + "required": ["msg"], + "title": "Model", + "type": "object", + }, + }, + }, schema["components"] + + +class ArgumentsTestcase(FastAPICompatible): + dependency_builder = staticmethod(Depends) + + def test_pydantic_field(self): + broker = self.broker_class() + + @broker.subscriber("msg") + async def msg( + msg: pydantic.PositiveInt = pydantic.Field( + 1, + description="some field", + title="Perfect", + examples=[1], + ), + ): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + payload = schema["components"]["schemas"] + + for key, v in payload.items(): + assert key == "Perfect" + + assert v == { + "default": 1, + "description": "some field", + "examples": [1], + "exclusiveMinimum": 0, + "title": "Perfect", + "type": "integer", + } + + def test_ignores_custom_field(self): + broker = self.broker_class() + + @broker.subscriber("test") + async def handle(id: int, user: Optional[str] = None, message=Context()): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + + payload = schema["components"]["schemas"] + + for key, v in payload.items(): + assert v == IsDict( + { + "properties": { + "id": {"title": "Id", "type": "integer"}, + "user": { + "anyOf": [{"type": "string"}, {"type": "null"}], + "default": None, + "title": "User", + }, + }, + "required": ["id"], + "title": key, + "type": "object", + } + ) | IsDict( # TODO: remove when deprecating PydanticV1 + { + "properties": { + "id": {"title": "Id", "type": "integer"}, + "user": {"title": "User", "type": "string"}, + }, + "required": ["id"], + "title": "Handle:Message:Payload", + "type": "object", + } + ) diff --git a/tests/asyncapi/rabbit/v3_0_0/test_arguments.py b/tests/asyncapi/rabbit/v3_0_0/test_arguments.py index e69de29bb2..0530fdd610 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_arguments.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_arguments.py @@ -0,0 +1,66 @@ +from faststream.asyncapi.generate import get_app_schema +from faststream.rabbit import ExchangeType, RabbitBroker, RabbitExchange, RabbitQueue +from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase + + +class TestArguments(ArgumentsTestcase): + broker_class = RabbitBroker + + def test_subscriber_bindings(self): + broker = self.broker_class() + + @broker.subscriber( + RabbitQueue("test", auto_delete=True), + RabbitExchange("test-ex", type=ExchangeType.TOPIC), + ) + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + key = tuple(schema["channels"].keys())[0] # noqa: RUF015 + + assert schema["channels"][key]["bindings"] == { + "amqp": { + "bindingVersion": "0.2.0", + "exchange": { + "autoDelete": False, + "durable": False, + "name": "test-ex", + "type": "topic", + "vhost": "/", + }, + "is": "routingKey", + "queue": { + "autoDelete": True, + "durable": False, + "exclusive": False, + "name": "test", + "vhost": "/", + }, + } + } + + def test_subscriber_fanout_bindings(self): + broker = self.broker_class() + + @broker.subscriber( + RabbitQueue("test", auto_delete=True), + RabbitExchange("test-ex", type=ExchangeType.FANOUT), + ) + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + key = tuple(schema["channels"].keys())[0] # noqa: RUF015 + + assert schema["channels"][key]["bindings"] == { + "amqp": { + "bindingVersion": "0.2.0", + "exchange": { + "autoDelete": False, + "durable": False, + "name": "test-ex", + "type": "fanout", + "vhost": "/", + }, + "is": "routingKey", + } + } From 7935f8aa81713f139e2438e9fae79cb3a8df758e Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Wed, 31 Jul 2024 23:09:19 +0300 Subject: [PATCH 022/245] AsyncAPI 3.0.0 Kafka arguments tests --- tests/asyncapi/kafka/v3_0_0/test_arguments.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tests/asyncapi/kafka/v3_0_0/test_arguments.py diff --git a/tests/asyncapi/kafka/v3_0_0/test_arguments.py b/tests/asyncapi/kafka/v3_0_0/test_arguments.py new file mode 100644 index 0000000000..14c0487e6b --- /dev/null +++ b/tests/asyncapi/kafka/v3_0_0/test_arguments.py @@ -0,0 +1,20 @@ +from faststream.asyncapi.generate import get_app_schema +from faststream.kafka import KafkaBroker +from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase + + +class TestArguments(ArgumentsTestcase): + broker_class = KafkaBroker + + def test_subscriber_bindings(self): + broker = self.broker_class() + + @broker.subscriber("test") + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + key = tuple(schema["channels"].keys())[0] # noqa: RUF015 + + assert schema["channels"][key]["bindings"] == { + "kafka": {"bindingVersion": "0.4.0", "topic": "test"} + } From 14b9178dce47f024d8f8bb6f3f2a8cecc6f0c284 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Wed, 31 Jul 2024 23:09:59 +0300 Subject: [PATCH 023/245] AsyncAPI 3.0.0 Nats arguments tests --- tests/asyncapi/nats/v3_0_0/test_arguments.py | 20 +++++++++++++++++++ tests/asyncapi/redis/v3_0_0/test_arguments.py | 0 2 files changed, 20 insertions(+) create mode 100644 tests/asyncapi/nats/v3_0_0/test_arguments.py create mode 100644 tests/asyncapi/redis/v3_0_0/test_arguments.py diff --git a/tests/asyncapi/nats/v3_0_0/test_arguments.py b/tests/asyncapi/nats/v3_0_0/test_arguments.py new file mode 100644 index 0000000000..25f6508524 --- /dev/null +++ b/tests/asyncapi/nats/v3_0_0/test_arguments.py @@ -0,0 +1,20 @@ +from faststream.asyncapi.generate import get_app_schema +from faststream.nats import NatsBroker +from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase + + +class TestArguments(ArgumentsTestcase): + broker_class = NatsBroker + + def test_subscriber_bindings(self): + broker = self.broker_class() + + @broker.subscriber("test") + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + key = tuple(schema["channels"].keys())[0] # noqa: RUF015 + + assert schema["channels"][key]["bindings"] == { + "nats": {"bindingVersion": "custom", "subject": "test"} + } diff --git a/tests/asyncapi/redis/v3_0_0/test_arguments.py b/tests/asyncapi/redis/v3_0_0/test_arguments.py new file mode 100644 index 0000000000..e69de29bb2 From b2eacd5f6f93635ce7da1399a36ad8916f4147b8 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Wed, 31 Jul 2024 23:11:51 +0300 Subject: [PATCH 024/245] AsyncAPI 3.0.0 Redis arguments tests --- tests/asyncapi/redis/v3_0_0/test_arguments.py | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/tests/asyncapi/redis/v3_0_0/test_arguments.py b/tests/asyncapi/redis/v3_0_0/test_arguments.py index e69de29bb2..c34c88a12e 100644 --- a/tests/asyncapi/redis/v3_0_0/test_arguments.py +++ b/tests/asyncapi/redis/v3_0_0/test_arguments.py @@ -0,0 +1,86 @@ +from faststream.asyncapi.generate import get_app_schema +from faststream.redis import RedisBroker, StreamSub +from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase + + +class TestArguments(ArgumentsTestcase): + broker_class = RedisBroker + + def test_channel_subscriber(self): + broker = self.broker_class() + + @broker.subscriber("test") + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + key = tuple(schema["channels"].keys())[0] # noqa: RUF015 + + assert schema["channels"][key]["bindings"] == { + "redis": { + "bindingVersion": "custom", + "channel": "test", + "method": "subscribe", + } + } + + def test_channel_pattern_subscriber(self): + broker = self.broker_class() + + @broker.subscriber("test.{path}") + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + key = tuple(schema["channels"].keys())[0] # noqa: RUF015 + + assert schema["channels"][key]["bindings"] == { + "redis": { + "bindingVersion": "custom", + "channel": "test.*", + "method": "psubscribe", + } + } + + def test_list_subscriber(self): + broker = self.broker_class() + + @broker.subscriber(list="test") + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + key = tuple(schema["channels"].keys())[0] # noqa: RUF015 + + assert schema["channels"][key]["bindings"] == { + "redis": {"bindingVersion": "custom", "channel": "test", "method": "lpop"} + } + + def test_stream_subscriber(self): + broker = self.broker_class() + + @broker.subscriber(stream="test") + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + key = tuple(schema["channels"].keys())[0] # noqa: RUF015 + + assert schema["channels"][key]["bindings"] == { + "redis": {"bindingVersion": "custom", "channel": "test", "method": "xread"} + } + + def test_stream_group_subscriber(self): + broker = self.broker_class() + + @broker.subscriber(stream=StreamSub("test", group="group", consumer="consumer")) + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + key = tuple(schema["channels"].keys())[0] # noqa: RUF015 + + assert schema["channels"][key]["bindings"] == { + "redis": { + "bindingVersion": "custom", + "channel": "test", + "consumer_name": "consumer", + "group_name": "group", + "method": "xreadgroup", + } + } From bd49362691777daa3b74910742c17d9ee2d8b1c5 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Wed, 31 Jul 2024 23:12:37 +0300 Subject: [PATCH 025/245] AsyncAPI 3.0.0 Confluent arguments tests --- .../confluent/v3_0_0/test_arguments.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tests/asyncapi/confluent/v3_0_0/test_arguments.py diff --git a/tests/asyncapi/confluent/v3_0_0/test_arguments.py b/tests/asyncapi/confluent/v3_0_0/test_arguments.py new file mode 100644 index 0000000000..821d8df6be --- /dev/null +++ b/tests/asyncapi/confluent/v3_0_0/test_arguments.py @@ -0,0 +1,20 @@ +from faststream.asyncapi.generate import get_app_schema +from faststream.confluent import KafkaBroker +from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase + + +class TestArguments(ArgumentsTestcase): + broker_class = KafkaBroker + + def test_subscriber_bindings(self): + broker = self.broker_class() + + @broker.subscriber("test") + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker)).to_jsonable() + key = tuple(schema["channels"].keys())[0] # noqa: RUF015 + + assert schema["channels"][key]["bindings"] == { + "kafka": {"bindingVersion": "0.4.0", "topic": "test"} + } From 66de63d221fd3baaaacb514e2a2f638280a29907 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Wed, 31 Jul 2024 23:48:54 +0300 Subject: [PATCH 026/245] AsyncAPI 3.0.0 RabbitMQ router tests --- tests/asyncapi/base/v3_0_0/router.py | 166 ++++++++++++++++++++ tests/asyncapi/rabbit/v3_0_0/test_router.py | 141 +++++++++++++++++ 2 files changed, 307 insertions(+) create mode 100644 tests/asyncapi/base/v3_0_0/router.py create mode 100644 tests/asyncapi/rabbit/v3_0_0/test_router.py diff --git a/tests/asyncapi/base/v3_0_0/router.py b/tests/asyncapi/base/v3_0_0/router.py new file mode 100644 index 0000000000..b6f9bb5f5d --- /dev/null +++ b/tests/asyncapi/base/v3_0_0/router.py @@ -0,0 +1,166 @@ +from typing import Type + +from dirty_equals import IsStr + +from faststream import FastStream +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.broker.core.usecase import BrokerUsecase +from faststream.broker.router import ArgsContainer, BrokerRouter, SubscriberRoute + + +class RouterTestcase: + broker_class: Type[BrokerUsecase] + router_class: Type[BrokerRouter] + publisher_class: Type[ArgsContainer] + route_class: Type[SubscriberRoute] + + def test_delay_subscriber(self): + broker = self.broker_class() + + async def handle(msg): ... + + router = self.router_class( + handlers=(self.route_class(handle, "test"),), + ) + + broker.include_router(router) + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + payload = schema["components"]["schemas"] + key = list(payload.keys())[0] # noqa: RUF015 + assert payload[key]["title"] == key == "Handle:Message:Payload" + + def test_delay_publisher(self): + broker = self.broker_class() + + async def handle(msg): ... + + router = self.router_class( + handlers=( + self.route_class( + handle, + "test", + publishers=(self.publisher_class("test2", schema=int),), + ), + ), + ) + + broker.include_router(router) + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)) + schemas = schema.components.schemas + del schemas["Handle:Message:Payload"] + + for i, j in schemas.items(): + assert ( + i == j["title"] == IsStr(regex=r"test2[\w:]*:Publisher:Message:Payload") + ) + assert j["type"] == "integer" + + def test_not_include(self): + broker = self.broker_class() + router = self.router_class(include_in_schema=False) + + @router.subscriber("test") + @router.publisher("test") + async def handle(msg): ... + + broker.include_router(router) + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)) + assert schema.channels == {}, schema.channels + + def test_not_include_in_method(self): + broker = self.broker_class() + router = self.router_class() + + @router.subscriber("test") + @router.publisher("test") + async def handle(msg): ... + + broker.include_router(router, include_in_schema=False) + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)) + assert schema.channels == {}, schema.channels + + def test_respect_subrouter(self): + broker = self.broker_class() + router = self.router_class() + router2 = self.router_class(include_in_schema=False) + + @router2.subscriber("test") + @router2.publisher("test") + async def handle(msg): ... + + router.include_router(router2) + broker.include_router(router) + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)) + + assert schema.channels == {}, schema.channels + + def test_not_include_subrouter(self): + broker = self.broker_class() + router = self.router_class(include_in_schema=False) + router2 = self.router_class() + + @router2.subscriber("test") + @router2.publisher("test") + async def handle(msg): ... + + router.include_router(router2) + broker.include_router(router) + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)) + + assert schema.channels == {} + + def test_not_include_subrouter_by_method(self): + broker = self.broker_class() + router = self.router_class() + router2 = self.router_class() + + @router2.subscriber("test") + @router2.publisher("test") + async def handle(msg): ... + + router.include_router(router2, include_in_schema=False) + broker.include_router(router) + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)) + + assert schema.channels == {} + + def test_all_nested_routers_by_method(self): + broker = self.broker_class() + router = self.router_class() + router2 = self.router_class() + + @router2.subscriber("test") + @router2.publisher("test") + async def handle(msg): ... + + router.include_router(router2) + broker.include_router(router, include_in_schema=False) + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)) + + assert schema.channels == {} + + def test_include_subrouter(self): + broker = self.broker_class() + router = self.router_class() + router2 = self.router_class() + + @router2.subscriber("test") + @router2.publisher("test") + async def handle(msg): ... + + router.include_router(router2) + broker.include_router(router) + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)) + + assert len(schema.channels) == 2 diff --git a/tests/asyncapi/rabbit/v3_0_0/test_router.py b/tests/asyncapi/rabbit/v3_0_0/test_router.py new file mode 100644 index 0000000000..ce77c35b92 --- /dev/null +++ b/tests/asyncapi/rabbit/v3_0_0/test_router.py @@ -0,0 +1,141 @@ +from faststream import FastStream +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.rabbit import ( + RabbitBroker, + RabbitPublisher, + RabbitQueue, + RabbitRoute, + RabbitRouter, +) +from tests.asyncapi.base.arguments import ArgumentsTestcase +from tests.asyncapi.base.publisher import PublisherTestcase +from tests.asyncapi.base.v3_0_0.router import RouterTestcase + + +class TestRouter(RouterTestcase): + broker_class = RabbitBroker + router_class = RabbitRouter + route_class = RabbitRoute + publisher_class = RabbitPublisher + + def test_prefix(self): + broker = self.broker_class() + + router = self.router_class(prefix="test_") + + @router.subscriber(RabbitQueue("test", routing_key="key")) + async def handle(msg): ... + + broker.include_router(router) + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert ( + schema + == { + "info": { + "title": "FastStream", + "version": "0.1.0", + "description": "" + }, + "asyncapi": "3.0.0", + "defaultContentType": "application/json", + "servers": { + "development": { + "host": "guest:guest@localhost:5672", + "pathname": "/", + "protocol": "amqp", + "protocolVersion": "0.9.1" + } + }, + "channels": { + "test_test:_:Handle": { + "address": "test_test:_:Handle", + "servers": [ + { + "$ref": "#/servers/development" + } + ], + "messages": { + "SubscribeMessage": { + "$ref": "#/components/messages/test_test:_:Handle:SubscribeMessage" + } + }, + "bindings": { + "amqp": { + "is": "routingKey", + "bindingVersion": "0.2.0", + "queue": { + "name": "test_test", + "durable": False, + "exclusive": False, + "autoDelete": False, + "vhost": "/" + }, + "exchange": { + "type": "default", + "vhost": "/" + } + } + } + } + }, + "operations": { + "test_test:_:HandleSubscribe": { + "action": "receive", + "bindings": { + "amqp": { + "cc": "test_key", + "ack": True, + "bindingVersion": "0.2.0" + } + }, + "messages": [ + { + "$ref": "#/channels/test_test:_:Handle/messages/SubscribeMessage" + } + ], + "channel": { + "$ref": "#/channels/test_test:_:Handle" + } + } + }, + "components": { + "messages": { + "test_test:_:Handle:Message": { + "title": "test_test:_:Handle:Message", + "correlationId": { + "location": "$message.header#/correlation_id" + }, + "payload": { + "$ref": "#/components/schemas/Handle:Message:Payload" + } + } + }, + "schemas": { + "Handle:Message:Payload": { + "title": "Handle:Message:Payload" + } + } + } + } + ), schema + + +class TestRouterArguments(ArgumentsTestcase): + broker_class = RabbitRouter + + def build_app(self, router): + broker = RabbitBroker() + broker.include_router(router) + return FastStream(broker) + + +class TestRouterPublisher(PublisherTestcase): + broker_class = RabbitRouter + + def build_app(self, router): + broker = RabbitBroker() + broker.include_router(router) + return FastStream(broker) From 62d6633957081dfecc650a37ca4f9f4a7631632b Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Thu, 1 Aug 2024 09:59:52 +0300 Subject: [PATCH 027/245] AsyncAPI 3.0.0 Kafka router tests --- tests/asyncapi/kafka/v3_0_0/test_router.py | 114 +++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 tests/asyncapi/kafka/v3_0_0/test_router.py diff --git a/tests/asyncapi/kafka/v3_0_0/test_router.py b/tests/asyncapi/kafka/v3_0_0/test_router.py new file mode 100644 index 0000000000..270afced29 --- /dev/null +++ b/tests/asyncapi/kafka/v3_0_0/test_router.py @@ -0,0 +1,114 @@ +from faststream import FastStream +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.kafka import KafkaBroker, KafkaPublisher, KafkaRoute, KafkaRouter +from tests.asyncapi.base.arguments import ArgumentsTestcase +from tests.asyncapi.base.publisher import PublisherTestcase +from tests.asyncapi.base.v3_0_0.router import RouterTestcase + + +class TestRouter(RouterTestcase): + broker_class = KafkaBroker + router_class = KafkaRouter + route_class = KafkaRoute + publisher_class = KafkaPublisher + + def test_prefix(self): + broker = self.broker_class() + + router = self.router_class(prefix="test_") + + @router.subscriber("test") + async def handle(msg): ... + + broker.include_router(router) + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert schema == { + "info": { + "title": "FastStream", + "version": "0.1.0", + "description": "" + }, + "asyncapi": "3.0.0", + "defaultContentType": "application/json", + "servers": { + "development": { + "host": "", + "pathname": "localhost", + "protocol": "kafka", + "protocolVersion": "auto" + } + }, + "channels": { + "test_test:Handle": { + "address": "test_test:Handle", + "servers": [ + { + "$ref": "#/servers/development" + } + ], + "messages": { + "SubscribeMessage": { + "$ref": "#/components/messages/test_test:Handle:SubscribeMessage" + } + }, + "bindings": { + "kafka": { + "topic": "test_test", + "bindingVersion": "0.4.0" + } + } + } + }, + "operations": { + "test_test:HandleSubscribe": { + "action": "receive", + "messages": [ + { + "$ref": "#/channels/test_test:Handle/messages/SubscribeMessage" + } + ], + "channel": { + "$ref": "#/channels/test_test:Handle" + } + } + }, + "components": { + "messages": { + "test_test:Handle:Message": { + "title": "test_test:Handle:Message", + "correlationId": { + "location": "$message.header#/correlation_id" + }, + "payload": { + "$ref": "#/components/schemas/Handle:Message:Payload" + } + } + }, + "schemas": { + "Handle:Message:Payload": { + "title": "Handle:Message:Payload" + } + } + } + } + + +class TestRouterArguments(ArgumentsTestcase): + broker_class = KafkaRouter + + def build_app(self, router): + broker = KafkaBroker() + broker.include_router(router) + return FastStream(broker) + + +class TestRouterPublisher(PublisherTestcase): + broker_class = KafkaRouter + + def build_app(self, router): + broker = KafkaBroker() + broker.include_router(router) + return FastStream(broker) From ce2903c9c1197fd9b442af51ca333e9f8ba23101 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Thu, 1 Aug 2024 10:08:31 +0300 Subject: [PATCH 028/245] AsyncAPI 3.0.0 Nats router tests --- tests/asyncapi/nats/v3_0_0/test_router.py | 114 ++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 tests/asyncapi/nats/v3_0_0/test_router.py diff --git a/tests/asyncapi/nats/v3_0_0/test_router.py b/tests/asyncapi/nats/v3_0_0/test_router.py new file mode 100644 index 0000000000..7ebe5b99b3 --- /dev/null +++ b/tests/asyncapi/nats/v3_0_0/test_router.py @@ -0,0 +1,114 @@ +from faststream import FastStream +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.nats import NatsBroker, NatsPublisher, NatsRoute, NatsRouter +from tests.asyncapi.base.arguments import ArgumentsTestcase +from tests.asyncapi.base.publisher import PublisherTestcase +from tests.asyncapi.base.v3_0_0.router import RouterTestcase + + +class TestRouter(RouterTestcase): + broker_class = NatsBroker + router_class = NatsRouter + route_class = NatsRoute + publisher_class = NatsPublisher + + def test_prefix(self): + broker = self.broker_class() + + router = self.router_class(prefix="test_") + + @router.subscriber("test") + async def handle(msg): ... + + broker.include_router(router) + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert schema == { + "info": { + "title": "FastStream", + "version": "0.1.0", + "description": "" + }, + "asyncapi": "3.0.0", + "defaultContentType": "application/json", + "servers": { + "development": { + "host": "localhost:4222", + "pathname": "", + "protocol": "nats", + "protocolVersion": "custom" + } + }, + "channels": { + "test_test:Handle": { + "address": "test_test:Handle", + "servers": [ + { + "$ref": "#/servers/development" + } + ], + "messages": { + "SubscribeMessage": { + "$ref": "#/components/messages/test_test:Handle:SubscribeMessage" + } + }, + "bindings": { + "nats": { + "subject": "test_test", + "bindingVersion": "custom" + } + } + } + }, + "operations": { + "test_test:HandleSubscribe": { + "action": "receive", + "messages": [ + { + "$ref": "#/channels/test_test:Handle/messages/SubscribeMessage" + } + ], + "channel": { + "$ref": "#/channels/test_test:Handle" + } + } + }, + "components": { + "messages": { + "test_test:Handle:Message": { + "title": "test_test:Handle:Message", + "correlationId": { + "location": "$message.header#/correlation_id" + }, + "payload": { + "$ref": "#/components/schemas/Handle:Message:Payload" + } + } + }, + "schemas": { + "Handle:Message:Payload": { + "title": "Handle:Message:Payload" + } + } + } + } + + +class TestRouterArguments(ArgumentsTestcase): + broker_class = NatsRouter + + def build_app(self, router): + broker = NatsBroker() + broker.include_router(router) + return FastStream(broker) + + +class TestRouterPublisher(PublisherTestcase): + broker_class = NatsRouter + + def build_app(self, router): + broker = NatsBroker() + broker.include_router(router) + return FastStream(broker) From d9312aff222f5eb8215d2750c126d08893414182 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Thu, 1 Aug 2024 10:10:20 +0300 Subject: [PATCH 029/245] AsyncAPI 3.0.0 Redis router tests --- .../asyncapi/confluent/v3_0_0/test_router.py | 0 tests/asyncapi/redis/v3_0_0/test_router.py | 115 ++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 tests/asyncapi/confluent/v3_0_0/test_router.py create mode 100644 tests/asyncapi/redis/v3_0_0/test_router.py diff --git a/tests/asyncapi/confluent/v3_0_0/test_router.py b/tests/asyncapi/confluent/v3_0_0/test_router.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/asyncapi/redis/v3_0_0/test_router.py b/tests/asyncapi/redis/v3_0_0/test_router.py new file mode 100644 index 0000000000..b11ada430c --- /dev/null +++ b/tests/asyncapi/redis/v3_0_0/test_router.py @@ -0,0 +1,115 @@ +from faststream import FastStream +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.redis import RedisBroker, RedisPublisher, RedisRoute, RedisRouter +from tests.asyncapi.base.arguments import ArgumentsTestcase +from tests.asyncapi.base.publisher import PublisherTestcase +from tests.asyncapi.base.v3_0_0.router import RouterTestcase + + +class TestRouter(RouterTestcase): + broker_class = RedisBroker + router_class = RedisRouter + route_class = RedisRoute + publisher_class = RedisPublisher + + def test_prefix(self): + broker = self.broker_class() + + router = self.router_class(prefix="test_") + + @router.subscriber("test") + async def handle(msg): ... + + broker.include_router(router) + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert schema == { + "info": { + "title": "FastStream", + "version": "0.1.0", + "description": "" + }, + "asyncapi": "3.0.0", + "defaultContentType": "application/json", + "servers": { + "development": { + "host": "localhost:6379", + "pathname": "", + "protocol": "redis", + "protocolVersion": "custom" + } + }, + "channels": { + "test_test:Handle": { + "address": "test_test:Handle", + "servers": [ + { + "$ref": "#/servers/development" + } + ], + "messages": { + "SubscribeMessage": { + "$ref": "#/components/messages/test_test:Handle:SubscribeMessage" + } + }, + "bindings": { + "redis": { + "channel": "test_test", + "method": "subscribe", + "bindingVersion": "custom" + } + } + } + }, + "operations": { + "test_test:HandleSubscribe": { + "action": "receive", + "messages": [ + { + "$ref": "#/channels/test_test:Handle/messages/SubscribeMessage" + } + ], + "channel": { + "$ref": "#/channels/test_test:Handle" + } + } + }, + "components": { + "messages": { + "test_test:Handle:Message": { + "title": "test_test:Handle:Message", + "correlationId": { + "location": "$message.header#/correlation_id" + }, + "payload": { + "$ref": "#/components/schemas/Handle:Message:Payload" + } + } + }, + "schemas": { + "Handle:Message:Payload": { + "title": "Handle:Message:Payload" + } + } + } + } + + +class TestRouterArguments(ArgumentsTestcase): + broker_class = RedisRouter + + def build_app(self, router): + broker = RedisBroker() + broker.include_router(router) + return FastStream(broker) + + +class TestRouterPublisher(PublisherTestcase): + broker_class = RedisRouter + + def build_app(self, router): + broker = RedisBroker() + broker.include_router(router) + return FastStream(broker) From 97e1d31ccac10a8da9aa29ce06e451c79a1bf0a9 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Thu, 1 Aug 2024 10:15:18 +0300 Subject: [PATCH 030/245] AsyncAPI 3.0.0 Confluent router tests --- .../asyncapi/confluent/v3_0_0/test_router.py | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/tests/asyncapi/confluent/v3_0_0/test_router.py b/tests/asyncapi/confluent/v3_0_0/test_router.py index e69de29bb2..fc47bc9d58 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_router.py +++ b/tests/asyncapi/confluent/v3_0_0/test_router.py @@ -0,0 +1,114 @@ +from faststream import FastStream +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.confluent import KafkaBroker, KafkaPublisher, KafkaRoute, KafkaRouter +from tests.asyncapi.base.arguments import ArgumentsTestcase +from tests.asyncapi.base.publisher import PublisherTestcase +from tests.asyncapi.base.v3_0_0.router import RouterTestcase + + +class TestRouter(RouterTestcase): + broker_class = KafkaBroker + router_class = KafkaRouter + route_class = KafkaRoute + publisher_class = KafkaPublisher + + def test_prefix(self): + broker = self.broker_class() + + router = self.router_class(prefix="test_") + + @router.subscriber("test") + async def handle(msg): ... + + broker.include_router(router) + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert schema == { + "info": { + "title": "FastStream", + "version": "0.1.0", + "description": "" + }, + "asyncapi": "3.0.0", + "defaultContentType": "application/json", + "servers": { + "development": { + "host": "localhost", + "pathname": "", + "protocol": "kafka", + "protocolVersion": "auto" + } + }, + "channels": { + "test_test:Handle": { + "address": "test_test:Handle", + "servers": [ + { + "$ref": "#/servers/development" + } + ], + "messages": { + "SubscribeMessage": { + "$ref": "#/components/messages/test_test:Handle:SubscribeMessage" + } + }, + "bindings": { + "kafka": { + "topic": "test_test", + "bindingVersion": "0.4.0" + } + } + } + }, + "operations": { + "test_test:HandleSubscribe": { + "action": "receive", + "messages": [ + { + "$ref": "#/channels/test_test:Handle/messages/SubscribeMessage" + } + ], + "channel": { + "$ref": "#/channels/test_test:Handle" + } + } + }, + "components": { + "messages": { + "test_test:Handle:Message": { + "title": "test_test:Handle:Message", + "correlationId": { + "location": "$message.header#/correlation_id" + }, + "payload": { + "$ref": "#/components/schemas/Handle:Message:Payload" + } + } + }, + "schemas": { + "Handle:Message:Payload": { + "title": "Handle:Message:Payload" + } + } + } + } + + +class TestRouterArguments(ArgumentsTestcase): + broker_class = KafkaRouter + + def build_app(self, router): + broker = KafkaBroker() + broker.include_router(router) + return FastStream(broker) + + +class TestRouterPublisher(PublisherTestcase): + broker_class = KafkaRouter + + def build_app(self, router): + broker = KafkaBroker() + broker.include_router(router) + return FastStream(broker) From f209d9aa36ca8a7c33d4c93b2e7d3752ad721f5c Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Thu, 1 Aug 2024 10:15:48 +0300 Subject: [PATCH 031/245] AsyncAPI 3.0.0 Kafka router tests fix --- tests/asyncapi/kafka/v3_0_0/test_router.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/asyncapi/kafka/v3_0_0/test_router.py b/tests/asyncapi/kafka/v3_0_0/test_router.py index 270afced29..cf1792dfda 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_router.py +++ b/tests/asyncapi/kafka/v3_0_0/test_router.py @@ -35,8 +35,8 @@ async def handle(msg): ... "defaultContentType": "application/json", "servers": { "development": { - "host": "", - "pathname": "localhost", + "host": "localhost", + "pathname": "", "protocol": "kafka", "protocolVersion": "auto" } From 5d32b94c8e01295ad2380dd33cf8f9a1bada6465 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 2 Aug 2024 21:05:39 +0300 Subject: [PATCH 032/245] AsyncAPI RabbitMQ fastapi tests --- tests/asyncapi/base/v3_0_0/arguments.py | 51 ++++--- tests/asyncapi/base/v3_0_0/fastapi.py | 139 ++++++++++++++++++ tests/asyncapi/base/v3_0_0/publisher.py | 21 +-- .../confluent/v3_0_0/test_arguments.py | 2 +- .../confluent/v3_0_0/test_publisher.py | 2 +- tests/asyncapi/kafka/v3_0_0/test_arguments.py | 2 +- tests/asyncapi/kafka/v3_0_0/test_publisher.py | 2 +- tests/asyncapi/nats/v3_0_0/test_arguments.py | 2 +- tests/asyncapi/nats/v3_0_0/test_publisher.py | 2 +- .../asyncapi/rabbit/v3_0_0/test_arguments.py | 2 +- tests/asyncapi/rabbit/v3_0_0/test_fastapi.py | 43 ++++++ .../asyncapi/rabbit/v3_0_0/test_publisher.py | 2 +- tests/asyncapi/redis/v3_0_0/test_arguments.py | 2 +- tests/asyncapi/redis/v3_0_0/test_publisher.py | 2 +- 14 files changed, 230 insertions(+), 44 deletions(-) create mode 100644 tests/asyncapi/base/v3_0_0/fastapi.py create mode 100644 tests/asyncapi/rabbit/v3_0_0/test_fastapi.py diff --git a/tests/asyncapi/base/v3_0_0/arguments.py b/tests/asyncapi/base/v3_0_0/arguments.py index 5c4bf1e2b3..4f2041ddbc 100644 --- a/tests/asyncapi/base/v3_0_0/arguments.py +++ b/tests/asyncapi/base/v3_0_0/arguments.py @@ -1,8 +1,7 @@ import json -import pprint from dataclasses import dataclass from enum import Enum -from typing import Optional, Type, Union +from typing import Optional, Union, Callable import pydantic from dirty_equals import IsDict, IsPartialDict, IsStr @@ -15,11 +14,12 @@ from faststream.asyncapi.generate import get_app_schema from faststream.asyncapi.version import AsyncAPIVersion from faststream.broker.core.usecase import BrokerUsecase +from faststream.broker.fastapi import StreamRouter from tests.marks import pydantic_v2 class FastAPICompatible: - broker_class: Type[BrokerUsecase] + broker_factory: Callable[[], Union[BrokerUsecase, StreamRouter]] dependency_builder = staticmethod(APIDepends) def build_app(self, broker): @@ -27,7 +27,7 @@ def build_app(self, broker): return FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0) def test_custom_naming(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber("test", title="custom_name", description="test description") async def handle(msg): ... @@ -39,7 +39,7 @@ async def handle(msg): ... assert schema["channels"][key]["description"] == "test description" def test_docstring_description(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber("test", title="custom_name") async def handle(msg): @@ -54,7 +54,7 @@ async def handle(msg): ][key]["description"] def test_empty(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber("test") async def handle(): ... @@ -71,7 +71,7 @@ async def handle(): ... } def test_no_type(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber("test") async def handle(msg): ... @@ -85,7 +85,7 @@ async def handle(msg): ... assert v == {"title": key} def test_simple_type(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber("test") async def handle(msg: int): ... @@ -100,7 +100,7 @@ async def handle(msg: int): ... assert v == {"title": key, "type": "integer"} def test_simple_optional_type(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber("test") async def handle(msg: Optional[int]): ... @@ -124,7 +124,7 @@ async def handle(msg: Optional[int]): ... ), v def test_simple_type_with_default(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber("test") async def handle(msg: int = 1): ... @@ -142,7 +142,7 @@ async def handle(msg: int = 1): ... } def test_multi_args_no_type(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber("test") async def handle(msg, another): ... @@ -164,7 +164,7 @@ async def handle(msg, another): ... } def test_multi_args_with_type(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber("test") async def handle(msg: str, another: int): ... @@ -186,7 +186,7 @@ async def handle(msg: str, another: int): ... } def test_multi_args_with_default(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber("test") async def handle(msg: str, another: Optional[int] = None): ... @@ -226,7 +226,7 @@ class User: id: int name: str = "" - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber("test") async def handle(user: User): ... @@ -252,7 +252,7 @@ class User(pydantic.BaseModel): name: str = "" id: int - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber("test") async def handle(user: User): ... @@ -283,7 +283,7 @@ class User(pydantic.BaseModel): id: int status: Status - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber("test") async def handle(user: User): ... @@ -321,7 +321,7 @@ class User(pydantic.BaseModel): id: int email: Email - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber("test") async def handle(user: User, description: str = ""): ... @@ -377,7 +377,7 @@ class User(pydantic.BaseModel): class Config: schema_extra = {"examples": [{"name": "john", "id": 1}]} # noqa: RUF012 - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber("test") async def handle(user: User): ... @@ -404,7 +404,7 @@ class User(pydantic.BaseModel): name: str = "" id: int - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber( # pragma: no branch "test", @@ -432,7 +432,7 @@ async def handle_default(msg): ... assert "HandleDefault:Message:Payload" in list(payload.keys()) def test_ignores_depends(self): - broker = self.broker_class() + broker = self.broker_factory() def dep(name: str = ""): return name @@ -475,7 +475,7 @@ class Sub(pydantic.BaseModel): Union[Sub2, Sub], pydantic.Field(discriminator="type") ] - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber("test") async def handle(user: descriminator): ... @@ -484,6 +484,9 @@ async def handle(user: descriminator): ... key = next(iter(schema["components"]["messages"].keys())) assert key == IsStr(regex=r"test[\w:]*:Handle:Message") + with open("schema5.json", "w") as file: + json.dump(schema["components"], file, indent=4) + # TODO: payload are not moved assert schema["components"] == { "messages": { key: { @@ -533,7 +536,7 @@ class Sub(pydantic.BaseModel): class Model(pydantic.BaseModel): msg: Union[Sub2, Sub] = pydantic.Field(..., discriminator="type") - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber("test") async def handle(user: Model): ... @@ -590,7 +593,7 @@ class ArgumentsTestcase(FastAPICompatible): dependency_builder = staticmethod(Depends) def test_pydantic_field(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber("msg") async def msg( @@ -619,7 +622,7 @@ async def msg( } def test_ignores_custom_field(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber("test") async def handle(id: int, user: Optional[str] = None, message=Context()): ... diff --git a/tests/asyncapi/base/v3_0_0/fastapi.py b/tests/asyncapi/base/v3_0_0/fastapi.py new file mode 100644 index 0000000000..0c6617aff0 --- /dev/null +++ b/tests/asyncapi/base/v3_0_0/fastapi.py @@ -0,0 +1,139 @@ +from typing import Any, Callable, Type + +import pytest +from dirty_equals import IsStr +from fastapi import FastAPI +from fastapi.testclient import TestClient + +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.broker.core.usecase import BrokerUsecase +from faststream.broker.fastapi.router import StreamRouter +from faststream.broker.types import MsgType + + +class FastAPITestCase: + router_factory: Type[StreamRouter[MsgType]] + broker_wrapper: Callable[[BrokerUsecase[MsgType, Any]], BrokerUsecase[MsgType, Any]] + + @pytest.mark.asyncio() + async def test_fastapi_full_information(self): + broker = self.router_factory( + protocol="custom", + protocol_version="1.1.1", + description="Test broker description", + schema_url="/asyncapi_schema", + asyncapi_tags=[{"name": "test"}], + asyncapi_version=AsyncAPIVersion.v3_0, + ) + + app = FastAPI( + lifespan=broker.lifespan_context, + title="CustomApp", + version="1.1.1", + description="Test description", + contact={"name": "support", "url": "https://support.com"}, + license_info={"name": "some", "url": "https://some.com"}, + ) + app.include_router(broker) + + async with self.broker_wrapper(broker.broker): + with TestClient(app) as client: + response_json = client.get("/asyncapi_schema.json") + + assert response_json.json() == { + "asyncapi": "3.0.0", + "defaultContentType": "application/json", + "info": { + "title": "CustomApp", + "version": "1.1.1", + "description": "Test description", + "contact": { + "name": "support", + "url": IsStr(regex=r"https\:\/\/support\.com\/?"), + }, + "license": { + "name": "some", + "url": IsStr(regex=r"https\:\/\/some\.com\/?"), + }, + }, + "servers": { + "development": { + "host": IsStr(), + "pathname": IsStr(), + "protocol": "custom", + "description": "Test broker description", + "protocolVersion": "1.1.1", + "tags": [ + { + "name": "test" + } + ] + } + }, + "channels": {}, + "operations": {}, + "components": { + "messages": {}, + "schemas": {} + } + } + + @pytest.mark.asyncio() + async def test_fastapi_asyncapi_routes(self): + broker = self.router_factory(schema_url="/asyncapi_schema", asyncapi_version=AsyncAPIVersion.v3_0, ) + + @broker.subscriber("test") + async def handler(): ... + + app = FastAPI(lifespan=broker.lifespan_context) + app.include_router(broker) + + async with self.broker_wrapper(broker.broker): + with TestClient(app) as client: + schema = get_app_schema(broker) + + response_json = client.get("/asyncapi_schema.json") + assert response_json.json() == schema.to_jsonable() + + response_yaml = client.get("/asyncapi_schema.yaml") + assert response_yaml.text == schema.to_yaml() + + response_html = client.get("/asyncapi_schema") + assert response_html.status_code == 200 + + @pytest.mark.asyncio() + async def test_fastapi_asyncapi_not_fount(self): + broker = self.router_factory(include_in_schema=False, asyncapi_version=AsyncAPIVersion.v3_0, ) + + app = FastAPI(lifespan=broker.lifespan_context) + app.include_router(broker) + + async with self.broker_wrapper(broker.broker): + with TestClient(app) as client: + response_json = client.get("/asyncapi.json") + assert response_json.status_code == 404 + + response_yaml = client.get("/asyncapi.yaml") + assert response_yaml.status_code == 404 + + response_html = client.get("/asyncapi") + assert response_html.status_code == 404 + + @pytest.mark.asyncio() + async def test_fastapi_asyncapi_not_fount_by_url(self): + broker = self.router_factory(schema_url=None, asyncapi_version=AsyncAPIVersion.v3_0, ) + + app = FastAPI(lifespan=broker.lifespan_context) + app.include_router(broker) + + async with self.broker_wrapper(broker.broker): + with TestClient(app) as client: + response_json = client.get("/asyncapi.json") + assert response_json.status_code == 404 + + response_yaml = client.get("/asyncapi.yaml") + assert response_yaml.status_code == 404 + + response_html = client.get("/asyncapi") + assert response_html.status_code == 404 diff --git a/tests/asyncapi/base/v3_0_0/publisher.py b/tests/asyncapi/base/v3_0_0/publisher.py index 9dc1df1b76..2dad4f6c97 100644 --- a/tests/asyncapi/base/v3_0_0/publisher.py +++ b/tests/asyncapi/base/v3_0_0/publisher.py @@ -1,4 +1,4 @@ -from typing import Type +from typing import Type, Callable, Union import pydantic @@ -6,17 +6,18 @@ from faststream.asyncapi.generate import get_app_schema from faststream.asyncapi.version import AsyncAPIVersion from faststream.broker.core.usecase import BrokerUsecase +from faststream.broker.fastapi import StreamRouter class PublisherTestcase: - broker_class: Type[BrokerUsecase] + broker_factory: Callable[[], Union[BrokerUsecase, StreamRouter]] def build_app(self, broker): """Patch it to test FastAPI scheme generation too.""" return FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0) def test_publisher_with_description(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.publisher("test", description="test description") async def handle(msg): ... @@ -27,7 +28,7 @@ async def handle(msg): ... assert schema["channels"][key]["description"] == "test description" def test_basic_publisher(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.publisher("test") async def handle(msg): ... @@ -43,7 +44,7 @@ async def handle(msg): ... assert v == {} def test_none_publisher(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.publisher("test") async def handle(msg): ... @@ -55,7 +56,7 @@ async def handle(msg): ... assert v == {} def test_typed_publisher(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.publisher("test") async def handle(msg) -> int: ... @@ -71,7 +72,7 @@ class User(pydantic.BaseModel): name: str = "" id: int - broker = self.broker_class() + broker = self.broker_factory() @broker.publisher("test") async def handle(msg) -> User: ... @@ -92,7 +93,7 @@ async def handle(msg) -> User: ... } def test_delayed(self): - broker = self.broker_class() + broker = self.broker_factory() pub = broker.publisher("test") @@ -106,7 +107,7 @@ async def handle(msg) -> int: ... assert v["type"] == "integer" def test_with_schema(self): - broker = self.broker_class() + broker = self.broker_factory() broker.publisher("test", title="Custom", schema=int) @@ -117,7 +118,7 @@ def test_with_schema(self): assert v["type"] == "integer" def test_not_include(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.publisher("test", include_in_schema=False) @broker.subscriber("in-test", include_in_schema=False) diff --git a/tests/asyncapi/confluent/v3_0_0/test_arguments.py b/tests/asyncapi/confluent/v3_0_0/test_arguments.py index 821d8df6be..1ca69abd9c 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_arguments.py +++ b/tests/asyncapi/confluent/v3_0_0/test_arguments.py @@ -4,7 +4,7 @@ class TestArguments(ArgumentsTestcase): - broker_class = KafkaBroker + broker_factory = KafkaBroker def test_subscriber_bindings(self): broker = self.broker_class() diff --git a/tests/asyncapi/confluent/v3_0_0/test_publisher.py b/tests/asyncapi/confluent/v3_0_0/test_publisher.py index 7cc53143e0..779163ce6d 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_publisher.py +++ b/tests/asyncapi/confluent/v3_0_0/test_publisher.py @@ -4,7 +4,7 @@ class TestArguments(PublisherTestcase): - broker_class = KafkaBroker + broker_factory = KafkaBroker def test_publisher_bindings(self): broker = self.broker_class() diff --git a/tests/asyncapi/kafka/v3_0_0/test_arguments.py b/tests/asyncapi/kafka/v3_0_0/test_arguments.py index 14c0487e6b..f3e1003f7f 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_arguments.py +++ b/tests/asyncapi/kafka/v3_0_0/test_arguments.py @@ -4,7 +4,7 @@ class TestArguments(ArgumentsTestcase): - broker_class = KafkaBroker + broker_factory = KafkaBroker def test_subscriber_bindings(self): broker = self.broker_class() diff --git a/tests/asyncapi/kafka/v3_0_0/test_publisher.py b/tests/asyncapi/kafka/v3_0_0/test_publisher.py index f86395b016..326da4ceef 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_publisher.py +++ b/tests/asyncapi/kafka/v3_0_0/test_publisher.py @@ -4,7 +4,7 @@ class TestArguments(PublisherTestcase): - broker_class = KafkaBroker + broker_factory = KafkaBroker def test_publisher_bindings(self): broker = self.broker_class() diff --git a/tests/asyncapi/nats/v3_0_0/test_arguments.py b/tests/asyncapi/nats/v3_0_0/test_arguments.py index 25f6508524..b4c2ab0e0b 100644 --- a/tests/asyncapi/nats/v3_0_0/test_arguments.py +++ b/tests/asyncapi/nats/v3_0_0/test_arguments.py @@ -4,7 +4,7 @@ class TestArguments(ArgumentsTestcase): - broker_class = NatsBroker + broker_factory = NatsBroker def test_subscriber_bindings(self): broker = self.broker_class() diff --git a/tests/asyncapi/nats/v3_0_0/test_publisher.py b/tests/asyncapi/nats/v3_0_0/test_publisher.py index 7851fce715..750ffc7ad3 100644 --- a/tests/asyncapi/nats/v3_0_0/test_publisher.py +++ b/tests/asyncapi/nats/v3_0_0/test_publisher.py @@ -4,7 +4,7 @@ class TestArguments(PublisherTestcase): - broker_class = NatsBroker + broker_factory = NatsBroker def test_publisher_bindings(self): broker = self.broker_class() diff --git a/tests/asyncapi/rabbit/v3_0_0/test_arguments.py b/tests/asyncapi/rabbit/v3_0_0/test_arguments.py index 0530fdd610..5e8c489ff6 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_arguments.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_arguments.py @@ -4,7 +4,7 @@ class TestArguments(ArgumentsTestcase): - broker_class = RabbitBroker + broker_factory = RabbitBroker def test_subscriber_bindings(self): broker = self.broker_class() diff --git a/tests/asyncapi/rabbit/v3_0_0/test_fastapi.py b/tests/asyncapi/rabbit/v3_0_0/test_fastapi.py new file mode 100644 index 0000000000..1cb3ae10a8 --- /dev/null +++ b/tests/asyncapi/rabbit/v3_0_0/test_fastapi.py @@ -0,0 +1,43 @@ +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.rabbit.fastapi import RabbitRouter +from faststream.rabbit.testing import TestRabbitBroker +from faststream.security import SASLPlaintext +from tests.asyncapi.base.v3_0_0.arguments import FastAPICompatible +from tests.asyncapi.base.v3_0_0.fastapi import FastAPITestCase +from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase + + +class TestRouterArguments(FastAPITestCase, FastAPICompatible): + broker_factory = staticmethod(lambda: RabbitRouter(asyncapi_version=AsyncAPIVersion.v3_0)) + router_factory = RabbitRouter + broker_wrapper = staticmethod(TestRabbitBroker) + + def build_app(self, router): + return router + + +class TestRouterPublisher(PublisherTestcase): + broker_factory = staticmethod(lambda: RabbitRouter(asyncapi_version=AsyncAPIVersion.v3_0)) + + def build_app(self, router): + return router + + +def test_fastapi_security_schema(): + security = SASLPlaintext(username="user", password="pass", use_ssl=False) + + router = RabbitRouter(security=security, asyncapi_version=AsyncAPIVersion.v3_0) + + schema = get_app_schema(router,).to_jsonable() + + assert schema["servers"]["development"] == { + "protocol": "amqp", + "protocolVersion": "0.9.1", + "security": [{"user-password": []}], + "host": "user:pass@localhost:5672", # pragma: allowlist secret + "pathname": "/", # pragma: allowlist secret + } + assert schema["components"]["securitySchemes"] == { + "user-password": {"type": "userPassword"} + } diff --git a/tests/asyncapi/rabbit/v3_0_0/test_publisher.py b/tests/asyncapi/rabbit/v3_0_0/test_publisher.py index b5e4011591..064dddec3f 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_publisher.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_publisher.py @@ -4,7 +4,7 @@ class TestArguments(PublisherTestcase): - broker_class = RabbitBroker + broker_factory = RabbitBroker def test_just_exchange(self): broker = self.broker_class("amqp://guest:guest@localhost:5672/vhost") diff --git a/tests/asyncapi/redis/v3_0_0/test_arguments.py b/tests/asyncapi/redis/v3_0_0/test_arguments.py index c34c88a12e..dabd62da05 100644 --- a/tests/asyncapi/redis/v3_0_0/test_arguments.py +++ b/tests/asyncapi/redis/v3_0_0/test_arguments.py @@ -4,7 +4,7 @@ class TestArguments(ArgumentsTestcase): - broker_class = RedisBroker + broker_factory = RedisBroker def test_channel_subscriber(self): broker = self.broker_class() diff --git a/tests/asyncapi/redis/v3_0_0/test_publisher.py b/tests/asyncapi/redis/v3_0_0/test_publisher.py index de7cead72a..bea3abba06 100644 --- a/tests/asyncapi/redis/v3_0_0/test_publisher.py +++ b/tests/asyncapi/redis/v3_0_0/test_publisher.py @@ -4,7 +4,7 @@ class TestArguments(PublisherTestcase): - broker_class = RedisBroker + broker_factory = RedisBroker def test_channel_publisher(self): broker = self.broker_class() From 35bc863693a5e6d873e5a6f4e182a184a74ef972 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 2 Aug 2024 21:06:07 +0300 Subject: [PATCH 033/245] RabbitRouter asyncapi_version argument --- faststream/rabbit/fastapi/router.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/faststream/rabbit/fastapi/router.py b/faststream/rabbit/fastapi/router.py index b634c2738f..9d0f0ff72d 100644 --- a/faststream/rabbit/fastapi/router.py +++ b/faststream/rabbit/fastapi/router.py @@ -21,6 +21,7 @@ from typing_extensions import Annotated, Doc, deprecated, override from faststream.__about__ import SERVICE_NAME +from faststream.asyncapi.version import AsyncAPIVersion from faststream.broker.fastapi.router import StreamRouter from faststream.broker.utils import default_filter from faststream.rabbit.broker.broker import RabbitBroker as RB @@ -180,6 +181,10 @@ def __init__( Optional[str], Doc("AsyncAPI server description."), ] = None, + asyncapi_version: Annotated[ + AsyncAPIVersion, + Doc("Version of AsyncAPI for schema generation") + ] = AsyncAPIVersion.v2_6, asyncapi_tags: Annotated[ Optional[Iterable[Union["asyncapi.Tag", "asyncapi.TagDict"]]], Doc("AsyncAPI server tags."), @@ -452,6 +457,7 @@ def __init__( logger=logger, log_level=log_level, log_fmt=log_fmt, + asyncapi_version=asyncapi_version, asyncapi_tags=asyncapi_tags, schema_url=schema_url, setup_state=setup_state, From 8136d5e4d8532d828c5ac3e814ebe2c5f920dc80 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 2 Aug 2024 21:17:16 +0300 Subject: [PATCH 034/245] tests fix --- tests/asyncapi/confluent/v3_0_0/test_arguments.py | 2 +- tests/asyncapi/confluent/v3_0_0/test_publisher.py | 2 +- tests/asyncapi/kafka/v3_0_0/test_arguments.py | 2 +- tests/asyncapi/kafka/v3_0_0/test_publisher.py | 2 +- tests/asyncapi/nats/v3_0_0/test_arguments.py | 2 +- tests/asyncapi/nats/v3_0_0/test_publisher.py | 2 +- tests/asyncapi/rabbit/v3_0_0/test_arguments.py | 4 ++-- tests/asyncapi/rabbit/v3_0_0/test_publisher.py | 8 ++++---- tests/asyncapi/redis/v3_0_0/test_arguments.py | 10 +++++----- tests/asyncapi/redis/v3_0_0/test_publisher.py | 6 +++--- 10 files changed, 20 insertions(+), 20 deletions(-) diff --git a/tests/asyncapi/confluent/v3_0_0/test_arguments.py b/tests/asyncapi/confluent/v3_0_0/test_arguments.py index 1ca69abd9c..2aed50c24e 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_arguments.py +++ b/tests/asyncapi/confluent/v3_0_0/test_arguments.py @@ -7,7 +7,7 @@ class TestArguments(ArgumentsTestcase): broker_factory = KafkaBroker def test_subscriber_bindings(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber("test") async def handle(msg): ... diff --git a/tests/asyncapi/confluent/v3_0_0/test_publisher.py b/tests/asyncapi/confluent/v3_0_0/test_publisher.py index 779163ce6d..a4e89fdc42 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_publisher.py +++ b/tests/asyncapi/confluent/v3_0_0/test_publisher.py @@ -7,7 +7,7 @@ class TestArguments(PublisherTestcase): broker_factory = KafkaBroker def test_publisher_bindings(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.publisher("test") async def handle(msg): ... diff --git a/tests/asyncapi/kafka/v3_0_0/test_arguments.py b/tests/asyncapi/kafka/v3_0_0/test_arguments.py index f3e1003f7f..f146ef6f47 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_arguments.py +++ b/tests/asyncapi/kafka/v3_0_0/test_arguments.py @@ -7,7 +7,7 @@ class TestArguments(ArgumentsTestcase): broker_factory = KafkaBroker def test_subscriber_bindings(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber("test") async def handle(msg): ... diff --git a/tests/asyncapi/kafka/v3_0_0/test_publisher.py b/tests/asyncapi/kafka/v3_0_0/test_publisher.py index 326da4ceef..3ad1f788c7 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_publisher.py +++ b/tests/asyncapi/kafka/v3_0_0/test_publisher.py @@ -7,7 +7,7 @@ class TestArguments(PublisherTestcase): broker_factory = KafkaBroker def test_publisher_bindings(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.publisher("test") async def handle(msg): ... diff --git a/tests/asyncapi/nats/v3_0_0/test_arguments.py b/tests/asyncapi/nats/v3_0_0/test_arguments.py index b4c2ab0e0b..7158237f74 100644 --- a/tests/asyncapi/nats/v3_0_0/test_arguments.py +++ b/tests/asyncapi/nats/v3_0_0/test_arguments.py @@ -7,7 +7,7 @@ class TestArguments(ArgumentsTestcase): broker_factory = NatsBroker def test_subscriber_bindings(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber("test") async def handle(msg): ... diff --git a/tests/asyncapi/nats/v3_0_0/test_publisher.py b/tests/asyncapi/nats/v3_0_0/test_publisher.py index 750ffc7ad3..0d0adbc1bd 100644 --- a/tests/asyncapi/nats/v3_0_0/test_publisher.py +++ b/tests/asyncapi/nats/v3_0_0/test_publisher.py @@ -7,7 +7,7 @@ class TestArguments(PublisherTestcase): broker_factory = NatsBroker def test_publisher_bindings(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.publisher("test") async def handle(msg): ... diff --git a/tests/asyncapi/rabbit/v3_0_0/test_arguments.py b/tests/asyncapi/rabbit/v3_0_0/test_arguments.py index 5e8c489ff6..4e66f1d214 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_arguments.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_arguments.py @@ -7,7 +7,7 @@ class TestArguments(ArgumentsTestcase): broker_factory = RabbitBroker def test_subscriber_bindings(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber( RabbitQueue("test", auto_delete=True), @@ -40,7 +40,7 @@ async def handle(msg): ... } def test_subscriber_fanout_bindings(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber( RabbitQueue("test", auto_delete=True), diff --git a/tests/asyncapi/rabbit/v3_0_0/test_publisher.py b/tests/asyncapi/rabbit/v3_0_0/test_publisher.py index 064dddec3f..4c9e94f99e 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_publisher.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_publisher.py @@ -7,7 +7,7 @@ class TestArguments(PublisherTestcase): broker_factory = RabbitBroker def test_just_exchange(self): - broker = self.broker_class("amqp://guest:guest@localhost:5672/vhost") + broker = self.broker_factory("amqp://guest:guest@localhost:5672/vhost") @broker.publisher(exchange="test-ex") async def handle(msg): ... @@ -66,7 +66,7 @@ async def handle(msg): ... } def test_publisher_bindings(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.publisher( RabbitQueue("test", auto_delete=True), @@ -99,7 +99,7 @@ async def handle(msg): ... } def test_useless_queue_bindings(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.publisher( RabbitQueue("test", auto_delete=True), @@ -153,7 +153,7 @@ async def handle(msg): ... } def test_reusable_exchange(self): - broker = self.broker_class("amqp://guest:guest@localhost:5672/vhost") + broker = self.broker_factory("amqp://guest:guest@localhost:5672/vhost") @broker.publisher(exchange="test-ex", routing_key="key1") @broker.publisher(exchange="test-ex", routing_key="key2", priority=10) diff --git a/tests/asyncapi/redis/v3_0_0/test_arguments.py b/tests/asyncapi/redis/v3_0_0/test_arguments.py index dabd62da05..77e41974f0 100644 --- a/tests/asyncapi/redis/v3_0_0/test_arguments.py +++ b/tests/asyncapi/redis/v3_0_0/test_arguments.py @@ -7,7 +7,7 @@ class TestArguments(ArgumentsTestcase): broker_factory = RedisBroker def test_channel_subscriber(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber("test") async def handle(msg): ... @@ -24,7 +24,7 @@ async def handle(msg): ... } def test_channel_pattern_subscriber(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber("test.{path}") async def handle(msg): ... @@ -41,7 +41,7 @@ async def handle(msg): ... } def test_list_subscriber(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber(list="test") async def handle(msg): ... @@ -54,7 +54,7 @@ async def handle(msg): ... } def test_stream_subscriber(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber(stream="test") async def handle(msg): ... @@ -67,7 +67,7 @@ async def handle(msg): ... } def test_stream_group_subscriber(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.subscriber(stream=StreamSub("test", group="group", consumer="consumer")) async def handle(msg): ... diff --git a/tests/asyncapi/redis/v3_0_0/test_publisher.py b/tests/asyncapi/redis/v3_0_0/test_publisher.py index bea3abba06..20814d42bf 100644 --- a/tests/asyncapi/redis/v3_0_0/test_publisher.py +++ b/tests/asyncapi/redis/v3_0_0/test_publisher.py @@ -7,7 +7,7 @@ class TestArguments(PublisherTestcase): broker_factory = RedisBroker def test_channel_publisher(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.publisher("test") async def handle(msg): ... @@ -24,7 +24,7 @@ async def handle(msg): ... } def test_list_publisher(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.publisher(list="test") async def handle(msg): ... @@ -37,7 +37,7 @@ async def handle(msg): ... } def test_stream_publisher(self): - broker = self.broker_class() + broker = self.broker_factory() @broker.publisher(stream="test") async def handle(msg): ... From 0e477fd6d5190e160c21fc735c33cc8c4a60eb2a Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 2 Aug 2024 21:22:57 +0300 Subject: [PATCH 035/245] KafkaBroker asyncapi_version argument --- faststream/kafka/fastapi/fastapi.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/faststream/kafka/fastapi/fastapi.py b/faststream/kafka/fastapi/fastapi.py index 17b8c03192..a80320e534 100644 --- a/faststream/kafka/fastapi/fastapi.py +++ b/faststream/kafka/fastapi/fastapi.py @@ -29,6 +29,7 @@ from typing_extensions import Annotated, Doc, deprecated, override from faststream.__about__ import SERVICE_NAME +from faststream.asyncapi.version import AsyncAPIVersion from faststream.broker.fastapi.router import StreamRouter from faststream.broker.utils import default_filter from faststream.kafka.broker.broker import KafkaBroker as KB @@ -306,6 +307,10 @@ def __init__( Optional[str], Doc("AsyncAPI server description."), ] = None, + asyncapi_version: Annotated[ + AsyncAPIVersion, + Doc("Version of AsyncAPI for schema generation") + ] = AsyncAPIVersion.v2_6, asyncapi_tags: Annotated[ Optional[Iterable[Union["asyncapi.Tag", "asyncapi.TagDict"]]], Doc("AsyncAPI server tags."), @@ -591,6 +596,7 @@ def __init__( protocol=protocol, description=description, protocol_version=protocol_version, + asyncapi_version=asyncapi_version, asyncapi_tags=asyncapi_tags, asyncapi_url=asyncapi_url, # FastAPI args From 80659cbdfb01474de41e9e9ae1ee7c5a8194208b Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 2 Aug 2024 21:24:39 +0300 Subject: [PATCH 036/245] AsyncAPI Kafka fastapi tests --- tests/asyncapi/kafka/v3_0_0/test_fastapi.py | 44 +++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 tests/asyncapi/kafka/v3_0_0/test_fastapi.py diff --git a/tests/asyncapi/kafka/v3_0_0/test_fastapi.py b/tests/asyncapi/kafka/v3_0_0/test_fastapi.py new file mode 100644 index 0000000000..1a2d619799 --- /dev/null +++ b/tests/asyncapi/kafka/v3_0_0/test_fastapi.py @@ -0,0 +1,44 @@ +from typing import Type + +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.kafka.fastapi import KafkaRouter +from faststream.kafka.testing import TestKafkaBroker +from faststream.security import SASLPlaintext +from tests.asyncapi.base.v3_0_0.arguments import FastAPICompatible +from tests.asyncapi.base.v3_0_0.fastapi import FastAPITestCase +from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase + + +class TestRouterArguments(FastAPITestCase, FastAPICompatible): + broker_factory = staticmethod(lambda: KafkaRouter(asyncapi_version=AsyncAPIVersion.v3_0)) + router_factory = KafkaRouter + broker_wrapper = staticmethod(TestKafkaBroker) + + def build_app(self, router): + return router + + +class TestRouterPublisher(PublisherTestcase): + broker_factory = staticmethod(lambda: KafkaRouter(asyncapi_version=AsyncAPIVersion.v3_0)) + + def build_app(self, router): + return router + + +def test_fastapi_security_schema(): + security = SASLPlaintext(username="user", password="pass", use_ssl=False) + + broker = KafkaRouter("localhost:9092", security=security) + + schema = get_app_schema(broker).to_jsonable() + + assert schema["servers"]["development"] == { + "protocol": "kafka", + "protocolVersion": "auto", + "security": [{"user-password": []}], + "url": "localhost:9092", + } + assert schema["components"]["securitySchemes"] == { + "user-password": {"type": "userPassword"} + } From b1ae755101d1479d161312cf140b39aaa7575672 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 2 Aug 2024 21:34:21 +0300 Subject: [PATCH 037/245] Confluent KafkaBroker asyncapi_version argument --- faststream/confluent/fastapi/fastapi.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/faststream/confluent/fastapi/fastapi.py b/faststream/confluent/fastapi/fastapi.py index eacfc7b37a..d4144c0f19 100644 --- a/faststream/confluent/fastapi/fastapi.py +++ b/faststream/confluent/fastapi/fastapi.py @@ -26,6 +26,7 @@ from typing_extensions import Annotated, Doc, deprecated, override from faststream.__about__ import SERVICE_NAME +from faststream.asyncapi.version import AsyncAPIVersion from faststream.broker.fastapi.router import StreamRouter from faststream.broker.utils import default_filter from faststream.confluent.broker.broker import KafkaBroker as KB @@ -298,6 +299,10 @@ def __init__( Optional[str], Doc("AsyncAPI server description."), ] = None, + asyncapi_version: Annotated[ + AsyncAPIVersion, + Doc("Version of AsyncAPI for schema generation") + ] = AsyncAPIVersion.v2_6, asyncapi_tags: Annotated[ Optional[Iterable[Union["asyncapi.Tag", "asyncapi.TagDict"]]], Doc("AsyncAPI server tags."), @@ -576,6 +581,7 @@ def __init__( protocol=protocol, description=description, protocol_version=protocol_version, + asyncapi_version=asyncapi_version, asyncapi_tags=asyncapi_tags, asyncapi_url=asyncapi_url, # FastAPI kwargs From 319da09e3c1164417e261bdee40e683a3ca983cf Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 2 Aug 2024 21:34:43 +0300 Subject: [PATCH 038/245] Confluent fastapi tests --- .../asyncapi/confluent/v3_0_0/test_fastapi.py | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 tests/asyncapi/confluent/v3_0_0/test_fastapi.py diff --git a/tests/asyncapi/confluent/v3_0_0/test_fastapi.py b/tests/asyncapi/confluent/v3_0_0/test_fastapi.py new file mode 100644 index 0000000000..7afb3c6b99 --- /dev/null +++ b/tests/asyncapi/confluent/v3_0_0/test_fastapi.py @@ -0,0 +1,44 @@ +from typing import Type + +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.confluent.fastapi import KafkaRouter +from faststream.confluent.testing import TestKafkaBroker +from faststream.security import SASLPlaintext +from tests.asyncapi.base.v3_0_0.arguments import FastAPICompatible +from tests.asyncapi.base.v3_0_0.fastapi import FastAPITestCase +from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase + + +class TestRouterArguments(FastAPITestCase, FastAPICompatible): + broker_factory = staticmethod(lambda: KafkaRouter(asyncapi_version=AsyncAPIVersion.v3_0)) + router_factory = KafkaRouter + broker_wrapper = staticmethod(TestKafkaBroker) + + def build_app(self, router): + return router + + +class TestRouterPublisher(PublisherTestcase): + broker_factory = staticmethod(lambda: KafkaRouter(asyncapi_version=AsyncAPIVersion.v3_0)) + + def build_app(self, router): + return router + + +def test_fastapi_security_schema(): + security = SASLPlaintext(username="user", password="pass", use_ssl=False) + + broker = KafkaRouter("localhost:9092", security=security) + + schema = get_app_schema(broker).to_jsonable() + + assert schema["servers"]["development"] == { + "protocol": "kafka", + "protocolVersion": "auto", + "security": [{"user-password": []}], + "url": "localhost:9092", + } + assert schema["components"]["securitySchemes"] == { + "user-password": {"type": "userPassword"} + } From fcb4f3412bf8a4060992c7d6f319a1f99c840137 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 2 Aug 2024 21:46:01 +0300 Subject: [PATCH 039/245] Nats fastapi tests --- faststream/nats/fastapi/fastapi.py | 6 ++++++ tests/asyncapi/nats/v3_0_0/test_fastapi.py | 24 ++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 tests/asyncapi/nats/v3_0_0/test_fastapi.py diff --git a/faststream/nats/fastapi/fastapi.py b/faststream/nats/fastapi/fastapi.py index 263465543e..db9152c433 100644 --- a/faststream/nats/fastapi/fastapi.py +++ b/faststream/nats/fastapi/fastapi.py @@ -33,6 +33,7 @@ from typing_extensions import Annotated, Doc, deprecated, override from faststream.__about__ import SERVICE_NAME +from faststream.asyncapi.version import AsyncAPIVersion from faststream.broker.fastapi.router import StreamRouter from faststream.broker.utils import default_filter from faststream.nats.broker import NatsBroker @@ -259,6 +260,10 @@ def __init__( Optional[str], Doc("AsyncAPI server description."), ] = None, + asyncapi_version: Annotated[ + AsyncAPIVersion, + Doc("Version of AsyncAPI for schema generation") + ] = AsyncAPIVersion.v2_6, asyncapi_tags: Annotated[ Optional[Iterable[Union["asyncapi.Tag", "asyncapi.TagDict"]]], Doc("AsyncAPI server tags."), @@ -549,6 +554,7 @@ def __init__( logger=logger, log_level=log_level, log_fmt=log_fmt, + asyncapi_version=asyncapi_version, asyncapi_tags=asyncapi_tags, schema_url=schema_url, setup_state=setup_state, diff --git a/tests/asyncapi/nats/v3_0_0/test_fastapi.py b/tests/asyncapi/nats/v3_0_0/test_fastapi.py new file mode 100644 index 0000000000..badc37b44a --- /dev/null +++ b/tests/asyncapi/nats/v3_0_0/test_fastapi.py @@ -0,0 +1,24 @@ +from typing import Type + +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.nats import TestNatsBroker +from faststream.nats.fastapi import NatsRouter +from tests.asyncapi.base.v3_0_0.arguments import FastAPICompatible +from tests.asyncapi.base.v3_0_0.fastapi import FastAPITestCase +from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase + + +class TestRouterArguments(FastAPITestCase, FastAPICompatible): + broker_factory = staticmethod(lambda: NatsRouter(asyncapi_version=AsyncAPIVersion.v3_0)) + router_factory = NatsRouter + broker_wrapper = staticmethod(TestNatsBroker) + + def build_app(self, router): + return router + + +class TestRouterPublisher(PublisherTestcase): + broker_factory = staticmethod(lambda: NatsRouter(asyncapi_version=AsyncAPIVersion.v3_0)) + + def build_app(self, router): + return router From 676a454f49150c4c4cc1628ef8d75967db28159c Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 2 Aug 2024 21:52:40 +0300 Subject: [PATCH 040/245] RedisRouter asyncapi_version argument --- faststream/redis/fastapi/fastapi.py | 6 ++++++ tests/asyncapi/redis/v3_0_0/test_fastapi.py | 0 2 files changed, 6 insertions(+) create mode 100644 tests/asyncapi/redis/v3_0_0/test_fastapi.py diff --git a/faststream/redis/fastapi/fastapi.py b/faststream/redis/fastapi/fastapi.py index 85ce2bf1e7..93c61e4a0e 100644 --- a/faststream/redis/fastapi/fastapi.py +++ b/faststream/redis/fastapi/fastapi.py @@ -27,6 +27,7 @@ from typing_extensions import Annotated, Doc, deprecated, override from faststream.__about__ import SERVICE_NAME +from faststream.asyncapi.version import AsyncAPIVersion from faststream.broker.fastapi.router import StreamRouter from faststream.broker.utils import default_filter from faststream.redis.broker.broker import RedisBroker as RB @@ -129,6 +130,10 @@ def __init__( Optional[str], Doc("AsyncAPI server description."), ] = None, + asyncapi_version: Annotated[ + AsyncAPIVersion, + Doc("Version of AsyncAPI for schema generation") + ] = AsyncAPIVersion.v2_6, asyncapi_tags: Annotated[ Optional[Iterable[Union["asyncapi.Tag", "asyncapi.TagDict"]]], Doc("AsyncAPI server tags."), @@ -410,6 +415,7 @@ def __init__( protocol=protocol, description=description, protocol_version=protocol_version, + asyncapi_version=asyncapi_version, asyncapi_tags=asyncapi_tags, asyncapi_url=asyncapi_url, # FastAPI kwargs diff --git a/tests/asyncapi/redis/v3_0_0/test_fastapi.py b/tests/asyncapi/redis/v3_0_0/test_fastapi.py new file mode 100644 index 0000000000..e69de29bb2 From c91a29bf9e4ff478e762fbda60287005fb3bc0f5 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 2 Aug 2024 21:53:21 +0300 Subject: [PATCH 041/245] Redis asyncapi fastapi tests --- tests/asyncapi/redis/v3_0_0/test_fastapi.py | 24 +++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/asyncapi/redis/v3_0_0/test_fastapi.py b/tests/asyncapi/redis/v3_0_0/test_fastapi.py index e69de29bb2..2140570c27 100644 --- a/tests/asyncapi/redis/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/redis/v3_0_0/test_fastapi.py @@ -0,0 +1,24 @@ +from typing import Type + +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.redis import TestRedisBroker +from faststream.redis.fastapi import RedisRouter +from tests.asyncapi.base.v3_0_0.arguments import FastAPICompatible +from tests.asyncapi.base.v3_0_0.fastapi import FastAPITestCase +from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase + + +class TestRouterArguments(FastAPITestCase, FastAPICompatible): + broker_factory = staticmethod(lambda: RedisRouter(asyncapi_version=AsyncAPIVersion.v3_0)) + router_factory = RedisRouter + broker_wrapper = staticmethod(TestRedisBroker) + + def build_app(self, router): + return router + + +class TestRouterPublisher(PublisherTestcase): + broker_factory = staticmethod(lambda: RedisRouter(asyncapi_version=AsyncAPIVersion.v3_0)) + + def build_app(self, router): + return router From 3af70787c93651ec033a679dc074fa49bf44c82a Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 2 Aug 2024 22:14:07 +0300 Subject: [PATCH 042/245] RabbitMQ asyncapi test connection --- .../asyncapi/rabbit/v3_0_0/test_connection.py | 143 ++++++++++++++++++ tests/asyncapi/redis/v3_0_0/test_fastapi.py | 2 - 2 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 tests/asyncapi/rabbit/v3_0_0/test_connection.py diff --git a/tests/asyncapi/rabbit/v3_0_0/test_connection.py b/tests/asyncapi/rabbit/v3_0_0/test_connection.py new file mode 100644 index 0000000000..a34940e38b --- /dev/null +++ b/tests/asyncapi/rabbit/v3_0_0/test_connection.py @@ -0,0 +1,143 @@ +from faststream import FastStream +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.schema import Tag +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.rabbit import RabbitBroker + + +def test_base(): + schema = get_app_schema( + FastStream( + RabbitBroker( + "amqps://localhost", + port=5673, + protocol_version="0.9.0", + description="Test description", + tags=(Tag(name="some-tag", description="experimental"),), + ), + asyncapi_version=AsyncAPIVersion.v3_0, + ) + ).to_jsonable() + + assert schema == { + "asyncapi": "3.0.0", + "channels": {}, + "operations": {}, + "components": {"messages": {}, "schemas": {}}, + "defaultContentType": "application/json", + "info": {"description": "", "title": "FastStream", "version": "0.1.0"}, + "servers": { + "development": { + "description": "Test description", + "protocol": "amqps", + "protocolVersion": "0.9.0", + "tags": [{"description": "experimental", "name": "some-tag"}], + "host": "guest:guest@localhost:5673", # pragma: allowlist secret + "pathname": "/", + } + }, + } + + +def test_kwargs(): + broker = RabbitBroker( + "amqp://guest:guest@localhost:5672/?heartbeat=300", # pragma: allowlist secret + host="127.0.0.1", + ) + + assert ( + broker.url + == "amqp://guest:guest@127.0.0.1:5672/?heartbeat=300" # pragma: allowlist secret + ) + + +def test_custom(): + broker = RabbitBroker( + "amqps://localhost", + asyncapi_url="amqp://guest:guest@127.0.0.1:5672/vh", # pragma: allowlist secret + ) + + broker.publisher("test") + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert ( + schema + == { + "asyncapi": "3.0.0", + "channels": { + "test:_:Publisher": { + 'address': 'test:_:Publisher', + "bindings": { + "amqp": { + "bindingVersion": "0.2.0", + "exchange": {"type": "default", "vhost": "/vh"}, + "is": "routingKey", + "queue": { + "autoDelete": False, + "durable": False, + "exclusive": False, + "name": "test", + "vhost": "/vh", + }, + } + }, + "servers": [ + { + '$ref': '#/servers/development', + } + ], + 'messages': { + 'Message': { + '$ref': '#/components/messages/test:_:Publisher:Message', + }, + } + } + }, + 'operations': { + 'test:_:Publisher': { + 'action': 'send', + 'bindings': { + 'amqp': { + 'ack': True, + 'bindingVersion': '0.2.0', + 'cc': 'test', + 'deliveryMode': 1, + 'mandatory': True, + }, + }, + 'channel': { + '$ref': '#/channels/test:_:Publisher', + }, + 'messages': [ + { + '$ref': '#/channels/test:_:Publisher/messages/Message', + }, + ], + }, + }, + "components": { + "messages": { + "test:_:Publisher:Message": { + "correlationId": { + "location": "$message.header#/correlation_id" + }, + "payload": { + '$ref': '#/components/schemas/test:_:Publisher:Message:Payload' + }, + "title": "test:_:Publisher:Message", + } + }, + "schemas": {'test:_:Publisher:Message:Payload': {}}, + }, + "defaultContentType": "application/json", + "info": {"description": "", "title": "FastStream", "version": "0.1.0"}, + "servers": { + "development": { + "protocol": "amqp", + "protocolVersion": "0.9.1", + "host": "guest:guest@127.0.0.1:5672", # pragma: allowlist secret + "pathname": "/vh", # pragma: allowlist secret + } + }, + } + ) diff --git a/tests/asyncapi/redis/v3_0_0/test_fastapi.py b/tests/asyncapi/redis/v3_0_0/test_fastapi.py index 2140570c27..a588c33b54 100644 --- a/tests/asyncapi/redis/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/redis/v3_0_0/test_fastapi.py @@ -1,5 +1,3 @@ -from typing import Type - from faststream.asyncapi.version import AsyncAPIVersion from faststream.redis import TestRedisBroker from faststream.redis.fastapi import RedisRouter From 1d769af8385d1743c9eaefd3806a0f692a258c3d Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 3 Aug 2024 10:00:01 +0300 Subject: [PATCH 043/245] Kafka asyncapi connection test --- .../confluent/v3_0_0/test_connection.py | 0 .../asyncapi/kafka/v3_0_0/test_connection.py | 104 ++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 tests/asyncapi/confluent/v3_0_0/test_connection.py create mode 100644 tests/asyncapi/kafka/v3_0_0/test_connection.py diff --git a/tests/asyncapi/confluent/v3_0_0/test_connection.py b/tests/asyncapi/confluent/v3_0_0/test_connection.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/asyncapi/kafka/v3_0_0/test_connection.py b/tests/asyncapi/kafka/v3_0_0/test_connection.py new file mode 100644 index 0000000000..107338fb82 --- /dev/null +++ b/tests/asyncapi/kafka/v3_0_0/test_connection.py @@ -0,0 +1,104 @@ +from faststream import FastStream +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.schema import Tag +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.kafka import KafkaBroker + + +def test_base(): + schema = get_app_schema( + FastStream( + KafkaBroker( + "kafka:9092", + protocol="plaintext", + protocol_version="0.9.0", + description="Test description", + tags=(Tag(name="some-tag", description="experimental"),), + ), + asyncapi_version=AsyncAPIVersion.v3_0, + ) + ).to_jsonable() + + assert schema == { + "asyncapi": "3.0.0", + "channels": {}, + "operations": {}, + "components": {"messages": {}, "schemas": {}}, + "defaultContentType": "application/json", + "info": {"description": "", "title": "FastStream", "version": "0.1.0"}, + "servers": { + "development": { + "description": "Test description", + "protocol": "plaintext", + "protocolVersion": "0.9.0", + "tags": [{"description": "experimental", "name": "some-tag"}], + "host": "kafka:9092", + "pathname": "", + } + }, + } + + +def test_multi(): + schema = get_app_schema( + FastStream( + KafkaBroker(["kafka:9092", "kafka:9093"]), + asyncapi_version=AsyncAPIVersion.v3_0, + ) + ).to_jsonable() + + assert schema == { + "asyncapi": "3.0.0", + "channels": {}, + "operations": {}, + "components": {"messages": {}, "schemas": {}}, + "defaultContentType": "application/json", + "info": {"description": "", "title": "FastStream", "version": "0.1.0"}, + "servers": { + "Server1": { + "protocol": "kafka", + "protocolVersion": "auto", + "host": "kafka:9092", + "pathname": "", + }, + "Server2": { + "protocol": "kafka", + "protocolVersion": "auto", + "host": "kafka:9093", + "pathname": "", + }, + }, + } + + +def test_custom(): + schema = get_app_schema( + FastStream( + KafkaBroker( + ["kafka:9092", "kafka:9093"], + asyncapi_url=["kafka:9094", "kafka:9095"], + ), + asyncapi_version=AsyncAPIVersion.v3_0, + ) + ).to_jsonable() + + assert schema == { + "asyncapi": "3.0.0", + "channels": {}, + "operations": {}, + "components": {"messages": {}, "schemas": {}}, + "defaultContentType": "application/json", + "info": {"description": "", "title": "FastStream", "version": "0.1.0"}, + "servers": { + "Server1": { + "protocol": "kafka", + "protocolVersion": "auto", + "url": "kafka:9094", + }, + "Server2": { + "protocol": "kafka", + "protocolVersion": "auto", + "url": "kafka:9095", + }, + }, + } From ae9c4e602eb86d8e9b4e11d8a2b26066db871635 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 3 Aug 2024 10:04:26 +0300 Subject: [PATCH 044/245] Confluent asyncapi connection test --- .../confluent/v3_0_0/test_connection.py | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/tests/asyncapi/confluent/v3_0_0/test_connection.py b/tests/asyncapi/confluent/v3_0_0/test_connection.py index e69de29bb2..99de423865 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_connection.py +++ b/tests/asyncapi/confluent/v3_0_0/test_connection.py @@ -0,0 +1,104 @@ +from faststream import FastStream +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.schema import Tag +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.confluent import KafkaBroker + + +def test_base(): + schema = get_app_schema( + FastStream( + KafkaBroker( + "kafka:9092", + protocol="plaintext", + protocol_version="0.9.0", + description="Test description", + tags=(Tag(name="some-tag", description="experimental"),), + ), + asyncapi_version=AsyncAPIVersion.v3_0, + ) + ).to_jsonable() + + assert schema == { + "asyncapi": "3.0.0", + "channels": {}, + "operations": {}, + "components": {"messages": {}, "schemas": {}}, + "defaultContentType": "application/json", + "info": {"description": "", "title": "FastStream", "version": "0.1.0"}, + "servers": { + "development": { + "description": "Test description", + "protocol": "plaintext", + "protocolVersion": "0.9.0", + "tags": [{"description": "experimental", "name": "some-tag"}], + "host": "kafka:9092", + "pathname": "", + } + }, + } + + +def test_multi(): + schema = get_app_schema( + FastStream( + KafkaBroker(["kafka:9092", "kafka:9093"]), + asyncapi_version=AsyncAPIVersion.v3_0, + ) + ).to_jsonable() + + assert schema == { + "asyncapi": "3.0.0", + "channels": {}, + "operations": {}, + "components": {"messages": {}, "schemas": {}}, + "defaultContentType": "application/json", + "info": {"description": "", "title": "FastStream", "version": "0.1.0"}, + "servers": { + "Server1": { + "protocol": "kafka", + "protocolVersion": "auto", + "host": "kafka:9092", + "pathname": "", + }, + "Server2": { + "protocol": "kafka", + "protocolVersion": "auto", + "host": "kafka:9093", + "pathname": "", + }, + }, + } + + +def test_custom(): + schema = get_app_schema( + FastStream( + KafkaBroker( + ["kafka:9092", "kafka:9093"], + asyncapi_url=["kafka:9094", "kafka:9095"], + ), + asyncapi_version=AsyncAPIVersion.v3_0, + ) + ).to_jsonable() + + assert schema == { + "asyncapi": "3.0.0", + "channels": {}, + "operations": {}, + "components": {"messages": {}, "schemas": {}}, + "defaultContentType": "application/json", + "info": {"description": "", "title": "FastStream", "version": "0.1.0"}, + "servers": { + "Server1": { + "protocol": "kafka", + "protocolVersion": "auto", + "url": "kafka:9094", + }, + "Server2": { + "protocol": "kafka", + "protocolVersion": "auto", + "url": "kafka:9095", + }, + }, + } From 29c1804bd113ed7eb788407b43ed14c1c596c365 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 3 Aug 2024 10:10:12 +0300 Subject: [PATCH 045/245] Nats asyncapi connection test --- tests/asyncapi/nats/v3_0_0/test_connection.py | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 tests/asyncapi/nats/v3_0_0/test_connection.py diff --git a/tests/asyncapi/nats/v3_0_0/test_connection.py b/tests/asyncapi/nats/v3_0_0/test_connection.py new file mode 100644 index 0000000000..bba75c17d4 --- /dev/null +++ b/tests/asyncapi/nats/v3_0_0/test_connection.py @@ -0,0 +1,108 @@ +from faststream import FastStream +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.schema import Tag +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.nats import NatsBroker + + +def test_base(): + schema = get_app_schema( + FastStream( + NatsBroker( + "nats:9092", + protocol="plaintext", + protocol_version="0.9.0", + description="Test description", + tags=(Tag(name="some-tag", description="experimental"),), + ), + asyncapi_version=AsyncAPIVersion.v3_0, + ) + ).to_jsonable() + + assert schema == { + "asyncapi": "3.0.0", + "channels": {}, + "operations": {}, + "components": {"messages": {}, "schemas": {}}, + "defaultContentType": "application/json", + "info": {"description": "", "title": "FastStream", "version": "0.1.0"}, + "servers": { + "development": { + "description": "Test description", + "protocol": "plaintext", + "protocolVersion": "0.9.0", + "tags": [{"description": "experimental", "name": "some-tag"}], + "host": "nats:9092", + "pathname": "", + } + }, + }, schema + + +def test_multi(): + schema = get_app_schema( + FastStream( + NatsBroker( + ["nats:9092", "nats:9093"] + ), + asyncapi_version=AsyncAPIVersion.v3_0, + ) + ).to_jsonable() + + assert schema == { + "asyncapi": "3.0.0", + "channels": {}, + "operations": {}, + "components": {"messages": {}, "schemas": {}}, + "defaultContentType": "application/json", + "info": {"description": "", "title": "FastStream", "version": "0.1.0"}, + "servers": { + "Server1": { + "protocol": "nats", + "protocolVersion": "custom", + "host": "nats:9092", + "pathname": "", + }, + "Server2": { + "protocol": "nats", + "protocolVersion": "custom", + "host": "nats:9093", + "pathname": "", + }, + }, + } + + +def test_custom(): + schema = get_app_schema( + FastStream( + NatsBroker( + ["nats:9092", "nats:9093"], + asyncapi_url=["nats:9094", "nats:9095"], + ), + asyncapi_version=AsyncAPIVersion.v3_0, + ) + ).to_jsonable() + + assert schema == { + "asyncapi": "3.0.0", + "channels": {}, + "operations": {}, + "components": {"messages": {}, "schemas": {}}, + "defaultContentType": "application/json", + "info": {"description": "", "title": "FastStream", "version": "0.1.0"}, + "servers": { + "Server1": { + "protocol": "nats", + "protocolVersion": "custom", + "host": "nats:9094", + "pathname": "", + }, + "Server2": { + "protocol": "nats", + "protocolVersion": "custom", + "host": "nats:9095", + "pathname": "", + }, + }, + } From aebada3de3f8494c6d35128c16d72e0cb9a65a47 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 3 Aug 2024 10:15:06 +0300 Subject: [PATCH 046/245] Redis asyncapi connection test --- .../asyncapi/redis/v3_0_0/test_connection.py | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 tests/asyncapi/redis/v3_0_0/test_connection.py diff --git a/tests/asyncapi/redis/v3_0_0/test_connection.py b/tests/asyncapi/redis/v3_0_0/test_connection.py new file mode 100644 index 0000000000..e6eed37127 --- /dev/null +++ b/tests/asyncapi/redis/v3_0_0/test_connection.py @@ -0,0 +1,68 @@ +from faststream import FastStream +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.schema import Tag +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.redis import RedisBroker + + +def test_base(): + schema = get_app_schema( + FastStream( + RedisBroker( + "redis://localhost:6379", + protocol="plaintext", + protocol_version="0.9.0", + description="Test description", + tags=(Tag(name="some-tag", description="experimental"),), + ), + asyncapi_version=AsyncAPIVersion.v3_0, + ) + ).to_jsonable() + + assert schema == { + "asyncapi": "3.0.0", + "channels": {}, + "operations": {}, + "components": {"messages": {}, "schemas": {}}, + "defaultContentType": "application/json", + "info": {"description": "", "title": "FastStream", "version": "0.1.0"}, + "servers": { + "development": { + "description": "Test description", + "protocol": "plaintext", + "protocolVersion": "0.9.0", + "tags": [{"description": "experimental", "name": "some-tag"}], + "host": "localhost:6379", + "pathname": "", + } + }, + }, schema + + +def test_custom(): + schema = get_app_schema( + FastStream( + RedisBroker( + "redis://localhost:6379", + asyncapi_url="rediss://127.0.0.1:8000" + ), + asyncapi_version=AsyncAPIVersion.v3_0, + ) + ).to_jsonable() + + assert schema == { + "asyncapi": "3.0.0", + "channels": {}, + "operations": {}, + "components": {"messages": {}, "schemas": {}}, + "defaultContentType": "application/json", + "info": {"description": "", "title": "FastStream", "version": "0.1.0"}, + "servers": { + "development": { + "protocol": "rediss", + "protocolVersion": "custom", + "host": "127.0.0.1:8000", + "pathname": "", + } + }, + } From 47d5c0aba4250e75e68ea6741112061c3b67766e Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 3 Aug 2024 21:16:43 +0300 Subject: [PATCH 047/245] RabbitMQ AsyncAPI security tests --- tests/asyncapi/rabbit/v3_0_0/test_security.py | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 tests/asyncapi/rabbit/v3_0_0/test_security.py diff --git a/tests/asyncapi/rabbit/v3_0_0/test_security.py b/tests/asyncapi/rabbit/v3_0_0/test_security.py new file mode 100644 index 0000000000..babe62d5ea --- /dev/null +++ b/tests/asyncapi/rabbit/v3_0_0/test_security.py @@ -0,0 +1,126 @@ +import ssl + +from faststream.app import FastStream +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.rabbit import RabbitBroker +from faststream.security import ( + BaseSecurity, + SASLPlaintext, +) + + +def test_base_security_schema(): + ssl_context = ssl.create_default_context() + security = BaseSecurity(ssl_context=ssl_context) + + broker = RabbitBroker("amqp://guest:guest@localhost:5672/", security=security) + + assert ( + broker.url == "amqps://guest:guest@localhost:5672/" # pragma: allowlist secret + ) # pragma: allowlist secret + assert broker._connection_kwargs.get("ssl_context") is ssl_context + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert schema == { + "asyncapi": "3.0.0", + "channels": {}, + "operations": {}, + "components": {"messages": {}, "schemas": {}, "securitySchemes": {}}, + "defaultContentType": "application/json", + "info": {"description": "", "title": "FastStream", "version": "0.1.0"}, + "servers": { + "development": { + "protocol": "amqps", + "protocolVersion": "0.9.1", + "security": [], + "host": "guest:guest@localhost:5672", # pragma: allowlist secret + "pathname": "/", + } + }, + } + + +def test_plaintext_security_schema(): + ssl_context = ssl.create_default_context() + + security = SASLPlaintext( + ssl_context=ssl_context, + username="admin", + password="password", # pragma: allowlist secret + ) + + broker = RabbitBroker("amqp://guest:guest@localhost/", security=security) + + assert ( + broker.url + == "amqps://admin:password@localhost:5671/" # pragma: allowlist secret + ) # pragma: allowlist secret + assert broker._connection_kwargs.get("ssl_context") is ssl_context + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + assert ( + schema + == { + "asyncapi": "3.0.0", + "channels": {}, + "operations": {}, + "components": { + "messages": {}, + "schemas": {}, + "securitySchemes": {"user-password": {"type": "userPassword"}}, + }, + "defaultContentType": "application/json", + "info": {"description": "", "title": "FastStream", "version": "0.1.0"}, + "servers": { + "development": { + "protocol": "amqps", + "protocolVersion": "0.9.1", + "security": [{"user-password": []}], + "host": "admin:password@localhost:5671", # pragma: allowlist secret + "pathname": "/", + } + }, + } + ) + + +def test_plaintext_security_schema_without_ssl(): + security = SASLPlaintext( + username="admin", + password="password", # pragma: allowlist secret + ) + + broker = RabbitBroker("amqp://guest:guest@localhost:5672/", security=security) + + assert ( + broker.url + == "amqp://admin:password@localhost:5672/" # pragma: allowlist secret + ) # pragma: allowlist secret + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + assert ( + schema + == { + "asyncapi": "3.0.0", + "channels": {}, + "operations": {}, + "components": { + "messages": {}, + "schemas": {}, + "securitySchemes": {"user-password": {"type": "userPassword"}}, + }, + "defaultContentType": "application/json", + "info": {"description": "", "title": "FastStream", "version": "0.1.0"}, + "servers": { + "development": { + "protocol": "amqp", + "protocolVersion": "0.9.1", + "security": [{"user-password": []}], + "host": "admin:password@localhost:5672", # pragma: allowlist secret + "pathname": "/", # pragma: allowlist secret + } + }, + } + ) From 889a66c4bfdbc6e8181e8a60808ab1f968c4284a Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 3 Aug 2024 21:20:51 +0300 Subject: [PATCH 048/245] Kafka AsyncAPI security tests --- tests/asyncapi/kafka/v3_0_0/test_security.py | 229 +++++++++++++++++++ 1 file changed, 229 insertions(+) create mode 100644 tests/asyncapi/kafka/v3_0_0/test_security.py diff --git a/tests/asyncapi/kafka/v3_0_0/test_security.py b/tests/asyncapi/kafka/v3_0_0/test_security.py new file mode 100644 index 0000000000..d2db7d942f --- /dev/null +++ b/tests/asyncapi/kafka/v3_0_0/test_security.py @@ -0,0 +1,229 @@ +import ssl +from copy import deepcopy + +from faststream.app import FastStream +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.kafka import KafkaBroker +from faststream.security import ( + BaseSecurity, + SASLPlaintext, + SASLScram256, + SASLScram512, +) + +basic_schema = { + "info": { + "title": "FastStream", + "version": "0.1.0", + "description": "" + }, + "asyncapi": "3.0.0", + "defaultContentType": "application/json", + "servers": { + "development": { + "host": "", + "pathname": "9092", + "protocol": "kafka-secure", + "protocolVersion": "auto", + "security": [] + } + }, + "channels": { + "test_1:TestTopic": { + "address": "test_1:TestTopic", + "servers": [ + { + "$ref": "#/servers/development" + } + ], + "messages": { + "SubscribeMessage": { + "$ref": "#/components/messages/test_1:TestTopic:SubscribeMessage" + } + }, + "bindings": { + "kafka": { + "topic": "test_1", + "bindingVersion": "0.4.0" + } + } + }, + "test_2:Publisher": { + "address": "test_2:Publisher", + "servers": [ + { + "$ref": "#/servers/development" + } + ], + "messages": { + "Message": { + "$ref": "#/components/messages/test_2:Publisher:Message" + } + }, + "bindings": { + "kafka": { + "topic": "test_2", + "bindingVersion": "0.4.0" + } + } + } + }, + "operations": { + "test_1:TestTopicSubscribe": { + "action": "receive", + "messages": [ + { + "$ref": "#/channels/test_1:TestTopic/messages/SubscribeMessage" + } + ], + "channel": { + "$ref": "#/channels/test_1:TestTopic" + } + }, + "test_2:Publisher": { + "action": "send", + "messages": [ + { + "$ref": "#/channels/test_2:Publisher/messages/Message" + } + ], + "channel": { + "$ref": "#/channels/test_2:Publisher" + } + } + }, + "components": { + "messages": { + "test_1:TestTopic:Message": { + "title": "test_1:TestTopic:Message", + "correlationId": { + "location": "$message.header#/correlation_id" + }, + "payload": { + "$ref": "#/components/schemas/TestTopic:Message:Payload" + } + }, + "test_2:Publisher:Message": { + "title": "test_2:Publisher:Message", + "correlationId": { + "location": "$message.header#/correlation_id" + }, + "payload": { + "$ref": "#/components/schemas/test_2:Publisher:Message:Payload" + } + } + }, + "schemas": { + "TestTopic:Message:Payload": { + "title": "TestTopic:Message:Payload", + "type": "string" + }, + "test_2:Publisher:Message:Payload": { + "title": "test_2:Publisher:Message:Payload", + "type": "string" + } + }, + "securitySchemes": {} + } +} + + +def test_base_security_schema(): + ssl_context = ssl.create_default_context() + security = BaseSecurity(ssl_context=ssl_context) + + broker = KafkaBroker("localhost:9092", security=security) + app = FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0) + + @broker.publisher("test_2") + @broker.subscriber("test_1") + async def test_topic(msg: str) -> str: + pass + + schema = get_app_schema(app).to_jsonable() + + assert schema == basic_schema + + +def test_plaintext_security_schema(): + ssl_context = ssl.create_default_context() + security = SASLPlaintext( + ssl_context=ssl_context, + username="admin", + password="password", # pragma: allowlist secret + ) + + broker = KafkaBroker("localhost:9092", security=security) + app = FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0) + + @broker.publisher("test_2") + @broker.subscriber("test_1") + async def test_topic(msg: str) -> str: + pass + + schema = get_app_schema(app).to_jsonable() + + plaintext_security_schema = deepcopy(basic_schema) + plaintext_security_schema["servers"]["development"]["security"] = [ + {"user-password": []} + ] + plaintext_security_schema["components"]["securitySchemes"] = { + "user-password": {"type": "userPassword"} + } + + assert schema == plaintext_security_schema + + +def test_scram256_security_schema(): + ssl_context = ssl.create_default_context() + security = SASLScram256( + ssl_context=ssl_context, + username="admin", + password="password", # pragma: allowlist secret + ) + + broker = KafkaBroker("localhost:9092", security=security) + app = FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0) + + @broker.publisher("test_2") + @broker.subscriber("test_1") + async def test_topic(msg: str) -> str: + pass + + schema = get_app_schema(app).to_jsonable() + + sasl256_security_schema = deepcopy(basic_schema) + sasl256_security_schema["servers"]["development"]["security"] = [{"scram256": []}] + sasl256_security_schema["components"]["securitySchemes"] = { + "scram256": {"type": "scramSha256"} + } + + assert schema == sasl256_security_schema + + +def test_scram512_security_schema(): + ssl_context = ssl.create_default_context() + security = SASLScram512( + ssl_context=ssl_context, + username="admin", + password="password", # pragma: allowlist secret + ) + + broker = KafkaBroker("localhost:9092", security=security) + app = FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0) + + @broker.publisher("test_2") + @broker.subscriber("test_1") + async def test_topic(msg: str) -> str: + pass + + schema = get_app_schema(app).to_jsonable() + + sasl512_security_schema = deepcopy(basic_schema) + sasl512_security_schema["servers"]["development"]["security"] = [{"scram512": []}] + sasl512_security_schema["components"]["securitySchemes"] = { + "scram512": {"type": "scramSha512"} + } + + assert schema == sasl512_security_schema From 62d68874a6a23acf173d488331bb4b04f0f3f958 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 3 Aug 2024 21:23:16 +0300 Subject: [PATCH 049/245] Confluent AsyncAPI security tests --- .../confluent/v3_0_0/test_security.py | 229 ++++++++++++++++++ 1 file changed, 229 insertions(+) create mode 100644 tests/asyncapi/confluent/v3_0_0/test_security.py diff --git a/tests/asyncapi/confluent/v3_0_0/test_security.py b/tests/asyncapi/confluent/v3_0_0/test_security.py new file mode 100644 index 0000000000..ae06f90f3d --- /dev/null +++ b/tests/asyncapi/confluent/v3_0_0/test_security.py @@ -0,0 +1,229 @@ +import ssl +from copy import deepcopy + +from faststream.app import FastStream +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.confluent import KafkaBroker +from faststream.security import ( + BaseSecurity, + SASLPlaintext, + SASLScram256, + SASLScram512, +) + +basic_schema = { + "info": { + "title": "FastStream", + "version": "0.1.0", + "description": "" + }, + "asyncapi": "3.0.0", + "defaultContentType": "application/json", + "servers": { + "development": { + "host": "", + "pathname": "9092", + "protocol": "kafka-secure", + "protocolVersion": "auto", + "security": [] + } + }, + "channels": { + "test_1:TestTopic": { + "address": "test_1:TestTopic", + "servers": [ + { + "$ref": "#/servers/development" + } + ], + "messages": { + "SubscribeMessage": { + "$ref": "#/components/messages/test_1:TestTopic:SubscribeMessage" + } + }, + "bindings": { + "kafka": { + "topic": "test_1", + "bindingVersion": "0.4.0" + } + } + }, + "test_2:Publisher": { + "address": "test_2:Publisher", + "servers": [ + { + "$ref": "#/servers/development" + } + ], + "messages": { + "Message": { + "$ref": "#/components/messages/test_2:Publisher:Message" + } + }, + "bindings": { + "kafka": { + "topic": "test_2", + "bindingVersion": "0.4.0" + } + } + } + }, + "operations": { + "test_1:TestTopicSubscribe": { + "action": "receive", + "messages": [ + { + "$ref": "#/channels/test_1:TestTopic/messages/SubscribeMessage" + } + ], + "channel": { + "$ref": "#/channels/test_1:TestTopic" + } + }, + "test_2:Publisher": { + "action": "send", + "messages": [ + { + "$ref": "#/channels/test_2:Publisher/messages/Message" + } + ], + "channel": { + "$ref": "#/channels/test_2:Publisher" + } + } + }, + "components": { + "messages": { + "test_1:TestTopic:Message": { + "title": "test_1:TestTopic:Message", + "correlationId": { + "location": "$message.header#/correlation_id" + }, + "payload": { + "$ref": "#/components/schemas/TestTopic:Message:Payload" + } + }, + "test_2:Publisher:Message": { + "title": "test_2:Publisher:Message", + "correlationId": { + "location": "$message.header#/correlation_id" + }, + "payload": { + "$ref": "#/components/schemas/test_2:Publisher:Message:Payload" + } + } + }, + "schemas": { + "TestTopic:Message:Payload": { + "title": "TestTopic:Message:Payload", + "type": "string" + }, + "test_2:Publisher:Message:Payload": { + "title": "test_2:Publisher:Message:Payload", + "type": "string" + } + }, + "securitySchemes": {} + } +} + + +def test_base_security_schema(): + ssl_context = ssl.create_default_context() + security = BaseSecurity(ssl_context=ssl_context) + + broker = KafkaBroker("localhost:9092", security=security) + app = FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0) + + @broker.publisher("test_2") + @broker.subscriber("test_1") + async def test_topic(msg: str) -> str: + pass + + schema = get_app_schema(app).to_jsonable() + + assert schema == basic_schema + + +def test_plaintext_security_schema(): + ssl_context = ssl.create_default_context() + security = SASLPlaintext( + ssl_context=ssl_context, + username="admin", + password="password", # pragma: allowlist secret + ) + + broker = KafkaBroker("localhost:9092", security=security) + app = FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0) + + @broker.publisher("test_2") + @broker.subscriber("test_1") + async def test_topic(msg: str) -> str: + pass + + schema = get_app_schema(app).to_jsonable() + + plaintext_security_schema = deepcopy(basic_schema) + plaintext_security_schema["servers"]["development"]["security"] = [ + {"user-password": []} + ] + plaintext_security_schema["components"]["securitySchemes"] = { + "user-password": {"type": "userPassword"} + } + + assert schema == plaintext_security_schema + + +def test_scram256_security_schema(): + ssl_context = ssl.create_default_context() + security = SASLScram256( + ssl_context=ssl_context, + username="admin", + password="password", # pragma: allowlist secret + ) + + broker = KafkaBroker("localhost:9092", security=security) + app = FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0) + + @broker.publisher("test_2") + @broker.subscriber("test_1") + async def test_topic(msg: str) -> str: + pass + + schema = get_app_schema(app).to_jsonable() + + sasl256_security_schema = deepcopy(basic_schema) + sasl256_security_schema["servers"]["development"]["security"] = [{"scram256": []}] + sasl256_security_schema["components"]["securitySchemes"] = { + "scram256": {"type": "scramSha256"} + } + + assert schema == sasl256_security_schema + + +def test_scram512_security_schema(): + ssl_context = ssl.create_default_context() + security = SASLScram512( + ssl_context=ssl_context, + username="admin", + password="password", # pragma: allowlist secret + ) + + broker = KafkaBroker("localhost:9092", security=security) + app = FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0) + + @broker.publisher("test_2") + @broker.subscriber("test_1") + async def test_topic(msg: str) -> str: + pass + + schema = get_app_schema(app).to_jsonable() + + sasl512_security_schema = deepcopy(basic_schema) + sasl512_security_schema["servers"]["development"]["security"] = [{"scram512": []}] + sasl512_security_schema["components"]["securitySchemes"] = { + "scram512": {"type": "scramSha512"} + } + + assert schema == sasl512_security_schema From b04315cef297a12a86d4984a13424c801ff73f18 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 3 Aug 2024 21:29:53 +0300 Subject: [PATCH 050/245] Redis AsyncAPI security tests --- tests/asyncapi/redis/v3_0_0/test_security.py | 118 +++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 tests/asyncapi/redis/v3_0_0/test_security.py diff --git a/tests/asyncapi/redis/v3_0_0/test_security.py b/tests/asyncapi/redis/v3_0_0/test_security.py new file mode 100644 index 0000000000..ac3b12849d --- /dev/null +++ b/tests/asyncapi/redis/v3_0_0/test_security.py @@ -0,0 +1,118 @@ +import ssl + +from faststream.app import FastStream +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.redis import RedisBroker +from faststream.security import ( + BaseSecurity, + SASLPlaintext, +) + + +def test_base_security_schema(): + ssl_context = ssl.create_default_context() + security = BaseSecurity(ssl_context=ssl_context) + + broker = RedisBroker("rediss://localhost:6379/", security=security) + + assert ( + broker.url == "rediss://localhost:6379/" # pragma: allowlist secret + ) # pragma: allowlist secret + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert schema == { + "asyncapi": "3.0.0", + "channels": {}, + "operations": {}, + "components": {"messages": {}, "schemas": {}, "securitySchemes": {}}, + "defaultContentType": "application/json", + "info": {"description": "", "title": "FastStream", "version": "0.1.0"}, + "servers": { + "development": { + "protocol": "rediss", + "protocolVersion": "custom", + "security": [], + "host": "localhost:6379", + "pathname": "/", + } + }, + } + + +def test_plaintext_security_schema(): + ssl_context = ssl.create_default_context() + + security = SASLPlaintext( + ssl_context=ssl_context, + username="admin", + password="password", # pragma: allowlist secret + ) + + broker = RedisBroker("redis://localhost:6379/", security=security) + + assert ( + broker.url == "redis://localhost:6379/" # pragma: allowlist secret + ) # pragma: allowlist secret + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert schema == { + "asyncapi": "3.0.0", + "channels": {}, + "operations": {}, + "components": { + "messages": {}, + "schemas": {}, + "securitySchemes": {"user-password": {"type": "userPassword"}}, + }, + "defaultContentType": "application/json", + "info": {"description": "", "title": "FastStream", "version": "0.1.0"}, + "servers": { + "development": { + "protocol": "redis", + "protocolVersion": "custom", + "security": [{"user-password": []}], + "host": "localhost:6379", + "pathname": "/", + } + }, + } + + +def test_plaintext_security_schema_without_ssl(): + security = SASLPlaintext( + username="admin", + password="password", # pragma: allowlist secret + ) + + broker = RedisBroker("redis://localhost:6379/", security=security) + + assert ( + broker.url == "redis://localhost:6379/" # pragma: allowlist secret + ) # pragma: allowlist secret + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert schema == { + "asyncapi": "3.0.0", + "channels": {}, + "operations": {}, + "components": { + "messages": {}, + "schemas": {}, + "securitySchemes": {"user-password": {"type": "userPassword"}}, + }, + "defaultContentType": "application/json", + "info": {"description": "", "title": "FastStream", "version": "0.1.0"}, + "servers": { + "development": { + "protocol": "redis", + "protocolVersion": "custom", + "security": [{"user-password": []}], + "host": "localhost:6379", + "pathname": "/", + } + }, + } From ed7d8d94addcfafc049e37b7d7aebe7f54d2b921 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 3 Aug 2024 21:43:16 +0300 Subject: [PATCH 051/245] Nats AsyncAPI kv schema test --- tests/asyncapi/nats/v3_0_0/test_kv_schema.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 tests/asyncapi/nats/v3_0_0/test_kv_schema.py diff --git a/tests/asyncapi/nats/v3_0_0/test_kv_schema.py b/tests/asyncapi/nats/v3_0_0/test_kv_schema.py new file mode 100644 index 0000000000..bcda197f31 --- /dev/null +++ b/tests/asyncapi/nats/v3_0_0/test_kv_schema.py @@ -0,0 +1,15 @@ +from faststream import FastStream +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.nats import NatsBroker + + +def test_kv_schema(): + broker = NatsBroker() + + @broker.subscriber("test", kv_watch="test") + async def handle(): ... + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert schema["channels"] == {} From 8e7e4e65b12dd0399065d5925f23c8c8ac9037b0 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 3 Aug 2024 21:43:57 +0300 Subject: [PATCH 052/245] Nats AsyncAPI obj schema test --- tests/asyncapi/nats/v3_0_0/test_obj_schema.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 tests/asyncapi/nats/v3_0_0/test_obj_schema.py diff --git a/tests/asyncapi/nats/v3_0_0/test_obj_schema.py b/tests/asyncapi/nats/v3_0_0/test_obj_schema.py new file mode 100644 index 0000000000..dd3907d73e --- /dev/null +++ b/tests/asyncapi/nats/v3_0_0/test_obj_schema.py @@ -0,0 +1,15 @@ +from faststream import FastStream +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.nats import NatsBroker + + +def test_obj_schema(): + broker = NatsBroker() + + @broker.subscriber("test", obj_watch=True) + async def handle(): ... + + schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + + assert schema["channels"] == {} From a8397681de3f69b12cf2f56ae38d6c420f9e6f12 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 3 Aug 2024 22:36:35 +0300 Subject: [PATCH 053/245] Test file structure update --- tests/asyncapi/confluent/v2_6_0/__init__.py | 3 +++ tests/asyncapi/confluent/{ => v2_6_0}/test_arguments.py | 0 tests/asyncapi/confluent/{ => v2_6_0}/test_connection.py | 0 tests/asyncapi/confluent/{ => v2_6_0}/test_fastapi.py | 0 tests/asyncapi/confluent/{ => v2_6_0}/test_naming.py | 0 tests/asyncapi/confluent/{ => v2_6_0}/test_publisher.py | 0 tests/asyncapi/confluent/{ => v2_6_0}/test_router.py | 0 tests/asyncapi/confluent/{ => v2_6_0}/test_security.py | 0 tests/asyncapi/confluent/v3_0_0/__init__.py | 3 +++ tests/asyncapi/kafka/v2_6_0/__init__.py | 3 +++ tests/asyncapi/kafka/{ => v2_6_0}/test_app.py | 0 tests/asyncapi/kafka/{ => v2_6_0}/test_arguments.py | 0 tests/asyncapi/kafka/{ => v2_6_0}/test_connection.py | 0 tests/asyncapi/kafka/{ => v2_6_0}/test_fastapi.py | 0 tests/asyncapi/kafka/{ => v2_6_0}/test_naming.py | 0 tests/asyncapi/kafka/{ => v2_6_0}/test_publisher.py | 0 tests/asyncapi/kafka/{ => v2_6_0}/test_router.py | 0 tests/asyncapi/kafka/{ => v2_6_0}/test_security.py | 0 tests/asyncapi/nats/v2_6_0/__init__.py | 3 +++ tests/asyncapi/nats/{ => v2_6_0}/test_arguments.py | 0 tests/asyncapi/nats/{ => v2_6_0}/test_connection.py | 0 tests/asyncapi/nats/{ => v2_6_0}/test_fastapi.py | 0 tests/asyncapi/nats/{ => v2_6_0}/test_kv_schema.py | 0 tests/asyncapi/nats/{ => v2_6_0}/test_naming.py | 0 tests/asyncapi/nats/{ => v2_6_0}/test_obj_schema.py | 0 tests/asyncapi/nats/{ => v2_6_0}/test_publisher.py | 0 tests/asyncapi/nats/{ => v2_6_0}/test_router.py | 0 tests/asyncapi/nats/v3_0_0/__init__.py | 3 +++ tests/asyncapi/redis/v2_6_0/__init__.py | 3 +++ tests/asyncapi/redis/{ => v2_6_0}/test_arguments.py | 0 tests/asyncapi/redis/{ => v2_6_0}/test_connection.py | 0 tests/asyncapi/redis/{ => v2_6_0}/test_fastapi.py | 0 tests/asyncapi/redis/{ => v2_6_0}/test_naming.py | 0 tests/asyncapi/redis/{ => v2_6_0}/test_publisher.py | 0 tests/asyncapi/redis/{ => v2_6_0}/test_router.py | 0 tests/asyncapi/redis/{ => v2_6_0}/test_security.py | 0 tests/asyncapi/redis/v3_0_0/__init__.py | 3 +++ 37 files changed, 21 insertions(+) create mode 100644 tests/asyncapi/confluent/v2_6_0/__init__.py rename tests/asyncapi/confluent/{ => v2_6_0}/test_arguments.py (100%) rename tests/asyncapi/confluent/{ => v2_6_0}/test_connection.py (100%) rename tests/asyncapi/confluent/{ => v2_6_0}/test_fastapi.py (100%) rename tests/asyncapi/confluent/{ => v2_6_0}/test_naming.py (100%) rename tests/asyncapi/confluent/{ => v2_6_0}/test_publisher.py (100%) rename tests/asyncapi/confluent/{ => v2_6_0}/test_router.py (100%) rename tests/asyncapi/confluent/{ => v2_6_0}/test_security.py (100%) create mode 100644 tests/asyncapi/kafka/v2_6_0/__init__.py rename tests/asyncapi/kafka/{ => v2_6_0}/test_app.py (100%) rename tests/asyncapi/kafka/{ => v2_6_0}/test_arguments.py (100%) rename tests/asyncapi/kafka/{ => v2_6_0}/test_connection.py (100%) rename tests/asyncapi/kafka/{ => v2_6_0}/test_fastapi.py (100%) rename tests/asyncapi/kafka/{ => v2_6_0}/test_naming.py (100%) rename tests/asyncapi/kafka/{ => v2_6_0}/test_publisher.py (100%) rename tests/asyncapi/kafka/{ => v2_6_0}/test_router.py (100%) rename tests/asyncapi/kafka/{ => v2_6_0}/test_security.py (100%) create mode 100644 tests/asyncapi/nats/v2_6_0/__init__.py rename tests/asyncapi/nats/{ => v2_6_0}/test_arguments.py (100%) rename tests/asyncapi/nats/{ => v2_6_0}/test_connection.py (100%) rename tests/asyncapi/nats/{ => v2_6_0}/test_fastapi.py (100%) rename tests/asyncapi/nats/{ => v2_6_0}/test_kv_schema.py (100%) rename tests/asyncapi/nats/{ => v2_6_0}/test_naming.py (100%) rename tests/asyncapi/nats/{ => v2_6_0}/test_obj_schema.py (100%) rename tests/asyncapi/nats/{ => v2_6_0}/test_publisher.py (100%) rename tests/asyncapi/nats/{ => v2_6_0}/test_router.py (100%) create mode 100644 tests/asyncapi/redis/v2_6_0/__init__.py rename tests/asyncapi/redis/{ => v2_6_0}/test_arguments.py (100%) rename tests/asyncapi/redis/{ => v2_6_0}/test_connection.py (100%) rename tests/asyncapi/redis/{ => v2_6_0}/test_fastapi.py (100%) rename tests/asyncapi/redis/{ => v2_6_0}/test_naming.py (100%) rename tests/asyncapi/redis/{ => v2_6_0}/test_publisher.py (100%) rename tests/asyncapi/redis/{ => v2_6_0}/test_router.py (100%) rename tests/asyncapi/redis/{ => v2_6_0}/test_security.py (100%) diff --git a/tests/asyncapi/confluent/v2_6_0/__init__.py b/tests/asyncapi/confluent/v2_6_0/__init__.py new file mode 100644 index 0000000000..c4a1803708 --- /dev/null +++ b/tests/asyncapi/confluent/v2_6_0/__init__.py @@ -0,0 +1,3 @@ +import pytest + +pytest.importorskip("confluent_kafka") diff --git a/tests/asyncapi/confluent/test_arguments.py b/tests/asyncapi/confluent/v2_6_0/test_arguments.py similarity index 100% rename from tests/asyncapi/confluent/test_arguments.py rename to tests/asyncapi/confluent/v2_6_0/test_arguments.py diff --git a/tests/asyncapi/confluent/test_connection.py b/tests/asyncapi/confluent/v2_6_0/test_connection.py similarity index 100% rename from tests/asyncapi/confluent/test_connection.py rename to tests/asyncapi/confluent/v2_6_0/test_connection.py diff --git a/tests/asyncapi/confluent/test_fastapi.py b/tests/asyncapi/confluent/v2_6_0/test_fastapi.py similarity index 100% rename from tests/asyncapi/confluent/test_fastapi.py rename to tests/asyncapi/confluent/v2_6_0/test_fastapi.py diff --git a/tests/asyncapi/confluent/test_naming.py b/tests/asyncapi/confluent/v2_6_0/test_naming.py similarity index 100% rename from tests/asyncapi/confluent/test_naming.py rename to tests/asyncapi/confluent/v2_6_0/test_naming.py diff --git a/tests/asyncapi/confluent/test_publisher.py b/tests/asyncapi/confluent/v2_6_0/test_publisher.py similarity index 100% rename from tests/asyncapi/confluent/test_publisher.py rename to tests/asyncapi/confluent/v2_6_0/test_publisher.py diff --git a/tests/asyncapi/confluent/test_router.py b/tests/asyncapi/confluent/v2_6_0/test_router.py similarity index 100% rename from tests/asyncapi/confluent/test_router.py rename to tests/asyncapi/confluent/v2_6_0/test_router.py diff --git a/tests/asyncapi/confluent/test_security.py b/tests/asyncapi/confluent/v2_6_0/test_security.py similarity index 100% rename from tests/asyncapi/confluent/test_security.py rename to tests/asyncapi/confluent/v2_6_0/test_security.py diff --git a/tests/asyncapi/confluent/v3_0_0/__init__.py b/tests/asyncapi/confluent/v3_0_0/__init__.py index e69de29bb2..c4a1803708 100644 --- a/tests/asyncapi/confluent/v3_0_0/__init__.py +++ b/tests/asyncapi/confluent/v3_0_0/__init__.py @@ -0,0 +1,3 @@ +import pytest + +pytest.importorskip("confluent_kafka") diff --git a/tests/asyncapi/kafka/v2_6_0/__init__.py b/tests/asyncapi/kafka/v2_6_0/__init__.py new file mode 100644 index 0000000000..bd6bc708fc --- /dev/null +++ b/tests/asyncapi/kafka/v2_6_0/__init__.py @@ -0,0 +1,3 @@ +import pytest + +pytest.importorskip("aiokafka") diff --git a/tests/asyncapi/kafka/test_app.py b/tests/asyncapi/kafka/v2_6_0/test_app.py similarity index 100% rename from tests/asyncapi/kafka/test_app.py rename to tests/asyncapi/kafka/v2_6_0/test_app.py diff --git a/tests/asyncapi/kafka/test_arguments.py b/tests/asyncapi/kafka/v2_6_0/test_arguments.py similarity index 100% rename from tests/asyncapi/kafka/test_arguments.py rename to tests/asyncapi/kafka/v2_6_0/test_arguments.py diff --git a/tests/asyncapi/kafka/test_connection.py b/tests/asyncapi/kafka/v2_6_0/test_connection.py similarity index 100% rename from tests/asyncapi/kafka/test_connection.py rename to tests/asyncapi/kafka/v2_6_0/test_connection.py diff --git a/tests/asyncapi/kafka/test_fastapi.py b/tests/asyncapi/kafka/v2_6_0/test_fastapi.py similarity index 100% rename from tests/asyncapi/kafka/test_fastapi.py rename to tests/asyncapi/kafka/v2_6_0/test_fastapi.py diff --git a/tests/asyncapi/kafka/test_naming.py b/tests/asyncapi/kafka/v2_6_0/test_naming.py similarity index 100% rename from tests/asyncapi/kafka/test_naming.py rename to tests/asyncapi/kafka/v2_6_0/test_naming.py diff --git a/tests/asyncapi/kafka/test_publisher.py b/tests/asyncapi/kafka/v2_6_0/test_publisher.py similarity index 100% rename from tests/asyncapi/kafka/test_publisher.py rename to tests/asyncapi/kafka/v2_6_0/test_publisher.py diff --git a/tests/asyncapi/kafka/test_router.py b/tests/asyncapi/kafka/v2_6_0/test_router.py similarity index 100% rename from tests/asyncapi/kafka/test_router.py rename to tests/asyncapi/kafka/v2_6_0/test_router.py diff --git a/tests/asyncapi/kafka/test_security.py b/tests/asyncapi/kafka/v2_6_0/test_security.py similarity index 100% rename from tests/asyncapi/kafka/test_security.py rename to tests/asyncapi/kafka/v2_6_0/test_security.py diff --git a/tests/asyncapi/nats/v2_6_0/__init__.py b/tests/asyncapi/nats/v2_6_0/__init__.py new file mode 100644 index 0000000000..87ead90ee6 --- /dev/null +++ b/tests/asyncapi/nats/v2_6_0/__init__.py @@ -0,0 +1,3 @@ +import pytest + +pytest.importorskip("nats") diff --git a/tests/asyncapi/nats/test_arguments.py b/tests/asyncapi/nats/v2_6_0/test_arguments.py similarity index 100% rename from tests/asyncapi/nats/test_arguments.py rename to tests/asyncapi/nats/v2_6_0/test_arguments.py diff --git a/tests/asyncapi/nats/test_connection.py b/tests/asyncapi/nats/v2_6_0/test_connection.py similarity index 100% rename from tests/asyncapi/nats/test_connection.py rename to tests/asyncapi/nats/v2_6_0/test_connection.py diff --git a/tests/asyncapi/nats/test_fastapi.py b/tests/asyncapi/nats/v2_6_0/test_fastapi.py similarity index 100% rename from tests/asyncapi/nats/test_fastapi.py rename to tests/asyncapi/nats/v2_6_0/test_fastapi.py diff --git a/tests/asyncapi/nats/test_kv_schema.py b/tests/asyncapi/nats/v2_6_0/test_kv_schema.py similarity index 100% rename from tests/asyncapi/nats/test_kv_schema.py rename to tests/asyncapi/nats/v2_6_0/test_kv_schema.py diff --git a/tests/asyncapi/nats/test_naming.py b/tests/asyncapi/nats/v2_6_0/test_naming.py similarity index 100% rename from tests/asyncapi/nats/test_naming.py rename to tests/asyncapi/nats/v2_6_0/test_naming.py diff --git a/tests/asyncapi/nats/test_obj_schema.py b/tests/asyncapi/nats/v2_6_0/test_obj_schema.py similarity index 100% rename from tests/asyncapi/nats/test_obj_schema.py rename to tests/asyncapi/nats/v2_6_0/test_obj_schema.py diff --git a/tests/asyncapi/nats/test_publisher.py b/tests/asyncapi/nats/v2_6_0/test_publisher.py similarity index 100% rename from tests/asyncapi/nats/test_publisher.py rename to tests/asyncapi/nats/v2_6_0/test_publisher.py diff --git a/tests/asyncapi/nats/test_router.py b/tests/asyncapi/nats/v2_6_0/test_router.py similarity index 100% rename from tests/asyncapi/nats/test_router.py rename to tests/asyncapi/nats/v2_6_0/test_router.py diff --git a/tests/asyncapi/nats/v3_0_0/__init__.py b/tests/asyncapi/nats/v3_0_0/__init__.py index e69de29bb2..87ead90ee6 100644 --- a/tests/asyncapi/nats/v3_0_0/__init__.py +++ b/tests/asyncapi/nats/v3_0_0/__init__.py @@ -0,0 +1,3 @@ +import pytest + +pytest.importorskip("nats") diff --git a/tests/asyncapi/redis/v2_6_0/__init__.py b/tests/asyncapi/redis/v2_6_0/__init__.py new file mode 100644 index 0000000000..4752ef19b1 --- /dev/null +++ b/tests/asyncapi/redis/v2_6_0/__init__.py @@ -0,0 +1,3 @@ +import pytest + +pytest.importorskip("redis") diff --git a/tests/asyncapi/redis/test_arguments.py b/tests/asyncapi/redis/v2_6_0/test_arguments.py similarity index 100% rename from tests/asyncapi/redis/test_arguments.py rename to tests/asyncapi/redis/v2_6_0/test_arguments.py diff --git a/tests/asyncapi/redis/test_connection.py b/tests/asyncapi/redis/v2_6_0/test_connection.py similarity index 100% rename from tests/asyncapi/redis/test_connection.py rename to tests/asyncapi/redis/v2_6_0/test_connection.py diff --git a/tests/asyncapi/redis/test_fastapi.py b/tests/asyncapi/redis/v2_6_0/test_fastapi.py similarity index 100% rename from tests/asyncapi/redis/test_fastapi.py rename to tests/asyncapi/redis/v2_6_0/test_fastapi.py diff --git a/tests/asyncapi/redis/test_naming.py b/tests/asyncapi/redis/v2_6_0/test_naming.py similarity index 100% rename from tests/asyncapi/redis/test_naming.py rename to tests/asyncapi/redis/v2_6_0/test_naming.py diff --git a/tests/asyncapi/redis/test_publisher.py b/tests/asyncapi/redis/v2_6_0/test_publisher.py similarity index 100% rename from tests/asyncapi/redis/test_publisher.py rename to tests/asyncapi/redis/v2_6_0/test_publisher.py diff --git a/tests/asyncapi/redis/test_router.py b/tests/asyncapi/redis/v2_6_0/test_router.py similarity index 100% rename from tests/asyncapi/redis/test_router.py rename to tests/asyncapi/redis/v2_6_0/test_router.py diff --git a/tests/asyncapi/redis/test_security.py b/tests/asyncapi/redis/v2_6_0/test_security.py similarity index 100% rename from tests/asyncapi/redis/test_security.py rename to tests/asyncapi/redis/v2_6_0/test_security.py diff --git a/tests/asyncapi/redis/v3_0_0/__init__.py b/tests/asyncapi/redis/v3_0_0/__init__.py index e69de29bb2..4752ef19b1 100644 --- a/tests/asyncapi/redis/v3_0_0/__init__.py +++ b/tests/asyncapi/redis/v3_0_0/__init__.py @@ -0,0 +1,3 @@ +import pytest + +pytest.importorskip("redis") From f92dc6d1e334fab8bd7641961b677197de38290b Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 3 Aug 2024 23:42:43 +0300 Subject: [PATCH 054/245] AsyncAPI 3.0.0 schemas files structure refactoring --- faststream/asyncapi/generate.py | 1 - faststream/asyncapi/schema/__init__.py | 8 +- faststream/asyncapi/schema/info.py | 32 ----- faststream/asyncapi/schema/main.py | 111 +----------------- .../schema/{v3 => v2_6_0}/__init__.py | 0 faststream/asyncapi/schema/v3_0_0/__init__.py | 15 +++ .../schema/{v3 => v3_0_0}/channels.py | 2 +- .../asyncapi/schema/v3_0_0/components.py | 55 +++++++++ faststream/asyncapi/schema/v3_0_0/info.py | 47 ++++++++ .../schema/{v3 => v3_0_0}/operations.py | 6 +- faststream/asyncapi/schema/v3_0_0/schema.py | 64 ++++++++++ .../asyncapi/schema/{v3 => v3_0_0}/servers.py | 2 +- 12 files changed, 189 insertions(+), 154 deletions(-) rename faststream/asyncapi/schema/{v3 => v2_6_0}/__init__.py (100%) create mode 100644 faststream/asyncapi/schema/v3_0_0/__init__.py rename faststream/asyncapi/schema/{v3 => v3_0_0}/channels.py (97%) create mode 100644 faststream/asyncapi/schema/v3_0_0/components.py create mode 100644 faststream/asyncapi/schema/v3_0_0/info.py rename faststream/asyncapi/schema/{v3 => v3_0_0}/operations.py (90%) create mode 100644 faststream/asyncapi/schema/v3_0_0/schema.py rename faststream/asyncapi/schema/{v3 => v3_0_0}/servers.py (98%) diff --git a/faststream/asyncapi/generate.py b/faststream/asyncapi/generate.py index 78f3549c4b..75e934960a 100644 --- a/faststream/asyncapi/generate.py +++ b/faststream/asyncapi/generate.py @@ -1,6 +1,5 @@ from faststream.asyncapi.schema import ( BaseSchema, - ) from faststream.asyncapi.v2_6_0.generate import get_app_schema as get_app_schema_v2_6 from faststream.asyncapi.v3_0_0.generate import get_app_schema as get_app_schema_v3 diff --git a/faststream/asyncapi/schema/__init__.py b/faststream/asyncapi/schema/__init__.py index 2605adde91..1bc3daccd5 100644 --- a/faststream/asyncapi/schema/__init__.py +++ b/faststream/asyncapi/schema/__init__.py @@ -11,7 +11,6 @@ Contact, ContactDict, InfoV2_6, - InfoV3_0, License, LicenseDict, ) @@ -19,7 +18,6 @@ BaseSchema, Components, SchemaV2_6, - SchemaV3_0, ) from faststream.asyncapi.schema.message import CorrelationId, Message from faststream.asyncapi.schema.operations import Operation @@ -32,20 +30,18 @@ Tag, TagDict, ) -from faststream.asyncapi.schema.v3.operations import OperationV3_0 from faststream.asyncapi.version import AsyncAPIVersion +from . import v3_0_0 __all__ = ( # main "AsyncAPIVersion", "BaseSchema", "SchemaV2_6", - "SchemaV3_0", "Components", # info "BaseInfo", "InfoV2_6", - "InfoV3_0", "Contact", "ContactDict", "License", @@ -71,5 +67,5 @@ "SecuritySchemaComponent", # subscription "Operation", - "OperationV3_0", + "v3_0_0", ) diff --git a/faststream/asyncapi/schema/info.py b/faststream/asyncapi/schema/info.py index 970e7c019d..fcc6b4132e 100644 --- a/faststream/asyncapi/schema/info.py +++ b/faststream/asyncapi/schema/info.py @@ -3,7 +3,6 @@ Callable, Dict, Iterable, - List, Optional, Type, Union, @@ -19,16 +18,7 @@ JsonSchemaValue, with_info_plain_validator_function, ) -from faststream.asyncapi.schema.utils import ( # noqa: TCH001 - ExternalDocs, - ExternalDocsDict, - Tag, - TagDict, -) from faststream.log import logger -from faststream.types import ( # noqa: TCH001 - AnyDict, -) try: import email_validator @@ -214,25 +204,3 @@ class InfoV2_6(BaseInfo): # noqa: N801 termsOfService: Optional[AnyHttpUrl] = None contact: Optional[Union[Contact, ContactDict, Dict[str, Any]]] = None license: Optional[Union[License, LicenseDict, Dict[str, Any]]] = None - - -class InfoV3_0(BaseInfo): # noqa: N801 - """A class to represent information. - - Attributes: - termsOfService : terms of service for the information (default: None) - contact : contact information for the information (default: None) - license : license information for the information (default: None) - tags : optional list of tags - externalDocs : optional external documentation - - """ - - termsOfService: Optional[AnyHttpUrl] = None - contact: Optional[Union[Contact, ContactDict, Dict[str, Any]]] = None - license: Optional[Union[License, LicenseDict, Dict[str, Any]]] = None - tags: Optional[List[Union["Tag", "TagDict", "AnyDict"]]] = None - externalDocs: Optional[ - Union["ExternalDocs", "ExternalDocsDict", "AnyDict"] - ] = None - diff --git a/faststream/asyncapi/schema/main.py b/faststream/asyncapi/schema/main.py index b230eabcd0..eaa06199e9 100644 --- a/faststream/asyncapi/schema/main.py +++ b/faststream/asyncapi/schema/main.py @@ -4,7 +4,7 @@ from faststream._compat import PYDANTIC_V2, model_to_json, model_to_jsonable from faststream.asyncapi.schema.channels import Channel -from faststream.asyncapi.schema.info import BaseInfo, InfoV2_6, InfoV3_0 +from faststream.asyncapi.schema.info import BaseInfo, InfoV2_6 from faststream.asyncapi.schema.message import Message from faststream.asyncapi.schema.servers import Server from faststream.asyncapi.schema.utils import ( @@ -13,13 +13,8 @@ Tag, TagDict, ) -from faststream.asyncapi.schema.v3.channels import ChannelV3_0 -from faststream.asyncapi.schema.v3.operations import OperationV3_0 -from faststream.asyncapi.schema.v3.servers import ServerV3_0 from faststream.asyncapi.version import AsyncAPIVersion -ASYNC_API_VERSION = "2.6.0" - class Components(BaseModel): # TODO @@ -70,55 +65,6 @@ class Config: extra = "allow" -class ComponentsV3_0(BaseModel): - # TODO - # servers - # serverVariables - # channels - """A class to represent components in a system. - - Attributes: - messages : Optional dictionary of messages - schemas : Optional dictionary of schemas - - Note: - The following attributes are not implemented yet: - - servers - - serverVariables - - channels - - securitySchemes - - parameters - - correlationIds - - operationTraits - - messageTraits - - serverBindings - - channelBindings - - operationBindings - - messageBindings - - """ - - messages: Optional[Dict[str, Message]] = None - schemas: Optional[Dict[str, Dict[str, Any]]] = None - securitySchemes: Optional[Dict[str, Dict[str, Any]]] = None - # parameters - # correlationIds - # operationTraits - # messageTraits - # serverBindings - # channelBindings - # operationBindings - # messageBindings - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" - - class BaseSchema(BaseModel): """A class to represent a schema. @@ -217,58 +163,3 @@ def to_yaml(self) -> str: io = StringIO(initial_value="", newline="\n") yaml.dump(self.to_jsonable(), io, sort_keys=False) return io.getvalue() - - -class SchemaV3_0(BaseSchema): # noqa: N801 - """A class to represent a schema. - - Attributes: - asyncapi : version of the async API - id : optional ID - defaultContentType : optional default content type - info : information about the schema - servers : optional dictionary of servers - channels : dictionary of channels - components : optional components of the schema - - Methods: - to_jsonable() -> Any: Convert the schema to a JSON-serializable object. - to_json() -> str: Convert the schema to a JSON string. - to_yaml() -> str: Convert the schema to a YAML string. - - """ - - asyncapi: AsyncAPIVersion = AsyncAPIVersion.v3_0 - id: Optional[str] = None - defaultContentType: Optional[str] = None - info: InfoV3_0 - servers: Optional[Dict[str, ServerV3_0]] = None - channels: Dict[str, ChannelV3_0] - operations: Dict[str, OperationV3_0] - components: Optional[Components] = None - - def to_jsonable(self) -> Any: - """Convert the schema to a JSON-serializable object.""" - return model_to_jsonable( - self, - by_alias=True, - exclude_none=True, - ) - - def to_json(self) -> str: - """Convert the schema to a JSON string.""" - return model_to_json( - self, - by_alias=True, - exclude_none=True, - ) - - def to_yaml(self) -> str: - """Convert the schema to a YAML string.""" - from io import StringIO - - import yaml - - io = StringIO(initial_value="", newline="\n") - yaml.dump(self.to_jsonable(), io, sort_keys=False) - return io.getvalue() diff --git a/faststream/asyncapi/schema/v3/__init__.py b/faststream/asyncapi/schema/v2_6_0/__init__.py similarity index 100% rename from faststream/asyncapi/schema/v3/__init__.py rename to faststream/asyncapi/schema/v2_6_0/__init__.py diff --git a/faststream/asyncapi/schema/v3_0_0/__init__.py b/faststream/asyncapi/schema/v3_0_0/__init__.py new file mode 100644 index 0000000000..01a9788a2e --- /dev/null +++ b/faststream/asyncapi/schema/v3_0_0/__init__.py @@ -0,0 +1,15 @@ +from .channels import Channel +from .components import Components +from .info import Info +from .operations import Operation +from .schema import Schema +from .servers import Server + +__all__ = ( + "Channel", + "Components", + "Info", + "Operation", + "Schema", + "Server", +) diff --git a/faststream/asyncapi/schema/v3/channels.py b/faststream/asyncapi/schema/v3_0_0/channels.py similarity index 97% rename from faststream/asyncapi/schema/v3/channels.py rename to faststream/asyncapi/schema/v3_0_0/channels.py index 7d4803b2b3..34c1c549b1 100644 --- a/faststream/asyncapi/schema/v3/channels.py +++ b/faststream/asyncapi/schema/v3_0_0/channels.py @@ -8,7 +8,7 @@ from faststream.asyncapi.schema.utils import Parameter, Reference -class ChannelV3_0(BaseModel): +class Channel(BaseModel): """A class to represent a channel. Attributes: diff --git a/faststream/asyncapi/schema/v3_0_0/components.py b/faststream/asyncapi/schema/v3_0_0/components.py new file mode 100644 index 0000000000..ef23de6e12 --- /dev/null +++ b/faststream/asyncapi/schema/v3_0_0/components.py @@ -0,0 +1,55 @@ +from typing import Any, Dict, Optional + +from pydantic import BaseModel + +from faststream._compat import PYDANTIC_V2 +from faststream.asyncapi.schema.message import Message + + +class Components(BaseModel): + # TODO + # servers + # serverVariables + # channels + """A class to represent components in a system. + + Attributes: + messages : Optional dictionary of messages + schemas : Optional dictionary of schemas + + Note: + The following attributes are not implemented yet: + - servers + - serverVariables + - channels + - securitySchemes + - parameters + - correlationIds + - operationTraits + - messageTraits + - serverBindings + - channelBindings + - operationBindings + - messageBindings + + """ + + messages: Optional[Dict[str, Message]] = None + schemas: Optional[Dict[str, Dict[str, Any]]] = None + securitySchemes: Optional[Dict[str, Dict[str, Any]]] = None + # parameters + # correlationIds + # operationTraits + # messageTraits + # serverBindings + # channelBindings + # operationBindings + # messageBindings + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" diff --git a/faststream/asyncapi/schema/v3_0_0/info.py b/faststream/asyncapi/schema/v3_0_0/info.py new file mode 100644 index 0000000000..f210caf4d6 --- /dev/null +++ b/faststream/asyncapi/schema/v3_0_0/info.py @@ -0,0 +1,47 @@ +from typing import ( + Any, + Dict, + List, + Optional, + Union, +) + +from pydantic import AnyHttpUrl + +from faststream.asyncapi.schema.info import ( + BaseInfo, + Contact, + ContactDict, + License, + LicenseDict, +) +from faststream.asyncapi.schema.utils import ( # noqa: TCH001 + ExternalDocs, + ExternalDocsDict, + Tag, + TagDict, +) +from faststream.types import ( # noqa: TCH001 + AnyDict, +) + + +class Info(BaseInfo): # noqa: N801 + """A class to represent information. + + Attributes: + termsOfService : terms of service for the information (default: None) + contact : contact information for the information (default: None) + license : license information for the information (default: None) + tags : optional list of tags + externalDocs : optional external documentation + + """ + + termsOfService: Optional[AnyHttpUrl] = None + contact: Optional[Union[Contact, ContactDict, Dict[str, Any]]] = None + license: Optional[Union[License, LicenseDict, Dict[str, Any]]] = None + tags: Optional[List[Union["Tag", "TagDict", "AnyDict"]]] = None + externalDocs: Optional[ + Union["ExternalDocs", "ExternalDocsDict", "AnyDict"] + ] = None diff --git a/faststream/asyncapi/schema/v3/operations.py b/faststream/asyncapi/schema/v3_0_0/operations.py similarity index 90% rename from faststream/asyncapi/schema/v3/operations.py rename to faststream/asyncapi/schema/v3_0_0/operations.py index 3da166c1c3..48935eba3b 100644 --- a/faststream/asyncapi/schema/v3/operations.py +++ b/faststream/asyncapi/schema/v3_0_0/operations.py @@ -11,10 +11,10 @@ Tag, TagDict, ) -from faststream.asyncapi.schema.v3.channels import ChannelV3_0 +from faststream.asyncapi.schema.v3_0_0.channels import Channel -class OperationV3_0(BaseModel): +class Operation(BaseModel): """A class to represent an operation. Attributes: @@ -35,7 +35,7 @@ class OperationV3_0(BaseModel): bindings: Optional[OperationBinding] = None messages: List[Reference] - channel: Union[ChannelV3_0, Reference] + channel: Union[Channel, Reference] security: Optional[Dict[str, List[str]]] = None diff --git a/faststream/asyncapi/schema/v3_0_0/schema.py b/faststream/asyncapi/schema/v3_0_0/schema.py new file mode 100644 index 0000000000..30506e2a26 --- /dev/null +++ b/faststream/asyncapi/schema/v3_0_0/schema.py @@ -0,0 +1,64 @@ +from typing import Any, Dict, Optional + +from faststream._compat import model_to_json, model_to_jsonable +from faststream.asyncapi.schema.main import BaseSchema, Components +from faststream.asyncapi.schema.v3_0_0.info import Info +from faststream.asyncapi.schema.v3_0_0.channels import Channel +from faststream.asyncapi.schema.v3_0_0.operations import Operation +from faststream.asyncapi.schema.v3_0_0.servers import Server +from faststream.asyncapi.version import AsyncAPIVersion + + +class Schema(BaseSchema): # noqa: N801 + """A class to represent a schema. + + Attributes: + asyncapi : version of the async API + id : optional ID + defaultContentType : optional default content type + info : information about the schema + servers : optional dictionary of servers + channels : dictionary of channels + components : optional components of the schema + + Methods: + to_jsonable() -> Any: Convert the schema to a JSON-serializable object. + to_json() -> str: Convert the schema to a JSON string. + to_yaml() -> str: Convert the schema to a YAML string. + + """ + + asyncapi: AsyncAPIVersion = AsyncAPIVersion.v3_0 + id: Optional[str] = None + defaultContentType: Optional[str] = None + info: Info + servers: Optional[Dict[str, Server]] = None + channels: Dict[str, Channel] + operations: Dict[str, Operation] + components: Optional[Components] = None + + def to_jsonable(self) -> Any: + """Convert the schema to a JSON-serializable object.""" + return model_to_jsonable( + self, + by_alias=True, + exclude_none=True, + ) + + def to_json(self) -> str: + """Convert the schema to a JSON string.""" + return model_to_json( + self, + by_alias=True, + exclude_none=True, + ) + + def to_yaml(self) -> str: + """Convert the schema to a YAML string.""" + from io import StringIO + + import yaml + + io = StringIO(initial_value="", newline="\n") + yaml.dump(self.to_jsonable(), io, sort_keys=False) + return io.getvalue() diff --git a/faststream/asyncapi/schema/v3/servers.py b/faststream/asyncapi/schema/v3_0_0/servers.py similarity index 98% rename from faststream/asyncapi/schema/v3/servers.py rename to faststream/asyncapi/schema/v3_0_0/servers.py index 537e08992f..b63a0ac203 100644 --- a/faststream/asyncapi/schema/v3/servers.py +++ b/faststream/asyncapi/schema/v3_0_0/servers.py @@ -34,7 +34,7 @@ class Config: extra = "allow" -class ServerV3_0(BaseModel): +class Server(BaseModel): """A class to represent a server. Attributes: From d059c613e211b080c4820b6e88a1fa952202a095 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 4 Aug 2024 00:14:30 +0300 Subject: [PATCH 055/245] AsyncAPI 3.0.0 Kafka connection test fix --- tests/asyncapi/kafka/v3_0_0/test_connection.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/asyncapi/kafka/v3_0_0/test_connection.py b/tests/asyncapi/kafka/v3_0_0/test_connection.py index 107338fb82..8c1b7dc9ab 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_connection.py +++ b/tests/asyncapi/kafka/v3_0_0/test_connection.py @@ -93,12 +93,14 @@ def test_custom(): "Server1": { "protocol": "kafka", "protocolVersion": "auto", - "url": "kafka:9094", + "host": "kafka:9094", + "pathname": "", }, "Server2": { "protocol": "kafka", "protocolVersion": "auto", - "url": "kafka:9095", + "host": "kafka:9095", + "pathname": "", }, }, } From 5028e265edb73b8ab4b1ec79ac22be699b21a1d0 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 4 Aug 2024 00:20:36 +0300 Subject: [PATCH 056/245] AsyncAPI 3.0.0 tests fix --- tests/asyncapi/confluent/v3_0_0/test_connection.py | 6 ++++-- tests/asyncapi/confluent/v3_0_0/test_security.py | 4 ++-- tests/asyncapi/kafka/v3_0_0/test_security.py | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/asyncapi/confluent/v3_0_0/test_connection.py b/tests/asyncapi/confluent/v3_0_0/test_connection.py index 99de423865..0b2619454f 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_connection.py +++ b/tests/asyncapi/confluent/v3_0_0/test_connection.py @@ -93,12 +93,14 @@ def test_custom(): "Server1": { "protocol": "kafka", "protocolVersion": "auto", - "url": "kafka:9094", + "host": "kafka:9094", + "pathname": "", }, "Server2": { "protocol": "kafka", "protocolVersion": "auto", - "url": "kafka:9095", + "host": "kafka:9095", + "pathname": "", }, }, } diff --git a/tests/asyncapi/confluent/v3_0_0/test_security.py b/tests/asyncapi/confluent/v3_0_0/test_security.py index ae06f90f3d..b1ee30ca73 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_security.py +++ b/tests/asyncapi/confluent/v3_0_0/test_security.py @@ -22,8 +22,8 @@ "defaultContentType": "application/json", "servers": { "development": { - "host": "", - "pathname": "9092", + "host": "localhost:9092", + "pathname": "", "protocol": "kafka-secure", "protocolVersion": "auto", "security": [] diff --git a/tests/asyncapi/kafka/v3_0_0/test_security.py b/tests/asyncapi/kafka/v3_0_0/test_security.py index d2db7d942f..a5729e1d2d 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_security.py +++ b/tests/asyncapi/kafka/v3_0_0/test_security.py @@ -22,8 +22,8 @@ "defaultContentType": "application/json", "servers": { "development": { - "host": "", - "pathname": "9092", + "host": "localhost:9092", + "pathname": "", "protocol": "kafka-secure", "protocolVersion": "auto", "security": [] From cf69dd4cbc0b9e60fd481818286a87feeae647f1 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 8 Sep 2024 00:23:18 +0300 Subject: [PATCH 057/245] AsyncAPI schemas refactoring --- faststream/asyncapi/abc.py | 2 +- faststream/asyncapi/schema/__init__.py | 17 +-- faststream/asyncapi/schema/info.py | 21 --- faststream/asyncapi/schema/main.py | 123 +----------------- faststream/asyncapi/schema/v2_6_0/__init__.py | 15 +++ .../asyncapi/schema/{ => v2_6_0}/channels.py | 2 +- .../asyncapi/schema/v2_6_0/components.py | 61 +++++++++ faststream/asyncapi/schema/v2_6_0/info.py | 34 +++++ .../schema/{ => v2_6_0}/operations.py | 2 +- faststream/asyncapi/schema/v2_6_0/schema.py | 73 +++++++++++ faststream/asyncapi/schema/v2_6_0/servers.py | 48 +++++++ faststream/asyncapi/schema/v3_0_0/channels.py | 4 +- faststream/asyncapi/schema/v3_0_0/info.py | 2 +- faststream/asyncapi/schema/v3_0_0/schema.py | 7 +- faststream/cli/docs/app.py | 4 +- faststream/confluent/publisher/asyncapi.py | 9 +- faststream/confluent/subscriber/asyncapi.py | 9 +- faststream/kafka/publisher/asyncapi.py | 9 +- faststream/kafka/subscriber/asyncapi.py | 9 +- faststream/nats/publisher/asyncapi.py | 9 +- faststream/nats/subscriber/asyncapi.py | 13 +- faststream/rabbit/publisher/asyncapi.py | 5 +- faststream/rabbit/subscriber/asyncapi.py | 5 +- faststream/redis/publisher/asyncapi.py | 14 +- faststream/redis/subscriber/asyncapi.py | 9 +- scripts/start_test_env.sh | 2 +- 26 files changed, 289 insertions(+), 219 deletions(-) rename faststream/asyncapi/schema/{ => v2_6_0}/channels.py (95%) create mode 100644 faststream/asyncapi/schema/v2_6_0/components.py create mode 100644 faststream/asyncapi/schema/v2_6_0/info.py rename faststream/asyncapi/schema/{ => v2_6_0}/operations.py (100%) create mode 100644 faststream/asyncapi/schema/v2_6_0/schema.py create mode 100644 faststream/asyncapi/schema/v2_6_0/servers.py diff --git a/faststream/asyncapi/abc.py b/faststream/asyncapi/abc.py index 64dd0fccde..bc1faeb905 100644 --- a/faststream/asyncapi/abc.py +++ b/faststream/asyncapi/abc.py @@ -2,7 +2,7 @@ from typing import Any, Dict, Optional from faststream.asyncapi.proto import AsyncAPIProto -from faststream.asyncapi.schema.channels import Channel +from faststream.asyncapi.schema.v2_6_0.channels import Channel class AsyncAPIOperation(AsyncAPIProto): diff --git a/faststream/asyncapi/schema/__init__.py b/faststream/asyncapi/schema/__init__.py index 1bc3daccd5..eb2e8b5ff8 100644 --- a/faststream/asyncapi/schema/__init__.py +++ b/faststream/asyncapi/schema/__init__.py @@ -1,26 +1,22 @@ """AsyncAPI schema related functions.""" +from faststream.asyncapi.schema import v2_6_0, v3_0_0 from faststream.asyncapi.schema.bindings import ( ChannelBinding, OperationBinding, ServerBinding, ) -from faststream.asyncapi.schema.channels import Channel from faststream.asyncapi.schema.info import ( BaseInfo, Contact, ContactDict, - InfoV2_6, License, LicenseDict, ) from faststream.asyncapi.schema.main import ( BaseSchema, - Components, - SchemaV2_6, ) from faststream.asyncapi.schema.message import CorrelationId, Message -from faststream.asyncapi.schema.operations import Operation from faststream.asyncapi.schema.security import SecuritySchemaComponent from faststream.asyncapi.schema.servers import Server from faststream.asyncapi.schema.utils import ( @@ -31,17 +27,13 @@ TagDict, ) from faststream.asyncapi.version import AsyncAPIVersion -from . import v3_0_0 __all__ = ( # main "AsyncAPIVersion", "BaseSchema", - "SchemaV2_6", - "Components", # info "BaseInfo", - "InfoV2_6", "Contact", "ContactDict", "License", @@ -49,7 +41,6 @@ # servers "Server", # channels - "Channel", # utils "Tag", "TagDict", @@ -61,11 +52,11 @@ "ChannelBinding", "OperationBinding", # messages - "Message", "CorrelationId", + "Message", # security "SecuritySchemaComponent", - # subscription - "Operation", + # AsyncAPI schemas by versions + "v2_6_0", "v3_0_0", ) diff --git a/faststream/asyncapi/schema/info.py b/faststream/asyncapi/schema/info.py index fcc6b4132e..bc5adbc3e0 100644 --- a/faststream/asyncapi/schema/info.py +++ b/faststream/asyncapi/schema/info.py @@ -1,11 +1,9 @@ from typing import ( Any, Callable, - Dict, Iterable, Optional, Type, - Union, ) from pydantic import AnyHttpUrl, BaseModel @@ -185,22 +183,3 @@ class BaseInfo(BaseModel): class Config: extra = "allow" - - - -class InfoV2_6(BaseInfo): # noqa: N801 - """A class to represent information. - - Attributes: - title : title of the information - version : version of the information (default: "1.0.0") - description : description of the information (default: "") - termsOfService : terms of service for the information (default: None) - contact : contact information for the information (default: None) - license : license information for the information (default: None) - - """ - - termsOfService: Optional[AnyHttpUrl] = None - contact: Optional[Union[Contact, ContactDict, Dict[str, Any]]] = None - license: Optional[Union[License, LicenseDict, Dict[str, Any]]] = None diff --git a/faststream/asyncapi/schema/main.py b/faststream/asyncapi/schema/main.py index eaa06199e9..a7e6f88db5 100644 --- a/faststream/asyncapi/schema/main.py +++ b/faststream/asyncapi/schema/main.py @@ -1,68 +1,9 @@ -from typing import Any, Dict, List, Optional, Union +from typing import Any from pydantic import BaseModel -from faststream._compat import PYDANTIC_V2, model_to_json, model_to_jsonable -from faststream.asyncapi.schema.channels import Channel -from faststream.asyncapi.schema.info import BaseInfo, InfoV2_6 -from faststream.asyncapi.schema.message import Message -from faststream.asyncapi.schema.servers import Server -from faststream.asyncapi.schema.utils import ( - ExternalDocs, - ExternalDocsDict, - Tag, - TagDict, -) -from faststream.asyncapi.version import AsyncAPIVersion - - -class Components(BaseModel): - # TODO - # servers - # serverVariables - # channels - """A class to represent components in a system. - - Attributes: - messages : Optional dictionary of messages - schemas : Optional dictionary of schemas - - Note: - The following attributes are not implemented yet: - - servers - - serverVariables - - channels - - securitySchemes - - parameters - - correlationIds - - operationTraits - - messageTraits - - serverBindings - - channelBindings - - operationBindings - - messageBindings - - """ - - messages: Optional[Dict[str, Message]] = None - schemas: Optional[Dict[str, Dict[str, Any]]] = None - securitySchemes: Optional[Dict[str, Dict[str, Any]]] = None - # parameters - # correlationIds - # operationTraits - # messageTraits - # serverBindings - # channelBindings - # operationBindings - # messageBindings - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" +from faststream._compat import model_to_json, model_to_jsonable +from faststream.asyncapi.schema.info import BaseInfo class BaseSchema(BaseModel): @@ -105,61 +46,3 @@ def to_yaml(self) -> str: io = StringIO(initial_value="", newline="\n") yaml.dump(self.to_jsonable(), io, sort_keys=False) return io.getvalue() - - -class SchemaV2_6(BaseSchema): # noqa: N801 - """A class to represent a schema. - - Attributes: - asyncapi : version of the async API - id : optional ID - defaultContentType : optional default content type - info : information about the schema - servers : optional dictionary of servers - channels : dictionary of channels - components : optional components of the schema - tags : optional list of tags - externalDocs : optional external documentation - - Methods: - to_jsonable() -> Any: Convert the schema to a JSON-serializable object. - to_json() -> str: Convert the schema to a JSON string. - to_yaml() -> str: Convert the schema to a YAML string. - - """ - - asyncapi: AsyncAPIVersion = AsyncAPIVersion.v2_6 - id: Optional[str] = None - defaultContentType: Optional[str] = None - info: InfoV2_6 - servers: Optional[Dict[str, Server]] = None - channels: Dict[str, Channel] - components: Optional[Components] = None - tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = None - externalDocs: Optional[Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]] = None - - def to_jsonable(self) -> Any: - """Convert the schema to a JSON-serializable object.""" - return model_to_jsonable( - self, - by_alias=True, - exclude_none=True, - ) - - def to_json(self) -> str: - """Convert the schema to a JSON string.""" - return model_to_json( - self, - by_alias=True, - exclude_none=True, - ) - - def to_yaml(self) -> str: - """Convert the schema to a YAML string.""" - from io import StringIO - - import yaml - - io = StringIO(initial_value="", newline="\n") - yaml.dump(self.to_jsonable(), io, sort_keys=False) - return io.getvalue() diff --git a/faststream/asyncapi/schema/v2_6_0/__init__.py b/faststream/asyncapi/schema/v2_6_0/__init__.py index e69de29bb2..01a9788a2e 100644 --- a/faststream/asyncapi/schema/v2_6_0/__init__.py +++ b/faststream/asyncapi/schema/v2_6_0/__init__.py @@ -0,0 +1,15 @@ +from .channels import Channel +from .components import Components +from .info import Info +from .operations import Operation +from .schema import Schema +from .servers import Server + +__all__ = ( + "Channel", + "Components", + "Info", + "Operation", + "Schema", + "Server", +) diff --git a/faststream/asyncapi/schema/channels.py b/faststream/asyncapi/schema/v2_6_0/channels.py similarity index 95% rename from faststream/asyncapi/schema/channels.py rename to faststream/asyncapi/schema/v2_6_0/channels.py index cfee0d342b..bd2703317c 100644 --- a/faststream/asyncapi/schema/channels.py +++ b/faststream/asyncapi/schema/v2_6_0/channels.py @@ -4,8 +4,8 @@ from faststream._compat import PYDANTIC_V2 from faststream.asyncapi.schema.bindings import ChannelBinding -from faststream.asyncapi.schema.operations import Operation from faststream.asyncapi.schema.utils import Parameter +from faststream.asyncapi.schema.v2_6_0.operations import Operation class Channel(BaseModel): diff --git a/faststream/asyncapi/schema/v2_6_0/components.py b/faststream/asyncapi/schema/v2_6_0/components.py new file mode 100644 index 0000000000..32b6d2d443 --- /dev/null +++ b/faststream/asyncapi/schema/v2_6_0/components.py @@ -0,0 +1,61 @@ +from typing import ( + Any, + Dict, + Optional, +) + +from pydantic import BaseModel + +from faststream._compat import ( + PYDANTIC_V2, +) +from faststream.asyncapi.schema.message import Message + + +class Components(BaseModel): + # TODO + # servers + # serverVariables + # channels + """A class to represent components in a system. + + Attributes: + messages : Optional dictionary of messages + schemas : Optional dictionary of schemas + + Note: + The following attributes are not implemented yet: + - servers + - serverVariables + - channels + - securitySchemes + - parameters + - correlationIds + - operationTraits + - messageTraits + - serverBindings + - channelBindings + - operationBindings + - messageBindings + + """ + + messages: Optional[Dict[str, Message]] = None + schemas: Optional[Dict[str, Dict[str, Any]]] = None + securitySchemes: Optional[Dict[str, Dict[str, Any]]] = None + # parameters + # correlationIds + # operationTraits + # messageTraits + # serverBindings + # channelBindings + # operationBindings + # messageBindings + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" diff --git a/faststream/asyncapi/schema/v2_6_0/info.py b/faststream/asyncapi/schema/v2_6_0/info.py new file mode 100644 index 0000000000..d371584b32 --- /dev/null +++ b/faststream/asyncapi/schema/v2_6_0/info.py @@ -0,0 +1,34 @@ +from typing import ( + Any, + Dict, + Optional, + Union, +) + +from pydantic import AnyHttpUrl + +from faststream.asyncapi.schema.info import ( + BaseInfo, + Contact, + ContactDict, + License, + LicenseDict, +) + + +class Info(BaseInfo): + """A class to represent information. + + Attributes: + title : title of the information + version : version of the information (default: "1.0.0") + description : description of the information (default: "") + termsOfService : terms of service for the information (default: None) + contact : contact information for the information (default: None) + license : license information for the information (default: None) + + """ + + termsOfService: Optional[AnyHttpUrl] = None + contact: Optional[Union[Contact, ContactDict, Dict[str, Any]]] = None + license: Optional[Union[License, LicenseDict, Dict[str, Any]]] = None diff --git a/faststream/asyncapi/schema/operations.py b/faststream/asyncapi/schema/v2_6_0/operations.py similarity index 100% rename from faststream/asyncapi/schema/operations.py rename to faststream/asyncapi/schema/v2_6_0/operations.py index c929d71263..75627d09ac 100644 --- a/faststream/asyncapi/schema/operations.py +++ b/faststream/asyncapi/schema/v2_6_0/operations.py @@ -3,8 +3,8 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.schema.bindings import OperationBinding from faststream.asyncapi.schema.message import Message +from faststream.asyncapi.schema.bindings import OperationBinding from faststream.asyncapi.schema.utils import ( ExternalDocs, ExternalDocsDict, diff --git a/faststream/asyncapi/schema/v2_6_0/schema.py b/faststream/asyncapi/schema/v2_6_0/schema.py new file mode 100644 index 0000000000..c565f26b41 --- /dev/null +++ b/faststream/asyncapi/schema/v2_6_0/schema.py @@ -0,0 +1,73 @@ +from typing import Any, Dict, List, Optional, Union + +from faststream._compat import model_to_json, model_to_jsonable +from faststream.asyncapi.schema.main import BaseSchema +from faststream.asyncapi.schema.servers import Server +from faststream.asyncapi.schema.utils import ( + ExternalDocs, + ExternalDocsDict, + Tag, + TagDict, +) +from faststream.asyncapi.schema.v2_6_0.channels import Channel +from faststream.asyncapi.schema.v2_6_0.components import Components +from faststream.asyncapi.schema.v2_6_0.info import Info +from faststream.asyncapi.version import AsyncAPIVersion + + +class Schema(BaseSchema): + """A class to represent a schema. + + Attributes: + asyncapi : version of the async API + id : optional ID + defaultContentType : optional default content type + info : information about the schema + servers : optional dictionary of servers + channels : dictionary of channels + components : optional components of the schema + tags : optional list of tags + externalDocs : optional external documentation + + Methods: + to_jsonable() -> Any: Convert the schema to a JSON-serializable object. + to_json() -> str: Convert the schema to a JSON string. + to_yaml() -> str: Convert the schema to a YAML string. + + """ + + asyncapi: AsyncAPIVersion = AsyncAPIVersion.v2_6 + id: Optional[str] = None + defaultContentType: Optional[str] = None + info: Info + servers: Optional[Dict[str, Server]] = None + channels: Dict[str, Channel] + components: Optional[Components] = None + tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = None + externalDocs: Optional[Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]] = None + + def to_jsonable(self) -> Any: + """Convert the schema to a JSON-serializable object.""" + return model_to_jsonable( + self, + by_alias=True, + exclude_none=True, + ) + + def to_json(self) -> str: + """Convert the schema to a JSON string.""" + return model_to_json( + self, + by_alias=True, + exclude_none=True, + ) + + def to_yaml(self) -> str: + """Convert the schema to a YAML string.""" + from io import StringIO + + import yaml + + io = StringIO(initial_value="", newline="\n") + yaml.dump(self.to_jsonable(), io, sort_keys=False) + return io.getvalue() diff --git a/faststream/asyncapi/schema/v2_6_0/servers.py b/faststream/asyncapi/schema/v2_6_0/servers.py new file mode 100644 index 0000000000..7e1d892091 --- /dev/null +++ b/faststream/asyncapi/schema/v2_6_0/servers.py @@ -0,0 +1,48 @@ +from typing import Any, Dict, List, Optional, Union + +from pydantic import BaseModel + +from faststream._compat import PYDANTIC_V2 +from faststream.asyncapi.schema.bindings import ServerBinding +from faststream.asyncapi.schema.servers import SecurityRequirement, ServerVariable +from faststream.asyncapi.schema.utils import Reference, Tag, TagDict + + +class Server(BaseModel): + """A class to represent a server. + + Attributes: + url : URL of the server + protocol : protocol used by the server + description : optional description of the server + protocolVersion : optional version of the protocol used by the server + tags : optional list of tags associated with the server + security : optional security requirement for the server + variables : optional dictionary of server variables + bindings : optional server binding + + Note: + The attributes `description`, `protocolVersion`, `tags`, `security`, `variables`, and `bindings` are all optional. + + Configurations: + If `PYDANTIC_V2` is True, the model configuration is set to allow extra attributes. + Otherwise, the `Config` class is defined with the `extra` attribute set to "allow". + + """ + + url: str + protocol: str + description: Optional[str] = None + protocolVersion: Optional[str] = None + tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = None + security: Optional[SecurityRequirement] = None + variables: Optional[Dict[str, Union[ServerVariable, Reference]]] = None + bindings: Optional[Union[ServerBinding, Reference]] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" diff --git a/faststream/asyncapi/schema/v3_0_0/channels.py b/faststream/asyncapi/schema/v3_0_0/channels.py index 34c1c549b1..85190ef4da 100644 --- a/faststream/asyncapi/schema/v3_0_0/channels.py +++ b/faststream/asyncapi/schema/v3_0_0/channels.py @@ -3,8 +3,8 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.schema.bindings import ChannelBinding from faststream.asyncapi.schema.message import Message +from faststream.asyncapi.schema.bindings import ChannelBinding from faststream.asyncapi.schema.utils import Parameter, Reference @@ -26,7 +26,7 @@ class Channel(BaseModel): address: str description: Optional[str] = None - servers: Optional[List[str]] = None + servers: Optional[List[Dict[str, str]]] = None messages: Dict[str, Union[Message, Reference]] bindings: Optional[ChannelBinding] = None parameters: Optional[Parameter] = None diff --git a/faststream/asyncapi/schema/v3_0_0/info.py b/faststream/asyncapi/schema/v3_0_0/info.py index f210caf4d6..055c49fd7f 100644 --- a/faststream/asyncapi/schema/v3_0_0/info.py +++ b/faststream/asyncapi/schema/v3_0_0/info.py @@ -26,7 +26,7 @@ ) -class Info(BaseInfo): # noqa: N801 +class Info(BaseInfo): """A class to represent information. Attributes: diff --git a/faststream/asyncapi/schema/v3_0_0/schema.py b/faststream/asyncapi/schema/v3_0_0/schema.py index 30506e2a26..5b6fa1a69b 100644 --- a/faststream/asyncapi/schema/v3_0_0/schema.py +++ b/faststream/asyncapi/schema/v3_0_0/schema.py @@ -1,15 +1,16 @@ from typing import Any, Dict, Optional from faststream._compat import model_to_json, model_to_jsonable -from faststream.asyncapi.schema.main import BaseSchema, Components -from faststream.asyncapi.schema.v3_0_0.info import Info +from faststream.asyncapi.schema.main import BaseSchema from faststream.asyncapi.schema.v3_0_0.channels import Channel +from faststream.asyncapi.schema.v3_0_0.components import Components +from faststream.asyncapi.schema.v3_0_0.info import Info from faststream.asyncapi.schema.v3_0_0.operations import Operation from faststream.asyncapi.schema.v3_0_0.servers import Server from faststream.asyncapi.version import AsyncAPIVersion -class Schema(BaseSchema): # noqa: N801 +class Schema(BaseSchema): """A class to represent a schema. Attributes: diff --git a/faststream/cli/docs/app.py b/faststream/cli/docs/app.py index a1b436fc9f..845df47b22 100644 --- a/faststream/cli/docs/app.py +++ b/faststream/cli/docs/app.py @@ -8,7 +8,7 @@ from faststream._compat import json_dumps, model_parse from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.schema import SchemaV2_6 +from faststream.asyncapi.schema.v2_6_0 import Schema from faststream.asyncapi.site import serve_app from faststream.cli.utils.imports import import_from_string from faststream.exceptions import INSTALL_WATCHFILES, INSTALL_YAML @@ -184,6 +184,6 @@ def _parse_and_serve( ) # TODO: add schema choosing based on FastStream.asyncapi_version - raw_schema = model_parse(SchemaV2_6, data) + raw_schema = model_parse(Schema, data) serve_app(raw_schema, host, port) diff --git a/faststream/confluent/publisher/asyncapi.py b/faststream/confluent/publisher/asyncapi.py index f82c0a12f9..a35142139c 100644 --- a/faststream/confluent/publisher/asyncapi.py +++ b/faststream/confluent/publisher/asyncapi.py @@ -13,11 +13,10 @@ from typing_extensions import override from faststream.asyncapi.schema import ( - Channel, ChannelBinding, CorrelationId, Message, - Operation, + v2_6_0, ) from faststream.asyncapi.schema.bindings import kafka from faststream.asyncapi.utils import resolve_payloads @@ -41,13 +40,13 @@ class AsyncAPIPublisher(LogicPublisher[MsgType]): def get_name(self) -> str: return f"{self.topic}:Publisher" - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> Dict[str, v2_6_0.Channel]: payloads = self.get_payloads() return { - self.name: Channel( + self.name: v2_6_0.Channel( description=self.description, - publish=Operation( + publish=v2_6_0.Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads, "Publisher"), diff --git a/faststream/confluent/subscriber/asyncapi.py b/faststream/confluent/subscriber/asyncapi.py index ca56bec6d6..a49d7f1b1b 100644 --- a/faststream/confluent/subscriber/asyncapi.py +++ b/faststream/confluent/subscriber/asyncapi.py @@ -5,11 +5,10 @@ ) from faststream.asyncapi.schema import ( - Channel, ChannelBinding, CorrelationId, Message, - Operation, + v2_6_0, ) from faststream.asyncapi.schema.bindings import kafka from faststream.asyncapi.utils import resolve_payloads @@ -30,16 +29,16 @@ class AsyncAPISubscriber(LogicSubscriber[MsgType]): def get_name(self) -> str: return f'{",".join(self.topics)}:{self.call_name}' - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> Dict[str, v2_6_0.Channel]: channels = {} payloads = self.get_payloads() for t in self.topics: handler_name = self.title_ or f"{t}:{self.call_name}" - channels[handler_name] = Channel( + channels[handler_name] = v2_6_0.Channel( description=self.description, - subscribe=Operation( + subscribe=v2_6_0.Operation( message=Message( title=f"{handler_name}:Message", payload=resolve_payloads(payloads), diff --git a/faststream/kafka/publisher/asyncapi.py b/faststream/kafka/publisher/asyncapi.py index 623f9a2761..dba499a86f 100644 --- a/faststream/kafka/publisher/asyncapi.py +++ b/faststream/kafka/publisher/asyncapi.py @@ -13,11 +13,10 @@ from typing_extensions import override from faststream.asyncapi.schema import ( - Channel, ChannelBinding, CorrelationId, Message, - Operation, + v2_6_0, ) from faststream.asyncapi.schema.bindings import kafka from faststream.asyncapi.utils import resolve_payloads @@ -41,13 +40,13 @@ class AsyncAPIPublisher(LogicPublisher[MsgType]): def get_name(self) -> str: return f"{self.topic}:Publisher" - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> Dict[str, v2_6_0.Channel]: payloads = self.get_payloads() return { - self.name: Channel( + self.name: v2_6_0.Channel( description=self.description, - publish=Operation( + publish=v2_6_0.Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads, "Publisher"), diff --git a/faststream/kafka/subscriber/asyncapi.py b/faststream/kafka/subscriber/asyncapi.py index 9adb8dad3c..9692c9ed90 100644 --- a/faststream/kafka/subscriber/asyncapi.py +++ b/faststream/kafka/subscriber/asyncapi.py @@ -5,11 +5,10 @@ ) from faststream.asyncapi.schema import ( - Channel, ChannelBinding, CorrelationId, Message, - Operation, + v2_6_0, ) from faststream.asyncapi.schema.bindings import kafka from faststream.asyncapi.utils import resolve_payloads @@ -30,7 +29,7 @@ class AsyncAPISubscriber(LogicSubscriber[MsgType]): def get_name(self) -> str: return f'{",".join(self.topics)}:{self.call_name}' - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> Dict[str, v2_6_0.Channel]: channels = {} payloads = self.get_payloads() @@ -38,9 +37,9 @@ def get_schema(self) -> Dict[str, Channel]: for t in self.topics: handler_name = self.title_ or f"{t}:{self.call_name}" - channels[handler_name] = Channel( + channels[handler_name] = v2_6_0.Channel( description=self.description, - subscribe=Operation( + subscribe=v2_6_0.Operation( message=Message( title=f"{handler_name}:Message", payload=resolve_payloads(payloads), diff --git a/faststream/nats/publisher/asyncapi.py b/faststream/nats/publisher/asyncapi.py index 1546b675f8..f639aeb524 100644 --- a/faststream/nats/publisher/asyncapi.py +++ b/faststream/nats/publisher/asyncapi.py @@ -3,11 +3,10 @@ from typing_extensions import override from faststream.asyncapi.schema import ( - Channel, ChannelBinding, CorrelationId, Message, - Operation, + v2_6_0, ) from faststream.asyncapi.schema.bindings import nats from faststream.asyncapi.utils import resolve_payloads @@ -26,13 +25,13 @@ class AsyncAPIPublisher(LogicPublisher): def get_name(self) -> str: return f"{self.subject}:Publisher" - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> Dict[str, v2_6_0.Channel]: payloads = self.get_payloads() return { - self.name: Channel( + self.name: v2_6_0.Channel( description=self.description, - publish=Operation( + publish=v2_6_0.Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads, "Publisher"), diff --git a/faststream/nats/subscriber/asyncapi.py b/faststream/nats/subscriber/asyncapi.py index ad0edb0bca..557f16ad9f 100644 --- a/faststream/nats/subscriber/asyncapi.py +++ b/faststream/nats/subscriber/asyncapi.py @@ -3,11 +3,10 @@ from typing_extensions import override from faststream.asyncapi.schema import ( - Channel, ChannelBinding, CorrelationId, Message, - Operation, + v2_6_0, ) from faststream.asyncapi.schema.bindings import nats from faststream.asyncapi.utils import resolve_payloads @@ -31,13 +30,13 @@ class AsyncAPISubscriber(LogicSubscriber[Any]): def get_name(self) -> str: return f"{self.subject}:{self.call_name}" - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> Dict[str, v2_6_0.Channel]: payloads = self.get_payloads() return { - self.name: Channel( + self.name: v2_6_0.Channel( description=self.description, - subscribe=Operation( + subscribe=v2_6_0.Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads), @@ -96,7 +95,7 @@ def get_name(self) -> str: return "" @override - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> Dict[str, v2_6_0.Channel]: return {} @@ -108,5 +107,5 @@ def get_name(self) -> str: return "" @override - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> Dict[str, v2_6_0.Channel]: return {} diff --git a/faststream/rabbit/publisher/asyncapi.py b/faststream/rabbit/publisher/asyncapi.py index 415365481d..de9b362ab9 100644 --- a/faststream/rabbit/publisher/asyncapi.py +++ b/faststream/rabbit/publisher/asyncapi.py @@ -3,12 +3,11 @@ from typing_extensions import override from faststream.asyncapi.schema import ( - Channel, ChannelBinding, CorrelationId, Message, - Operation, OperationBinding, + v2_6_0, ) from faststream.asyncapi.schema.bindings import amqp from faststream.asyncapi.utils import resolve_payloads @@ -43,7 +42,7 @@ def get_name(self) -> str: return f"{routing}:{getattr(self.exchange, 'name', None) or '_'}:Publisher" - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> Dict[str, v2_6_0.Channel]: payloads = self.get_payloads() return { diff --git a/faststream/rabbit/subscriber/asyncapi.py b/faststream/rabbit/subscriber/asyncapi.py index 2ba7cabaa5..39392e9d62 100644 --- a/faststream/rabbit/subscriber/asyncapi.py +++ b/faststream/rabbit/subscriber/asyncapi.py @@ -1,12 +1,11 @@ from typing import Dict from faststream.asyncapi.schema import ( - Channel, ChannelBinding, CorrelationId, Message, - Operation, OperationBinding, + v2_6_0, ) from faststream.asyncapi.schema.bindings import amqp from faststream.asyncapi.utils import resolve_payloads @@ -20,7 +19,7 @@ class AsyncAPISubscriber(LogicSubscriber): def get_name(self) -> str: return f"{self.queue.name}:{getattr(self.exchange, 'name', None) or '_'}:{self.call_name}" - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> Dict[str, v2_6_0.Channel]: payloads = self.get_payloads() return { diff --git a/faststream/redis/publisher/asyncapi.py b/faststream/redis/publisher/asyncapi.py index f79709667c..96d3ae430d 100644 --- a/faststream/redis/publisher/asyncapi.py +++ b/faststream/redis/publisher/asyncapi.py @@ -2,13 +2,7 @@ from typing_extensions import TypeAlias, override -from faststream.asyncapi.schema import ( - Channel, - ChannelBinding, - CorrelationId, - Message, - Operation, -) +from faststream.asyncapi.schema import ChannelBinding, CorrelationId, Message, v2_6_0 from faststream.asyncapi.schema.bindings import redis from faststream.asyncapi.utils import resolve_payloads from faststream.exceptions import SetupError @@ -38,13 +32,13 @@ class AsyncAPIPublisher(LogicPublisher, RedisAsyncAPIProtocol): """A class to represent a Redis publisher.""" - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> Dict[str, v2_6_0.Channel]: payloads = self.get_payloads() return { - self.name: Channel( + self.name: v2_6_0.Channel( description=self.description, - publish=Operation( + publish=v2_6_0.Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads, "Publisher"), diff --git a/faststream/redis/subscriber/asyncapi.py b/faststream/redis/subscriber/asyncapi.py index 36171b247b..585f04f61b 100644 --- a/faststream/redis/subscriber/asyncapi.py +++ b/faststream/redis/subscriber/asyncapi.py @@ -1,11 +1,10 @@ from typing import Dict from faststream.asyncapi.schema import ( - Channel, ChannelBinding, CorrelationId, Message, - Operation, + v2_6_0, ) from faststream.asyncapi.schema.bindings import redis from faststream.asyncapi.utils import resolve_payloads @@ -24,13 +23,13 @@ class AsyncAPISubscriber(LogicSubscriber, RedisAsyncAPIProtocol): """A class to represent a Redis handler.""" - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> Dict[str, v2_6_0.Channel]: payloads = self.get_payloads() return { - self.name: Channel( + self.name: v2_6_0.Channel( description=self.description, - subscribe=Operation( + subscribe=v2_6_0.Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads), diff --git a/scripts/start_test_env.sh b/scripts/start_test_env.sh index a0ae1627b8..906556db41 100755 --- a/scripts/start_test_env.sh +++ b/scripts/start_test_env.sh @@ -2,4 +2,4 @@ source ./scripts/set_variables.sh -docker-compose -p $DOCKER_COMPOSE_PROJECT -f docs/includes/docker-compose.yaml up -d --no-recreate +docker compose -p $DOCKER_COMPOSE_PROJECT -f docs/includes/docker-compose.yaml up -d --no-recreate From 9fc11d65483520a509f0b0a626459eda1be6a0c5 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Tue, 6 Aug 2024 21:47:32 +0300 Subject: [PATCH 058/245] Remove unneccessary TODO and reorder imports --- faststream/asyncapi/schema/__init__.py | 2 +- faststream/asyncapi/schema/{main.py => schema.py} | 0 faststream/asyncapi/schema/v2_6_0/operations.py | 2 +- faststream/asyncapi/schema/v2_6_0/schema.py | 2 +- faststream/asyncapi/schema/v3_0_0/channels.py | 2 +- faststream/asyncapi/schema/v3_0_0/schema.py | 2 +- faststream/cli/docs/app.py | 1 - tests/asyncapi/base/v3_0_0/arguments.py | 2 +- 8 files changed, 6 insertions(+), 7 deletions(-) rename faststream/asyncapi/schema/{main.py => schema.py} (100%) diff --git a/faststream/asyncapi/schema/__init__.py b/faststream/asyncapi/schema/__init__.py index eb2e8b5ff8..4d2be585bf 100644 --- a/faststream/asyncapi/schema/__init__.py +++ b/faststream/asyncapi/schema/__init__.py @@ -13,7 +13,7 @@ License, LicenseDict, ) -from faststream.asyncapi.schema.main import ( +from faststream.asyncapi.schema.schema import ( BaseSchema, ) from faststream.asyncapi.schema.message import CorrelationId, Message diff --git a/faststream/asyncapi/schema/main.py b/faststream/asyncapi/schema/schema.py similarity index 100% rename from faststream/asyncapi/schema/main.py rename to faststream/asyncapi/schema/schema.py diff --git a/faststream/asyncapi/schema/v2_6_0/operations.py b/faststream/asyncapi/schema/v2_6_0/operations.py index 75627d09ac..c929d71263 100644 --- a/faststream/asyncapi/schema/v2_6_0/operations.py +++ b/faststream/asyncapi/schema/v2_6_0/operations.py @@ -3,8 +3,8 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.schema.message import Message from faststream.asyncapi.schema.bindings import OperationBinding +from faststream.asyncapi.schema.message import Message from faststream.asyncapi.schema.utils import ( ExternalDocs, ExternalDocsDict, diff --git a/faststream/asyncapi/schema/v2_6_0/schema.py b/faststream/asyncapi/schema/v2_6_0/schema.py index c565f26b41..aa36968005 100644 --- a/faststream/asyncapi/schema/v2_6_0/schema.py +++ b/faststream/asyncapi/schema/v2_6_0/schema.py @@ -1,7 +1,7 @@ from typing import Any, Dict, List, Optional, Union from faststream._compat import model_to_json, model_to_jsonable -from faststream.asyncapi.schema.main import BaseSchema +from faststream.asyncapi.schema.schema import BaseSchema from faststream.asyncapi.schema.servers import Server from faststream.asyncapi.schema.utils import ( ExternalDocs, diff --git a/faststream/asyncapi/schema/v3_0_0/channels.py b/faststream/asyncapi/schema/v3_0_0/channels.py index 85190ef4da..514fe7a94b 100644 --- a/faststream/asyncapi/schema/v3_0_0/channels.py +++ b/faststream/asyncapi/schema/v3_0_0/channels.py @@ -3,8 +3,8 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.schema.message import Message from faststream.asyncapi.schema.bindings import ChannelBinding +from faststream.asyncapi.schema.message import Message from faststream.asyncapi.schema.utils import Parameter, Reference diff --git a/faststream/asyncapi/schema/v3_0_0/schema.py b/faststream/asyncapi/schema/v3_0_0/schema.py index 5b6fa1a69b..2cdcb48692 100644 --- a/faststream/asyncapi/schema/v3_0_0/schema.py +++ b/faststream/asyncapi/schema/v3_0_0/schema.py @@ -1,7 +1,7 @@ from typing import Any, Dict, Optional from faststream._compat import model_to_json, model_to_jsonable -from faststream.asyncapi.schema.main import BaseSchema +from faststream.asyncapi.schema.schema import BaseSchema from faststream.asyncapi.schema.v3_0_0.channels import Channel from faststream.asyncapi.schema.v3_0_0.components import Components from faststream.asyncapi.schema.v3_0_0.info import Info diff --git a/faststream/cli/docs/app.py b/faststream/cli/docs/app.py index 845df47b22..9f42080d4b 100644 --- a/faststream/cli/docs/app.py +++ b/faststream/cli/docs/app.py @@ -183,7 +183,6 @@ def _parse_and_serve( f"Unknown extension given - {app}; Please provide app in format [python_module:FastStream] or [asyncapi.yaml/.json] - path to your application or documentation" ) - # TODO: add schema choosing based on FastStream.asyncapi_version raw_schema = model_parse(Schema, data) serve_app(raw_schema, host, port) diff --git a/tests/asyncapi/base/v3_0_0/arguments.py b/tests/asyncapi/base/v3_0_0/arguments.py index 4f2041ddbc..c41e13f7db 100644 --- a/tests/asyncapi/base/v3_0_0/arguments.py +++ b/tests/asyncapi/base/v3_0_0/arguments.py @@ -486,7 +486,7 @@ async def handle(user: descriminator): ... with open("schema5.json", "w") as file: json.dump(schema["components"], file, indent=4) - # TODO: payload are not moved + assert schema["components"] == { "messages": { key: { From 3602f4f998d9636b3d6fe6ef3fa1e61a4d9dde4a Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Tue, 6 Aug 2024 22:44:54 +0300 Subject: [PATCH 059/245] AsyncAPI schema generations functions splitted by AsyncAPI version --- faststream/asyncapi/schema/__init__.py | 2 +- faststream/asyncapi/v2_6_0/__init__.py | 0 faststream/asyncapi/v2_6_0/generate.py | 213 ++++++++++++++++ faststream/asyncapi/v3_0_0/__init__.py | 0 faststream/asyncapi/v3_0_0/generate.py | 334 +++++++++++++++++++++++++ 5 files changed, 548 insertions(+), 1 deletion(-) create mode 100644 faststream/asyncapi/v2_6_0/__init__.py create mode 100644 faststream/asyncapi/v2_6_0/generate.py create mode 100644 faststream/asyncapi/v3_0_0/__init__.py create mode 100644 faststream/asyncapi/v3_0_0/generate.py diff --git a/faststream/asyncapi/schema/__init__.py b/faststream/asyncapi/schema/__init__.py index 4d2be585bf..1bb7160144 100644 --- a/faststream/asyncapi/schema/__init__.py +++ b/faststream/asyncapi/schema/__init__.py @@ -13,10 +13,10 @@ License, LicenseDict, ) +from faststream.asyncapi.schema.message import CorrelationId, Message from faststream.asyncapi.schema.schema import ( BaseSchema, ) -from faststream.asyncapi.schema.message import CorrelationId, Message from faststream.asyncapi.schema.security import SecuritySchemaComponent from faststream.asyncapi.schema.servers import Server from faststream.asyncapi.schema.utils import ( diff --git a/faststream/asyncapi/v2_6_0/__init__.py b/faststream/asyncapi/v2_6_0/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/faststream/asyncapi/v2_6_0/generate.py b/faststream/asyncapi/v2_6_0/generate.py new file mode 100644 index 0000000000..653328b3e8 --- /dev/null +++ b/faststream/asyncapi/v2_6_0/generate.py @@ -0,0 +1,213 @@ +from typing import TYPE_CHECKING, Any, Dict, List, Union + +from faststream._compat import DEF_KEY, HAS_FASTAPI +from faststream.asyncapi.schema import ( + Message, + Reference, + Server, + v2_6_0, +) +from faststream.constants import ContentTypes + +if TYPE_CHECKING: + from faststream.app import FastStream + from faststream.broker.core.usecase import BrokerUsecase + from faststream.broker.types import ConnectionType, MsgType + + if HAS_FASTAPI: + from faststream.broker.fastapi.router import StreamRouter + + +def get_app_schema(app: Union["FastStream", "StreamRouter[Any]"]) -> v2_6_0.Schema: + """Get the application schema.""" + broker = app.broker + if broker is None: # pragma: no cover + raise RuntimeError() + broker.setup() + + servers = get_broker_server(broker) + channels = get_broker_channels_2_6(broker) + + messages: Dict[str, Message] = {} + payloads: Dict[str, Dict[str, Any]] = {} + for channel_name, ch in channels.items(): + ch.servers = list(servers.keys()) + + if ch.subscribe is not None: + m = ch.subscribe.message + + if isinstance(m, Message): # pragma: no branch + ch.subscribe.message = _resolve_msg_payloads( + m, + channel_name, + payloads, + messages, + ) + + if ch.publish is not None: + m = ch.publish.message + + if isinstance(m, Message): # pragma: no branch + ch.publish.message = _resolve_msg_payloads( + m, + channel_name, + payloads, + messages, + ) + + schema = v2_6_0.Schema( + info=v2_6_0.Info( + title=app.title, + version=app.version, + description=app.description, + termsOfService=app.terms_of_service, + contact=app.contact, + license=app.license, + ), + defaultContentType=ContentTypes.json.value, + id=app.identifier, + tags=list(app.asyncapi_tags) if app.asyncapi_tags else None, + externalDocs=app.external_docs, + servers=servers, + channels=channels, + components=v2_6_0.Components( + messages=messages, + schemas=payloads, + securitySchemes=None + if broker.security is None + else broker.security.get_schema(), + ), + ) + return schema + + +def get_broker_server( + broker: "BrokerUsecase[MsgType, ConnectionType]", +) -> Dict[str, Server]: + """Get the broker server for an application.""" + servers = {} + + broker_meta: Dict[str, Any] = { + "protocol": broker.protocol, + "protocolVersion": broker.protocol_version, + "description": broker.description, + "tags": broker.tags, + # TODO + # "variables": "", + # "bindings": "", + } + + if broker.security is not None: + broker_meta["security"] = broker.security.get_requirement() + + if isinstance(broker.url, str): + servers["development"] = Server( + url=broker.url, + **broker_meta, + ) + + elif len(broker.url) == 1: + servers["development"] = Server( + url=broker.url[0], + **broker_meta, + ) + + else: + for i, url in enumerate(broker.url, 1): + servers[f"Server{i}"] = Server( + url=url, + **broker_meta, + ) + + return servers + + +def get_broker_channels_2_6( + broker: "BrokerUsecase[MsgType, ConnectionType]", +) -> Dict[str, v2_6_0.Channel]: + """Get the broker channels for an application.""" + channels = {} + + for h in broker._subscribers.values(): + channels.update(h.schema()) + + for p in broker._publishers.values(): + channels.update(p.schema()) + + return channels + + +def _resolve_msg_payloads( + m: Message, + channel_name: str, + payloads: Dict[str, Any], + messages: Dict[str, Any], +) -> Reference: + """Replace message payload by reference and normalize payloads. + + Payloads and messages are editable dicts to store schemas for reference in AsyncAPI. + """ + one_of_list: List[Reference] = [] + m.payload = _move_pydantic_refs(m.payload, DEF_KEY) + + if DEF_KEY in m.payload: + payloads.update(m.payload.pop(DEF_KEY)) + + one_of = m.payload.get("oneOf") + if isinstance(one_of, dict): + for p_title, p in one_of.items(): + payloads.update(p.pop(DEF_KEY, {})) + if p_title not in payloads: + payloads[p_title] = p + one_of_list.append(Reference(**{"$ref": f"#/components/schemas/{p_title}"})) + + elif one_of is not None: + for p in one_of: + p_title = next(iter(p.values())).split("/")[-1] + if p_title not in payloads: + payloads[p_title] = p + one_of_list.append(Reference(**{"$ref": f"#/components/schemas/{p_title}"})) + + if not one_of_list: + payloads.update(m.payload.pop(DEF_KEY, {})) + p_title = m.payload.get("title", f"{channel_name}Payload") + if p_title not in payloads: + payloads[p_title] = m.payload + m.payload = {"$ref": f"#/components/schemas/{p_title}"} + + else: + m.payload["oneOf"] = one_of_list + + assert m.title # nosec B101 + messages[m.title] = m + return Reference(**{"$ref": f"#/components/messages/{m.title}"}) + + +def _move_pydantic_refs( + original: Any, + key: str, +) -> Any: + """Remove pydantic references and replacem them by real schemas.""" + if not isinstance(original, Dict): + return original + + data = original.copy() + + for k in data: + item = data[k] + + if isinstance(item, str): + if key in item: + data[k] = data[k].replace(key, "components/schemas") + + elif isinstance(item, dict): + data[k] = _move_pydantic_refs(data[k], key) + + elif isinstance(item, List): + for i in range(len(data[k])): + data[k][i] = _move_pydantic_refs(item[i], key) + + if isinstance(desciminator := data.get("discriminator"), dict): + data["discriminator"] = desciminator["propertyName"] + + return data diff --git a/faststream/asyncapi/v3_0_0/__init__.py b/faststream/asyncapi/v3_0_0/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/faststream/asyncapi/v3_0_0/generate.py b/faststream/asyncapi/v3_0_0/generate.py new file mode 100644 index 0000000000..15646eb968 --- /dev/null +++ b/faststream/asyncapi/v3_0_0/generate.py @@ -0,0 +1,334 @@ +from typing import TYPE_CHECKING, Any, Dict, List, Union +from urllib.parse import urlparse + +from faststream._compat import DEF_KEY, HAS_FASTAPI +from faststream.asyncapi.schema import ( + Message, + Reference, + v3_0_0, +) +from faststream.constants import ContentTypes + +if TYPE_CHECKING: + from faststream.app import FastStream + from faststream.broker.core.usecase import BrokerUsecase + from faststream.broker.types import ConnectionType, MsgType + + if HAS_FASTAPI: + from faststream.broker.fastapi.router import StreamRouter + + +def get_app_schema(app: Union["FastStream", "StreamRouter[Any]"]) -> v3_0_0.Schema: + """Get the application schema.""" + broker = app.broker + if broker is None: # pragma: no cover + raise RuntimeError() + broker.setup() + + servers = get_broker_server(broker) + channels = get_broker_channels(broker) + operations = get_broker_operations(broker) + + messages: Dict[str, Message] = {} + payloads: Dict[str, Dict[str, Any]] = {} + + for channel_name, channel in channels.items(): + msgs: Dict[str, Union[Message, Reference]] = {} + for message_name, message in channel.messages.items(): + assert isinstance(message, Message) + + msgs[message_name] = _resolve_msg_payloads( + message_name, + message, + channel_name, + payloads, + messages + ) + + channel.messages = msgs + + channel.servers = [{"$ref": f"#/servers/{server_name}"} for server_name in list(servers.keys())] + + schema = v3_0_0.Schema( + info=v3_0_0.Info( + title=app.title, + version=app.version, + description=app.description, + termsOfService=app.terms_of_service, + contact=app.contact, + license=app.license, + tags=list(app.asyncapi_tags) if app.asyncapi_tags else None, + externalDocs=app.external_docs, + ), + defaultContentType=ContentTypes.json.value, + id=app.identifier, + servers=servers, + channels=channels, + operations=operations, + components=v3_0_0.Components( + messages=messages, + schemas=payloads, + securitySchemes=None + if broker.security is None + else broker.security.get_schema(), + ), + ) + return schema + + +def get_broker_server( + broker: "BrokerUsecase[MsgType, ConnectionType]", +) -> Dict[str, v3_0_0.Server]: + """Get the broker server for an application.""" + servers = {} + + broker_meta: Dict[str, Any] = { + "protocol": broker.protocol, + "protocolVersion": broker.protocol_version, + "description": broker.description, + "tags": broker.tags, + # TODO + # "variables": "", + # "bindings": "", + } + + if broker.security is not None: + broker_meta["security"] = broker.security.get_requirement() + + if isinstance(broker.url, str): + broker_url = broker.url + if "://" not in broker_url: + broker_url = "//" + broker_url + + url = urlparse(broker_url) + servers["development"] = v3_0_0.Server( + host=url.netloc, + pathname=url.path, + **broker_meta, + ) + + elif len(broker.url) == 1: + broker_url = broker.url[0] + if "://" not in broker_url: + broker_url = "//" + broker_url + + url = urlparse(broker_url) + servers["development"] = v3_0_0.Server( + host=url.netloc, + pathname=url.path, + **broker_meta, + ) + + else: + for i, broker_url in enumerate(broker.url, 1): + if "://" not in broker_url: + broker_url = "//" + broker_url + + parsed_url = urlparse(broker_url) + servers[f"Server{i}"] = v3_0_0.Server( + host=parsed_url.netloc, + pathname=parsed_url.path, + **broker_meta, + ) + + return servers + + +def get_broker_operations( + broker: "BrokerUsecase[MsgType, ConnectionType]", +) -> Dict[str, v3_0_0.Operation]: + """Get the broker operations for an application.""" + operations = {} + + for h in broker._subscribers.values(): + for channel_name, channel_2_6 in h.schema().items(): + if channel_2_6.subscribe is not None: + op = v3_0_0.Operation( + action="receive", + summary=channel_2_6.subscribe.summary, + description=channel_2_6.subscribe.description, + bindings=channel_2_6.subscribe.bindings, + messages=[ + Reference( + **{"$ref": f"#/channels/{channel_name}/messages/SubscribeMessage"}, + ) + ], + channel=Reference( + **{"$ref": f"#/channels/{channel_name}"}, + ), + security=channel_2_6.subscribe.security, + ) + operations[f"{channel_name}Subscribe"] = op + + elif channel_2_6.publish is not None: + op = v3_0_0.Operation( + action="send", + summary=channel_2_6.publish.summary, + description=channel_2_6.publish.description, + bindings=channel_2_6.publish.bindings, + messages=[ + Reference( + **{"$ref": f"#/channels/{channel_name}/messages/Message"}, + )] + , + channel=Reference( + **{"$ref": f"#/channels/{channel_name}"}, + ), + security=channel_2_6.publish.bindings, + ) + operations[f"{channel_name}"] = op + + for p in broker._publishers.values(): + for channel_name, channel_2_6 in p.schema().items(): + if channel_2_6.subscribe is not None: + op = v3_0_0.Operation( + action="send", + summary=channel_2_6.subscribe.summary, + description=channel_2_6.subscribe.description, + bindings=channel_2_6.subscribe.bindings, + messages=[ + Reference( + **{"$ref": f"#/channels/{channel_name}/messages/SubscribeMessage"}, + ) + ], + channel=Reference( + **{"$ref": f"#/channels/{channel_name}"}, + ), + security=channel_2_6.subscribe.security, + ) + operations[f"{channel_name}Subscribe"] = op + + elif channel_2_6.publish is not None: + op = v3_0_0.Operation( + action="send", + summary=channel_2_6.publish.summary, + description=channel_2_6.publish.description, + bindings=channel_2_6.publish.bindings, + messages=[ + Reference( + **{"$ref": f"#/channels/{channel_name}/messages/Message"}, + ) + ], + channel=Reference( + **{"$ref": f"#/channels/{channel_name}"}, + ), + security=channel_2_6.publish.security, + ) + operations[f"{channel_name}"] = op + + return operations + + +def get_broker_channels( + broker: "BrokerUsecase[MsgType, ConnectionType]", +) -> Dict[str, v3_0_0.Channel]: + """Get the broker channels for an application.""" + channels = {} + + for h in broker._subscribers.values(): + channels_schema_v3_0 = {} + for channel_name, channel_v2_6 in h.schema().items(): + if channel_v2_6.subscribe: + channel_v3_0 = v3_0_0.Channel( + address=channel_name, + messages={ + "SubscribeMessage": channel_v2_6.subscribe.message, + }, + description=channel_v2_6.description, + servers=channel_v2_6.servers, + bindings=channel_v2_6.bindings, + parameters=channel_v2_6.parameters + ) + + channels_schema_v3_0[channel_name] = channel_v3_0 + + channels.update(channels_schema_v3_0) + + for p in broker._publishers.values(): + channels_schema_v3_0 = {} + for channel_name, channel_v2_6 in p.schema().items(): + if channel_v2_6.publish: + channel_v3_0 = v3_0_0.Channel( + address=channel_name, + messages={ + "Message": channel_v2_6.publish.message, + }, + description=channel_v2_6.description, + servers=channel_v2_6.servers, + bindings=channel_v2_6.bindings, + parameters=channel_v2_6.parameters + ) + + channels_schema_v3_0[channel_name] = channel_v3_0 + + channels.update(channels_schema_v3_0) + + return channels + + +def _resolve_msg_payloads( + message_name: str, + m: Message, + channel_name: str, + payloads: Dict[str, Any], + messages: Dict[str, Any], +) -> Reference: + assert isinstance(m.payload, dict) + + m.payload = _move_pydantic_refs(m.payload, DEF_KEY) + if DEF_KEY in m.payload: + payloads.update(m.payload.pop(DEF_KEY)) + + one_of = m.payload.get("oneOf", None) + if isinstance(one_of, dict): + one_of_list = [] + p: Dict[str, Dict[str, Any]] = {} + for name, payload in one_of.items(): + payloads.update(p.pop(DEF_KEY, {})) + p[name] = payload + one_of_list.append(Reference(**{"$ref": f"#/components/schemas/{name}"})) + + payloads.update(p) + m.payload["oneOf"] = one_of_list + assert m.title + messages[m.title] = m + return Reference(**{"$ref": f"#/components/messages/{channel_name}:{message_name}"}) + + else: + payloads.update(m.payload.pop(DEF_KEY, {})) + payload_name = m.payload.get("title", f"{channel_name}:{message_name}:Payload") + payloads[payload_name] = m.payload + m.payload = {"$ref": f"#/components/schemas/{payload_name}"} + assert m.title + messages[m.title] = m + return Reference(**{"$ref": f"#/components/messages/{channel_name}:{message_name}"}) + + +def _move_pydantic_refs( + original: Any, + key: str, +) -> Any: + """Remove pydantic references and replace them by real schemas.""" + if not isinstance(original, Dict): + return original + + data = original.copy() + + for k in data: + item = data[k] + + if isinstance(item, str): + if key in item: + data[k] = data[k].replace(key, "components/schemas") + + elif isinstance(item, dict): + data[k] = _move_pydantic_refs(data[k], key) + + elif isinstance(item, List): + for i in range(len(data[k])): + data[k][i] = _move_pydantic_refs(item[i], key) + + if isinstance(desciminator := data.get("discriminator"), dict): + data["discriminator"] = desciminator["propertyName"] + + return data From 4b60bf6bffe2dea2eae9ee2a3bae8f8e3cddc46c Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 8 Sep 2024 00:24:29 +0300 Subject: [PATCH 060/245] AsyncAPI schema splitting by versions --- faststream/asyncapi/abc.py | 2 +- faststream/asyncapi/schema/__init__.py | 6 --- faststream/asyncapi/schema/servers.py | 44 +------------------ faststream/asyncapi/v2_6_0/generate.py | 17 ++++--- .../v2_6_0 => v2_6_0/schema}/__init__.py | 0 .../v2_6_0 => v2_6_0/schema}/channels.py | 2 +- .../v2_6_0 => v2_6_0/schema}/components.py | 0 .../{schema/v2_6_0 => v2_6_0/schema}/info.py | 0 .../v2_6_0 => v2_6_0/schema}/operations.py | 0 .../v2_6_0 => v2_6_0/schema}/schema.py | 8 ++-- .../v2_6_0 => v2_6_0/schema}/servers.py | 0 faststream/asyncapi/v3_0_0/generate.py | 41 ++++++++++------- .../v3_0_0 => v3_0_0/schema}/__init__.py | 0 .../v3_0_0 => v3_0_0/schema}/channels.py | 0 .../v3_0_0 => v3_0_0/schema}/components.py | 0 .../{schema/v3_0_0 => v3_0_0/schema}/info.py | 0 .../v3_0_0 => v3_0_0/schema}/operations.py | 2 +- .../v3_0_0 => v3_0_0/schema}/schema.py | 10 ++--- .../v3_0_0 => v3_0_0/schema}/servers.py | 0 faststream/cli/docs/app.py | 2 +- faststream/confluent/publisher/asyncapi.py | 11 +++-- faststream/confluent/subscriber/asyncapi.py | 11 +++-- faststream/kafka/publisher/asyncapi.py | 11 +++-- faststream/kafka/subscriber/asyncapi.py | 11 +++-- faststream/nats/publisher/asyncapi.py | 11 +++-- faststream/nats/subscriber/asyncapi.py | 15 ++++--- faststream/rabbit/publisher/asyncapi.py | 9 ++-- faststream/rabbit/subscriber/asyncapi.py | 9 ++-- faststream/redis/publisher/asyncapi.py | 16 +++++-- faststream/redis/subscriber/asyncapi.py | 11 +++-- 30 files changed, 124 insertions(+), 125 deletions(-) rename faststream/asyncapi/{schema/v2_6_0 => v2_6_0/schema}/__init__.py (100%) rename faststream/asyncapi/{schema/v2_6_0 => v2_6_0/schema}/channels.py (95%) rename faststream/asyncapi/{schema/v2_6_0 => v2_6_0/schema}/components.py (100%) rename faststream/asyncapi/{schema/v2_6_0 => v2_6_0/schema}/info.py (100%) rename faststream/asyncapi/{schema/v2_6_0 => v2_6_0/schema}/operations.py (100%) rename faststream/asyncapi/{schema/v2_6_0 => v2_6_0/schema}/schema.py (89%) rename faststream/asyncapi/{schema/v2_6_0 => v2_6_0/schema}/servers.py (100%) rename faststream/asyncapi/{schema/v3_0_0 => v3_0_0/schema}/__init__.py (100%) rename faststream/asyncapi/{schema/v3_0_0 => v3_0_0/schema}/channels.py (100%) rename faststream/asyncapi/{schema/v3_0_0 => v3_0_0/schema}/components.py (100%) rename faststream/asyncapi/{schema/v3_0_0 => v3_0_0/schema}/info.py (100%) rename faststream/asyncapi/{schema/v3_0_0 => v3_0_0/schema}/operations.py (95%) rename faststream/asyncapi/{schema/v3_0_0 => v3_0_0/schema}/schema.py (85%) rename faststream/asyncapi/{schema/v3_0_0 => v3_0_0/schema}/servers.py (100%) diff --git a/faststream/asyncapi/abc.py b/faststream/asyncapi/abc.py index bc1faeb905..d3ac4e9a63 100644 --- a/faststream/asyncapi/abc.py +++ b/faststream/asyncapi/abc.py @@ -2,7 +2,7 @@ from typing import Any, Dict, Optional from faststream.asyncapi.proto import AsyncAPIProto -from faststream.asyncapi.schema.v2_6_0.channels import Channel +from faststream.asyncapi.v2_6_0.schema.channels import Channel class AsyncAPIOperation(AsyncAPIProto): diff --git a/faststream/asyncapi/schema/__init__.py b/faststream/asyncapi/schema/__init__.py index 1bb7160144..a959afc105 100644 --- a/faststream/asyncapi/schema/__init__.py +++ b/faststream/asyncapi/schema/__init__.py @@ -1,6 +1,5 @@ """AsyncAPI schema related functions.""" -from faststream.asyncapi.schema import v2_6_0, v3_0_0 from faststream.asyncapi.schema.bindings import ( ChannelBinding, OperationBinding, @@ -18,7 +17,6 @@ BaseSchema, ) from faststream.asyncapi.schema.security import SecuritySchemaComponent -from faststream.asyncapi.schema.servers import Server from faststream.asyncapi.schema.utils import ( ExternalDocs, ExternalDocsDict, @@ -39,7 +37,6 @@ "License", "LicenseDict", # servers - "Server", # channels # utils "Tag", @@ -56,7 +53,4 @@ "Message", # security "SecuritySchemaComponent", - # AsyncAPI schemas by versions - "v2_6_0", - "v3_0_0", ) diff --git a/faststream/asyncapi/schema/servers.py b/faststream/asyncapi/schema/servers.py index 06e2829c69..725db45389 100644 --- a/faststream/asyncapi/schema/servers.py +++ b/faststream/asyncapi/schema/servers.py @@ -1,10 +1,8 @@ -from typing import Any, Dict, List, Optional, Union +from typing import Dict, List, Optional from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.schema.bindings import ServerBinding -from faststream.asyncapi.schema.utils import Reference, Tag, TagDict SecurityRequirement = List[Dict[str, List[str]]] @@ -32,43 +30,3 @@ class ServerVariable(BaseModel): class Config: extra = "allow" - - -class Server(BaseModel): - """A class to represent a server. - - Attributes: - url : URL of the server - protocol : protocol used by the server - description : optional description of the server - protocolVersion : optional version of the protocol used by the server - tags : optional list of tags associated with the server - security : optional security requirement for the server - variables : optional dictionary of server variables - bindings : optional server binding - - Note: - The attributes `description`, `protocolVersion`, `tags`, `security`, `variables`, and `bindings` are all optional. - - Configurations: - If `PYDANTIC_V2` is True, the model configuration is set to allow extra attributes. - Otherwise, the `Config` class is defined with the `extra` attribute set to "allow". - - """ - - url: str - protocol: str - description: Optional[str] = None - protocolVersion: Optional[str] = None - tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = None - security: Optional[SecurityRequirement] = None - variables: Optional[Dict[str, Union[ServerVariable, Reference]]] = None - bindings: Optional[Union[ServerBinding, Reference]] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" diff --git a/faststream/asyncapi/v2_6_0/generate.py b/faststream/asyncapi/v2_6_0/generate.py index 653328b3e8..e19182e0e8 100644 --- a/faststream/asyncapi/v2_6_0/generate.py +++ b/faststream/asyncapi/v2_6_0/generate.py @@ -4,8 +4,13 @@ from faststream.asyncapi.schema import ( Message, Reference, +) +from faststream.asyncapi.v2_6_0.schema import ( + Channel, + Components, + Info, + Schema, Server, - v2_6_0, ) from faststream.constants import ContentTypes @@ -18,7 +23,7 @@ from faststream.broker.fastapi.router import StreamRouter -def get_app_schema(app: Union["FastStream", "StreamRouter[Any]"]) -> v2_6_0.Schema: +def get_app_schema(app: Union["FastStream", "StreamRouter[Any]"]) -> Schema: """Get the application schema.""" broker = app.broker if broker is None: # pragma: no cover @@ -55,8 +60,8 @@ def get_app_schema(app: Union["FastStream", "StreamRouter[Any]"]) -> v2_6_0.Sche messages, ) - schema = v2_6_0.Schema( - info=v2_6_0.Info( + schema = Schema( + info=Info( title=app.title, version=app.version, description=app.description, @@ -70,7 +75,7 @@ def get_app_schema(app: Union["FastStream", "StreamRouter[Any]"]) -> v2_6_0.Sche externalDocs=app.external_docs, servers=servers, channels=channels, - components=v2_6_0.Components( + components=Components( messages=messages, schemas=payloads, securitySchemes=None @@ -124,7 +129,7 @@ def get_broker_server( def get_broker_channels_2_6( broker: "BrokerUsecase[MsgType, ConnectionType]", -) -> Dict[str, v2_6_0.Channel]: +) -> Dict[str, Channel]: """Get the broker channels for an application.""" channels = {} diff --git a/faststream/asyncapi/schema/v2_6_0/__init__.py b/faststream/asyncapi/v2_6_0/schema/__init__.py similarity index 100% rename from faststream/asyncapi/schema/v2_6_0/__init__.py rename to faststream/asyncapi/v2_6_0/schema/__init__.py diff --git a/faststream/asyncapi/schema/v2_6_0/channels.py b/faststream/asyncapi/v2_6_0/schema/channels.py similarity index 95% rename from faststream/asyncapi/schema/v2_6_0/channels.py rename to faststream/asyncapi/v2_6_0/schema/channels.py index bd2703317c..8389a66d27 100644 --- a/faststream/asyncapi/schema/v2_6_0/channels.py +++ b/faststream/asyncapi/v2_6_0/schema/channels.py @@ -5,7 +5,7 @@ from faststream._compat import PYDANTIC_V2 from faststream.asyncapi.schema.bindings import ChannelBinding from faststream.asyncapi.schema.utils import Parameter -from faststream.asyncapi.schema.v2_6_0.operations import Operation +from faststream.asyncapi.v2_6_0.schema.operations import Operation class Channel(BaseModel): diff --git a/faststream/asyncapi/schema/v2_6_0/components.py b/faststream/asyncapi/v2_6_0/schema/components.py similarity index 100% rename from faststream/asyncapi/schema/v2_6_0/components.py rename to faststream/asyncapi/v2_6_0/schema/components.py diff --git a/faststream/asyncapi/schema/v2_6_0/info.py b/faststream/asyncapi/v2_6_0/schema/info.py similarity index 100% rename from faststream/asyncapi/schema/v2_6_0/info.py rename to faststream/asyncapi/v2_6_0/schema/info.py diff --git a/faststream/asyncapi/schema/v2_6_0/operations.py b/faststream/asyncapi/v2_6_0/schema/operations.py similarity index 100% rename from faststream/asyncapi/schema/v2_6_0/operations.py rename to faststream/asyncapi/v2_6_0/schema/operations.py diff --git a/faststream/asyncapi/schema/v2_6_0/schema.py b/faststream/asyncapi/v2_6_0/schema/schema.py similarity index 89% rename from faststream/asyncapi/schema/v2_6_0/schema.py rename to faststream/asyncapi/v2_6_0/schema/schema.py index aa36968005..31361740c5 100644 --- a/faststream/asyncapi/schema/v2_6_0/schema.py +++ b/faststream/asyncapi/v2_6_0/schema/schema.py @@ -2,16 +2,16 @@ from faststream._compat import model_to_json, model_to_jsonable from faststream.asyncapi.schema.schema import BaseSchema -from faststream.asyncapi.schema.servers import Server from faststream.asyncapi.schema.utils import ( ExternalDocs, ExternalDocsDict, Tag, TagDict, ) -from faststream.asyncapi.schema.v2_6_0.channels import Channel -from faststream.asyncapi.schema.v2_6_0.components import Components -from faststream.asyncapi.schema.v2_6_0.info import Info +from faststream.asyncapi.v2_6_0.schema.channels import Channel +from faststream.asyncapi.v2_6_0.schema.components import Components +from faststream.asyncapi.v2_6_0.schema.info import Info +from faststream.asyncapi.v2_6_0.schema.servers import Server from faststream.asyncapi.version import AsyncAPIVersion diff --git a/faststream/asyncapi/schema/v2_6_0/servers.py b/faststream/asyncapi/v2_6_0/schema/servers.py similarity index 100% rename from faststream/asyncapi/schema/v2_6_0/servers.py rename to faststream/asyncapi/v2_6_0/schema/servers.py diff --git a/faststream/asyncapi/v3_0_0/generate.py b/faststream/asyncapi/v3_0_0/generate.py index 15646eb968..992b96aabe 100644 --- a/faststream/asyncapi/v3_0_0/generate.py +++ b/faststream/asyncapi/v3_0_0/generate.py @@ -5,7 +5,14 @@ from faststream.asyncapi.schema import ( Message, Reference, - v3_0_0, +) +from faststream.asyncapi.v3_0_0.schema import ( + Channel, + Components, + Info, + Operation, + Schema, + Server, ) from faststream.constants import ContentTypes @@ -18,7 +25,7 @@ from faststream.broker.fastapi.router import StreamRouter -def get_app_schema(app: Union["FastStream", "StreamRouter[Any]"]) -> v3_0_0.Schema: +def get_app_schema(app: Union["FastStream", "StreamRouter[Any]"]) -> Schema: """Get the application schema.""" broker = app.broker if broker is None: # pragma: no cover @@ -49,8 +56,8 @@ def get_app_schema(app: Union["FastStream", "StreamRouter[Any]"]) -> v3_0_0.Sche channel.servers = [{"$ref": f"#/servers/{server_name}"} for server_name in list(servers.keys())] - schema = v3_0_0.Schema( - info=v3_0_0.Info( + schema = Schema( + info=Info( title=app.title, version=app.version, description=app.description, @@ -65,7 +72,7 @@ def get_app_schema(app: Union["FastStream", "StreamRouter[Any]"]) -> v3_0_0.Sche servers=servers, channels=channels, operations=operations, - components=v3_0_0.Components( + components=Components( messages=messages, schemas=payloads, securitySchemes=None @@ -78,7 +85,7 @@ def get_app_schema(app: Union["FastStream", "StreamRouter[Any]"]) -> v3_0_0.Sche def get_broker_server( broker: "BrokerUsecase[MsgType, ConnectionType]", -) -> Dict[str, v3_0_0.Server]: +) -> Dict[str, Server]: """Get the broker server for an application.""" servers = {} @@ -101,7 +108,7 @@ def get_broker_server( broker_url = "//" + broker_url url = urlparse(broker_url) - servers["development"] = v3_0_0.Server( + servers["development"] = Server( host=url.netloc, pathname=url.path, **broker_meta, @@ -113,7 +120,7 @@ def get_broker_server( broker_url = "//" + broker_url url = urlparse(broker_url) - servers["development"] = v3_0_0.Server( + servers["development"] = Server( host=url.netloc, pathname=url.path, **broker_meta, @@ -125,7 +132,7 @@ def get_broker_server( broker_url = "//" + broker_url parsed_url = urlparse(broker_url) - servers[f"Server{i}"] = v3_0_0.Server( + servers[f"Server{i}"] = Server( host=parsed_url.netloc, pathname=parsed_url.path, **broker_meta, @@ -136,14 +143,14 @@ def get_broker_server( def get_broker_operations( broker: "BrokerUsecase[MsgType, ConnectionType]", -) -> Dict[str, v3_0_0.Operation]: +) -> Dict[str, Operation]: """Get the broker operations for an application.""" operations = {} for h in broker._subscribers.values(): for channel_name, channel_2_6 in h.schema().items(): if channel_2_6.subscribe is not None: - op = v3_0_0.Operation( + op = Operation( action="receive", summary=channel_2_6.subscribe.summary, description=channel_2_6.subscribe.description, @@ -161,7 +168,7 @@ def get_broker_operations( operations[f"{channel_name}Subscribe"] = op elif channel_2_6.publish is not None: - op = v3_0_0.Operation( + op = Operation( action="send", summary=channel_2_6.publish.summary, description=channel_2_6.publish.description, @@ -181,7 +188,7 @@ def get_broker_operations( for p in broker._publishers.values(): for channel_name, channel_2_6 in p.schema().items(): if channel_2_6.subscribe is not None: - op = v3_0_0.Operation( + op = Operation( action="send", summary=channel_2_6.subscribe.summary, description=channel_2_6.subscribe.description, @@ -199,7 +206,7 @@ def get_broker_operations( operations[f"{channel_name}Subscribe"] = op elif channel_2_6.publish is not None: - op = v3_0_0.Operation( + op = Operation( action="send", summary=channel_2_6.publish.summary, description=channel_2_6.publish.description, @@ -221,7 +228,7 @@ def get_broker_operations( def get_broker_channels( broker: "BrokerUsecase[MsgType, ConnectionType]", -) -> Dict[str, v3_0_0.Channel]: +) -> Dict[str, Channel]: """Get the broker channels for an application.""" channels = {} @@ -229,7 +236,7 @@ def get_broker_channels( channels_schema_v3_0 = {} for channel_name, channel_v2_6 in h.schema().items(): if channel_v2_6.subscribe: - channel_v3_0 = v3_0_0.Channel( + channel_v3_0 = Channel( address=channel_name, messages={ "SubscribeMessage": channel_v2_6.subscribe.message, @@ -248,7 +255,7 @@ def get_broker_channels( channels_schema_v3_0 = {} for channel_name, channel_v2_6 in p.schema().items(): if channel_v2_6.publish: - channel_v3_0 = v3_0_0.Channel( + channel_v3_0 = Channel( address=channel_name, messages={ "Message": channel_v2_6.publish.message, diff --git a/faststream/asyncapi/schema/v3_0_0/__init__.py b/faststream/asyncapi/v3_0_0/schema/__init__.py similarity index 100% rename from faststream/asyncapi/schema/v3_0_0/__init__.py rename to faststream/asyncapi/v3_0_0/schema/__init__.py diff --git a/faststream/asyncapi/schema/v3_0_0/channels.py b/faststream/asyncapi/v3_0_0/schema/channels.py similarity index 100% rename from faststream/asyncapi/schema/v3_0_0/channels.py rename to faststream/asyncapi/v3_0_0/schema/channels.py diff --git a/faststream/asyncapi/schema/v3_0_0/components.py b/faststream/asyncapi/v3_0_0/schema/components.py similarity index 100% rename from faststream/asyncapi/schema/v3_0_0/components.py rename to faststream/asyncapi/v3_0_0/schema/components.py diff --git a/faststream/asyncapi/schema/v3_0_0/info.py b/faststream/asyncapi/v3_0_0/schema/info.py similarity index 100% rename from faststream/asyncapi/schema/v3_0_0/info.py rename to faststream/asyncapi/v3_0_0/schema/info.py diff --git a/faststream/asyncapi/schema/v3_0_0/operations.py b/faststream/asyncapi/v3_0_0/schema/operations.py similarity index 95% rename from faststream/asyncapi/schema/v3_0_0/operations.py rename to faststream/asyncapi/v3_0_0/schema/operations.py index 48935eba3b..c6c33ac74a 100644 --- a/faststream/asyncapi/schema/v3_0_0/operations.py +++ b/faststream/asyncapi/v3_0_0/schema/operations.py @@ -11,7 +11,7 @@ Tag, TagDict, ) -from faststream.asyncapi.schema.v3_0_0.channels import Channel +from faststream.asyncapi.v3_0_0.schema.channels import Channel class Operation(BaseModel): diff --git a/faststream/asyncapi/schema/v3_0_0/schema.py b/faststream/asyncapi/v3_0_0/schema/schema.py similarity index 85% rename from faststream/asyncapi/schema/v3_0_0/schema.py rename to faststream/asyncapi/v3_0_0/schema/schema.py index 2cdcb48692..fe61f7ae63 100644 --- a/faststream/asyncapi/schema/v3_0_0/schema.py +++ b/faststream/asyncapi/v3_0_0/schema/schema.py @@ -2,11 +2,11 @@ from faststream._compat import model_to_json, model_to_jsonable from faststream.asyncapi.schema.schema import BaseSchema -from faststream.asyncapi.schema.v3_0_0.channels import Channel -from faststream.asyncapi.schema.v3_0_0.components import Components -from faststream.asyncapi.schema.v3_0_0.info import Info -from faststream.asyncapi.schema.v3_0_0.operations import Operation -from faststream.asyncapi.schema.v3_0_0.servers import Server +from faststream.asyncapi.v3_0_0.schema.channels import Channel +from faststream.asyncapi.v3_0_0.schema.components import Components +from faststream.asyncapi.v3_0_0.schema.info import Info +from faststream.asyncapi.v3_0_0.schema.operations import Operation +from faststream.asyncapi.v3_0_0.schema.servers import Server from faststream.asyncapi.version import AsyncAPIVersion diff --git a/faststream/asyncapi/schema/v3_0_0/servers.py b/faststream/asyncapi/v3_0_0/schema/servers.py similarity index 100% rename from faststream/asyncapi/schema/v3_0_0/servers.py rename to faststream/asyncapi/v3_0_0/schema/servers.py diff --git a/faststream/cli/docs/app.py b/faststream/cli/docs/app.py index 9f42080d4b..4ecaa05728 100644 --- a/faststream/cli/docs/app.py +++ b/faststream/cli/docs/app.py @@ -8,8 +8,8 @@ from faststream._compat import json_dumps, model_parse from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.schema.v2_6_0 import Schema from faststream.asyncapi.site import serve_app +from faststream.asyncapi.v2_6_0.schema import Schema from faststream.cli.utils.imports import import_from_string from faststream.exceptions import INSTALL_WATCHFILES, INSTALL_YAML diff --git a/faststream/confluent/publisher/asyncapi.py b/faststream/confluent/publisher/asyncapi.py index a35142139c..a0f5db5e56 100644 --- a/faststream/confluent/publisher/asyncapi.py +++ b/faststream/confluent/publisher/asyncapi.py @@ -16,10 +16,13 @@ ChannelBinding, CorrelationId, Message, - v2_6_0, ) from faststream.asyncapi.schema.bindings import kafka from faststream.asyncapi.utils import resolve_payloads +from faststream.asyncapi.v2_6_0.schema import ( + Channel, + Operation, +) from faststream.broker.types import MsgType from faststream.confluent.publisher.usecase import ( BatchPublisher, @@ -40,13 +43,13 @@ class AsyncAPIPublisher(LogicPublisher[MsgType]): def get_name(self) -> str: return f"{self.topic}:Publisher" - def get_schema(self) -> Dict[str, v2_6_0.Channel]: + def get_schema(self) -> Dict[str, Channel]: payloads = self.get_payloads() return { - self.name: v2_6_0.Channel( + self.name: Channel( description=self.description, - publish=v2_6_0.Operation( + publish=Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads, "Publisher"), diff --git a/faststream/confluent/subscriber/asyncapi.py b/faststream/confluent/subscriber/asyncapi.py index a49d7f1b1b..fd8f7b94ac 100644 --- a/faststream/confluent/subscriber/asyncapi.py +++ b/faststream/confluent/subscriber/asyncapi.py @@ -8,10 +8,13 @@ ChannelBinding, CorrelationId, Message, - v2_6_0, ) from faststream.asyncapi.schema.bindings import kafka from faststream.asyncapi.utils import resolve_payloads +from faststream.asyncapi.v2_6_0.schema import ( + Channel, + Operation, +) from faststream.broker.types import MsgType from faststream.confluent.subscriber.usecase import ( BatchSubscriber, @@ -29,16 +32,16 @@ class AsyncAPISubscriber(LogicSubscriber[MsgType]): def get_name(self) -> str: return f'{",".join(self.topics)}:{self.call_name}' - def get_schema(self) -> Dict[str, v2_6_0.Channel]: + def get_schema(self) -> Dict[str, Channel]: channels = {} payloads = self.get_payloads() for t in self.topics: handler_name = self.title_ or f"{t}:{self.call_name}" - channels[handler_name] = v2_6_0.Channel( + channels[handler_name] = Channel( description=self.description, - subscribe=v2_6_0.Operation( + subscribe=Operation( message=Message( title=f"{handler_name}:Message", payload=resolve_payloads(payloads), diff --git a/faststream/kafka/publisher/asyncapi.py b/faststream/kafka/publisher/asyncapi.py index dba499a86f..b8eca07757 100644 --- a/faststream/kafka/publisher/asyncapi.py +++ b/faststream/kafka/publisher/asyncapi.py @@ -16,10 +16,13 @@ ChannelBinding, CorrelationId, Message, - v2_6_0, ) from faststream.asyncapi.schema.bindings import kafka from faststream.asyncapi.utils import resolve_payloads +from faststream.asyncapi.v2_6_0.schema import ( + Channel, + Operation, +) from faststream.broker.types import MsgType from faststream.exceptions import SetupError from faststream.kafka.publisher.usecase import ( @@ -40,13 +43,13 @@ class AsyncAPIPublisher(LogicPublisher[MsgType]): def get_name(self) -> str: return f"{self.topic}:Publisher" - def get_schema(self) -> Dict[str, v2_6_0.Channel]: + def get_schema(self) -> Dict[str, Channel]: payloads = self.get_payloads() return { - self.name: v2_6_0.Channel( + self.name: Channel( description=self.description, - publish=v2_6_0.Operation( + publish=Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads, "Publisher"), diff --git a/faststream/kafka/subscriber/asyncapi.py b/faststream/kafka/subscriber/asyncapi.py index 9692c9ed90..007a4f01e3 100644 --- a/faststream/kafka/subscriber/asyncapi.py +++ b/faststream/kafka/subscriber/asyncapi.py @@ -8,10 +8,13 @@ ChannelBinding, CorrelationId, Message, - v2_6_0, ) from faststream.asyncapi.schema.bindings import kafka from faststream.asyncapi.utils import resolve_payloads +from faststream.asyncapi.v2_6_0.schema import ( + Channel, + Operation, +) from faststream.broker.types import MsgType from faststream.kafka.subscriber.usecase import ( BatchSubscriber, @@ -29,7 +32,7 @@ class AsyncAPISubscriber(LogicSubscriber[MsgType]): def get_name(self) -> str: return f'{",".join(self.topics)}:{self.call_name}' - def get_schema(self) -> Dict[str, v2_6_0.Channel]: + def get_schema(self) -> Dict[str, Channel]: channels = {} payloads = self.get_payloads() @@ -37,9 +40,9 @@ def get_schema(self) -> Dict[str, v2_6_0.Channel]: for t in self.topics: handler_name = self.title_ or f"{t}:{self.call_name}" - channels[handler_name] = v2_6_0.Channel( + channels[handler_name] = Channel( description=self.description, - subscribe=v2_6_0.Operation( + subscribe=Operation( message=Message( title=f"{handler_name}:Message", payload=resolve_payloads(payloads), diff --git a/faststream/nats/publisher/asyncapi.py b/faststream/nats/publisher/asyncapi.py index f639aeb524..26e448d06e 100644 --- a/faststream/nats/publisher/asyncapi.py +++ b/faststream/nats/publisher/asyncapi.py @@ -6,10 +6,13 @@ ChannelBinding, CorrelationId, Message, - v2_6_0, ) from faststream.asyncapi.schema.bindings import nats from faststream.asyncapi.utils import resolve_payloads +from faststream.asyncapi.v2_6_0.schema import ( + Channel, + Operation, +) from faststream.nats.publisher.usecase import LogicPublisher if TYPE_CHECKING: @@ -25,13 +28,13 @@ class AsyncAPIPublisher(LogicPublisher): def get_name(self) -> str: return f"{self.subject}:Publisher" - def get_schema(self) -> Dict[str, v2_6_0.Channel]: + def get_schema(self) -> Dict[str, Channel]: payloads = self.get_payloads() return { - self.name: v2_6_0.Channel( + self.name: Channel( description=self.description, - publish=v2_6_0.Operation( + publish=Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads, "Publisher"), diff --git a/faststream/nats/subscriber/asyncapi.py b/faststream/nats/subscriber/asyncapi.py index 557f16ad9f..039c2bd2f8 100644 --- a/faststream/nats/subscriber/asyncapi.py +++ b/faststream/nats/subscriber/asyncapi.py @@ -6,10 +6,13 @@ ChannelBinding, CorrelationId, Message, - v2_6_0, ) from faststream.asyncapi.schema.bindings import nats from faststream.asyncapi.utils import resolve_payloads +from faststream.asyncapi.v2_6_0.schema import ( + Channel, + Operation, +) from faststream.nats.subscriber.usecase import ( BatchPullStreamSubscriber, ConcurrentCoreSubscriber, @@ -30,13 +33,13 @@ class AsyncAPISubscriber(LogicSubscriber[Any]): def get_name(self) -> str: return f"{self.subject}:{self.call_name}" - def get_schema(self) -> Dict[str, v2_6_0.Channel]: + def get_schema(self) -> Dict[str, Channel]: payloads = self.get_payloads() return { - self.name: v2_6_0.Channel( + self.name: Channel( description=self.description, - subscribe=v2_6_0.Operation( + subscribe=Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads), @@ -95,7 +98,7 @@ def get_name(self) -> str: return "" @override - def get_schema(self) -> Dict[str, v2_6_0.Channel]: + def get_schema(self) -> Dict[str, Channel]: return {} @@ -107,5 +110,5 @@ def get_name(self) -> str: return "" @override - def get_schema(self) -> Dict[str, v2_6_0.Channel]: + def get_schema(self) -> Dict[str, Channel]: return {} diff --git a/faststream/rabbit/publisher/asyncapi.py b/faststream/rabbit/publisher/asyncapi.py index de9b362ab9..74b9beb2c5 100644 --- a/faststream/rabbit/publisher/asyncapi.py +++ b/faststream/rabbit/publisher/asyncapi.py @@ -7,10 +7,13 @@ CorrelationId, Message, OperationBinding, - v2_6_0, ) from faststream.asyncapi.schema.bindings import amqp from faststream.asyncapi.utils import resolve_payloads +from faststream.asyncapi.v2_6_0.schema import ( + Channel, + Operation, +) from faststream.rabbit.publisher.usecase import LogicPublisher, PublishKwargs from faststream.rabbit.utils import is_routing_exchange @@ -42,12 +45,12 @@ def get_name(self) -> str: return f"{routing}:{getattr(self.exchange, 'name', None) or '_'}:Publisher" - def get_schema(self) -> Dict[str, v2_6_0.Channel]: + def get_schema(self) -> Dict[str, Channel]: payloads = self.get_payloads() return { self.name: Channel( - description=self.description, + description=self.description, # type: ignore[attr-defined] publish=Operation( bindings=OperationBinding( amqp=amqp.OperationBinding( diff --git a/faststream/rabbit/subscriber/asyncapi.py b/faststream/rabbit/subscriber/asyncapi.py index 39392e9d62..a8f9838f5b 100644 --- a/faststream/rabbit/subscriber/asyncapi.py +++ b/faststream/rabbit/subscriber/asyncapi.py @@ -5,10 +5,13 @@ CorrelationId, Message, OperationBinding, - v2_6_0, ) from faststream.asyncapi.schema.bindings import amqp from faststream.asyncapi.utils import resolve_payloads +from faststream.asyncapi.v2_6_0.schema import ( + Channel, + Operation, +) from faststream.rabbit.subscriber.usecase import LogicSubscriber from faststream.rabbit.utils import is_routing_exchange @@ -19,12 +22,12 @@ class AsyncAPISubscriber(LogicSubscriber): def get_name(self) -> str: return f"{self.queue.name}:{getattr(self.exchange, 'name', None) or '_'}:{self.call_name}" - def get_schema(self) -> Dict[str, v2_6_0.Channel]: + def get_schema(self) -> Dict[str, Channel]: payloads = self.get_payloads() return { self.name: Channel( - description=self.description, + description=self.description, # type: ignore[attr-defined] subscribe=Operation( bindings=OperationBinding( amqp=amqp.OperationBinding( diff --git a/faststream/redis/publisher/asyncapi.py b/faststream/redis/publisher/asyncapi.py index 96d3ae430d..a1978b2dce 100644 --- a/faststream/redis/publisher/asyncapi.py +++ b/faststream/redis/publisher/asyncapi.py @@ -2,9 +2,17 @@ from typing_extensions import TypeAlias, override -from faststream.asyncapi.schema import ChannelBinding, CorrelationId, Message, v2_6_0 +from faststream.asyncapi.schema import ( + ChannelBinding, + CorrelationId, + Message, +) from faststream.asyncapi.schema.bindings import redis from faststream.asyncapi.utils import resolve_payloads +from faststream.asyncapi.v2_6_0.schema import ( + Channel, + Operation, +) from faststream.exceptions import SetupError from faststream.redis.publisher.usecase import ( ChannelPublisher, @@ -32,13 +40,13 @@ class AsyncAPIPublisher(LogicPublisher, RedisAsyncAPIProtocol): """A class to represent a Redis publisher.""" - def get_schema(self) -> Dict[str, v2_6_0.Channel]: + def get_schema(self) -> Dict[str, Channel]: payloads = self.get_payloads() return { - self.name: v2_6_0.Channel( + self.name: Channel( description=self.description, - publish=v2_6_0.Operation( + publish=Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads, "Publisher"), diff --git a/faststream/redis/subscriber/asyncapi.py b/faststream/redis/subscriber/asyncapi.py index 585f04f61b..da2b374fc3 100644 --- a/faststream/redis/subscriber/asyncapi.py +++ b/faststream/redis/subscriber/asyncapi.py @@ -4,10 +4,13 @@ ChannelBinding, CorrelationId, Message, - v2_6_0, ) from faststream.asyncapi.schema.bindings import redis from faststream.asyncapi.utils import resolve_payloads +from faststream.asyncapi.v2_6_0.schema import ( + Channel, + Operation, +) from faststream.redis.schemas import ListSub, StreamSub from faststream.redis.schemas.proto import RedisAsyncAPIProtocol from faststream.redis.subscriber.usecase import ( @@ -23,13 +26,13 @@ class AsyncAPISubscriber(LogicSubscriber, RedisAsyncAPIProtocol): """A class to represent a Redis handler.""" - def get_schema(self) -> Dict[str, v2_6_0.Channel]: + def get_schema(self) -> Dict[str, Channel]: payloads = self.get_payloads() return { - self.name: v2_6_0.Channel( + self.name: Channel( description=self.description, - subscribe=v2_6_0.Operation( + subscribe=Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads), From 85da80f3a890a1d6dbac6b88335d806848ebfc3b Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Thu, 8 Aug 2024 20:45:00 +0300 Subject: [PATCH 061/245] Continue AsyncAPI schema splitting by version --- .../asyncapi_customization/custom_broker.py | 3 +- .../asyncapi_customization/custom_info.py | 4 +- faststream/app.py | 10 +- faststream/asyncapi/base/__init__.py | 7 + faststream/asyncapi/base/info.py | 28 +++ .../asyncapi/{schema => base}/schema.py | 2 +- faststream/asyncapi/schema/__init__.py | 56 ------ faststream/asyncapi/schema/info.py | 3 + faststream/asyncapi/schema/servers.py | 32 ---- faststream/asyncapi/v2_6_0/__init__.py | 7 + faststream/asyncapi/v2_6_0/generate.py | 6 +- faststream/asyncapi/v2_6_0/schema/__init__.py | 25 ++- .../{ => v2_6_0}/schema/bindings/__init__.py | 6 +- .../{ => v2_6_0}/schema/bindings/amqp.py | 0 .../{ => v2_6_0}/schema/bindings/kafka.py | 0 .../{ => v2_6_0}/schema/bindings/main.py | 10 +- .../{ => v2_6_0}/schema/bindings/nats.py | 0 .../{ => v2_6_0}/schema/bindings/redis.py | 0 .../{ => v2_6_0}/schema/bindings/sqs.py | 0 faststream/asyncapi/v2_6_0/schema/channels.py | 4 +- .../asyncapi/v2_6_0/schema/components.py | 2 +- faststream/asyncapi/v2_6_0/schema/info.py | 163 +++++++++++++++++- .../asyncapi/{ => v2_6_0}/schema/message.py | 2 +- .../asyncapi/v2_6_0/schema/operations.py | 6 +- faststream/asyncapi/v2_6_0/schema/schema.py | 12 +- .../asyncapi/{ => v2_6_0}/schema/security.py | 0 faststream/asyncapi/v2_6_0/schema/servers.py | 33 +++- .../asyncapi/{ => v2_6_0}/schema/utils.py | 0 faststream/asyncapi/v3_0_0/__init__.py | 7 + faststream/asyncapi/v3_0_0/generate.py | 6 +- faststream/asyncapi/v3_0_0/schema/channels.py | 6 +- .../asyncapi/v3_0_0/schema/components.py | 2 +- faststream/asyncapi/v3_0_0/schema/info.py | 6 +- .../asyncapi/v3_0_0/schema/operations.py | 4 +- faststream/asyncapi/v3_0_0/schema/schema.py | 2 +- faststream/asyncapi/v3_0_0/schema/servers.py | 30 +--- faststream/confluent/publisher/asyncapi.py | 8 +- faststream/confluent/subscriber/asyncapi.py | 8 +- faststream/kafka/publisher/asyncapi.py | 8 +- faststream/kafka/subscriber/asyncapi.py | 8 +- faststream/nats/publisher/asyncapi.py | 8 +- faststream/nats/subscriber/asyncapi.py | 8 +- faststream/rabbit/publisher/asyncapi.py | 13 +- faststream/rabbit/subscriber/asyncapi.py | 13 +- faststream/redis/publisher/asyncapi.py | 8 +- faststream/redis/schemas/proto.py | 2 +- faststream/redis/subscriber/asyncapi.py | 8 +- .../confluent/v2_6_0/test_connection.py | 2 +- .../confluent/v3_0_0/test_connection.py | 2 +- tests/asyncapi/kafka/v2_6_0/test_app.py | 4 +- .../asyncapi/kafka/v2_6_0/test_connection.py | 2 +- .../asyncapi/kafka/v3_0_0/test_connection.py | 2 +- tests/asyncapi/nats/v2_6_0/test_connection.py | 2 +- tests/asyncapi/nats/v3_0_0/test_connection.py | 2 +- .../asyncapi/rabbit/v2_6_0/test_connection.py | 2 +- .../asyncapi/rabbit/v3_0_0/test_connection.py | 2 +- .../asyncapi/redis/v2_6_0/test_connection.py | 2 +- .../asyncapi/redis/v3_0_0/test_connection.py | 2 +- 58 files changed, 350 insertions(+), 250 deletions(-) create mode 100644 faststream/asyncapi/base/__init__.py create mode 100644 faststream/asyncapi/base/info.py rename faststream/asyncapi/{schema => base}/schema.py (95%) delete mode 100644 faststream/asyncapi/schema/__init__.py delete mode 100644 faststream/asyncapi/schema/servers.py rename faststream/asyncapi/{ => v2_6_0}/schema/bindings/__init__.py (57%) rename faststream/asyncapi/{ => v2_6_0}/schema/bindings/amqp.py (100%) rename faststream/asyncapi/{ => v2_6_0}/schema/bindings/kafka.py (100%) rename faststream/asyncapi/{ => v2_6_0}/schema/bindings/main.py (85%) rename faststream/asyncapi/{ => v2_6_0}/schema/bindings/nats.py (100%) rename faststream/asyncapi/{ => v2_6_0}/schema/bindings/redis.py (100%) rename faststream/asyncapi/{ => v2_6_0}/schema/bindings/sqs.py (100%) rename faststream/asyncapi/{ => v2_6_0}/schema/message.py (97%) rename faststream/asyncapi/{ => v2_6_0}/schema/security.py (100%) rename faststream/asyncapi/{ => v2_6_0}/schema/utils.py (100%) diff --git a/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_broker.py b/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_broker.py index ac3a8f4234..74247b6d10 100644 --- a/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_broker.py +++ b/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_broker.py @@ -1,6 +1,5 @@ from faststream import FastStream -from faststream.kafka import KafkaBroker, KafkaMessage -from faststream.asyncapi.schema import Tag +from faststream.kafka import KafkaBroker broker = KafkaBroker( "localhost:9092", diff --git a/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_info.py b/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_info.py index 7c284c8299..621956bf15 100644 --- a/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_info.py +++ b/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_info.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.kafka import KafkaBroker, KafkaMessage -from faststream.asyncapi.schema import Contact, ExternalDocs, License, Tag +from faststream.asyncapi.v2_6_0.schema.info import License, Contact +from faststream.kafka import KafkaBroker broker = KafkaBroker("localhost:9092") description="""# Title of the description diff --git a/faststream/app.py b/faststream/app.py index 950b3f1164..52633ab18a 100644 --- a/faststream/app.py +++ b/faststream/app.py @@ -30,15 +30,17 @@ if TYPE_CHECKING: from faststream.asyncapi.schema import ( - Contact, - ContactDict, ExternalDocs, ExternalDocsDict, - License, - LicenseDict, Tag, TagDict, ) + from faststream.asyncapi.v2_6_0.schema.info import ( + Contact, + ContactDict, + License, + LicenseDict, + ) from faststream.broker.core.usecase import BrokerUsecase from faststream.types import ( AnyCallable, diff --git a/faststream/asyncapi/base/__init__.py b/faststream/asyncapi/base/__init__.py new file mode 100644 index 0000000000..9164dc3039 --- /dev/null +++ b/faststream/asyncapi/base/__init__.py @@ -0,0 +1,7 @@ +from .info import BaseInfo +from .schema import BaseSchema + +__all__ = ( + "BaseInfo", + "BaseSchema", +) diff --git a/faststream/asyncapi/base/info.py b/faststream/asyncapi/base/info.py new file mode 100644 index 0000000000..6472de4334 --- /dev/null +++ b/faststream/asyncapi/base/info.py @@ -0,0 +1,28 @@ +from pydantic import BaseModel + +from faststream._compat import ( + PYDANTIC_V2, +) + + +class BaseInfo(BaseModel): + """A class to represent information. + + Attributes: + title : title of the information + version : version of the information (default: "1.0.0") + description : description of the information (default: "") + + """ + + title: str + version: str = "1.0.0" + description: str = "" + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" diff --git a/faststream/asyncapi/schema/schema.py b/faststream/asyncapi/base/schema.py similarity index 95% rename from faststream/asyncapi/schema/schema.py rename to faststream/asyncapi/base/schema.py index a7e6f88db5..4584ef5092 100644 --- a/faststream/asyncapi/schema/schema.py +++ b/faststream/asyncapi/base/schema.py @@ -3,7 +3,7 @@ from pydantic import BaseModel from faststream._compat import model_to_json, model_to_jsonable -from faststream.asyncapi.schema.info import BaseInfo +from faststream.asyncapi.base.info import BaseInfo class BaseSchema(BaseModel): diff --git a/faststream/asyncapi/schema/__init__.py b/faststream/asyncapi/schema/__init__.py deleted file mode 100644 index a959afc105..0000000000 --- a/faststream/asyncapi/schema/__init__.py +++ /dev/null @@ -1,56 +0,0 @@ -"""AsyncAPI schema related functions.""" - -from faststream.asyncapi.schema.bindings import ( - ChannelBinding, - OperationBinding, - ServerBinding, -) -from faststream.asyncapi.schema.info import ( - BaseInfo, - Contact, - ContactDict, - License, - LicenseDict, -) -from faststream.asyncapi.schema.message import CorrelationId, Message -from faststream.asyncapi.schema.schema import ( - BaseSchema, -) -from faststream.asyncapi.schema.security import SecuritySchemaComponent -from faststream.asyncapi.schema.utils import ( - ExternalDocs, - ExternalDocsDict, - Reference, - Tag, - TagDict, -) -from faststream.asyncapi.version import AsyncAPIVersion - -__all__ = ( - # main - "AsyncAPIVersion", - "BaseSchema", - # info - "BaseInfo", - "Contact", - "ContactDict", - "License", - "LicenseDict", - # servers - # channels - # utils - "Tag", - "TagDict", - "ExternalDocs", - "ExternalDocsDict", - "Reference", - # bindings - "ServerBinding", - "ChannelBinding", - "OperationBinding", - # messages - "CorrelationId", - "Message", - # security - "SecuritySchemaComponent", -) diff --git a/faststream/asyncapi/schema/info.py b/faststream/asyncapi/schema/info.py index bc5adbc3e0..e22f4361a6 100644 --- a/faststream/asyncapi/schema/info.py +++ b/faststream/asyncapi/schema/info.py @@ -169,6 +169,9 @@ class BaseInfo(BaseModel): title : title of the information version : version of the information (default: "1.0.0") description : description of the information (default: "") + termsOfService : terms of service for the information (default: None) + contact : contact information for the information (default: None) + license : license information for the information (default: None) """ diff --git a/faststream/asyncapi/schema/servers.py b/faststream/asyncapi/schema/servers.py deleted file mode 100644 index 725db45389..0000000000 --- a/faststream/asyncapi/schema/servers.py +++ /dev/null @@ -1,32 +0,0 @@ -from typing import Dict, List, Optional - -from pydantic import BaseModel - -from faststream._compat import PYDANTIC_V2 - -SecurityRequirement = List[Dict[str, List[str]]] - - -class ServerVariable(BaseModel): - """A class to represent a server variable. - - Attributes: - enum : list of possible values for the server variable (optional) - default : default value for the server variable (optional) - description : description of the server variable (optional) - examples : list of example values for the server variable (optional) - - """ - - enum: Optional[List[str]] = None - default: Optional[str] = None - description: Optional[str] = None - examples: Optional[List[str]] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" diff --git a/faststream/asyncapi/v2_6_0/__init__.py b/faststream/asyncapi/v2_6_0/__init__.py index e69de29bb2..be8f2c412c 100644 --- a/faststream/asyncapi/v2_6_0/__init__.py +++ b/faststream/asyncapi/v2_6_0/__init__.py @@ -0,0 +1,7 @@ +from . import schema +from .generate import get_app_schema + +__all__ = ( + "schema", + "get_app_schema", +) diff --git a/faststream/asyncapi/v2_6_0/generate.py b/faststream/asyncapi/v2_6_0/generate.py index e19182e0e8..7cd0b7016e 100644 --- a/faststream/asyncapi/v2_6_0/generate.py +++ b/faststream/asyncapi/v2_6_0/generate.py @@ -1,17 +1,15 @@ from typing import TYPE_CHECKING, Any, Dict, List, Union from faststream._compat import DEF_KEY, HAS_FASTAPI -from faststream.asyncapi.schema import ( - Message, - Reference, -) from faststream.asyncapi.v2_6_0.schema import ( Channel, Components, Info, + Reference, Schema, Server, ) +from faststream.asyncapi.v2_6_0.schema.message import Message from faststream.constants import ContentTypes if TYPE_CHECKING: diff --git a/faststream/asyncapi/v2_6_0/schema/__init__.py b/faststream/asyncapi/v2_6_0/schema/__init__.py index 01a9788a2e..846f5c3f88 100644 --- a/faststream/asyncapi/v2_6_0/schema/__init__.py +++ b/faststream/asyncapi/v2_6_0/schema/__init__.py @@ -1,15 +1,36 @@ +from . import bindings from .channels import Channel from .components import Components -from .info import Info +from .info import Contact, ContactDict, Info, License, LicenseDict +from .message import CorrelationId, Message from .operations import Operation from .schema import Schema -from .servers import Server +from .security import OauthFlowObj, OauthFlows, SecuritySchemaComponent +from .servers import Server, ServerVariable +from .utils import ExternalDocs, ExternalDocsDict, Parameter, Reference, Tag, TagDict __all__ = ( "Channel", "Components", "Info", + "License", + "LicenseDict", + "Contact", + "ContactDict", "Operation", "Schema", + "OauthFlowObj", + "OauthFlows", + "SecuritySchemaComponent", "Server", + "ServerVariable", + "Message", + "CorrelationId", + "ExternalDocsDict", + "ExternalDocs", + "TagDict", + "Tag", + "Reference", + "Parameter", + "bindings", ) diff --git a/faststream/asyncapi/schema/bindings/__init__.py b/faststream/asyncapi/v2_6_0/schema/bindings/__init__.py similarity index 57% rename from faststream/asyncapi/schema/bindings/__init__.py rename to faststream/asyncapi/v2_6_0/schema/bindings/__init__.py index 4b29e49a83..39ce4b993c 100644 --- a/faststream/asyncapi/schema/bindings/__init__.py +++ b/faststream/asyncapi/v2_6_0/schema/bindings/__init__.py @@ -1,13 +1,11 @@ -"""AsyncAPI schema bindings related functions.""" - -from faststream.asyncapi.schema.bindings.main import ( +from .main import ( ChannelBinding, OperationBinding, ServerBinding, ) __all__ = ( + "ServerBinding", "ChannelBinding", "OperationBinding", - "ServerBinding", ) diff --git a/faststream/asyncapi/schema/bindings/amqp.py b/faststream/asyncapi/v2_6_0/schema/bindings/amqp.py similarity index 100% rename from faststream/asyncapi/schema/bindings/amqp.py rename to faststream/asyncapi/v2_6_0/schema/bindings/amqp.py diff --git a/faststream/asyncapi/schema/bindings/kafka.py b/faststream/asyncapi/v2_6_0/schema/bindings/kafka.py similarity index 100% rename from faststream/asyncapi/schema/bindings/kafka.py rename to faststream/asyncapi/v2_6_0/schema/bindings/kafka.py diff --git a/faststream/asyncapi/schema/bindings/main.py b/faststream/asyncapi/v2_6_0/schema/bindings/main.py similarity index 85% rename from faststream/asyncapi/schema/bindings/main.py rename to faststream/asyncapi/v2_6_0/schema/bindings/main.py index 582db39bf7..0cd5c7abfb 100644 --- a/faststream/asyncapi/schema/bindings/main.py +++ b/faststream/asyncapi/v2_6_0/schema/bindings/main.py @@ -3,11 +3,11 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.schema.bindings import amqp as amqp_bindings -from faststream.asyncapi.schema.bindings import kafka as kafka_bindings -from faststream.asyncapi.schema.bindings import nats as nats_bindings -from faststream.asyncapi.schema.bindings import redis as redis_bindings -from faststream.asyncapi.schema.bindings import sqs as sqs_bindings +from faststream.asyncapi.v2_6_0.schema.bindings import amqp as amqp_bindings +from faststream.asyncapi.v2_6_0.schema.bindings import kafka as kafka_bindings +from faststream.asyncapi.v2_6_0.schema.bindings import nats as nats_bindings +from faststream.asyncapi.v2_6_0.schema.bindings import redis as redis_bindings +from faststream.asyncapi.v2_6_0.schema.bindings import sqs as sqs_bindings class ServerBinding(BaseModel): diff --git a/faststream/asyncapi/schema/bindings/nats.py b/faststream/asyncapi/v2_6_0/schema/bindings/nats.py similarity index 100% rename from faststream/asyncapi/schema/bindings/nats.py rename to faststream/asyncapi/v2_6_0/schema/bindings/nats.py diff --git a/faststream/asyncapi/schema/bindings/redis.py b/faststream/asyncapi/v2_6_0/schema/bindings/redis.py similarity index 100% rename from faststream/asyncapi/schema/bindings/redis.py rename to faststream/asyncapi/v2_6_0/schema/bindings/redis.py diff --git a/faststream/asyncapi/schema/bindings/sqs.py b/faststream/asyncapi/v2_6_0/schema/bindings/sqs.py similarity index 100% rename from faststream/asyncapi/schema/bindings/sqs.py rename to faststream/asyncapi/v2_6_0/schema/bindings/sqs.py diff --git a/faststream/asyncapi/v2_6_0/schema/channels.py b/faststream/asyncapi/v2_6_0/schema/channels.py index 8389a66d27..0c8af7e74a 100644 --- a/faststream/asyncapi/v2_6_0/schema/channels.py +++ b/faststream/asyncapi/v2_6_0/schema/channels.py @@ -3,9 +3,9 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.schema.bindings import ChannelBinding -from faststream.asyncapi.schema.utils import Parameter +from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding from faststream.asyncapi.v2_6_0.schema.operations import Operation +from faststream.asyncapi.v2_6_0.schema.utils import Parameter class Channel(BaseModel): diff --git a/faststream/asyncapi/v2_6_0/schema/components.py b/faststream/asyncapi/v2_6_0/schema/components.py index 32b6d2d443..bff01e61bf 100644 --- a/faststream/asyncapi/v2_6_0/schema/components.py +++ b/faststream/asyncapi/v2_6_0/schema/components.py @@ -9,7 +9,7 @@ from faststream._compat import ( PYDANTIC_V2, ) -from faststream.asyncapi.schema.message import Message +from faststream.asyncapi.v2_6_0.schema.message import Message class Components(BaseModel): diff --git a/faststream/asyncapi/v2_6_0/schema/info.py b/faststream/asyncapi/v2_6_0/schema/info.py index d371584b32..e3219176fd 100644 --- a/faststream/asyncapi/v2_6_0/schema/info.py +++ b/faststream/asyncapi/v2_6_0/schema/info.py @@ -1,19 +1,168 @@ from typing import ( Any, + Callable, Dict, + Iterable, Optional, + Type, Union, ) -from pydantic import AnyHttpUrl +from pydantic import AnyHttpUrl, BaseModel +from typing_extensions import Required, TypedDict -from faststream.asyncapi.schema.info import ( - BaseInfo, - Contact, - ContactDict, - License, - LicenseDict, +from faststream._compat import ( + PYDANTIC_V2, + CoreSchema, + GetJsonSchemaHandler, + JsonSchemaValue, + with_info_plain_validator_function, ) +from faststream.asyncapi.base import BaseInfo +from faststream.log import logger + +try: + import email_validator + + if email_validator is None: + raise ImportError + from pydantic import EmailStr + +except ImportError: # pragma: no cover + # NOTE: EmailStr mock was copied from the FastAPI + # https://github.com/tiangolo/fastapi/blob/master/fastapi/openapi/models.py#24 + class EmailStr(str): # type: ignore + """EmailStr is a string that should be an email. + + Note: EmailStr mock was copied from the FastAPI: + https://github.com/tiangolo/fastapi/blob/master/fastapi/openapi/models.py#24 + + """ + + @classmethod + def __get_validators__(cls) -> Iterable[Callable[..., Any]]: + """Returns the validators for the EmailStr class.""" + yield cls.validate + + @classmethod + def validate(cls, v: Any) -> str: + """Validates the EmailStr class.""" + logger.warning( + "email-validator bot installed, email fields will be treated as str.\n" + "To install, run: pip install email-validator" + ) + return str(v) + + @classmethod + def _validate(cls, __input_value: Any, _: Any) -> str: + logger.warning( + "email-validator bot installed, email fields will be treated as str.\n" + "To install, run: pip install email-validator" + ) + return str(__input_value) + + @classmethod + def __get_pydantic_json_schema__( + cls, + core_schema: CoreSchema, + handler: GetJsonSchemaHandler, + ) -> JsonSchemaValue: + """Returns the JSON schema for the EmailStr class. + + Args: + core_schema : the core schema + handler : the handler + """ + return {"type": "string", "format": "email"} + + @classmethod + def __get_pydantic_core_schema__( + cls, + source: Type[Any], + handler: Callable[[Any], CoreSchema], + ) -> JsonSchemaValue: + """Returns the core schema for the EmailStr class. + + Args: + source : the source + handler : the handler + """ + return with_info_plain_validator_function(cls._validate) # type: ignore[no-any-return] + + +class ContactDict(TypedDict, total=False): + """A class to represent a dictionary of contact information. + + Attributes: + name : required name of the contact (type: str) + url : URL of the contact (type: AnyHttpUrl) + email : email address of the contact (type: EmailStr) + + """ + + name: Required[str] + url: AnyHttpUrl + email: EmailStr + + +class Contact(BaseModel): + """A class to represent a contact. + + Attributes: + name : name of the contact (str) + url : URL of the contact (Optional[AnyHttpUrl]) + email : email of the contact (Optional[EmailStr]) + + """ + + name: str + url: Optional[AnyHttpUrl] = None + email: Optional[EmailStr] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" + + +class LicenseDict(TypedDict, total=False): + """A dictionary-like class to represent a license. + + Attributes: + name : required name of the license (type: str) + url : URL of the license (type: AnyHttpUrl) + + """ + + name: Required[str] + url: AnyHttpUrl + + +class License(BaseModel): + """A class to represent a license. + + Attributes: + name : name of the license + url : URL of the license (optional) + + Config: + extra : allow additional attributes in the model (PYDANTIC_V2) + + """ + + name: str + url: Optional[AnyHttpUrl] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" class Info(BaseInfo): diff --git a/faststream/asyncapi/schema/message.py b/faststream/asyncapi/v2_6_0/schema/message.py similarity index 97% rename from faststream/asyncapi/schema/message.py rename to faststream/asyncapi/v2_6_0/schema/message.py index 3c9a09f22e..c462e6aa33 100644 --- a/faststream/asyncapi/schema/message.py +++ b/faststream/asyncapi/v2_6_0/schema/message.py @@ -3,7 +3,7 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.schema.utils import ( +from faststream.asyncapi.v2_6_0.schema.utils import ( ExternalDocs, Tag, ) diff --git a/faststream/asyncapi/v2_6_0/schema/operations.py b/faststream/asyncapi/v2_6_0/schema/operations.py index c929d71263..54a2a2ac71 100644 --- a/faststream/asyncapi/v2_6_0/schema/operations.py +++ b/faststream/asyncapi/v2_6_0/schema/operations.py @@ -3,9 +3,9 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.schema.bindings import OperationBinding -from faststream.asyncapi.schema.message import Message -from faststream.asyncapi.schema.utils import ( +from faststream.asyncapi.v2_6_0.schema.bindings import OperationBinding +from faststream.asyncapi.v2_6_0.schema.message import Message +from faststream.asyncapi.v2_6_0.schema.utils import ( ExternalDocs, ExternalDocsDict, Reference, diff --git a/faststream/asyncapi/v2_6_0/schema/schema.py b/faststream/asyncapi/v2_6_0/schema/schema.py index 31361740c5..143ed74288 100644 --- a/faststream/asyncapi/v2_6_0/schema/schema.py +++ b/faststream/asyncapi/v2_6_0/schema/schema.py @@ -1,17 +1,17 @@ from typing import Any, Dict, List, Optional, Union from faststream._compat import model_to_json, model_to_jsonable -from faststream.asyncapi.schema.schema import BaseSchema -from faststream.asyncapi.schema.utils import ( +from faststream.asyncapi.base import BaseSchema +from faststream.asyncapi.v2_6_0.schema.channels import Channel +from faststream.asyncapi.v2_6_0.schema.components import Components +from faststream.asyncapi.v2_6_0.schema.info import Info +from faststream.asyncapi.v2_6_0.schema.servers import Server +from faststream.asyncapi.v2_6_0.schema.utils import ( ExternalDocs, ExternalDocsDict, Tag, TagDict, ) -from faststream.asyncapi.v2_6_0.schema.channels import Channel -from faststream.asyncapi.v2_6_0.schema.components import Components -from faststream.asyncapi.v2_6_0.schema.info import Info -from faststream.asyncapi.v2_6_0.schema.servers import Server from faststream.asyncapi.version import AsyncAPIVersion diff --git a/faststream/asyncapi/schema/security.py b/faststream/asyncapi/v2_6_0/schema/security.py similarity index 100% rename from faststream/asyncapi/schema/security.py rename to faststream/asyncapi/v2_6_0/schema/security.py diff --git a/faststream/asyncapi/v2_6_0/schema/servers.py b/faststream/asyncapi/v2_6_0/schema/servers.py index 7e1d892091..d6d2af2805 100644 --- a/faststream/asyncapi/v2_6_0/schema/servers.py +++ b/faststream/asyncapi/v2_6_0/schema/servers.py @@ -3,9 +3,36 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.schema.bindings import ServerBinding -from faststream.asyncapi.schema.servers import SecurityRequirement, ServerVariable -from faststream.asyncapi.schema.utils import Reference, Tag, TagDict +from faststream.asyncapi.v2_6_0.schema.bindings import ServerBinding +from faststream.asyncapi.v2_6_0.schema.utils import Reference, Tag, TagDict + +SecurityRequirement = List[Dict[str, List[str]]] + + +class ServerVariable(BaseModel): + """A class to represent a server variable. + + Attributes: + enum : list of possible values for the server variable (optional) + default : default value for the server variable (optional) + description : description of the server variable (optional) + examples : list of example values for the server variable (optional) + + """ + + enum: Optional[List[str]] = None + default: Optional[str] = None + description: Optional[str] = None + examples: Optional[List[str]] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" + class Server(BaseModel): diff --git a/faststream/asyncapi/schema/utils.py b/faststream/asyncapi/v2_6_0/schema/utils.py similarity index 100% rename from faststream/asyncapi/schema/utils.py rename to faststream/asyncapi/v2_6_0/schema/utils.py diff --git a/faststream/asyncapi/v3_0_0/__init__.py b/faststream/asyncapi/v3_0_0/__init__.py index e69de29bb2..be8f2c412c 100644 --- a/faststream/asyncapi/v3_0_0/__init__.py +++ b/faststream/asyncapi/v3_0_0/__init__.py @@ -0,0 +1,7 @@ +from . import schema +from .generate import get_app_schema + +__all__ = ( + "schema", + "get_app_schema", +) diff --git a/faststream/asyncapi/v3_0_0/generate.py b/faststream/asyncapi/v3_0_0/generate.py index 992b96aabe..6fd587225c 100644 --- a/faststream/asyncapi/v3_0_0/generate.py +++ b/faststream/asyncapi/v3_0_0/generate.py @@ -2,10 +2,8 @@ from urllib.parse import urlparse from faststream._compat import DEF_KEY, HAS_FASTAPI -from faststream.asyncapi.schema import ( - Message, - Reference, -) +from faststream.asyncapi.v2_6_0.schema import Reference +from faststream.asyncapi.v2_6_0.schema.message import Message from faststream.asyncapi.v3_0_0.schema import ( Channel, Components, diff --git a/faststream/asyncapi/v3_0_0/schema/channels.py b/faststream/asyncapi/v3_0_0/schema/channels.py index 514fe7a94b..d0489ff12c 100644 --- a/faststream/asyncapi/v3_0_0/schema/channels.py +++ b/faststream/asyncapi/v3_0_0/schema/channels.py @@ -3,9 +3,9 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.schema.bindings import ChannelBinding -from faststream.asyncapi.schema.message import Message -from faststream.asyncapi.schema.utils import Parameter, Reference +from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding +from faststream.asyncapi.v2_6_0.schema.message import Message +from faststream.asyncapi.v2_6_0.schema.utils import Parameter, Reference class Channel(BaseModel): diff --git a/faststream/asyncapi/v3_0_0/schema/components.py b/faststream/asyncapi/v3_0_0/schema/components.py index ef23de6e12..73f5176b3f 100644 --- a/faststream/asyncapi/v3_0_0/schema/components.py +++ b/faststream/asyncapi/v3_0_0/schema/components.py @@ -3,7 +3,7 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.schema.message import Message +from faststream.asyncapi.v2_6_0.schema.message import Message class Components(BaseModel): diff --git a/faststream/asyncapi/v3_0_0/schema/info.py b/faststream/asyncapi/v3_0_0/schema/info.py index 055c49fd7f..13f7d1478b 100644 --- a/faststream/asyncapi/v3_0_0/schema/info.py +++ b/faststream/asyncapi/v3_0_0/schema/info.py @@ -8,14 +8,14 @@ from pydantic import AnyHttpUrl -from faststream.asyncapi.schema.info import ( - BaseInfo, +from faststream.asyncapi.base import BaseInfo +from faststream.asyncapi.v2_6_0.schema.info import ( Contact, ContactDict, License, LicenseDict, ) -from faststream.asyncapi.schema.utils import ( # noqa: TCH001 +from faststream.asyncapi.v2_6_0.schema.utils import ( # noqa: TCH001 ExternalDocs, ExternalDocsDict, Tag, diff --git a/faststream/asyncapi/v3_0_0/schema/operations.py b/faststream/asyncapi/v3_0_0/schema/operations.py index c6c33ac74a..b727243713 100644 --- a/faststream/asyncapi/v3_0_0/schema/operations.py +++ b/faststream/asyncapi/v3_0_0/schema/operations.py @@ -3,8 +3,8 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.schema.bindings import OperationBinding -from faststream.asyncapi.schema.utils import ( +from faststream.asyncapi.v2_6_0.schema.bindings import OperationBinding +from faststream.asyncapi.v2_6_0.schema.utils import ( ExternalDocs, ExternalDocsDict, Reference, diff --git a/faststream/asyncapi/v3_0_0/schema/schema.py b/faststream/asyncapi/v3_0_0/schema/schema.py index fe61f7ae63..75505ba368 100644 --- a/faststream/asyncapi/v3_0_0/schema/schema.py +++ b/faststream/asyncapi/v3_0_0/schema/schema.py @@ -1,7 +1,7 @@ from typing import Any, Dict, Optional from faststream._compat import model_to_json, model_to_jsonable -from faststream.asyncapi.schema.schema import BaseSchema +from faststream.asyncapi.base import BaseSchema from faststream.asyncapi.v3_0_0.schema.channels import Channel from faststream.asyncapi.v3_0_0.schema.components import Components from faststream.asyncapi.v3_0_0.schema.info import Info diff --git a/faststream/asyncapi/v3_0_0/schema/servers.py b/faststream/asyncapi/v3_0_0/schema/servers.py index b63a0ac203..563e398318 100644 --- a/faststream/asyncapi/v3_0_0/schema/servers.py +++ b/faststream/asyncapi/v3_0_0/schema/servers.py @@ -3,37 +3,13 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.schema.bindings import ServerBinding -from faststream.asyncapi.schema.utils import Reference, Tag, TagDict +from faststream.asyncapi.v2_6_0.schema import ServerVariable +from faststream.asyncapi.v2_6_0.schema.bindings import ServerBinding +from faststream.asyncapi.v2_6_0.schema.utils import Reference, Tag, TagDict SecurityRequirement = List[Dict[str, List[str]]] -class ServerVariable(BaseModel): - """A class to represent a server variable. - - Attributes: - enum : list of possible values for the server variable (optional) - default : default value for the server variable (optional) - description : description of the server variable (optional) - examples : list of example values for the server variable (optional) - - """ - - enum: Optional[List[str]] = None - default: Optional[str] = None - description: Optional[str] = None - examples: Optional[List[str]] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" - - class Server(BaseModel): """A class to represent a server. diff --git a/faststream/confluent/publisher/asyncapi.py b/faststream/confluent/publisher/asyncapi.py index a0f5db5e56..49d38cc08c 100644 --- a/faststream/confluent/publisher/asyncapi.py +++ b/faststream/confluent/publisher/asyncapi.py @@ -12,17 +12,13 @@ from typing_extensions import override -from faststream.asyncapi.schema import ( - ChannelBinding, - CorrelationId, - Message, -) -from faststream.asyncapi.schema.bindings import kafka from faststream.asyncapi.utils import resolve_payloads from faststream.asyncapi.v2_6_0.schema import ( Channel, Operation, ) +from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding, kafka +from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message from faststream.broker.types import MsgType from faststream.confluent.publisher.usecase import ( BatchPublisher, diff --git a/faststream/confluent/subscriber/asyncapi.py b/faststream/confluent/subscriber/asyncapi.py index fd8f7b94ac..08ce6873c6 100644 --- a/faststream/confluent/subscriber/asyncapi.py +++ b/faststream/confluent/subscriber/asyncapi.py @@ -4,17 +4,13 @@ Tuple, ) -from faststream.asyncapi.schema import ( - ChannelBinding, - CorrelationId, - Message, -) -from faststream.asyncapi.schema.bindings import kafka from faststream.asyncapi.utils import resolve_payloads from faststream.asyncapi.v2_6_0.schema import ( Channel, Operation, ) +from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding, kafka +from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message from faststream.broker.types import MsgType from faststream.confluent.subscriber.usecase import ( BatchSubscriber, diff --git a/faststream/kafka/publisher/asyncapi.py b/faststream/kafka/publisher/asyncapi.py index b8eca07757..2d7de79785 100644 --- a/faststream/kafka/publisher/asyncapi.py +++ b/faststream/kafka/publisher/asyncapi.py @@ -12,17 +12,13 @@ from typing_extensions import override -from faststream.asyncapi.schema import ( - ChannelBinding, - CorrelationId, - Message, -) -from faststream.asyncapi.schema.bindings import kafka from faststream.asyncapi.utils import resolve_payloads from faststream.asyncapi.v2_6_0.schema import ( Channel, Operation, ) +from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding, kafka +from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message from faststream.broker.types import MsgType from faststream.exceptions import SetupError from faststream.kafka.publisher.usecase import ( diff --git a/faststream/kafka/subscriber/asyncapi.py b/faststream/kafka/subscriber/asyncapi.py index 007a4f01e3..b22f9013f9 100644 --- a/faststream/kafka/subscriber/asyncapi.py +++ b/faststream/kafka/subscriber/asyncapi.py @@ -4,17 +4,13 @@ Tuple, ) -from faststream.asyncapi.schema import ( - ChannelBinding, - CorrelationId, - Message, -) -from faststream.asyncapi.schema.bindings import kafka from faststream.asyncapi.utils import resolve_payloads from faststream.asyncapi.v2_6_0.schema import ( Channel, Operation, ) +from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding, kafka +from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message from faststream.broker.types import MsgType from faststream.kafka.subscriber.usecase import ( BatchSubscriber, diff --git a/faststream/nats/publisher/asyncapi.py b/faststream/nats/publisher/asyncapi.py index 26e448d06e..4bf49b7fc1 100644 --- a/faststream/nats/publisher/asyncapi.py +++ b/faststream/nats/publisher/asyncapi.py @@ -2,17 +2,13 @@ from typing_extensions import override -from faststream.asyncapi.schema import ( - ChannelBinding, - CorrelationId, - Message, -) -from faststream.asyncapi.schema.bindings import nats from faststream.asyncapi.utils import resolve_payloads from faststream.asyncapi.v2_6_0.schema import ( Channel, Operation, ) +from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding, nats +from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message from faststream.nats.publisher.usecase import LogicPublisher if TYPE_CHECKING: diff --git a/faststream/nats/subscriber/asyncapi.py b/faststream/nats/subscriber/asyncapi.py index 039c2bd2f8..bd8239362e 100644 --- a/faststream/nats/subscriber/asyncapi.py +++ b/faststream/nats/subscriber/asyncapi.py @@ -2,17 +2,13 @@ from typing_extensions import override -from faststream.asyncapi.schema import ( - ChannelBinding, - CorrelationId, - Message, -) -from faststream.asyncapi.schema.bindings import nats from faststream.asyncapi.utils import resolve_payloads from faststream.asyncapi.v2_6_0.schema import ( Channel, Operation, ) +from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding, nats +from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message from faststream.nats.subscriber.usecase import ( BatchPullStreamSubscriber, ConcurrentCoreSubscriber, diff --git a/faststream/rabbit/publisher/asyncapi.py b/faststream/rabbit/publisher/asyncapi.py index 74b9beb2c5..cf2befc6a6 100644 --- a/faststream/rabbit/publisher/asyncapi.py +++ b/faststream/rabbit/publisher/asyncapi.py @@ -2,18 +2,17 @@ from typing_extensions import override -from faststream.asyncapi.schema import ( - ChannelBinding, - CorrelationId, - Message, - OperationBinding, -) -from faststream.asyncapi.schema.bindings import amqp from faststream.asyncapi.utils import resolve_payloads from faststream.asyncapi.v2_6_0.schema import ( Channel, Operation, ) +from faststream.asyncapi.v2_6_0.schema.bindings import ( + ChannelBinding, + OperationBinding, + amqp, +) +from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message from faststream.rabbit.publisher.usecase import LogicPublisher, PublishKwargs from faststream.rabbit.utils import is_routing_exchange diff --git a/faststream/rabbit/subscriber/asyncapi.py b/faststream/rabbit/subscriber/asyncapi.py index a8f9838f5b..307488c1c4 100644 --- a/faststream/rabbit/subscriber/asyncapi.py +++ b/faststream/rabbit/subscriber/asyncapi.py @@ -1,17 +1,16 @@ from typing import Dict -from faststream.asyncapi.schema import ( - ChannelBinding, - CorrelationId, - Message, - OperationBinding, -) -from faststream.asyncapi.schema.bindings import amqp from faststream.asyncapi.utils import resolve_payloads from faststream.asyncapi.v2_6_0.schema import ( Channel, Operation, ) +from faststream.asyncapi.v2_6_0.schema.bindings import ( + ChannelBinding, + OperationBinding, + amqp, +) +from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message from faststream.rabbit.subscriber.usecase import LogicSubscriber from faststream.rabbit.utils import is_routing_exchange diff --git a/faststream/redis/publisher/asyncapi.py b/faststream/redis/publisher/asyncapi.py index a1978b2dce..032055bdf1 100644 --- a/faststream/redis/publisher/asyncapi.py +++ b/faststream/redis/publisher/asyncapi.py @@ -2,17 +2,13 @@ from typing_extensions import TypeAlias, override -from faststream.asyncapi.schema import ( - ChannelBinding, - CorrelationId, - Message, -) -from faststream.asyncapi.schema.bindings import redis from faststream.asyncapi.utils import resolve_payloads from faststream.asyncapi.v2_6_0.schema import ( Channel, Operation, ) +from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding, redis +from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message from faststream.exceptions import SetupError from faststream.redis.publisher.usecase import ( ChannelPublisher, diff --git a/faststream/redis/schemas/proto.py b/faststream/redis/schemas/proto.py index 2521a1a0a3..22ca0253f4 100644 --- a/faststream/redis/schemas/proto.py +++ b/faststream/redis/schemas/proto.py @@ -5,7 +5,7 @@ from faststream.exceptions import SetupError if TYPE_CHECKING: - from faststream.asyncapi.schema.bindings import redis + from faststream.asyncapi.v2_6_0.schema.bindings import redis from faststream.redis.schemas import ListSub, PubSub, StreamSub diff --git a/faststream/redis/subscriber/asyncapi.py b/faststream/redis/subscriber/asyncapi.py index da2b374fc3..622bdfecf6 100644 --- a/faststream/redis/subscriber/asyncapi.py +++ b/faststream/redis/subscriber/asyncapi.py @@ -1,16 +1,12 @@ from typing import Dict -from faststream.asyncapi.schema import ( - ChannelBinding, - CorrelationId, - Message, -) -from faststream.asyncapi.schema.bindings import redis from faststream.asyncapi.utils import resolve_payloads from faststream.asyncapi.v2_6_0.schema import ( Channel, Operation, ) +from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding, redis +from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message from faststream.redis.schemas import ListSub, StreamSub from faststream.redis.schemas.proto import RedisAsyncAPIProtocol from faststream.redis.subscriber.usecase import ( diff --git a/tests/asyncapi/confluent/v2_6_0/test_connection.py b/tests/asyncapi/confluent/v2_6_0/test_connection.py index d37cefbfa7..58d4fe26fd 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_connection.py +++ b/tests/asyncapi/confluent/v2_6_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.schema import Tag +from faststream.asyncapi.v2_6_0.schema import Tag from faststream.confluent import KafkaBroker diff --git a/tests/asyncapi/confluent/v3_0_0/test_connection.py b/tests/asyncapi/confluent/v3_0_0/test_connection.py index 0b2619454f..29a178de3f 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_connection.py +++ b/tests/asyncapi/confluent/v3_0_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.schema import Tag +from faststream.asyncapi.v2_6_0.schema import Tag from faststream.asyncapi.version import AsyncAPIVersion from faststream.confluent import KafkaBroker diff --git a/tests/asyncapi/kafka/v2_6_0/test_app.py b/tests/asyncapi/kafka/v2_6_0/test_app.py index 4a79ad1e96..badf19b188 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_app.py +++ b/tests/asyncapi/kafka/v2_6_0/test_app.py @@ -1,6 +1,8 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.schema import Contact, ExternalDocs, License, Tag +from faststream.asyncapi.v2_6_0.schema.info import License, Contact +from faststream.asyncapi.v2_6_0.schema.utils import Tag, ExternalDocs + from faststream.kafka import KafkaBroker diff --git a/tests/asyncapi/kafka/v2_6_0/test_connection.py b/tests/asyncapi/kafka/v2_6_0/test_connection.py index 25eb392361..e3d19231a7 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_connection.py +++ b/tests/asyncapi/kafka/v2_6_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.schema import Tag +from faststream.asyncapi.v2_6_0.schema import Tag from faststream.kafka import KafkaBroker diff --git a/tests/asyncapi/kafka/v3_0_0/test_connection.py b/tests/asyncapi/kafka/v3_0_0/test_connection.py index 8c1b7dc9ab..640a44f857 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_connection.py +++ b/tests/asyncapi/kafka/v3_0_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.schema import Tag +from faststream.asyncapi.v2_6_0.schema import Tag from faststream.asyncapi.version import AsyncAPIVersion from faststream.kafka import KafkaBroker diff --git a/tests/asyncapi/nats/v2_6_0/test_connection.py b/tests/asyncapi/nats/v2_6_0/test_connection.py index 0f1f5c057e..c3092a6ede 100644 --- a/tests/asyncapi/nats/v2_6_0/test_connection.py +++ b/tests/asyncapi/nats/v2_6_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.schema import Tag +from faststream.asyncapi.v2_6_0.schema import Tag from faststream.nats import NatsBroker diff --git a/tests/asyncapi/nats/v3_0_0/test_connection.py b/tests/asyncapi/nats/v3_0_0/test_connection.py index bba75c17d4..3400eb8803 100644 --- a/tests/asyncapi/nats/v3_0_0/test_connection.py +++ b/tests/asyncapi/nats/v3_0_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.schema import Tag +from faststream.asyncapi.v2_6_0.schema import Tag from faststream.asyncapi.version import AsyncAPIVersion from faststream.nats import NatsBroker diff --git a/tests/asyncapi/rabbit/v2_6_0/test_connection.py b/tests/asyncapi/rabbit/v2_6_0/test_connection.py index 4362e8ac48..45f76a416d 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_connection.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.schema import Tag +from faststream.asyncapi.v2_6_0.schema import Tag from faststream.rabbit import RabbitBroker diff --git a/tests/asyncapi/rabbit/v3_0_0/test_connection.py b/tests/asyncapi/rabbit/v3_0_0/test_connection.py index a34940e38b..7c8a467bba 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_connection.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.schema import Tag +from faststream.asyncapi.v2_6_0.schema import Tag from faststream.asyncapi.version import AsyncAPIVersion from faststream.rabbit import RabbitBroker diff --git a/tests/asyncapi/redis/v2_6_0/test_connection.py b/tests/asyncapi/redis/v2_6_0/test_connection.py index a5719d4a77..1e14be77fe 100644 --- a/tests/asyncapi/redis/v2_6_0/test_connection.py +++ b/tests/asyncapi/redis/v2_6_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.schema import Tag +from faststream.asyncapi.v2_6_0.schema import Tag from faststream.redis import RedisBroker diff --git a/tests/asyncapi/redis/v3_0_0/test_connection.py b/tests/asyncapi/redis/v3_0_0/test_connection.py index e6eed37127..4e42a74093 100644 --- a/tests/asyncapi/redis/v3_0_0/test_connection.py +++ b/tests/asyncapi/redis/v3_0_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.schema import Tag +from faststream.asyncapi.v2_6_0.schema import Tag from faststream.asyncapi.version import AsyncAPIVersion from faststream.redis import RedisBroker From 0b4fef816df7016a29424796ef8277d9adfa743b Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 9 Aug 2024 08:53:08 +0300 Subject: [PATCH 062/245] Channel specification --- faststream/asyncapi/proto.py | 22 +++-- faststream/asyncapi/v2_6_0/schema/channels.py | 5 +- faststream/asyncapi/v3_0_0/generate.py | 2 - faststream/asyncapi/v3_0_0/schema/channels.py | 6 +- faststream/broker/specification/__init__.py | 0 .../broker/specification/bindings/__init__.py | 9 ++ .../broker/specification/bindings/amqp.py | 92 +++++++++++++++++++ .../broker/specification/bindings/kafka.py | 54 +++++++++++ .../broker/specification/bindings/main.py | 48 ++++++++++ .../broker/specification/bindings/nats.py | 45 +++++++++ .../broker/specification/bindings/redis.py | 47 ++++++++++ .../broker/specification/bindings/sqs.py | 43 +++++++++ faststream/broker/specification/channel.py | 25 +++++ faststream/broker/specification/docs.py | 31 +++++++ faststream/broker/specification/message.py | 57 ++++++++++++ faststream/broker/specification/operation.py | 38 ++++++++ faststream/broker/specification/tag.py | 37 ++++++++ 17 files changed, 547 insertions(+), 14 deletions(-) create mode 100644 faststream/broker/specification/__init__.py create mode 100644 faststream/broker/specification/bindings/__init__.py create mode 100644 faststream/broker/specification/bindings/amqp.py create mode 100644 faststream/broker/specification/bindings/kafka.py create mode 100644 faststream/broker/specification/bindings/main.py create mode 100644 faststream/broker/specification/bindings/nats.py create mode 100644 faststream/broker/specification/bindings/redis.py create mode 100644 faststream/broker/specification/bindings/sqs.py create mode 100644 faststream/broker/specification/channel.py create mode 100644 faststream/broker/specification/docs.py create mode 100644 faststream/broker/specification/message.py create mode 100644 faststream/broker/specification/operation.py create mode 100644 faststream/broker/specification/tag.py diff --git a/faststream/asyncapi/proto.py b/faststream/asyncapi/proto.py index 81a76da837..adf6d28a5f 100644 --- a/faststream/asyncapi/proto.py +++ b/faststream/asyncapi/proto.py @@ -1,6 +1,8 @@ from abc import abstractmethod from typing import TYPE_CHECKING, Any, Dict, Optional, Protocol, Sequence, Union +from typing_extensions import Doc, Annotated + if TYPE_CHECKING: from faststream.asyncapi.schema import ( Contact, @@ -37,14 +39,18 @@ class AsyncAPIApplication(Protocol): class AsyncAPIProto(Protocol): """A class representing an asynchronous API operation.""" - title_: Optional[str] - """AsyncAPI object title.""" - - description_: Optional[str] - """AsyncAPI object description.""" - - include_in_schema: bool - """Whetever to include operation in AsyncAPI schema or not.""" + title_: Annotated[ + Optional[str], + Doc("AsyncAPI object title."), + ] + description_: Annotated[ + Optional[str], + Doc("AsyncAPI object description."), + ] + include_in_schema: Annotated[ + bool, + Doc("Whatever to include operation in AsyncAPI schema or not."), + ] @property @abstractmethod diff --git a/faststream/asyncapi/v2_6_0/schema/channels.py b/faststream/asyncapi/v2_6_0/schema/channels.py index 0c8af7e74a..f06a0166e5 100644 --- a/faststream/asyncapi/v2_6_0/schema/channels.py +++ b/faststream/asyncapi/v2_6_0/schema/channels.py @@ -5,7 +5,6 @@ from faststream._compat import PYDANTIC_V2 from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding from faststream.asyncapi.v2_6_0.schema.operations import Operation -from faststream.asyncapi.v2_6_0.schema.utils import Parameter class Channel(BaseModel): @@ -30,7 +29,9 @@ class Channel(BaseModel): bindings: Optional[ChannelBinding] = None subscribe: Optional[Operation] = None publish: Optional[Operation] = None - parameters: Optional[Parameter] = None + + # TODO: + # parameters: Optional[Parameter] = None if PYDANTIC_V2: model_config = {"extra": "allow"} diff --git a/faststream/asyncapi/v3_0_0/generate.py b/faststream/asyncapi/v3_0_0/generate.py index 6fd587225c..27a546dd32 100644 --- a/faststream/asyncapi/v3_0_0/generate.py +++ b/faststream/asyncapi/v3_0_0/generate.py @@ -242,7 +242,6 @@ def get_broker_channels( description=channel_v2_6.description, servers=channel_v2_6.servers, bindings=channel_v2_6.bindings, - parameters=channel_v2_6.parameters ) channels_schema_v3_0[channel_name] = channel_v3_0 @@ -261,7 +260,6 @@ def get_broker_channels( description=channel_v2_6.description, servers=channel_v2_6.servers, bindings=channel_v2_6.bindings, - parameters=channel_v2_6.parameters ) channels_schema_v3_0[channel_name] = channel_v3_0 diff --git a/faststream/asyncapi/v3_0_0/schema/channels.py b/faststream/asyncapi/v3_0_0/schema/channels.py index d0489ff12c..7fed29525e 100644 --- a/faststream/asyncapi/v3_0_0/schema/channels.py +++ b/faststream/asyncapi/v3_0_0/schema/channels.py @@ -5,7 +5,7 @@ from faststream._compat import PYDANTIC_V2 from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding from faststream.asyncapi.v2_6_0.schema.message import Message -from faststream.asyncapi.v2_6_0.schema.utils import Parameter, Reference +from faststream.asyncapi.v2_6_0.schema.utils import Reference class Channel(BaseModel): @@ -29,7 +29,9 @@ class Channel(BaseModel): servers: Optional[List[Dict[str, str]]] = None messages: Dict[str, Union[Message, Reference]] bindings: Optional[ChannelBinding] = None - parameters: Optional[Parameter] = None + + # TODO: + # parameters: Optional[Parameter] = None if PYDANTIC_V2: model_config = {"extra": "allow"} diff --git a/faststream/broker/specification/__init__.py b/faststream/broker/specification/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/faststream/broker/specification/bindings/__init__.py b/faststream/broker/specification/bindings/__init__.py new file mode 100644 index 0000000000..c304608c5b --- /dev/null +++ b/faststream/broker/specification/bindings/__init__.py @@ -0,0 +1,9 @@ +from .main import ( + ChannelBinding, + OperationBinding, +) + +__all__ = ( + "ChannelBinding", + "OperationBinding", +) diff --git a/faststream/broker/specification/bindings/amqp.py b/faststream/broker/specification/bindings/amqp.py new file mode 100644 index 0000000000..3702a7c80e --- /dev/null +++ b/faststream/broker/specification/bindings/amqp.py @@ -0,0 +1,92 @@ +"""AsyncAPI AMQP bindings. + +References: https://github.com/asyncapi/bindings/tree/master/amqp +""" +from dataclasses import dataclass +from typing import Literal, Optional + + +@dataclass +class Queue: + """A class to represent a queue. + + Attributes: + name : name of the queue + durable : indicates if the queue is durable + exclusive : indicates if the queue is exclusive + autoDelete : indicates if the queue should be automatically deleted + vhost : virtual host of the queue (default is "/") + """ + + name: str + durable: bool + exclusive: bool + autoDelete: bool + vhost: str = "/" + + +@dataclass +class Exchange: + """A class to represent an exchange. + + Attributes: + name : name of the exchange (optional) + type : type of the exchange, can be one of "default", "direct", "topic", "fanout", "headers" + durable : whether the exchange is durable (optional) + autoDelete : whether the exchange is automatically deleted (optional) + vhost : virtual host of the exchange, default is "/" + """ + + type: Literal["default", "direct", "topic", "fanout", "headers"] + name: Optional[str] = None + durable: Optional[bool] = None + autoDelete: Optional[bool] = None + vhost: str = "/" + + +@dataclass +class ServerBinding: + """A class to represent a server binding. + + Attributes: + bindingVersion : version of the binding (default: "0.2.0") + """ + + bindingVersion: str = "0.2.0" + + +@dataclass +class ChannelBinding: + """A class to represent channel binding. + + Attributes: + is_ : Type of binding, can be "queue" or "routingKey" + bindingVersion : Version of the binding + queue : Optional queue object + exchange : Optional exchange object + """ + + is_: Literal["queue", "routingKey"] + bindingVersion: str = "0.2.0" + queue: Optional[Queue] = None + exchange: Optional[Exchange] = None + + +@dataclass +class OperationBinding: + """A class to represent an operation binding. + + Attributes: + cc : optional string representing the cc + ack : boolean indicating if the operation is acknowledged + replyTo : optional dictionary representing the replyTo + bindingVersion : string representing the binding version + """ + + cc: Optional[str] = None + ack: bool = True + replyTo: Optional[str] = None + deliveryMode: Optional[int] = None + mandatory: Optional[bool] = None + priority: Optional[int] = None + bindingVersion: str = "0.2.0" diff --git a/faststream/broker/specification/bindings/kafka.py b/faststream/broker/specification/bindings/kafka.py new file mode 100644 index 0000000000..cbef7120e8 --- /dev/null +++ b/faststream/broker/specification/bindings/kafka.py @@ -0,0 +1,54 @@ +"""AsyncAPI Kafka bindings. + +References: https://github.com/asyncapi/bindings/tree/master/kafka +""" +from dataclasses import dataclass +from typing import Any, Dict, Optional + + +@dataclass +class ServerBinding: + """A class to represent a server binding. + + Attributes: + bindingVersion : version of the binding (default: "0.4.0") + """ + + bindingVersion: str = "0.4.0" + + +@dataclass +class ChannelBinding: + """A class to represent a channel binding. + + Attributes: + topic : optional string representing the topic + partitions : optional positive integer representing the number of partitions + replicas : optional positive integer representing the number of replicas + bindingVersion : string representing the binding version + """ + + topic: Optional[str] = None + partitions: Optional[int] = None + replicas: Optional[int] = None + bindingVersion: str = "0.4.0" + + # TODO: + # topicConfiguration + + +@dataclass +class OperationBinding: + """A class to represent an operation binding. + + Attributes: + groupId : optional dictionary representing the group ID + clientId : optional dictionary representing the client ID + replyTo : optional dictionary representing the reply-to + bindingVersion : version of the binding (default: "0.4.0") + """ + + groupId: Optional[Dict[str, Any]] = None + clientId: Optional[Dict[str, Any]] = None + replyTo: Optional[Dict[str, Any]] = None + bindingVersion: str = "0.4.0" diff --git a/faststream/broker/specification/bindings/main.py b/faststream/broker/specification/bindings/main.py new file mode 100644 index 0000000000..2c8ee09ba7 --- /dev/null +++ b/faststream/broker/specification/bindings/main.py @@ -0,0 +1,48 @@ +from dataclasses import dataclass +from typing import Optional + +from faststream.broker.specification.bindings import amqp as amqp_bindings +from faststream.broker.specification.bindings import kafka as kafka_bindings +from faststream.broker.specification.bindings import nats as nats_bindings +from faststream.broker.specification.bindings import redis as redis_bindings +from faststream.broker.specification.bindings import sqs as sqs_bindings + + +@dataclass +class ChannelBinding: + """A class to represent channel bindings. + + Attributes: + amqp : AMQP channel binding (optional) + kafka : Kafka channel binding (optional) + sqs : SQS channel binding (optional) + nats : NATS channel binding (optional) + redis : Redis channel binding (optional) + + """ + + amqp: Optional[amqp_bindings.ChannelBinding] = None + kafka: Optional[kafka_bindings.ChannelBinding] = None + sqs: Optional[sqs_bindings.ChannelBinding] = None + nats: Optional[nats_bindings.ChannelBinding] = None + redis: Optional[redis_bindings.ChannelBinding] = None + + +@dataclass +class OperationBinding: + """A class to represent an operation binding. + + Attributes: + amqp : AMQP operation binding (optional) + kafka : Kafka operation binding (optional) + sqs : SQS operation binding (optional) + nats : NATS operation binding (optional) + redis : Redis operation binding (optional) + + """ + + amqp: Optional[amqp_bindings.OperationBinding] = None + kafka: Optional[kafka_bindings.OperationBinding] = None + sqs: Optional[sqs_bindings.OperationBinding] = None + nats: Optional[nats_bindings.OperationBinding] = None + redis: Optional[redis_bindings.OperationBinding] = None diff --git a/faststream/broker/specification/bindings/nats.py b/faststream/broker/specification/bindings/nats.py new file mode 100644 index 0000000000..ee6b40ee5b --- /dev/null +++ b/faststream/broker/specification/bindings/nats.py @@ -0,0 +1,45 @@ +"""AsyncAPI NATS bindings. + +References: https://github.com/asyncapi/bindings/tree/master/nats +""" +from dataclasses import dataclass +from typing import Any, Dict, Optional + + +@dataclass +class ServerBinding: + """A class to represent a server binding. + + Attributes: + bindingVersion : version of the binding (default: "custom") + """ + + bindingVersion: str = "custom" + + +@dataclass +class ChannelBinding: + """A class to represent channel binding. + + Attributes: + subject : subject of the channel binding + queue : optional queue for the channel binding + bindingVersion : version of the channel binding, default is "custom" + """ + + subject: str + queue: Optional[str] = None + bindingVersion: str = "custom" + + +@dataclass +class OperationBinding: + """A class to represent an operation binding. + + Attributes: + replyTo : optional dictionary containing reply information + bindingVersion : version of the binding (default is "custom") + """ + + replyTo: Optional[Dict[str, Any]] = None + bindingVersion: str = "custom" diff --git a/faststream/broker/specification/bindings/redis.py b/faststream/broker/specification/bindings/redis.py new file mode 100644 index 0000000000..ae3e0922a6 --- /dev/null +++ b/faststream/broker/specification/bindings/redis.py @@ -0,0 +1,47 @@ +"""AsyncAPI Redis bindings. + +References: https://github.com/asyncapi/bindings/tree/master/redis +""" +from dataclasses import dataclass +from typing import Any, Dict, Optional + + +@dataclass +class ServerBinding: + """A class to represent a server binding. + + Attributes: + bindingVersion : version of the binding (default: "custom") + """ + + bindingVersion: str = "custom" + + +@dataclass +class ChannelBinding: + """A class to represent channel binding. + + Attributes: + channel : the channel name + method : the method used for binding (ssubscribe, psubscribe, subscribe) + bindingVersion : the version of the binding + """ + + channel: str + method: Optional[str] = None + group_name: Optional[str] = None + consumer_name: Optional[str] = None + bindingVersion: str = "custom" + + +@dataclass +class OperationBinding: + """A class to represent an operation binding. + + Attributes: + replyTo : optional dictionary containing reply information + bindingVersion : version of the binding (default is "custom") + """ + + replyTo: Optional[Dict[str, Any]] = None + bindingVersion: str = "custom" diff --git a/faststream/broker/specification/bindings/sqs.py b/faststream/broker/specification/bindings/sqs.py new file mode 100644 index 0000000000..fdc58288bf --- /dev/null +++ b/faststream/broker/specification/bindings/sqs.py @@ -0,0 +1,43 @@ +"""AsyncAPI SQS bindings. + +References: https://github.com/asyncapi/bindings/tree/master/sqs +""" +from dataclasses import dataclass +from typing import Any, Dict, Optional + + +@dataclass +class ServerBinding: + """A class to represent a server binding. + + Attributes: + bindingVersion : version of the binding (default: "custom") + """ + + bindingVersion: str = "custom" + + +@dataclass +class ChannelBinding: + """A class to represent channel binding. + + Attributes: + queue : a dictionary representing the queue + bindingVersion : a string representing the binding version (default: "custom") + """ + + queue: Dict[str, Any] + bindingVersion: str = "custom" + + +@dataclass +class OperationBinding: + """A class to represent an operation binding. + + Attributes: + replyTo : optional dictionary containing reply information + bindingVersion : version of the binding, default is "custom" + """ + + replyTo: Optional[Dict[str, Any]] = None + bindingVersion: str = "custom" diff --git a/faststream/broker/specification/channel.py b/faststream/broker/specification/channel.py new file mode 100644 index 0000000000..abe3d1f79e --- /dev/null +++ b/faststream/broker/specification/channel.py @@ -0,0 +1,25 @@ +from dataclasses import dataclass +from typing import List, Optional + +from faststream.broker.specification.bindings import ChannelBinding +from faststream.broker.specification.operation import Operation + + +@dataclass +class Channel: + """Channel specification. + + Attributes: + description : optional description of the channel + servers : optional list of servers associated with the channel + bindings : optional channel binding + subscribe : optional operation for subscribing to the channel + publish : optional operation for publishing to the channel + + """ + + description: Optional[str] = None + servers: Optional[List[str]] = None + bindings: Optional[ChannelBinding] = None + subscribe: Optional[Operation] = None + publish: Optional[Operation] = None diff --git a/faststream/broker/specification/docs.py b/faststream/broker/specification/docs.py new file mode 100644 index 0000000000..2828b8e4b0 --- /dev/null +++ b/faststream/broker/specification/docs.py @@ -0,0 +1,31 @@ +from dataclasses import dataclass +from typing import Optional + +from typing_extensions import Required, TypedDict + + +class ExternalDocsDict(TypedDict, total=False): + """A dictionary type for representing external documentation. + + Attributes: + url : Required URL for the external documentation + description : Description of the external documentation + + """ + + url: Required[str] + description: str + + +@dataclass +class ExternalDocs: + """A class to represent external documentation. + + Attributes: + url : URL of the external documentation + description : optional description of the external documentation + + """ + + url: str + description: Optional[str] = None diff --git a/faststream/broker/specification/message.py b/faststream/broker/specification/message.py new file mode 100644 index 0000000000..c2c5560743 --- /dev/null +++ b/faststream/broker/specification/message.py @@ -0,0 +1,57 @@ +from dataclasses import dataclass +from typing import Any, Dict, List, Optional, Union + +from faststream.broker.specification.docs import ExternalDocs +from faststream.broker.specification.tag import Tag + + +@dataclass +class CorrelationId: + """Correlation ID specification. + + Attributes: + description : optional description of the correlation ID + location : location of the correlation ID + + Configurations: + extra : allows extra fields in the correlation ID model + + """ + + location: str + description: Optional[str] = None + + +@dataclass +class Message: + """Message specification. + + Attributes: + title : title of the message + name : name of the message + summary : summary of the message + description : description of the message + messageId : ID of the message + correlationId : correlation ID of the message + contentType : content type of the message + payload : dictionary representing the payload of the message + tags : list of tags associated with the message + externalDocs : external documentation associated with the message + + """ + + payload: Dict[str, Any] + title: Optional[str] = None + name: Optional[str] = None + summary: Optional[str] = None + description: Optional[str] = None + messageId: Optional[str] = None + correlationId: Optional[CorrelationId] = None + contentType: Optional[str] = None + + tags: Optional[List[Union[Tag, Dict[str, Any]]]] = ( + None + ) + externalDocs: Optional[Union[ExternalDocs, Dict[str, Any]]] = ( + None + ) diff --git a/faststream/broker/specification/operation.py b/faststream/broker/specification/operation.py new file mode 100644 index 0000000000..381178eddb --- /dev/null +++ b/faststream/broker/specification/operation.py @@ -0,0 +1,38 @@ +from dataclasses import dataclass +from typing import Any, Dict, List, Optional, Union + +from faststream.broker.specification.bindings import OperationBinding +from faststream.broker.specification.docs import ExternalDocs, ExternalDocsDict +from faststream.broker.specification.message import Message +from faststream.broker.specification.tag import Tag, TagDict + + +@dataclass +class Operation: + """A class to represent an operation. + + Attributes: + operationId : ID of the operation + summary : summary of the operation + description : description of the operation + bindings : bindings of the operation + message : message of the operation + security : security details of the operation + tags : tags associated with the operation + externalDocs : external documentation for the operation + + """ + + message: Message + + operationId: Optional[str] = None + summary: Optional[str] = None + description: Optional[str] = None + + bindings: Optional[OperationBinding] = None + + security: Optional[Dict[str, List[str]]] = None + + tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = None + externalDocs: Optional[Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]] = None + diff --git a/faststream/broker/specification/tag.py b/faststream/broker/specification/tag.py new file mode 100644 index 0000000000..22e723f583 --- /dev/null +++ b/faststream/broker/specification/tag.py @@ -0,0 +1,37 @@ +from dataclasses import dataclass +from typing import Optional, Union + +from typing_extensions import Required, TypedDict + +from faststream.broker.specification.docs import ExternalDocs, ExternalDocsDict + + +class TagDict(TypedDict, total=False): + """A dictionary-like class for storing tags. + + Attributes: + name : required name of the tag + description : description of the tag + externalDocs : external documentation for the tag + + """ + + name: Required[str] + description: str + externalDocs: Union[ExternalDocs, ExternalDocsDict] + + +@dataclass +class Tag: + """A class to represent a tag. + + Attributes: + name : name of the tag + description : description of the tag (optional) + externalDocs : external documentation for the tag (optional) + + """ + + name: str + description: Optional[str] = None + externalDocs: Optional[Union[ExternalDocs, ExternalDocsDict]] = None From 6e2978be7961e64d977daf549c7c35a2ed9319d8 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 9 Aug 2024 09:34:16 +0300 Subject: [PATCH 063/245] Broker dependency from AsyncAPI 2.6.0 to internal specs representation --- faststream/asyncapi/abc.py | 2 +- faststream/asyncapi/proto.py | 2 +- faststream/asyncapi/v2_6_0/generate.py | 197 +++++++++++++++++- faststream/broker/core/usecase.py | 3 +- .../broker/specification/bindings/main.py | 2 +- faststream/confluent/publisher/asyncapi.py | 10 +- faststream/confluent/subscriber/asyncapi.py | 10 +- faststream/kafka/publisher/asyncapi.py | 10 +- faststream/kafka/subscriber/asyncapi.py | 10 +- faststream/nats/publisher/asyncapi.py | 10 +- faststream/nats/subscriber/asyncapi.py | 10 +- faststream/rabbit/publisher/asyncapi.py | 12 +- faststream/rabbit/subscriber/asyncapi.py | 14 +- faststream/redis/publisher/asyncapi.py | 10 +- faststream/redis/subscriber/asyncapi.py | 10 +- .../confluent/v2_6_0/test_connection.py | 2 +- .../confluent/v3_0_0/test_connection.py | 2 +- tests/asyncapi/kafka/v2_6_0/test_app.py | 3 +- .../asyncapi/kafka/v2_6_0/test_connection.py | 2 +- .../asyncapi/kafka/v3_0_0/test_connection.py | 2 +- tests/asyncapi/nats/v2_6_0/test_connection.py | 2 +- tests/asyncapi/nats/v3_0_0/test_connection.py | 2 +- .../asyncapi/rabbit/v2_6_0/test_connection.py | 2 +- .../asyncapi/rabbit/v3_0_0/test_connection.py | 2 +- .../asyncapi/redis/v2_6_0/test_connection.py | 2 +- .../asyncapi/redis/v3_0_0/test_connection.py | 2 +- 26 files changed, 247 insertions(+), 88 deletions(-) diff --git a/faststream/asyncapi/abc.py b/faststream/asyncapi/abc.py index d3ac4e9a63..25111f0570 100644 --- a/faststream/asyncapi/abc.py +++ b/faststream/asyncapi/abc.py @@ -2,7 +2,7 @@ from typing import Any, Dict, Optional from faststream.asyncapi.proto import AsyncAPIProto -from faststream.asyncapi.v2_6_0.schema.channels import Channel +from faststream.broker.specification.channel import Channel class AsyncAPIOperation(AsyncAPIProto): diff --git a/faststream/asyncapi/proto.py b/faststream/asyncapi/proto.py index adf6d28a5f..a1c9bcc05b 100644 --- a/faststream/asyncapi/proto.py +++ b/faststream/asyncapi/proto.py @@ -14,7 +14,7 @@ Tag, TagDict, ) - from faststream.asyncapi.schema.channels import Channel + from faststream.broker.specification.channel import Channel from faststream.broker.core.usecase import BrokerUsecase from faststream.types import ( AnyDict, diff --git a/faststream/asyncapi/v2_6_0/generate.py b/faststream/asyncapi/v2_6_0/generate.py index 7cd0b7016e..d6b96a411f 100644 --- a/faststream/asyncapi/v2_6_0/generate.py +++ b/faststream/asyncapi/v2_6_0/generate.py @@ -1,4 +1,5 @@ -from typing import TYPE_CHECKING, Any, Dict, List, Union +from dataclasses import asdict +from typing import TYPE_CHECKING, Any, Dict, List, Union, Optional from faststream._compat import DEF_KEY, HAS_FASTAPI from faststream.asyncapi.v2_6_0.schema import ( @@ -8,8 +9,19 @@ Reference, Schema, Server, + Tag, + TagDict, Operation, ExternalDocsDict, ExternalDocs, ) -from faststream.asyncapi.v2_6_0.schema.message import Message +from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding, amqp, kafka, sqs, nats, redis, OperationBinding +from faststream.asyncapi.v2_6_0.schema.message import Message, CorrelationId +from faststream.broker.specification.channel import Channel as SpecChannel +from faststream.broker.specification.operation import Operation as SpecOperation +from faststream.broker.specification.bindings import OperationBinding as SpecOperationBinding +from faststream.broker.specification.channel import ChannelBinding as SpecChannelBinding +from faststream.broker.specification.tag import Tag as SpecTag +from faststream.broker.specification.tag import TagDict as SpecTagDict +from faststream.broker.specification.docs import ExternalDocs as SpecExternalDocs +from faststream.broker.specification.docs import ExternalDocsDict as SpecExternalDocsDict from faststream.constants import ContentTypes if TYPE_CHECKING: @@ -29,7 +41,7 @@ def get_app_schema(app: Union["FastStream", "StreamRouter[Any]"]) -> Schema: broker.setup() servers = get_broker_server(broker) - channels = get_broker_channels_2_6(broker) + channels = get_broker_channels(broker) messages: Dict[str, Message] = {} payloads: Dict[str, Dict[str, Any]] = {} @@ -69,8 +81,8 @@ def get_app_schema(app: Union["FastStream", "StreamRouter[Any]"]) -> Schema: ), defaultContentType=ContentTypes.json.value, id=app.identifier, - tags=list(app.asyncapi_tags) if app.asyncapi_tags else None, - externalDocs=app.external_docs, + tags=_specs_tags_to_asyncapi(list(app.asyncapi_tags)) if app.asyncapi_tags else None, + externalDocs=_specs_external_docs_to_asyncapi(app.external_docs), servers=servers, channels=channels, components=Components( @@ -90,11 +102,24 @@ def get_broker_server( """Get the broker server for an application.""" servers = {} + if broker.tags: + tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = [] + + for tag in broker.tags: + if isinstance(tag, SpecTag): + tags.append(Tag(**asdict(tag))) + elif isinstance(tag, dict): + tags.append(tag) + else: + raise NotImplementedError(f"Unsupported tag type: {tag}; {type(tag)}") + else: + tags = None + broker_meta: Dict[str, Any] = { "protocol": broker.protocol, "protocolVersion": broker.protocol_version, "description": broker.description, - "tags": broker.tags, + "tags": tags if tags else None, # TODO # "variables": "", # "bindings": "", @@ -125,21 +150,175 @@ def get_broker_server( return servers -def get_broker_channels_2_6( +def get_broker_channels( broker: "BrokerUsecase[MsgType, ConnectionType]", ) -> Dict[str, Channel]: """Get the broker channels for an application.""" channels = {} for h in broker._subscribers.values(): - channels.update(h.schema()) + schema = h.schema() + channels.update({ + key: _specs_channel_to_asyncapi(channel) + for key, channel in schema.items() + }) for p in broker._publishers.values(): - channels.update(p.schema()) + schema = p.schema() + channels.update({ + key: _specs_channel_to_asyncapi(channel) + for key, channel in schema.items() + }) return channels +def _specs_channel_to_asyncapi(channel: SpecChannel) -> Channel: + return Channel( + description=channel.description, + servers=channel.servers, + + bindings=_specs_channel_binding_to_asyncapi(channel.bindings) + if channel.bindings else None, + + subscribe=_specs_operation_to_asyncapi(channel.subscribe) + if channel.subscribe else None, + + publish=_specs_operation_to_asyncapi(channel.publish) + if channel.publish else None, + ) + + +def _specs_channel_binding_to_asyncapi(binding: SpecChannelBinding) -> ChannelBinding: + return ChannelBinding( + amqp=amqp.ChannelBinding(**{ + "is": binding.amqp.is_, + "bindingVersion": binding.amqp.bindingVersion, + "queue": amqp.Queue( + name=binding.amqp.queue.name, + durable=binding.amqp.queue.durable, + exclusive=binding.amqp.queue.exclusive, + autoDelete=binding.amqp.queue.autoDelete, + vhost=binding.amqp.queue.vhost, + ) + if binding.amqp.queue else None, + "exchange": amqp.Exchange( + name=binding.amqp.exchange.name, + type=binding.amqp.exchange.type, + durable=binding.amqp.exchange.durable, + autoDelete=binding.amqp.exchange.autoDelete, + vhost=binding.amqp.exchange.vhost + ) + if binding.amqp.exchange else None, + } + ) + if binding.amqp else None, + + kafka=kafka.ChannelBinding(**asdict(binding.kafka)) + if binding.kafka else None, + + sqs=sqs.ChannelBinding(**asdict(binding.sqs)) + if binding.sqs else None, + + nats=nats.ChannelBinding(**asdict(binding.nats)) + if binding.nats else None, + + redis=redis.ChannelBinding(**asdict(binding.redis)) + if binding.redis else None, + ) + + +def _specs_operation_to_asyncapi(operation: SpecOperation) -> Operation: + return Operation( + operationId=operation.operationId, + summary=operation.summary, + description=operation.description, + + bindings=_specs_operation_binding_to_asyncapi(operation.bindings) + if operation.bindings else None, + + message=Message( + title=operation.message.title, + name=operation.message.name, + summary=operation.message.summary, + description=operation.message.description, + messageId=operation.message.messageId, + payload=operation.message.payload, + + correlationId=CorrelationId(**asdict(operation.message.correlationId)) + if operation.message.correlationId else None, + + contentType=operation.message.contentType, + + tags=_specs_tags_to_asyncapi(operation.tags) + if operation.tags else None, + + externalDocs=_specs_external_docs_to_asyncapi(operation.externalDocs) + if operation.externalDocs else None, + ), + + security=operation.security, + + tags=_specs_tags_to_asyncapi(operation.tags) + if operation.tags else None, + + externalDocs=_specs_external_docs_to_asyncapi(operation.externalDocs) + if operation.externalDocs else None, + ) + + +def _specs_operation_binding_to_asyncapi(binding: SpecOperationBinding) -> OperationBinding: + return OperationBinding( + amqp=amqp.OperationBinding(**asdict(binding.amqp)) + if binding.amqp else None, + + kafka=kafka.OperationBinding(**asdict(binding.kafka)) + if binding.kafka else None, + + sqs=kafka.OperationBinding(**asdict(binding.sqs)) + if binding.sqs else None, + + nats=kafka.OperationBinding(**asdict(binding.nats)) + if binding.nats else None, + + redis=kafka.OperationBinding(**asdict(binding.redis)) + if binding.redis else None, + ) + + +def _specs_tags_to_asyncapi( + tags: List[Union[SpecTag, SpecTagDict, Dict[str, Any]]] +) -> List[Union[Tag, TagDict, Dict[str, Any]]]: + asyncapi_tags = [] + + for tag in tags: + if isinstance(tag, SpecTag): + asyncapi_tags.append(Tag( + name=tag.name, + description=tag.description, + + externalDocs=_specs_external_docs_to_asyncapi(tag.externalDocs) + if tag.externalDocs else None, + )) + elif isinstance(tag, dict): + asyncapi_tags.append(tag) + else: + raise NotImplementedError + + return asyncapi_tags + + +def _specs_external_docs_to_asyncapi( + externalDocs: Union[SpecExternalDocs, SpecExternalDocsDict, Dict[str, Any]] +) -> Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]: + if isinstance(externalDocs, SpecExternalDocs): + return ExternalDocs( + **asdict(externalDocs) + ) + else: + return externalDocs + + def _resolve_msg_payloads( m: Message, channel_name: str, diff --git a/faststream/broker/core/usecase.py b/faststream/broker/core/usecase.py index 7069dd2652..4017e756d3 100644 --- a/faststream/broker/core/usecase.py +++ b/faststream/broker/core/usecase.py @@ -24,7 +24,6 @@ from faststream.broker.proto import SetupAble from faststream.broker.subscriber.proto import SubscriberProto from faststream.broker.types import ( - AsyncCustomCallable, BrokerMiddleware, ConnectionType, CustomCallable, @@ -40,9 +39,9 @@ from fast_depends.dependencies import Depends - from faststream.asyncapi.schema import Tag, TagDict from faststream.broker.message import StreamMessage from faststream.broker.publisher.proto import ProducerProto, PublisherProto + from faststream.broker.specification.tag import Tag, TagDict from faststream.security import BaseSecurity from faststream.types import AnyDict, Decorator, LoggerProto diff --git a/faststream/broker/specification/bindings/main.py b/faststream/broker/specification/bindings/main.py index 2c8ee09ba7..5c4b0d4893 100644 --- a/faststream/broker/specification/bindings/main.py +++ b/faststream/broker/specification/bindings/main.py @@ -16,7 +16,7 @@ class ChannelBinding: amqp : AMQP channel binding (optional) kafka : Kafka channel binding (optional) sqs : SQS channel binding (optional) - nats : NATS channel binding (optional) + nats : NATS channel binding (optional)d redis : Redis channel binding (optional) """ diff --git a/faststream/confluent/publisher/asyncapi.py b/faststream/confluent/publisher/asyncapi.py index 49d38cc08c..80d486d299 100644 --- a/faststream/confluent/publisher/asyncapi.py +++ b/faststream/confluent/publisher/asyncapi.py @@ -13,12 +13,10 @@ from typing_extensions import override from faststream.asyncapi.utils import resolve_payloads -from faststream.asyncapi.v2_6_0.schema import ( - Channel, - Operation, -) -from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding, kafka -from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message +from faststream.broker.specification.bindings import ChannelBinding, kafka +from faststream.broker.specification.channel import Channel +from faststream.broker.specification.message import CorrelationId, Message +from faststream.broker.specification.operation import Operation from faststream.broker.types import MsgType from faststream.confluent.publisher.usecase import ( BatchPublisher, diff --git a/faststream/confluent/subscriber/asyncapi.py b/faststream/confluent/subscriber/asyncapi.py index 08ce6873c6..5c29399e44 100644 --- a/faststream/confluent/subscriber/asyncapi.py +++ b/faststream/confluent/subscriber/asyncapi.py @@ -5,12 +5,10 @@ ) from faststream.asyncapi.utils import resolve_payloads -from faststream.asyncapi.v2_6_0.schema import ( - Channel, - Operation, -) -from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding, kafka -from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message +from faststream.broker.specification.bindings import ChannelBinding, kafka +from faststream.broker.specification.channel import Channel +from faststream.broker.specification.message import CorrelationId, Message +from faststream.broker.specification.operation import Operation from faststream.broker.types import MsgType from faststream.confluent.subscriber.usecase import ( BatchSubscriber, diff --git a/faststream/kafka/publisher/asyncapi.py b/faststream/kafka/publisher/asyncapi.py index 2d7de79785..6d7af751a3 100644 --- a/faststream/kafka/publisher/asyncapi.py +++ b/faststream/kafka/publisher/asyncapi.py @@ -13,12 +13,10 @@ from typing_extensions import override from faststream.asyncapi.utils import resolve_payloads -from faststream.asyncapi.v2_6_0.schema import ( - Channel, - Operation, -) -from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding, kafka -from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message +from faststream.broker.specification.bindings import ChannelBinding, kafka +from faststream.broker.specification.channel import Channel +from faststream.broker.specification.message import CorrelationId, Message +from faststream.broker.specification.operation import Operation from faststream.broker.types import MsgType from faststream.exceptions import SetupError from faststream.kafka.publisher.usecase import ( diff --git a/faststream/kafka/subscriber/asyncapi.py b/faststream/kafka/subscriber/asyncapi.py index b22f9013f9..331f0a6e85 100644 --- a/faststream/kafka/subscriber/asyncapi.py +++ b/faststream/kafka/subscriber/asyncapi.py @@ -5,12 +5,10 @@ ) from faststream.asyncapi.utils import resolve_payloads -from faststream.asyncapi.v2_6_0.schema import ( - Channel, - Operation, -) -from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding, kafka -from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message +from faststream.broker.specification.bindings import ChannelBinding, kafka +from faststream.broker.specification.channel import Channel +from faststream.broker.specification.message import CorrelationId, Message +from faststream.broker.specification.operation import Operation from faststream.broker.types import MsgType from faststream.kafka.subscriber.usecase import ( BatchSubscriber, diff --git a/faststream/nats/publisher/asyncapi.py b/faststream/nats/publisher/asyncapi.py index 4bf49b7fc1..568aa2d0e8 100644 --- a/faststream/nats/publisher/asyncapi.py +++ b/faststream/nats/publisher/asyncapi.py @@ -3,12 +3,10 @@ from typing_extensions import override from faststream.asyncapi.utils import resolve_payloads -from faststream.asyncapi.v2_6_0.schema import ( - Channel, - Operation, -) -from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding, nats -from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message +from faststream.broker.specification.bindings import ChannelBinding, nats +from faststream.broker.specification.channel import Channel +from faststream.broker.specification.message import CorrelationId, Message +from faststream.broker.specification.operation import Operation from faststream.nats.publisher.usecase import LogicPublisher if TYPE_CHECKING: diff --git a/faststream/nats/subscriber/asyncapi.py b/faststream/nats/subscriber/asyncapi.py index bd8239362e..e36f3869e2 100644 --- a/faststream/nats/subscriber/asyncapi.py +++ b/faststream/nats/subscriber/asyncapi.py @@ -3,12 +3,10 @@ from typing_extensions import override from faststream.asyncapi.utils import resolve_payloads -from faststream.asyncapi.v2_6_0.schema import ( - Channel, - Operation, -) -from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding, nats -from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message +from faststream.broker.specification.bindings import ChannelBinding, nats +from faststream.broker.specification.channel import Channel +from faststream.broker.specification.message import CorrelationId, Message +from faststream.broker.specification.operation import Operation from faststream.nats.subscriber.usecase import ( BatchPullStreamSubscriber, ConcurrentCoreSubscriber, diff --git a/faststream/rabbit/publisher/asyncapi.py b/faststream/rabbit/publisher/asyncapi.py index cf2befc6a6..ba5e7d0f7a 100644 --- a/faststream/rabbit/publisher/asyncapi.py +++ b/faststream/rabbit/publisher/asyncapi.py @@ -3,16 +3,14 @@ from typing_extensions import override from faststream.asyncapi.utils import resolve_payloads -from faststream.asyncapi.v2_6_0.schema import ( - Channel, - Operation, -) -from faststream.asyncapi.v2_6_0.schema.bindings import ( +from faststream.broker.specification.bindings import ( ChannelBinding, OperationBinding, amqp, ) -from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message +from faststream.broker.specification.channel import Channel +from faststream.broker.specification.message import CorrelationId, Message +from faststream.broker.specification.operation import Operation from faststream.rabbit.publisher.usecase import LogicPublisher, PublishKwargs from faststream.rabbit.utils import is_routing_exchange @@ -77,7 +75,7 @@ def get_schema(self) -> Dict[str, Channel]: bindings=ChannelBinding( amqp=amqp.ChannelBinding( **{ - "is": "routingKey", + "is_": "routingKey", # type: ignore "queue": amqp.Queue( name=self.queue.name, durable=self.queue.durable, diff --git a/faststream/rabbit/subscriber/asyncapi.py b/faststream/rabbit/subscriber/asyncapi.py index 307488c1c4..b634fe856c 100644 --- a/faststream/rabbit/subscriber/asyncapi.py +++ b/faststream/rabbit/subscriber/asyncapi.py @@ -1,16 +1,14 @@ from typing import Dict from faststream.asyncapi.utils import resolve_payloads -from faststream.asyncapi.v2_6_0.schema import ( - Channel, - Operation, -) -from faststream.asyncapi.v2_6_0.schema.bindings import ( +from faststream.broker.specification.bindings import ( ChannelBinding, OperationBinding, amqp, ) -from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message +from faststream.broker.specification.channel import Channel +from faststream.broker.specification.message import CorrelationId, Message +from faststream.broker.specification.operation import Operation from faststream.rabbit.subscriber.usecase import LogicSubscriber from faststream.rabbit.utils import is_routing_exchange @@ -46,7 +44,7 @@ def get_schema(self) -> Dict[str, Channel]: bindings=ChannelBinding( amqp=amqp.ChannelBinding( **{ - "is": "routingKey", + "is_": "routingKey", # type: ignore "queue": amqp.Queue( name=self.queue.name, durable=self.queue.durable, @@ -60,7 +58,7 @@ def get_schema(self) -> Dict[str, Channel]: amqp.Exchange(type="default", vhost=self.virtual_host) if not self.exchange.name else amqp.Exchange( - type=self.exchange.type.value, + type=self.exchange.type.value, # type: ignore name=self.exchange.name, durable=self.exchange.durable, autoDelete=self.exchange.auto_delete, diff --git a/faststream/redis/publisher/asyncapi.py b/faststream/redis/publisher/asyncapi.py index 032055bdf1..65854411db 100644 --- a/faststream/redis/publisher/asyncapi.py +++ b/faststream/redis/publisher/asyncapi.py @@ -3,12 +3,10 @@ from typing_extensions import TypeAlias, override from faststream.asyncapi.utils import resolve_payloads -from faststream.asyncapi.v2_6_0.schema import ( - Channel, - Operation, -) -from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding, redis -from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message +from faststream.broker.specification.bindings import ChannelBinding, redis +from faststream.broker.specification.channel import Channel +from faststream.broker.specification.message import CorrelationId, Message +from faststream.broker.specification.operation import Operation from faststream.exceptions import SetupError from faststream.redis.publisher.usecase import ( ChannelPublisher, diff --git a/faststream/redis/subscriber/asyncapi.py b/faststream/redis/subscriber/asyncapi.py index 622bdfecf6..9eeae7de70 100644 --- a/faststream/redis/subscriber/asyncapi.py +++ b/faststream/redis/subscriber/asyncapi.py @@ -1,12 +1,10 @@ from typing import Dict from faststream.asyncapi.utils import resolve_payloads -from faststream.asyncapi.v2_6_0.schema import ( - Channel, - Operation, -) -from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding, redis -from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message +from faststream.broker.specification.bindings import ChannelBinding, redis +from faststream.broker.specification.channel import Channel +from faststream.broker.specification.message import CorrelationId, Message +from faststream.broker.specification.operation import Operation from faststream.redis.schemas import ListSub, StreamSub from faststream.redis.schemas.proto import RedisAsyncAPIProtocol from faststream.redis.subscriber.usecase import ( diff --git a/tests/asyncapi/confluent/v2_6_0/test_connection.py b/tests/asyncapi/confluent/v2_6_0/test_connection.py index 58d4fe26fd..4c2f10a3f4 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_connection.py +++ b/tests/asyncapi/confluent/v2_6_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.v2_6_0.schema import Tag +from faststream.broker.specification.tag import Tag from faststream.confluent import KafkaBroker diff --git a/tests/asyncapi/confluent/v3_0_0/test_connection.py b/tests/asyncapi/confluent/v3_0_0/test_connection.py index 29a178de3f..85007336e1 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_connection.py +++ b/tests/asyncapi/confluent/v3_0_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.v2_6_0.schema import Tag +from faststream.broker.specification.tag import Tag from faststream.asyncapi.version import AsyncAPIVersion from faststream.confluent import KafkaBroker diff --git a/tests/asyncapi/kafka/v2_6_0/test_app.py b/tests/asyncapi/kafka/v2_6_0/test_app.py index badf19b188..9c0f33a285 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_app.py +++ b/tests/asyncapi/kafka/v2_6_0/test_app.py @@ -1,7 +1,8 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema from faststream.asyncapi.v2_6_0.schema.info import License, Contact -from faststream.asyncapi.v2_6_0.schema.utils import Tag, ExternalDocs +from faststream.broker.specification.tag import Tag +from faststream.broker.specification.docs import ExternalDocs from faststream.kafka import KafkaBroker diff --git a/tests/asyncapi/kafka/v2_6_0/test_connection.py b/tests/asyncapi/kafka/v2_6_0/test_connection.py index e3d19231a7..d238529e04 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_connection.py +++ b/tests/asyncapi/kafka/v2_6_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.v2_6_0.schema import Tag +from faststream.broker.specification.tag import Tag from faststream.kafka import KafkaBroker diff --git a/tests/asyncapi/kafka/v3_0_0/test_connection.py b/tests/asyncapi/kafka/v3_0_0/test_connection.py index 640a44f857..667ec9947c 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_connection.py +++ b/tests/asyncapi/kafka/v3_0_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.v2_6_0.schema import Tag +from faststream.broker.specification.tag import Tag from faststream.asyncapi.version import AsyncAPIVersion from faststream.kafka import KafkaBroker diff --git a/tests/asyncapi/nats/v2_6_0/test_connection.py b/tests/asyncapi/nats/v2_6_0/test_connection.py index c3092a6ede..4ac0232e99 100644 --- a/tests/asyncapi/nats/v2_6_0/test_connection.py +++ b/tests/asyncapi/nats/v2_6_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.v2_6_0.schema import Tag +from faststream.broker.specification.tag import Tag from faststream.nats import NatsBroker diff --git a/tests/asyncapi/nats/v3_0_0/test_connection.py b/tests/asyncapi/nats/v3_0_0/test_connection.py index 3400eb8803..d79014334a 100644 --- a/tests/asyncapi/nats/v3_0_0/test_connection.py +++ b/tests/asyncapi/nats/v3_0_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.v2_6_0.schema import Tag +from faststream.broker.specification.tag import Tag from faststream.asyncapi.version import AsyncAPIVersion from faststream.nats import NatsBroker diff --git a/tests/asyncapi/rabbit/v2_6_0/test_connection.py b/tests/asyncapi/rabbit/v2_6_0/test_connection.py index 45f76a416d..0ad747f1a1 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_connection.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.v2_6_0.schema import Tag +from faststream.broker.specification.tag import Tag from faststream.rabbit import RabbitBroker diff --git a/tests/asyncapi/rabbit/v3_0_0/test_connection.py b/tests/asyncapi/rabbit/v3_0_0/test_connection.py index 7c8a467bba..eb1bf2f260 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_connection.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.v2_6_0.schema import Tag +from faststream.broker.specification.tag import Tag from faststream.asyncapi.version import AsyncAPIVersion from faststream.rabbit import RabbitBroker diff --git a/tests/asyncapi/redis/v2_6_0/test_connection.py b/tests/asyncapi/redis/v2_6_0/test_connection.py index 1e14be77fe..a3331f6bc7 100644 --- a/tests/asyncapi/redis/v2_6_0/test_connection.py +++ b/tests/asyncapi/redis/v2_6_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.v2_6_0.schema import Tag +from faststream.broker.specification.tag import Tag from faststream.redis import RedisBroker diff --git a/tests/asyncapi/redis/v3_0_0/test_connection.py b/tests/asyncapi/redis/v3_0_0/test_connection.py index 4e42a74093..eba4b5bbc5 100644 --- a/tests/asyncapi/redis/v3_0_0/test_connection.py +++ b/tests/asyncapi/redis/v3_0_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.v2_6_0.schema import Tag +from faststream.broker.specification.tag import Tag from faststream.asyncapi.version import AsyncAPIVersion from faststream.redis import RedisBroker From 59ead93e327ba46d967be2ba371e626050340681 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 11 Aug 2024 13:21:30 +0300 Subject: [PATCH 064/245] AsyncAPI 3.0.0 generation from internal specs --- faststream/asyncapi/v2_6_0/generate.py | 41 ++++-- faststream/asyncapi/v3_0_0/generate.py | 182 +++++++++++++++++++------ 2 files changed, 169 insertions(+), 54 deletions(-) diff --git a/faststream/asyncapi/v2_6_0/generate.py b/faststream/asyncapi/v2_6_0/generate.py index d6b96a411f..01b1d575a0 100644 --- a/faststream/asyncapi/v2_6_0/generate.py +++ b/faststream/asyncapi/v2_6_0/generate.py @@ -1,27 +1,42 @@ from dataclasses import asdict -from typing import TYPE_CHECKING, Any, Dict, List, Union, Optional +from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union from faststream._compat import DEF_KEY, HAS_FASTAPI from faststream.asyncapi.v2_6_0.schema import ( Channel, Components, + ExternalDocs, + ExternalDocsDict, Info, + Operation, Reference, Schema, Server, Tag, - TagDict, Operation, ExternalDocsDict, ExternalDocs, + TagDict, +) +from faststream.asyncapi.v2_6_0.schema.bindings import ( + ChannelBinding, + OperationBinding, + amqp, + kafka, + nats, + redis, + sqs, +) +from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message +from faststream.broker.specification.bindings import ( + OperationBinding as SpecOperationBinding, ) -from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding, amqp, kafka, sqs, nats, redis, OperationBinding -from faststream.asyncapi.v2_6_0.schema.message import Message, CorrelationId from faststream.broker.specification.channel import Channel as SpecChannel -from faststream.broker.specification.operation import Operation as SpecOperation -from faststream.broker.specification.bindings import OperationBinding as SpecOperationBinding from faststream.broker.specification.channel import ChannelBinding as SpecChannelBinding +from faststream.broker.specification.docs import ExternalDocs as SpecExternalDocs +from faststream.broker.specification.docs import ( + ExternalDocsDict as SpecExternalDocsDict, +) +from faststream.broker.specification.operation import Operation as SpecOperation from faststream.broker.specification.tag import Tag as SpecTag from faststream.broker.specification.tag import TagDict as SpecTagDict -from faststream.broker.specification.docs import ExternalDocs as SpecExternalDocs -from faststream.broker.specification.docs import ExternalDocsDict as SpecExternalDocsDict from faststream.constants import ContentTypes if TYPE_CHECKING: @@ -119,7 +134,7 @@ def get_broker_server( "protocol": broker.protocol, "protocolVersion": broker.protocol_version, "description": broker.description, - "tags": tags if tags else None, + "tags": tags, # TODO # "variables": "", # "bindings": "", @@ -194,6 +209,7 @@ def _specs_channel_binding_to_asyncapi(binding: SpecChannelBinding) -> ChannelBi amqp=amqp.ChannelBinding(**{ "is": binding.amqp.is_, "bindingVersion": binding.amqp.bindingVersion, + "queue": amqp.Queue( name=binding.amqp.queue.name, durable=binding.amqp.queue.durable, @@ -202,6 +218,7 @@ def _specs_channel_binding_to_asyncapi(binding: SpecChannelBinding) -> ChannelBi vhost=binding.amqp.queue.vhost, ) if binding.amqp.queue else None, + "exchange": amqp.Exchange( name=binding.amqp.exchange.name, type=binding.amqp.exchange.type, @@ -211,7 +228,7 @@ def _specs_channel_binding_to_asyncapi(binding: SpecChannelBinding) -> ChannelBi ) if binding.amqp.exchange else None, } - ) + ) if binding.amqp else None, kafka=kafka.ChannelBinding(**asdict(binding.kafka)) @@ -389,7 +406,7 @@ def _move_pydantic_refs( for i in range(len(data[k])): data[k][i] = _move_pydantic_refs(item[i], key) - if isinstance(desciminator := data.get("discriminator"), dict): - data["discriminator"] = desciminator["propertyName"] + if isinstance(discriminator := data.get("discriminator"), dict): + data["discriminator"] = discriminator["propertyName"] return data diff --git a/faststream/asyncapi/v3_0_0/generate.py b/faststream/asyncapi/v3_0_0/generate.py index 27a546dd32..d7907cbb8a 100644 --- a/faststream/asyncapi/v3_0_0/generate.py +++ b/faststream/asyncapi/v3_0_0/generate.py @@ -1,9 +1,11 @@ -from typing import TYPE_CHECKING, Any, Dict, List, Union +from dataclasses import asdict +from typing import TYPE_CHECKING, Any, Dict, List, Union, Optional from urllib.parse import urlparse from faststream._compat import DEF_KEY, HAS_FASTAPI -from faststream.asyncapi.v2_6_0.schema import Reference -from faststream.asyncapi.v2_6_0.schema.message import Message +from faststream.asyncapi.v2_6_0.generate import _specs_channel_binding_to_asyncapi, _specs_operation_binding_to_asyncapi +from faststream.asyncapi.v2_6_0.schema import Reference, TagDict, Tag, ExternalDocsDict, ExternalDocs +from faststream.asyncapi.v2_6_0.schema.message import Message, CorrelationId from faststream.asyncapi.v3_0_0.schema import ( Channel, Components, @@ -12,6 +14,14 @@ Schema, Server, ) +from faststream.broker.specification.tag import ( + Tag as SpecTag, + TagDict as SpecTagDict, +) +from faststream.broker.specification.docs import ( + ExternalDocs as SpecExternalDocs, + ExternalDocsDict as SpecExternalDocsDict, +) from faststream.constants import ContentTypes if TYPE_CHECKING: @@ -62,8 +72,8 @@ def get_app_schema(app: Union["FastStream", "StreamRouter[Any]"]) -> Schema: termsOfService=app.terms_of_service, contact=app.contact, license=app.license, - tags=list(app.asyncapi_tags) if app.asyncapi_tags else None, - externalDocs=app.external_docs, + tags=_specs_tags_to_asyncapi(list(app.asyncapi_tags)) if app.asyncapi_tags else None, + externalDocs=_specs_external_docs_to_asyncapi(app.external_docs), ), defaultContentType=ContentTypes.json.value, id=app.identifier, @@ -87,11 +97,24 @@ def get_broker_server( """Get the broker server for an application.""" servers = {} + if broker.tags: + tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = [] + + for tag in broker.tags: + if isinstance(tag, SpecTag): + tags.append(Tag(**asdict(tag))) + elif isinstance(tag, dict): + tags.append(tag) + else: + raise NotImplementedError(f"Unsupported tag type: {tag}; {type(tag)}") + else: + tags = None + broker_meta: Dict[str, Any] = { "protocol": broker.protocol, "protocolVersion": broker.protocol_version, "description": broker.description, - "tags": broker.tags, + "tags": tags, # TODO # "variables": "", # "bindings": "", @@ -146,13 +169,14 @@ def get_broker_operations( operations = {} for h in broker._subscribers.values(): - for channel_name, channel_2_6 in h.schema().items(): - if channel_2_6.subscribe is not None: + for channel_name, specs_channel in h.schema().items(): + if specs_channel.subscribe is not None: op = Operation( action="receive", - summary=channel_2_6.subscribe.summary, - description=channel_2_6.subscribe.description, - bindings=channel_2_6.subscribe.bindings, + summary=specs_channel.subscribe.summary, + description=specs_channel.subscribe.description, + bindings=_specs_operation_binding_to_asyncapi(specs_channel.subscribe.bindings) + if specs_channel.subscribe.bindings else None, messages=[ Reference( **{"$ref": f"#/channels/{channel_name}/messages/SubscribeMessage"}, @@ -161,16 +185,17 @@ def get_broker_operations( channel=Reference( **{"$ref": f"#/channels/{channel_name}"}, ), - security=channel_2_6.subscribe.security, + security=specs_channel.subscribe.security, ) operations[f"{channel_name}Subscribe"] = op - elif channel_2_6.publish is not None: + elif specs_channel.publish is not None: op = Operation( action="send", - summary=channel_2_6.publish.summary, - description=channel_2_6.publish.description, - bindings=channel_2_6.publish.bindings, + summary=specs_channel.publish.summary, + description=specs_channel.publish.description, + bindings=_specs_operation_binding_to_asyncapi(specs_channel.publish.bindings) + if specs_channel.publish.bindings else None, messages=[ Reference( **{"$ref": f"#/channels/{channel_name}/messages/Message"}, @@ -179,18 +204,19 @@ def get_broker_operations( channel=Reference( **{"$ref": f"#/channels/{channel_name}"}, ), - security=channel_2_6.publish.bindings, + security=specs_channel.publish.bindings, ) operations[f"{channel_name}"] = op for p in broker._publishers.values(): - for channel_name, channel_2_6 in p.schema().items(): - if channel_2_6.subscribe is not None: + for channel_name, specs_channel in p.schema().items(): + if specs_channel.subscribe is not None: op = Operation( action="send", - summary=channel_2_6.subscribe.summary, - description=channel_2_6.subscribe.description, - bindings=channel_2_6.subscribe.bindings, + summary=specs_channel.subscribe.summary, + description=specs_channel.subscribe.description, + bindings=_specs_operation_binding_to_asyncapi(specs_channel.subscribe.bindings) + if specs_channel.subscribe.bindings else None, messages=[ Reference( **{"$ref": f"#/channels/{channel_name}/messages/SubscribeMessage"}, @@ -199,16 +225,17 @@ def get_broker_operations( channel=Reference( **{"$ref": f"#/channels/{channel_name}"}, ), - security=channel_2_6.subscribe.security, + security=specs_channel.subscribe.security, ) operations[f"{channel_name}Subscribe"] = op - elif channel_2_6.publish is not None: + elif specs_channel.publish is not None: op = Operation( action="send", - summary=channel_2_6.publish.summary, - description=channel_2_6.publish.description, - bindings=channel_2_6.publish.bindings, + summary=specs_channel.publish.summary, + description=specs_channel.publish.description, + bindings=_specs_operation_binding_to_asyncapi(specs_channel.publish.bindings) + if specs_channel.publish.bindings else None, messages=[ Reference( **{"$ref": f"#/channels/{channel_name}/messages/Message"}, @@ -217,7 +244,7 @@ def get_broker_operations( channel=Reference( **{"$ref": f"#/channels/{channel_name}"}, ), - security=channel_2_6.publish.security, + security=specs_channel.publish.security, ) operations[f"{channel_name}"] = op @@ -232,16 +259,35 @@ def get_broker_channels( for h in broker._subscribers.values(): channels_schema_v3_0 = {} - for channel_name, channel_v2_6 in h.schema().items(): - if channel_v2_6.subscribe: + for channel_name, specs_channel in h.schema().items(): + if specs_channel.subscribe: channel_v3_0 = Channel( address=channel_name, messages={ - "SubscribeMessage": channel_v2_6.subscribe.message, + "SubscribeMessage": Message( + title=specs_channel.subscribe.message.title, + name=specs_channel.subscribe.message.name, + summary=specs_channel.subscribe.message.summary, + description=specs_channel.subscribe.message.description, + messageId=specs_channel.subscribe.message.messageId, + payload=specs_channel.subscribe.message.payload, + + correlationId=CorrelationId(**asdict(specs_channel.subscribe.message.correlationId)) + if specs_channel.subscribe.message.correlationId else None, + + contentType=specs_channel.subscribe.message.contentType, + + tags=_specs_tags_to_asyncapi(specs_channel.subscribe.message.tags) + if specs_channel.subscribe.message.tags else None, + + externalDocs=_specs_external_docs_to_asyncapi(specs_channel.subscribe.message.externalDocs) + if specs_channel.subscribe.message.externalDocs else None, + ), }, - description=channel_v2_6.description, - servers=channel_v2_6.servers, - bindings=channel_v2_6.bindings, + description=specs_channel.description, + servers=specs_channel.servers, + bindings=_specs_channel_binding_to_asyncapi(specs_channel.bindings) + if specs_channel.bindings else None, ) channels_schema_v3_0[channel_name] = channel_v3_0 @@ -250,16 +296,35 @@ def get_broker_channels( for p in broker._publishers.values(): channels_schema_v3_0 = {} - for channel_name, channel_v2_6 in p.schema().items(): - if channel_v2_6.publish: + for channel_name, specs_channel in p.schema().items(): + if specs_channel.publish: channel_v3_0 = Channel( address=channel_name, messages={ - "Message": channel_v2_6.publish.message, + "Message": Message( + title=specs_channel.publish.message.title, + name=specs_channel.publish.message.name, + summary=specs_channel.publish.message.summary, + description=specs_channel.publish.message.description, + messageId=specs_channel.publish.message.messageId, + payload=specs_channel.publish.message.payload, + + correlationId=CorrelationId(**asdict(specs_channel.publish.message.correlationId)) + if specs_channel.publish.message.correlationId else None, + + contentType=specs_channel.publish.message.contentType, + + tags=_specs_tags_to_asyncapi(specs_channel.publish.message.tags) + if specs_channel.publish.message.tags else None, + + externalDocs=_specs_external_docs_to_asyncapi(specs_channel.publish.message.externalDocs) + if specs_channel.publish.message.externalDocs else None, + ), }, - description=channel_v2_6.description, - servers=channel_v2_6.servers, - bindings=channel_v2_6.bindings, + description=specs_channel.description, + servers=specs_channel.servers, + bindings=_specs_channel_binding_to_asyncapi(specs_channel.bindings) + if specs_channel.bindings else None, ) channels_schema_v3_0[channel_name] = channel_v3_0 @@ -269,6 +334,39 @@ def get_broker_channels( return channels +def _specs_tags_to_asyncapi( + tags: List[Union[SpecTag, SpecTagDict, Dict[str, Any]]] +) -> List[Union[Tag, TagDict, Dict[str, Any]]]: + asyncapi_tags = [] + + for tag in tags: + if isinstance(tag, SpecTag): + asyncapi_tags.append(Tag( + name=tag.name, + description=tag.description, + + externalDocs=_specs_external_docs_to_asyncapi(tag.externalDocs) + if tag.externalDocs else None, + )) + elif isinstance(tag, dict): + asyncapi_tags.append(tag) + else: + raise NotImplementedError + + return asyncapi_tags + + +def _specs_external_docs_to_asyncapi( + externalDocs: Union[SpecExternalDocs, SpecExternalDocsDict, Dict[str, Any]] +) -> Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]: + if isinstance(externalDocs, SpecExternalDocs): + return ExternalDocs( + **asdict(externalDocs) + ) + else: + return externalDocs + + def _resolve_msg_payloads( message_name: str, m: Message, @@ -331,7 +429,7 @@ def _move_pydantic_refs( for i in range(len(data[k])): data[k][i] = _move_pydantic_refs(item[i], key) - if isinstance(desciminator := data.get("discriminator"), dict): - data["discriminator"] = desciminator["propertyName"] + if isinstance(discriminator := data.get("discriminator"), dict): + data["discriminator"] = discriminator["propertyName"] return data From 84a8bb86775a38665f5fd608bccd1f4a7708c0c9 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 11 Aug 2024 16:26:30 +0300 Subject: [PATCH 065/245] mypy satisfied --- faststream/app.py | 14 ++- faststream/asyncapi/abc.py | 2 +- faststream/asyncapi/v2_6_0/generate.py | 54 +++----- faststream/asyncapi/v3_0_0/generate.py | 118 +++++------------- faststream/broker/core/usecase.py | 3 +- faststream/broker/specification/__init__.py | 0 faststream/confluent/publisher/asyncapi.py | 8 +- faststream/confluent/subscriber/asyncapi.py | 8 +- faststream/kafka/publisher/asyncapi.py | 8 +- faststream/kafka/subscriber/asyncapi.py | 8 +- faststream/nats/publisher/asyncapi.py | 8 +- faststream/nats/subscriber/asyncapi.py | 8 +- faststream/rabbit/publisher/asyncapi.py | 12 +- faststream/rabbit/subscriber/asyncapi.py | 12 +- faststream/redis/publisher/asyncapi.py | 8 +- faststream/redis/schemas/proto.py | 2 +- faststream/redis/subscriber/asyncapi.py | 8 +- faststream/specification/__init__.py | 15 +++ .../specification/bindings/__init__.py | 0 .../specification/bindings/amqp.py | 0 .../specification/bindings/kafka.py | 0 .../specification/bindings/main.py | 10 +- .../specification/bindings/nats.py | 0 .../specification/bindings/redis.py | 0 .../specification/bindings/sqs.py | 0 .../{broker => }/specification/channel.py | 4 +- faststream/{broker => }/specification/docs.py | 0 .../{broker => }/specification/message.py | 4 +- .../{broker => }/specification/operation.py | 8 +- faststream/{broker => }/specification/tag.py | 2 +- .../confluent/v2_6_0/test_connection.py | 2 +- .../confluent/v3_0_0/test_connection.py | 2 +- tests/asyncapi/kafka/v2_6_0/test_app.py | 4 +- .../asyncapi/kafka/v2_6_0/test_connection.py | 2 +- .../asyncapi/kafka/v3_0_0/test_connection.py | 2 +- tests/asyncapi/nats/v2_6_0/test_connection.py | 2 +- tests/asyncapi/nats/v3_0_0/test_connection.py | 2 +- .../asyncapi/rabbit/v2_6_0/test_connection.py | 2 +- .../asyncapi/rabbit/v3_0_0/test_connection.py | 2 +- .../asyncapi/redis/v2_6_0/test_connection.py | 2 +- .../asyncapi/redis/v3_0_0/test_connection.py | 2 +- 41 files changed, 146 insertions(+), 202 deletions(-) delete mode 100644 faststream/broker/specification/__init__.py create mode 100644 faststream/specification/__init__.py rename faststream/{broker => }/specification/bindings/__init__.py (100%) rename faststream/{broker => }/specification/bindings/amqp.py (100%) rename faststream/{broker => }/specification/bindings/kafka.py (100%) rename faststream/{broker => }/specification/bindings/main.py (78%) rename faststream/{broker => }/specification/bindings/nats.py (100%) rename faststream/{broker => }/specification/bindings/redis.py (100%) rename faststream/{broker => }/specification/bindings/sqs.py (100%) rename faststream/{broker => }/specification/channel.py (83%) rename faststream/{broker => }/specification/docs.py (100%) rename faststream/{broker => }/specification/message.py (92%) rename faststream/{broker => }/specification/operation.py (78%) rename faststream/{broker => }/specification/tag.py (91%) diff --git a/faststream/app.py b/faststream/app.py index 52633ab18a..8051554158 100644 --- a/faststream/app.py +++ b/faststream/app.py @@ -29,12 +29,6 @@ if TYPE_CHECKING: - from faststream.asyncapi.schema import ( - ExternalDocs, - ExternalDocsDict, - Tag, - TagDict, - ) from faststream.asyncapi.v2_6_0.schema.info import ( Contact, ContactDict, @@ -42,6 +36,14 @@ LicenseDict, ) from faststream.broker.core.usecase import BrokerUsecase + from faststream.specification.docs import ( + ExternalDocs, + ExternalDocsDict, + ) + from faststream.specification.tag import ( + Tag, + TagDict, + ) from faststream.types import ( AnyCallable, AnyDict, diff --git a/faststream/asyncapi/abc.py b/faststream/asyncapi/abc.py index 25111f0570..776952c357 100644 --- a/faststream/asyncapi/abc.py +++ b/faststream/asyncapi/abc.py @@ -2,7 +2,7 @@ from typing import Any, Dict, Optional from faststream.asyncapi.proto import AsyncAPIProto -from faststream.broker.specification.channel import Channel +from faststream.specification.channel import Channel class AsyncAPIOperation(AsyncAPIProto): diff --git a/faststream/asyncapi/v2_6_0/generate.py b/faststream/asyncapi/v2_6_0/generate.py index 01b1d575a0..0d0df0fb57 100644 --- a/faststream/asyncapi/v2_6_0/generate.py +++ b/faststream/asyncapi/v2_6_0/generate.py @@ -1,12 +1,12 @@ from dataclasses import asdict -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union +from typing import TYPE_CHECKING, Any, Dict, List, Union +from faststream import specification as spec from faststream._compat import DEF_KEY, HAS_FASTAPI from faststream.asyncapi.v2_6_0.schema import ( Channel, Components, ExternalDocs, - ExternalDocsDict, Info, Operation, Reference, @@ -25,18 +25,6 @@ sqs, ) from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message -from faststream.broker.specification.bindings import ( - OperationBinding as SpecOperationBinding, -) -from faststream.broker.specification.channel import Channel as SpecChannel -from faststream.broker.specification.channel import ChannelBinding as SpecChannelBinding -from faststream.broker.specification.docs import ExternalDocs as SpecExternalDocs -from faststream.broker.specification.docs import ( - ExternalDocsDict as SpecExternalDocsDict, -) -from faststream.broker.specification.operation import Operation as SpecOperation -from faststream.broker.specification.tag import Tag as SpecTag -from faststream.broker.specification.tag import TagDict as SpecTagDict from faststream.constants import ContentTypes if TYPE_CHECKING: @@ -97,7 +85,7 @@ def get_app_schema(app: Union["FastStream", "StreamRouter[Any]"]) -> Schema: defaultContentType=ContentTypes.json.value, id=app.identifier, tags=_specs_tags_to_asyncapi(list(app.asyncapi_tags)) if app.asyncapi_tags else None, - externalDocs=_specs_external_docs_to_asyncapi(app.external_docs), + externalDocs=_specs_external_docs_to_asyncapi(app.external_docs) if app.external_docs else None, servers=servers, channels=channels, components=Components( @@ -117,24 +105,22 @@ def get_broker_server( """Get the broker server for an application.""" servers = {} - if broker.tags: - tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = [] + tags: List[Union[Tag, Dict[str, Any]]] = [] + if broker.tags: for tag in broker.tags: - if isinstance(tag, SpecTag): + if isinstance(tag, spec.tag.Tag): tags.append(Tag(**asdict(tag))) elif isinstance(tag, dict): - tags.append(tag) + tags.append(dict(tag)) else: raise NotImplementedError(f"Unsupported tag type: {tag}; {type(tag)}") - else: - tags = None broker_meta: Dict[str, Any] = { "protocol": broker.protocol, "protocolVersion": broker.protocol_version, "description": broker.description, - "tags": tags, + "tags": tags if tags else None, # TODO # "variables": "", # "bindings": "", @@ -188,7 +174,7 @@ def get_broker_channels( return channels -def _specs_channel_to_asyncapi(channel: SpecChannel) -> Channel: +def _specs_channel_to_asyncapi(channel: spec.channel.Channel) -> Channel: return Channel( description=channel.description, servers=channel.servers, @@ -204,7 +190,7 @@ def _specs_channel_to_asyncapi(channel: SpecChannel) -> Channel: ) -def _specs_channel_binding_to_asyncapi(binding: SpecChannelBinding) -> ChannelBinding: +def _specs_channel_binding_to_asyncapi(binding: spec.bindings.ChannelBinding) -> ChannelBinding: return ChannelBinding( amqp=amqp.ChannelBinding(**{ "is": binding.amqp.is_, @@ -245,7 +231,7 @@ def _specs_channel_binding_to_asyncapi(binding: SpecChannelBinding) -> ChannelBi ) -def _specs_operation_to_asyncapi(operation: SpecOperation) -> Operation: +def _specs_operation_to_asyncapi(operation: spec.operation.Operation) -> Operation: return Operation( operationId=operation.operationId, summary=operation.summary, @@ -284,7 +270,7 @@ def _specs_operation_to_asyncapi(operation: SpecOperation) -> Operation: ) -def _specs_operation_binding_to_asyncapi(binding: SpecOperationBinding) -> OperationBinding: +def _specs_operation_binding_to_asyncapi(binding: spec.bindings.OperationBinding) -> OperationBinding: return OperationBinding( amqp=amqp.OperationBinding(**asdict(binding.amqp)) if binding.amqp else None, @@ -304,12 +290,12 @@ def _specs_operation_binding_to_asyncapi(binding: SpecOperationBinding) -> Opera def _specs_tags_to_asyncapi( - tags: List[Union[SpecTag, SpecTagDict, Dict[str, Any]]] + tags: List[Union[spec.tag.Tag, spec.tag.TagDict, Dict[str, Any]]] ) -> List[Union[Tag, TagDict, Dict[str, Any]]]: - asyncapi_tags = [] + asyncapi_tags: List[Union[Tag, TagDict, Dict[str, Any]]] = [] for tag in tags: - if isinstance(tag, SpecTag): + if isinstance(tag, spec.tag.Tag): asyncapi_tags.append(Tag( name=tag.name, description=tag.description, @@ -318,7 +304,7 @@ def _specs_tags_to_asyncapi( if tag.externalDocs else None, )) elif isinstance(tag, dict): - asyncapi_tags.append(tag) + asyncapi_tags.append(dict(tag)) else: raise NotImplementedError @@ -326,14 +312,14 @@ def _specs_tags_to_asyncapi( def _specs_external_docs_to_asyncapi( - externalDocs: Union[SpecExternalDocs, SpecExternalDocsDict, Dict[str, Any]] -) -> Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]: - if isinstance(externalDocs, SpecExternalDocs): + externalDocs: Union[spec.docs.ExternalDocs, spec.docs.ExternalDocsDict, Dict[str, Any]] +) -> Union[ExternalDocs, Dict[str, Any]]: + if isinstance(externalDocs, spec.docs.ExternalDocs): return ExternalDocs( **asdict(externalDocs) ) else: - return externalDocs + return dict(externalDocs) def _resolve_msg_payloads( diff --git a/faststream/asyncapi/v3_0_0/generate.py b/faststream/asyncapi/v3_0_0/generate.py index d7907cbb8a..2f297b3dc2 100644 --- a/faststream/asyncapi/v3_0_0/generate.py +++ b/faststream/asyncapi/v3_0_0/generate.py @@ -1,11 +1,21 @@ from dataclasses import asdict -from typing import TYPE_CHECKING, Any, Dict, List, Union, Optional +from typing import TYPE_CHECKING, Any, Dict, List, Union from urllib.parse import urlparse +from faststream import specification as spec from faststream._compat import DEF_KEY, HAS_FASTAPI -from faststream.asyncapi.v2_6_0.generate import _specs_channel_binding_to_asyncapi, _specs_operation_binding_to_asyncapi -from faststream.asyncapi.v2_6_0.schema import Reference, TagDict, Tag, ExternalDocsDict, ExternalDocs -from faststream.asyncapi.v2_6_0.schema.message import Message, CorrelationId +from faststream.asyncapi.v2_6_0.generate import ( + _specs_channel_binding_to_asyncapi, + _specs_operation_binding_to_asyncapi, + _specs_tags_to_asyncapi, +) +from faststream.asyncapi.v2_6_0.schema import ( + ExternalDocs, + ExternalDocsDict, + Reference, + Tag, +) +from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message from faststream.asyncapi.v3_0_0.schema import ( Channel, Components, @@ -14,14 +24,6 @@ Schema, Server, ) -from faststream.broker.specification.tag import ( - Tag as SpecTag, - TagDict as SpecTagDict, -) -from faststream.broker.specification.docs import ( - ExternalDocs as SpecExternalDocs, - ExternalDocsDict as SpecExternalDocsDict, -) from faststream.constants import ContentTypes if TYPE_CHECKING: @@ -73,7 +75,7 @@ def get_app_schema(app: Union["FastStream", "StreamRouter[Any]"]) -> Schema: contact=app.contact, license=app.license, tags=_specs_tags_to_asyncapi(list(app.asyncapi_tags)) if app.asyncapi_tags else None, - externalDocs=_specs_external_docs_to_asyncapi(app.external_docs), + externalDocs=_specs_external_docs_to_asyncapi(app.external_docs) if app.external_docs else None, ), defaultContentType=ContentTypes.json.value, id=app.identifier, @@ -97,24 +99,22 @@ def get_broker_server( """Get the broker server for an application.""" servers = {} + tags: List[Union[Tag, Dict[str, Any]]] = [] if broker.tags: - tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = [] for tag in broker.tags: - if isinstance(tag, SpecTag): + if isinstance(tag, spec.tag.Tag): tags.append(Tag(**asdict(tag))) elif isinstance(tag, dict): - tags.append(tag) + tags.append(dict(tag)) else: raise NotImplementedError(f"Unsupported tag type: {tag}; {type(tag)}") - else: - tags = None broker_meta: Dict[str, Any] = { "protocol": broker.protocol, "protocolVersion": broker.protocol_version, "description": broker.description, - "tags": tags, + "tags": tags if tags else None, # TODO # "variables": "", # "bindings": "", @@ -189,47 +189,9 @@ def get_broker_operations( ) operations[f"{channel_name}Subscribe"] = op - elif specs_channel.publish is not None: - op = Operation( - action="send", - summary=specs_channel.publish.summary, - description=specs_channel.publish.description, - bindings=_specs_operation_binding_to_asyncapi(specs_channel.publish.bindings) - if specs_channel.publish.bindings else None, - messages=[ - Reference( - **{"$ref": f"#/channels/{channel_name}/messages/Message"}, - )] - , - channel=Reference( - **{"$ref": f"#/channels/{channel_name}"}, - ), - security=specs_channel.publish.bindings, - ) - operations[f"{channel_name}"] = op - for p in broker._publishers.values(): for channel_name, specs_channel in p.schema().items(): - if specs_channel.subscribe is not None: - op = Operation( - action="send", - summary=specs_channel.subscribe.summary, - description=specs_channel.subscribe.description, - bindings=_specs_operation_binding_to_asyncapi(specs_channel.subscribe.bindings) - if specs_channel.subscribe.bindings else None, - messages=[ - Reference( - **{"$ref": f"#/channels/{channel_name}/messages/SubscribeMessage"}, - ) - ], - channel=Reference( - **{"$ref": f"#/channels/{channel_name}"}, - ), - security=specs_channel.subscribe.security, - ) - operations[f"{channel_name}Subscribe"] = op - - elif specs_channel.publish is not None: + if specs_channel.publish is not None: op = Operation( action="send", summary=specs_channel.publish.summary, @@ -277,7 +239,7 @@ def get_broker_channels( contentType=specs_channel.subscribe.message.contentType, - tags=_specs_tags_to_asyncapi(specs_channel.subscribe.message.tags) + tags=_specs_tags_to_asyncapi(specs_channel.subscribe.message.tags) # type: ignore if specs_channel.subscribe.message.tags else None, externalDocs=_specs_external_docs_to_asyncapi(specs_channel.subscribe.message.externalDocs) @@ -314,7 +276,7 @@ def get_broker_channels( contentType=specs_channel.publish.message.contentType, - tags=_specs_tags_to_asyncapi(specs_channel.publish.message.tags) + tags=_specs_tags_to_asyncapi(specs_channel.publish.message.tags) # type: ignore if specs_channel.publish.message.tags else None, externalDocs=_specs_external_docs_to_asyncapi(specs_channel.publish.message.externalDocs) @@ -334,37 +296,15 @@ def get_broker_channels( return channels -def _specs_tags_to_asyncapi( - tags: List[Union[SpecTag, SpecTagDict, Dict[str, Any]]] -) -> List[Union[Tag, TagDict, Dict[str, Any]]]: - asyncapi_tags = [] - - for tag in tags: - if isinstance(tag, SpecTag): - asyncapi_tags.append(Tag( - name=tag.name, - description=tag.description, - - externalDocs=_specs_external_docs_to_asyncapi(tag.externalDocs) - if tag.externalDocs else None, - )) - elif isinstance(tag, dict): - asyncapi_tags.append(tag) - else: - raise NotImplementedError - - return asyncapi_tags - - def _specs_external_docs_to_asyncapi( - externalDocs: Union[SpecExternalDocs, SpecExternalDocsDict, Dict[str, Any]] + externalDocs: Union[spec.docs.ExternalDocs, spec.docs.ExternalDocsDict, Dict[str, Any]] ) -> Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]: - if isinstance(externalDocs, SpecExternalDocs): + if isinstance(externalDocs, spec.docs.ExternalDocs): return ExternalDocs( **asdict(externalDocs) ) else: - return externalDocs + return dict(externalDocs) def _resolve_msg_payloads( @@ -377,19 +317,19 @@ def _resolve_msg_payloads( assert isinstance(m.payload, dict) m.payload = _move_pydantic_refs(m.payload, DEF_KEY) + if DEF_KEY in m.payload: payloads.update(m.payload.pop(DEF_KEY)) one_of = m.payload.get("oneOf", None) if isinstance(one_of, dict): one_of_list = [] - p: Dict[str, Dict[str, Any]] = {} + processed_payloads: Dict[str, Dict[str, Any]] = {} for name, payload in one_of.items(): - payloads.update(p.pop(DEF_KEY, {})) - p[name] = payload + processed_payloads[name] = payload one_of_list.append(Reference(**{"$ref": f"#/components/schemas/{name}"})) - payloads.update(p) + payloads.update(processed_payloads) m.payload["oneOf"] = one_of_list assert m.title messages[m.title] = m diff --git a/faststream/broker/core/usecase.py b/faststream/broker/core/usecase.py index 4017e756d3..ea2fce1d16 100644 --- a/faststream/broker/core/usecase.py +++ b/faststream/broker/core/usecase.py @@ -24,6 +24,7 @@ from faststream.broker.proto import SetupAble from faststream.broker.subscriber.proto import SubscriberProto from faststream.broker.types import ( + AsyncCustomCallable, BrokerMiddleware, ConnectionType, CustomCallable, @@ -41,8 +42,8 @@ from faststream.broker.message import StreamMessage from faststream.broker.publisher.proto import ProducerProto, PublisherProto - from faststream.broker.specification.tag import Tag, TagDict from faststream.security import BaseSecurity + from faststream.specification.tag import Tag, TagDict from faststream.types import AnyDict, Decorator, LoggerProto diff --git a/faststream/broker/specification/__init__.py b/faststream/broker/specification/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/faststream/confluent/publisher/asyncapi.py b/faststream/confluent/publisher/asyncapi.py index 80d486d299..577a752be7 100644 --- a/faststream/confluent/publisher/asyncapi.py +++ b/faststream/confluent/publisher/asyncapi.py @@ -13,10 +13,6 @@ from typing_extensions import override from faststream.asyncapi.utils import resolve_payloads -from faststream.broker.specification.bindings import ChannelBinding, kafka -from faststream.broker.specification.channel import Channel -from faststream.broker.specification.message import CorrelationId, Message -from faststream.broker.specification.operation import Operation from faststream.broker.types import MsgType from faststream.confluent.publisher.usecase import ( BatchPublisher, @@ -24,6 +20,10 @@ LogicPublisher, ) from faststream.exceptions import SetupError +from faststream.specification.bindings import ChannelBinding, kafka +from faststream.specification.channel import Channel +from faststream.specification.message import CorrelationId, Message +from faststream.specification.operation import Operation if TYPE_CHECKING: from confluent_kafka import Message as ConfluentMsg diff --git a/faststream/confluent/subscriber/asyncapi.py b/faststream/confluent/subscriber/asyncapi.py index 5c29399e44..615c4361c3 100644 --- a/faststream/confluent/subscriber/asyncapi.py +++ b/faststream/confluent/subscriber/asyncapi.py @@ -5,16 +5,16 @@ ) from faststream.asyncapi.utils import resolve_payloads -from faststream.broker.specification.bindings import ChannelBinding, kafka -from faststream.broker.specification.channel import Channel -from faststream.broker.specification.message import CorrelationId, Message -from faststream.broker.specification.operation import Operation from faststream.broker.types import MsgType from faststream.confluent.subscriber.usecase import ( BatchSubscriber, DefaultSubscriber, LogicSubscriber, ) +from faststream.specification.bindings import ChannelBinding, kafka +from faststream.specification.channel import Channel +from faststream.specification.message import CorrelationId, Message +from faststream.specification.operation import Operation if TYPE_CHECKING: from confluent_kafka import Message as ConfluentMsg diff --git a/faststream/kafka/publisher/asyncapi.py b/faststream/kafka/publisher/asyncapi.py index 6d7af751a3..386d08f5f3 100644 --- a/faststream/kafka/publisher/asyncapi.py +++ b/faststream/kafka/publisher/asyncapi.py @@ -13,10 +13,6 @@ from typing_extensions import override from faststream.asyncapi.utils import resolve_payloads -from faststream.broker.specification.bindings import ChannelBinding, kafka -from faststream.broker.specification.channel import Channel -from faststream.broker.specification.message import CorrelationId, Message -from faststream.broker.specification.operation import Operation from faststream.broker.types import MsgType from faststream.exceptions import SetupError from faststream.kafka.publisher.usecase import ( @@ -24,6 +20,10 @@ DefaultPublisher, LogicPublisher, ) +from faststream.specification.bindings import ChannelBinding, kafka +from faststream.specification.channel import Channel +from faststream.specification.message import CorrelationId, Message +from faststream.specification.operation import Operation if TYPE_CHECKING: from aiokafka import ConsumerRecord diff --git a/faststream/kafka/subscriber/asyncapi.py b/faststream/kafka/subscriber/asyncapi.py index 331f0a6e85..d0d33d13f6 100644 --- a/faststream/kafka/subscriber/asyncapi.py +++ b/faststream/kafka/subscriber/asyncapi.py @@ -5,16 +5,16 @@ ) from faststream.asyncapi.utils import resolve_payloads -from faststream.broker.specification.bindings import ChannelBinding, kafka -from faststream.broker.specification.channel import Channel -from faststream.broker.specification.message import CorrelationId, Message -from faststream.broker.specification.operation import Operation from faststream.broker.types import MsgType from faststream.kafka.subscriber.usecase import ( BatchSubscriber, DefaultSubscriber, LogicSubscriber, ) +from faststream.specification.bindings import ChannelBinding, kafka +from faststream.specification.channel import Channel +from faststream.specification.message import CorrelationId, Message +from faststream.specification.operation import Operation if TYPE_CHECKING: from aiokafka import ConsumerRecord diff --git a/faststream/nats/publisher/asyncapi.py b/faststream/nats/publisher/asyncapi.py index 568aa2d0e8..81bcfeccb5 100644 --- a/faststream/nats/publisher/asyncapi.py +++ b/faststream/nats/publisher/asyncapi.py @@ -3,11 +3,11 @@ from typing_extensions import override from faststream.asyncapi.utils import resolve_payloads -from faststream.broker.specification.bindings import ChannelBinding, nats -from faststream.broker.specification.channel import Channel -from faststream.broker.specification.message import CorrelationId, Message -from faststream.broker.specification.operation import Operation from faststream.nats.publisher.usecase import LogicPublisher +from faststream.specification.bindings import ChannelBinding, nats +from faststream.specification.channel import Channel +from faststream.specification.message import CorrelationId, Message +from faststream.specification.operation import Operation if TYPE_CHECKING: from nats.aio.msg import Msg diff --git a/faststream/nats/subscriber/asyncapi.py b/faststream/nats/subscriber/asyncapi.py index e36f3869e2..3202c0abc1 100644 --- a/faststream/nats/subscriber/asyncapi.py +++ b/faststream/nats/subscriber/asyncapi.py @@ -3,10 +3,6 @@ from typing_extensions import override from faststream.asyncapi.utils import resolve_payloads -from faststream.broker.specification.bindings import ChannelBinding, nats -from faststream.broker.specification.channel import Channel -from faststream.broker.specification.message import CorrelationId, Message -from faststream.broker.specification.operation import Operation from faststream.nats.subscriber.usecase import ( BatchPullStreamSubscriber, ConcurrentCoreSubscriber, @@ -19,6 +15,10 @@ PullStreamSubscriber, PushStreamSubscription, ) +from faststream.specification.bindings import ChannelBinding, nats +from faststream.specification.channel import Channel +from faststream.specification.message import CorrelationId, Message +from faststream.specification.operation import Operation class AsyncAPISubscriber(LogicSubscriber[Any]): diff --git a/faststream/rabbit/publisher/asyncapi.py b/faststream/rabbit/publisher/asyncapi.py index ba5e7d0f7a..330b42b9f7 100644 --- a/faststream/rabbit/publisher/asyncapi.py +++ b/faststream/rabbit/publisher/asyncapi.py @@ -3,16 +3,16 @@ from typing_extensions import override from faststream.asyncapi.utils import resolve_payloads -from faststream.broker.specification.bindings import ( +from faststream.rabbit.publisher.usecase import LogicPublisher, PublishKwargs +from faststream.rabbit.utils import is_routing_exchange +from faststream.specification.bindings import ( ChannelBinding, OperationBinding, amqp, ) -from faststream.broker.specification.channel import Channel -from faststream.broker.specification.message import CorrelationId, Message -from faststream.broker.specification.operation import Operation -from faststream.rabbit.publisher.usecase import LogicPublisher, PublishKwargs -from faststream.rabbit.utils import is_routing_exchange +from faststream.specification.channel import Channel +from faststream.specification.message import CorrelationId, Message +from faststream.specification.operation import Operation if TYPE_CHECKING: from aio_pika import IncomingMessage diff --git a/faststream/rabbit/subscriber/asyncapi.py b/faststream/rabbit/subscriber/asyncapi.py index b634fe856c..35643e4542 100644 --- a/faststream/rabbit/subscriber/asyncapi.py +++ b/faststream/rabbit/subscriber/asyncapi.py @@ -1,16 +1,16 @@ from typing import Dict from faststream.asyncapi.utils import resolve_payloads -from faststream.broker.specification.bindings import ( +from faststream.rabbit.subscriber.usecase import LogicSubscriber +from faststream.rabbit.utils import is_routing_exchange +from faststream.specification.bindings import ( ChannelBinding, OperationBinding, amqp, ) -from faststream.broker.specification.channel import Channel -from faststream.broker.specification.message import CorrelationId, Message -from faststream.broker.specification.operation import Operation -from faststream.rabbit.subscriber.usecase import LogicSubscriber -from faststream.rabbit.utils import is_routing_exchange +from faststream.specification.channel import Channel +from faststream.specification.message import CorrelationId, Message +from faststream.specification.operation import Operation class AsyncAPISubscriber(LogicSubscriber): diff --git a/faststream/redis/publisher/asyncapi.py b/faststream/redis/publisher/asyncapi.py index 65854411db..a849c0a8d0 100644 --- a/faststream/redis/publisher/asyncapi.py +++ b/faststream/redis/publisher/asyncapi.py @@ -3,10 +3,6 @@ from typing_extensions import TypeAlias, override from faststream.asyncapi.utils import resolve_payloads -from faststream.broker.specification.bindings import ChannelBinding, redis -from faststream.broker.specification.channel import Channel -from faststream.broker.specification.message import CorrelationId, Message -from faststream.broker.specification.operation import Operation from faststream.exceptions import SetupError from faststream.redis.publisher.usecase import ( ChannelPublisher, @@ -17,6 +13,10 @@ ) from faststream.redis.schemas import INCORRECT_SETUP_MSG, ListSub, PubSub, StreamSub from faststream.redis.schemas.proto import RedisAsyncAPIProtocol, validate_options +from faststream.specification.bindings import ChannelBinding, redis +from faststream.specification.channel import Channel +from faststream.specification.message import CorrelationId, Message +from faststream.specification.operation import Operation if TYPE_CHECKING: from faststream.broker.types import BrokerMiddleware, PublisherMiddleware diff --git a/faststream/redis/schemas/proto.py b/faststream/redis/schemas/proto.py index 22ca0253f4..f69d11e883 100644 --- a/faststream/redis/schemas/proto.py +++ b/faststream/redis/schemas/proto.py @@ -5,8 +5,8 @@ from faststream.exceptions import SetupError if TYPE_CHECKING: - from faststream.asyncapi.v2_6_0.schema.bindings import redis from faststream.redis.schemas import ListSub, PubSub, StreamSub + from faststream.specification.bindings import redis class RedisAsyncAPIProtocol(AsyncAPIOperation): diff --git a/faststream/redis/subscriber/asyncapi.py b/faststream/redis/subscriber/asyncapi.py index 9eeae7de70..622237d17b 100644 --- a/faststream/redis/subscriber/asyncapi.py +++ b/faststream/redis/subscriber/asyncapi.py @@ -1,10 +1,6 @@ from typing import Dict from faststream.asyncapi.utils import resolve_payloads -from faststream.broker.specification.bindings import ChannelBinding, redis -from faststream.broker.specification.channel import Channel -from faststream.broker.specification.message import CorrelationId, Message -from faststream.broker.specification.operation import Operation from faststream.redis.schemas import ListSub, StreamSub from faststream.redis.schemas.proto import RedisAsyncAPIProtocol from faststream.redis.subscriber.usecase import ( @@ -15,6 +11,10 @@ LogicSubscriber, StreamSubscriber, ) +from faststream.specification.bindings import ChannelBinding, redis +from faststream.specification.channel import Channel +from faststream.specification.message import CorrelationId, Message +from faststream.specification.operation import Operation class AsyncAPISubscriber(LogicSubscriber, RedisAsyncAPIProtocol): diff --git a/faststream/specification/__init__.py b/faststream/specification/__init__.py new file mode 100644 index 0000000000..3a92ffdba8 --- /dev/null +++ b/faststream/specification/__init__.py @@ -0,0 +1,15 @@ +from . import bindings +from . import channel +from . import docs +from . import message +from . import operation +from . import tag + +__all__ = ( + "bindings", + "channel", + "docs", + "message", + "operation", + "tag", +) diff --git a/faststream/broker/specification/bindings/__init__.py b/faststream/specification/bindings/__init__.py similarity index 100% rename from faststream/broker/specification/bindings/__init__.py rename to faststream/specification/bindings/__init__.py diff --git a/faststream/broker/specification/bindings/amqp.py b/faststream/specification/bindings/amqp.py similarity index 100% rename from faststream/broker/specification/bindings/amqp.py rename to faststream/specification/bindings/amqp.py diff --git a/faststream/broker/specification/bindings/kafka.py b/faststream/specification/bindings/kafka.py similarity index 100% rename from faststream/broker/specification/bindings/kafka.py rename to faststream/specification/bindings/kafka.py diff --git a/faststream/broker/specification/bindings/main.py b/faststream/specification/bindings/main.py similarity index 78% rename from faststream/broker/specification/bindings/main.py rename to faststream/specification/bindings/main.py index 5c4b0d4893..515c35ac74 100644 --- a/faststream/broker/specification/bindings/main.py +++ b/faststream/specification/bindings/main.py @@ -1,11 +1,11 @@ from dataclasses import dataclass from typing import Optional -from faststream.broker.specification.bindings import amqp as amqp_bindings -from faststream.broker.specification.bindings import kafka as kafka_bindings -from faststream.broker.specification.bindings import nats as nats_bindings -from faststream.broker.specification.bindings import redis as redis_bindings -from faststream.broker.specification.bindings import sqs as sqs_bindings +from faststream.specification.bindings import amqp as amqp_bindings +from faststream.specification.bindings import kafka as kafka_bindings +from faststream.specification.bindings import nats as nats_bindings +from faststream.specification.bindings import redis as redis_bindings +from faststream.specification.bindings import sqs as sqs_bindings @dataclass diff --git a/faststream/broker/specification/bindings/nats.py b/faststream/specification/bindings/nats.py similarity index 100% rename from faststream/broker/specification/bindings/nats.py rename to faststream/specification/bindings/nats.py diff --git a/faststream/broker/specification/bindings/redis.py b/faststream/specification/bindings/redis.py similarity index 100% rename from faststream/broker/specification/bindings/redis.py rename to faststream/specification/bindings/redis.py diff --git a/faststream/broker/specification/bindings/sqs.py b/faststream/specification/bindings/sqs.py similarity index 100% rename from faststream/broker/specification/bindings/sqs.py rename to faststream/specification/bindings/sqs.py diff --git a/faststream/broker/specification/channel.py b/faststream/specification/channel.py similarity index 83% rename from faststream/broker/specification/channel.py rename to faststream/specification/channel.py index abe3d1f79e..54976da55e 100644 --- a/faststream/broker/specification/channel.py +++ b/faststream/specification/channel.py @@ -1,8 +1,8 @@ from dataclasses import dataclass from typing import List, Optional -from faststream.broker.specification.bindings import ChannelBinding -from faststream.broker.specification.operation import Operation +from faststream.specification.bindings import ChannelBinding +from faststream.specification.operation import Operation @dataclass diff --git a/faststream/broker/specification/docs.py b/faststream/specification/docs.py similarity index 100% rename from faststream/broker/specification/docs.py rename to faststream/specification/docs.py diff --git a/faststream/broker/specification/message.py b/faststream/specification/message.py similarity index 92% rename from faststream/broker/specification/message.py rename to faststream/specification/message.py index c2c5560743..fc00da98b4 100644 --- a/faststream/broker/specification/message.py +++ b/faststream/specification/message.py @@ -1,8 +1,8 @@ from dataclasses import dataclass from typing import Any, Dict, List, Optional, Union -from faststream.broker.specification.docs import ExternalDocs -from faststream.broker.specification.tag import Tag +from faststream.specification.docs import ExternalDocs +from faststream.specification.tag import Tag @dataclass diff --git a/faststream/broker/specification/operation.py b/faststream/specification/operation.py similarity index 78% rename from faststream/broker/specification/operation.py rename to faststream/specification/operation.py index 381178eddb..85e219caa7 100644 --- a/faststream/broker/specification/operation.py +++ b/faststream/specification/operation.py @@ -1,10 +1,10 @@ from dataclasses import dataclass from typing import Any, Dict, List, Optional, Union -from faststream.broker.specification.bindings import OperationBinding -from faststream.broker.specification.docs import ExternalDocs, ExternalDocsDict -from faststream.broker.specification.message import Message -from faststream.broker.specification.tag import Tag, TagDict +from faststream.specification.bindings import OperationBinding +from faststream.specification.docs import ExternalDocs, ExternalDocsDict +from faststream.specification.message import Message +from faststream.specification.tag import Tag, TagDict @dataclass diff --git a/faststream/broker/specification/tag.py b/faststream/specification/tag.py similarity index 91% rename from faststream/broker/specification/tag.py rename to faststream/specification/tag.py index 22e723f583..163aff1cfc 100644 --- a/faststream/broker/specification/tag.py +++ b/faststream/specification/tag.py @@ -3,7 +3,7 @@ from typing_extensions import Required, TypedDict -from faststream.broker.specification.docs import ExternalDocs, ExternalDocsDict +from faststream.specification.docs import ExternalDocs, ExternalDocsDict class TagDict(TypedDict, total=False): diff --git a/tests/asyncapi/confluent/v2_6_0/test_connection.py b/tests/asyncapi/confluent/v2_6_0/test_connection.py index 4c2f10a3f4..49b7a61690 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_connection.py +++ b/tests/asyncapi/confluent/v2_6_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.broker.specification.tag import Tag +from faststream.specification.tag import Tag from faststream.confluent import KafkaBroker diff --git a/tests/asyncapi/confluent/v3_0_0/test_connection.py b/tests/asyncapi/confluent/v3_0_0/test_connection.py index 85007336e1..9317fb7118 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_connection.py +++ b/tests/asyncapi/confluent/v3_0_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.broker.specification.tag import Tag +from faststream.specification.tag import Tag from faststream.asyncapi.version import AsyncAPIVersion from faststream.confluent import KafkaBroker diff --git a/tests/asyncapi/kafka/v2_6_0/test_app.py b/tests/asyncapi/kafka/v2_6_0/test_app.py index 9c0f33a285..56472eea9d 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_app.py +++ b/tests/asyncapi/kafka/v2_6_0/test_app.py @@ -1,8 +1,8 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema from faststream.asyncapi.v2_6_0.schema.info import License, Contact -from faststream.broker.specification.tag import Tag -from faststream.broker.specification.docs import ExternalDocs +from faststream.specification.tag import Tag +from faststream.specification.docs import ExternalDocs from faststream.kafka import KafkaBroker diff --git a/tests/asyncapi/kafka/v2_6_0/test_connection.py b/tests/asyncapi/kafka/v2_6_0/test_connection.py index d238529e04..e5f47d0a82 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_connection.py +++ b/tests/asyncapi/kafka/v2_6_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.broker.specification.tag import Tag +from faststream.specification.tag import Tag from faststream.kafka import KafkaBroker diff --git a/tests/asyncapi/kafka/v3_0_0/test_connection.py b/tests/asyncapi/kafka/v3_0_0/test_connection.py index 667ec9947c..bd6ffdb3ce 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_connection.py +++ b/tests/asyncapi/kafka/v3_0_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.broker.specification.tag import Tag +from faststream.specification.tag import Tag from faststream.asyncapi.version import AsyncAPIVersion from faststream.kafka import KafkaBroker diff --git a/tests/asyncapi/nats/v2_6_0/test_connection.py b/tests/asyncapi/nats/v2_6_0/test_connection.py index 4ac0232e99..f7b83903ed 100644 --- a/tests/asyncapi/nats/v2_6_0/test_connection.py +++ b/tests/asyncapi/nats/v2_6_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.broker.specification.tag import Tag +from faststream.specification.tag import Tag from faststream.nats import NatsBroker diff --git a/tests/asyncapi/nats/v3_0_0/test_connection.py b/tests/asyncapi/nats/v3_0_0/test_connection.py index d79014334a..aa8314ad2f 100644 --- a/tests/asyncapi/nats/v3_0_0/test_connection.py +++ b/tests/asyncapi/nats/v3_0_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.broker.specification.tag import Tag +from faststream.specification.tag import Tag from faststream.asyncapi.version import AsyncAPIVersion from faststream.nats import NatsBroker diff --git a/tests/asyncapi/rabbit/v2_6_0/test_connection.py b/tests/asyncapi/rabbit/v2_6_0/test_connection.py index 0ad747f1a1..36f4d8f16c 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_connection.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.broker.specification.tag import Tag +from faststream.specification.tag import Tag from faststream.rabbit import RabbitBroker diff --git a/tests/asyncapi/rabbit/v3_0_0/test_connection.py b/tests/asyncapi/rabbit/v3_0_0/test_connection.py index eb1bf2f260..5fefaca3c4 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_connection.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.broker.specification.tag import Tag +from faststream.specification.tag import Tag from faststream.asyncapi.version import AsyncAPIVersion from faststream.rabbit import RabbitBroker diff --git a/tests/asyncapi/redis/v2_6_0/test_connection.py b/tests/asyncapi/redis/v2_6_0/test_connection.py index a3331f6bc7..3ed3bec345 100644 --- a/tests/asyncapi/redis/v2_6_0/test_connection.py +++ b/tests/asyncapi/redis/v2_6_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.broker.specification.tag import Tag +from faststream.specification.tag import Tag from faststream.redis import RedisBroker diff --git a/tests/asyncapi/redis/v3_0_0/test_connection.py b/tests/asyncapi/redis/v3_0_0/test_connection.py index eba4b5bbc5..e10f27920e 100644 --- a/tests/asyncapi/redis/v3_0_0/test_connection.py +++ b/tests/asyncapi/redis/v3_0_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.broker.specification.tag import Tag +from faststream.specification.tag import Tag from faststream.asyncapi.version import AsyncAPIVersion from faststream.redis import RedisBroker From 238ddc49950b11e3b625c602b6dad211a864dbc2 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 11 Aug 2024 16:35:14 +0300 Subject: [PATCH 066/245] lint.sh satisfied --- faststream/specification/__init__.py | 7 +-- tests/asyncapi/base/v3_0_0/arguments.py | 2 +- tests/asyncapi/base/v3_0_0/publisher.py | 2 +- .../confluent/v2_6_0/test_connection.py | 2 +- .../confluent/v3_0_0/test_connection.py | 2 +- .../asyncapi/confluent/v3_0_0/test_fastapi.py | 1 - tests/asyncapi/kafka/v2_6_0/test_app.py | 7 ++- .../asyncapi/kafka/v2_6_0/test_connection.py | 2 +- .../asyncapi/kafka/v3_0_0/test_connection.py | 2 +- tests/asyncapi/kafka/v3_0_0/test_fastapi.py | 1 - tests/asyncapi/nats/v2_6_0/test_connection.py | 2 +- tests/asyncapi/nats/v3_0_0/test_connection.py | 2 +- tests/asyncapi/nats/v3_0_0/test_fastapi.py | 1 - .../asyncapi/rabbit/v2_6_0/test_connection.py | 2 +- .../asyncapi/rabbit/v3_0_0/test_connection.py | 44 +++++++++---------- tests/asyncapi/rabbit/v3_0_0/test_naming.py | 24 +++++----- .../asyncapi/rabbit/v3_0_0/test_publisher.py | 12 ++--- .../asyncapi/redis/v2_6_0/test_connection.py | 2 +- .../asyncapi/redis/v3_0_0/test_connection.py | 2 +- 19 files changed, 55 insertions(+), 64 deletions(-) diff --git a/faststream/specification/__init__.py b/faststream/specification/__init__.py index 3a92ffdba8..164a74ca70 100644 --- a/faststream/specification/__init__.py +++ b/faststream/specification/__init__.py @@ -1,9 +1,4 @@ -from . import bindings -from . import channel -from . import docs -from . import message -from . import operation -from . import tag +from . import bindings, channel, docs, message, operation, tag __all__ = ( "bindings", diff --git a/tests/asyncapi/base/v3_0_0/arguments.py b/tests/asyncapi/base/v3_0_0/arguments.py index c41e13f7db..8f94a9a622 100644 --- a/tests/asyncapi/base/v3_0_0/arguments.py +++ b/tests/asyncapi/base/v3_0_0/arguments.py @@ -1,7 +1,7 @@ import json from dataclasses import dataclass from enum import Enum -from typing import Optional, Union, Callable +from typing import Callable, Optional, Union import pydantic from dirty_equals import IsDict, IsPartialDict, IsStr diff --git a/tests/asyncapi/base/v3_0_0/publisher.py b/tests/asyncapi/base/v3_0_0/publisher.py index 2dad4f6c97..dc3086915b 100644 --- a/tests/asyncapi/base/v3_0_0/publisher.py +++ b/tests/asyncapi/base/v3_0_0/publisher.py @@ -1,4 +1,4 @@ -from typing import Type, Callable, Union +from typing import Callable, Union import pydantic diff --git a/tests/asyncapi/confluent/v2_6_0/test_connection.py b/tests/asyncapi/confluent/v2_6_0/test_connection.py index 49b7a61690..b2aad0a080 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_connection.py +++ b/tests/asyncapi/confluent/v2_6_0/test_connection.py @@ -1,7 +1,7 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.specification.tag import Tag from faststream.confluent import KafkaBroker +from faststream.specification.tag import Tag def test_base(): diff --git a/tests/asyncapi/confluent/v3_0_0/test_connection.py b/tests/asyncapi/confluent/v3_0_0/test_connection.py index 9317fb7118..f97aa8dcd1 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_connection.py +++ b/tests/asyncapi/confluent/v3_0_0/test_connection.py @@ -1,8 +1,8 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.specification.tag import Tag from faststream.asyncapi.version import AsyncAPIVersion from faststream.confluent import KafkaBroker +from faststream.specification.tag import Tag def test_base(): diff --git a/tests/asyncapi/confluent/v3_0_0/test_fastapi.py b/tests/asyncapi/confluent/v3_0_0/test_fastapi.py index 7afb3c6b99..2d08ca4917 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/confluent/v3_0_0/test_fastapi.py @@ -1,4 +1,3 @@ -from typing import Type from faststream.asyncapi.generate import get_app_schema from faststream.asyncapi.version import AsyncAPIVersion diff --git a/tests/asyncapi/kafka/v2_6_0/test_app.py b/tests/asyncapi/kafka/v2_6_0/test_app.py index 56472eea9d..e848624c37 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_app.py +++ b/tests/asyncapi/kafka/v2_6_0/test_app.py @@ -1,10 +1,9 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.v2_6_0.schema.info import License, Contact -from faststream.specification.tag import Tag -from faststream.specification.docs import ExternalDocs - +from faststream.asyncapi.v2_6_0.schema.info import Contact, License from faststream.kafka import KafkaBroker +from faststream.specification.docs import ExternalDocs +from faststream.specification.tag import Tag def test_base(): diff --git a/tests/asyncapi/kafka/v2_6_0/test_connection.py b/tests/asyncapi/kafka/v2_6_0/test_connection.py index e5f47d0a82..8e67a19d63 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_connection.py +++ b/tests/asyncapi/kafka/v2_6_0/test_connection.py @@ -1,7 +1,7 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.specification.tag import Tag from faststream.kafka import KafkaBroker +from faststream.specification.tag import Tag def test_base(): diff --git a/tests/asyncapi/kafka/v3_0_0/test_connection.py b/tests/asyncapi/kafka/v3_0_0/test_connection.py index bd6ffdb3ce..da20f08b66 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_connection.py +++ b/tests/asyncapi/kafka/v3_0_0/test_connection.py @@ -1,8 +1,8 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.specification.tag import Tag from faststream.asyncapi.version import AsyncAPIVersion from faststream.kafka import KafkaBroker +from faststream.specification.tag import Tag def test_base(): diff --git a/tests/asyncapi/kafka/v3_0_0/test_fastapi.py b/tests/asyncapi/kafka/v3_0_0/test_fastapi.py index 1a2d619799..21cbb41e72 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/kafka/v3_0_0/test_fastapi.py @@ -1,4 +1,3 @@ -from typing import Type from faststream.asyncapi.generate import get_app_schema from faststream.asyncapi.version import AsyncAPIVersion diff --git a/tests/asyncapi/nats/v2_6_0/test_connection.py b/tests/asyncapi/nats/v2_6_0/test_connection.py index f7b83903ed..641f3bae22 100644 --- a/tests/asyncapi/nats/v2_6_0/test_connection.py +++ b/tests/asyncapi/nats/v2_6_0/test_connection.py @@ -1,7 +1,7 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.specification.tag import Tag from faststream.nats import NatsBroker +from faststream.specification.tag import Tag def test_base(): diff --git a/tests/asyncapi/nats/v3_0_0/test_connection.py b/tests/asyncapi/nats/v3_0_0/test_connection.py index aa8314ad2f..44130a2ac9 100644 --- a/tests/asyncapi/nats/v3_0_0/test_connection.py +++ b/tests/asyncapi/nats/v3_0_0/test_connection.py @@ -1,8 +1,8 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.specification.tag import Tag from faststream.asyncapi.version import AsyncAPIVersion from faststream.nats import NatsBroker +from faststream.specification.tag import Tag def test_base(): diff --git a/tests/asyncapi/nats/v3_0_0/test_fastapi.py b/tests/asyncapi/nats/v3_0_0/test_fastapi.py index badc37b44a..2c397f0dc9 100644 --- a/tests/asyncapi/nats/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/nats/v3_0_0/test_fastapi.py @@ -1,4 +1,3 @@ -from typing import Type from faststream.asyncapi.version import AsyncAPIVersion from faststream.nats import TestNatsBroker diff --git a/tests/asyncapi/rabbit/v2_6_0/test_connection.py b/tests/asyncapi/rabbit/v2_6_0/test_connection.py index 36f4d8f16c..4512ea42ce 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_connection.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_connection.py @@ -1,7 +1,7 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.specification.tag import Tag from faststream.rabbit import RabbitBroker +from faststream.specification.tag import Tag def test_base(): diff --git a/tests/asyncapi/rabbit/v3_0_0/test_connection.py b/tests/asyncapi/rabbit/v3_0_0/test_connection.py index 5fefaca3c4..42bf1e2ce5 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_connection.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_connection.py @@ -1,8 +1,8 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.specification.tag import Tag from faststream.asyncapi.version import AsyncAPIVersion from faststream.rabbit import RabbitBroker +from faststream.specification.tag import Tag def test_base(): @@ -66,7 +66,7 @@ def test_custom(): "asyncapi": "3.0.0", "channels": { "test:_:Publisher": { - 'address': 'test:_:Publisher', + "address": "test:_:Publisher", "bindings": { "amqp": { "bindingVersion": "0.2.0", @@ -83,34 +83,34 @@ def test_custom(): }, "servers": [ { - '$ref': '#/servers/development', + "$ref": "#/servers/development", } ], - 'messages': { - 'Message': { - '$ref': '#/components/messages/test:_:Publisher:Message', + "messages": { + "Message": { + "$ref": "#/components/messages/test:_:Publisher:Message", }, } } }, - 'operations': { - 'test:_:Publisher': { - 'action': 'send', - 'bindings': { - 'amqp': { - 'ack': True, - 'bindingVersion': '0.2.0', - 'cc': 'test', - 'deliveryMode': 1, - 'mandatory': True, + "operations": { + "test:_:Publisher": { + "action": "send", + "bindings": { + "amqp": { + "ack": True, + "bindingVersion": "0.2.0", + "cc": "test", + "deliveryMode": 1, + "mandatory": True, }, }, - 'channel': { - '$ref': '#/channels/test:_:Publisher', + "channel": { + "$ref": "#/channels/test:_:Publisher", }, - 'messages': [ + "messages": [ { - '$ref': '#/channels/test:_:Publisher/messages/Message', + "$ref": "#/channels/test:_:Publisher/messages/Message", }, ], }, @@ -122,12 +122,12 @@ def test_custom(): "location": "$message.header#/correlation_id" }, "payload": { - '$ref': '#/components/schemas/test:_:Publisher:Message:Payload' + "$ref": "#/components/schemas/test:_:Publisher:Message:Payload" }, "title": "test:_:Publisher:Message", } }, - "schemas": {'test:_:Publisher:Message:Payload': {}}, + "schemas": {"test:_:Publisher:Message:Payload": {}}, }, "defaultContentType": "application/json", "info": {"description": "", "title": "FastStream", "version": "0.1.0"}, diff --git a/tests/asyncapi/rabbit/v3_0_0/test_naming.py b/tests/asyncapi/rabbit/v3_0_0/test_naming.py index 611359df71..c124ccd128 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_naming.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_naming.py @@ -89,22 +89,22 @@ async def handle(): ... }, } }, - 'operations': { - 'test:_:HandleSubscribe': { - 'action': 'receive', - 'bindings': { - 'amqp': { - 'ack': True, - 'bindingVersion': '0.2.0', - 'cc': 'test', + "operations": { + "test:_:HandleSubscribe": { + "action": "receive", + "bindings": { + "amqp": { + "ack": True, + "bindingVersion": "0.2.0", + "cc": "test", }, }, - 'channel': { - '$ref': '#/channels/test:_:Handle', + "channel": { + "$ref": "#/channels/test:_:Handle", }, - 'messages': [ + "messages": [ { - '$ref': '#/channels/test:_:Handle/messages/SubscribeMessage', + "$ref": "#/channels/test:_:Handle/messages/SubscribeMessage", }, ], }, diff --git a/tests/asyncapi/rabbit/v3_0_0/test_publisher.py b/tests/asyncapi/rabbit/v3_0_0/test_publisher.py index 4c9e94f99e..f9b24c1e54 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_publisher.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_publisher.py @@ -182,9 +182,9 @@ async def handle(msg): ... "$ref": "#/servers/development", } ], - 'messages': { - 'Message': { - '$ref': '#/components/messages/key1:test-ex:Publisher:Message', + "messages": { + "Message": { + "$ref": "#/components/messages/key1:test-ex:Publisher:Message", }, }, @@ -209,9 +209,9 @@ async def handle(msg): ... "$ref": "#/servers/development", } ], - 'messages': { - 'Message': { - '$ref': '#/components/messages/key2:test-ex:Publisher:Message', + "messages": { + "Message": { + "$ref": "#/components/messages/key2:test-ex:Publisher:Message", }, }, }, diff --git a/tests/asyncapi/redis/v2_6_0/test_connection.py b/tests/asyncapi/redis/v2_6_0/test_connection.py index 3ed3bec345..dcd5f9c100 100644 --- a/tests/asyncapi/redis/v2_6_0/test_connection.py +++ b/tests/asyncapi/redis/v2_6_0/test_connection.py @@ -1,7 +1,7 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.specification.tag import Tag from faststream.redis import RedisBroker +from faststream.specification.tag import Tag def test_base(): diff --git a/tests/asyncapi/redis/v3_0_0/test_connection.py b/tests/asyncapi/redis/v3_0_0/test_connection.py index e10f27920e..b77b7dda70 100644 --- a/tests/asyncapi/redis/v3_0_0/test_connection.py +++ b/tests/asyncapi/redis/v3_0_0/test_connection.py @@ -1,8 +1,8 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema -from faststream.specification.tag import Tag from faststream.asyncapi.version import AsyncAPIVersion from faststream.redis import RedisBroker +from faststream.specification.tag import Tag def test_base(): From 6056ff5707db8453f6929bae4aaeb3c534e45820 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 11 Aug 2024 19:28:56 +0300 Subject: [PATCH 067/245] Merge conflict fix --- faststream/asyncapi/generate.py | 5 ++--- faststream/asyncapi/proto.py | 18 +++++++----------- faststream/asyncapi/v2_6_0/generate.py | 10 ++++------ faststream/asyncapi/v3_0_0/generate.py | 10 ++++------ 4 files changed, 17 insertions(+), 26 deletions(-) diff --git a/faststream/asyncapi/generate.py b/faststream/asyncapi/generate.py index 75e934960a..9550ca0732 100644 --- a/faststream/asyncapi/generate.py +++ b/faststream/asyncapi/generate.py @@ -1,6 +1,5 @@ -from faststream.asyncapi.schema import ( - BaseSchema, -) +from faststream.asyncapi.base import BaseSchema +from faststream.asyncapi.proto import AsyncAPIApplication from faststream.asyncapi.v2_6_0.generate import get_app_schema as get_app_schema_v2_6 from faststream.asyncapi.v3_0_0.generate import get_app_schema as get_app_schema_v3 from faststream.asyncapi.version import AsyncAPIVersion diff --git a/faststream/asyncapi/proto.py b/faststream/asyncapi/proto.py index a1c9bcc05b..f1a6d9ad29 100644 --- a/faststream/asyncapi/proto.py +++ b/faststream/asyncapi/proto.py @@ -3,18 +3,13 @@ from typing_extensions import Doc, Annotated +from faststream.asyncapi.v2_6_0.schema.info import License, LicenseDict, Contact, ContactDict +from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.docs import ExternalDocs, ExternalDocsDict +from faststream.specification.tag import Tag, TagDict + if TYPE_CHECKING: - from faststream.asyncapi.schema import ( - Contact, - ContactDict, - ExternalDocs, - ExternalDocsDict, - License, - LicenseDict, - Tag, - TagDict, - ) - from faststream.broker.specification.channel import Channel + from faststream.specification.channel import Channel from faststream.broker.core.usecase import BrokerUsecase from faststream.types import ( AnyDict, @@ -33,6 +28,7 @@ class AsyncAPIApplication(Protocol): contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] asyncapi_tags: Optional[Sequence[Union["Tag", "TagDict", "AnyDict"]]] external_docs: Optional[Union["ExternalDocs", "ExternalDocsDict", "AnyDict"]] + asyncapi_version: AsyncAPIVersion identifier: Optional[str] diff --git a/faststream/asyncapi/v2_6_0/generate.py b/faststream/asyncapi/v2_6_0/generate.py index 0d0df0fb57..d42cf9c954 100644 --- a/faststream/asyncapi/v2_6_0/generate.py +++ b/faststream/asyncapi/v2_6_0/generate.py @@ -2,7 +2,8 @@ from typing import TYPE_CHECKING, Any, Dict, List, Union from faststream import specification as spec -from faststream._compat import DEF_KEY, HAS_FASTAPI +from faststream._compat import DEF_KEY +from faststream.asyncapi.proto import AsyncAPIApplication from faststream.asyncapi.v2_6_0.schema import ( Channel, Components, @@ -28,15 +29,12 @@ from faststream.constants import ContentTypes if TYPE_CHECKING: - from faststream.app import FastStream + from faststream.asyncapi.proto import AsyncAPIApplication from faststream.broker.core.usecase import BrokerUsecase from faststream.broker.types import ConnectionType, MsgType - if HAS_FASTAPI: - from faststream.broker.fastapi.router import StreamRouter - -def get_app_schema(app: Union["FastStream", "StreamRouter[Any]"]) -> Schema: +def get_app_schema(app: AsyncAPIApplication) -> Schema: """Get the application schema.""" broker = app.broker if broker is None: # pragma: no cover diff --git a/faststream/asyncapi/v3_0_0/generate.py b/faststream/asyncapi/v3_0_0/generate.py index 2f297b3dc2..7e3ee30872 100644 --- a/faststream/asyncapi/v3_0_0/generate.py +++ b/faststream/asyncapi/v3_0_0/generate.py @@ -3,7 +3,8 @@ from urllib.parse import urlparse from faststream import specification as spec -from faststream._compat import DEF_KEY, HAS_FASTAPI +from faststream._compat import DEF_KEY +from faststream.asyncapi.proto import AsyncAPIApplication from faststream.asyncapi.v2_6_0.generate import ( _specs_channel_binding_to_asyncapi, _specs_operation_binding_to_asyncapi, @@ -27,15 +28,12 @@ from faststream.constants import ContentTypes if TYPE_CHECKING: - from faststream.app import FastStream + from faststream.asyncapi.proto import AsyncAPIApplication from faststream.broker.core.usecase import BrokerUsecase from faststream.broker.types import ConnectionType, MsgType - if HAS_FASTAPI: - from faststream.broker.fastapi.router import StreamRouter - -def get_app_schema(app: Union["FastStream", "StreamRouter[Any]"]) -> Schema: +def get_app_schema(app: AsyncAPIApplication) -> Schema: """Get the application schema.""" broker = app.broker if broker is None: # pragma: no cover From 516c7841f8ad455e8e5a75252208141db5eb2992 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 11 Aug 2024 21:56:38 +0300 Subject: [PATCH 068/245] Cycle import fix --- faststream/app.py | 12 +- faststream/asgi/app.py | 12 +- faststream/asyncapi/generate.py | 6 +- faststream/asyncapi/proto.py | 10 +- faststream/asyncapi/v2_6_0/generate.py | 29 +++- faststream/asyncapi/v3_0_0/generate.py | 9 +- faststream/specification/__init__.py | 3 +- faststream/specification/info.py | 183 +++++++++++++++++++++++++ 8 files changed, 241 insertions(+), 23 deletions(-) create mode 100644 faststream/specification/info.py diff --git a/faststream/app.py b/faststream/app.py index 8051554158..fe76930a26 100644 --- a/faststream/app.py +++ b/faststream/app.py @@ -29,17 +29,17 @@ if TYPE_CHECKING: - from faststream.asyncapi.v2_6_0.schema.info import ( - Contact, - ContactDict, - License, - LicenseDict, - ) from faststream.broker.core.usecase import BrokerUsecase from faststream.specification.docs import ( ExternalDocs, ExternalDocsDict, ) + from faststream.specification.info import ( + Contact, + ContactDict, + License, + LicenseDict, + ) from faststream.specification.tag import ( Tag, TagDict, diff --git a/faststream/asgi/app.py b/faststream/asgi/app.py index c91a4e0517..b2bff09d36 100644 --- a/faststream/asgi/app.py +++ b/faststream/asgi/app.py @@ -20,17 +20,21 @@ if TYPE_CHECKING: from faststream.asgi.types import ASGIApp, Receive, Scope, Send - from faststream.asyncapi.schema import ( - Contact, - ContactDict, + from faststream.broker.core.usecase import BrokerUsecase + from faststream.specification.docs import ( ExternalDocs, ExternalDocsDict, + ) + from faststream.specification.info import ( + Contact, + ContactDict, License, LicenseDict, + ) + from faststream.specification.tag import ( Tag, TagDict, ) - from faststream.broker.core.usecase import BrokerUsecase from faststream.types import ( AnyCallable, AnyDict, diff --git a/faststream/asyncapi/generate.py b/faststream/asyncapi/generate.py index 9550ca0732..8ed43a360d 100644 --- a/faststream/asyncapi/generate.py +++ b/faststream/asyncapi/generate.py @@ -1,9 +1,13 @@ +from typing import TYPE_CHECKING + from faststream.asyncapi.base import BaseSchema -from faststream.asyncapi.proto import AsyncAPIApplication from faststream.asyncapi.v2_6_0.generate import get_app_schema as get_app_schema_v2_6 from faststream.asyncapi.v3_0_0.generate import get_app_schema as get_app_schema_v3 from faststream.asyncapi.version import AsyncAPIVersion +if TYPE_CHECKING: + from faststream.asyncapi.proto import AsyncAPIApplication + def get_app_schema(app: "AsyncAPIApplication") -> BaseSchema: if app.asyncapi_version == AsyncAPIVersion.v3_0: diff --git a/faststream/asyncapi/proto.py b/faststream/asyncapi/proto.py index f1a6d9ad29..27b5c5bec1 100644 --- a/faststream/asyncapi/proto.py +++ b/faststream/asyncapi/proto.py @@ -1,16 +1,16 @@ from abc import abstractmethod from typing import TYPE_CHECKING, Any, Dict, Optional, Protocol, Sequence, Union -from typing_extensions import Doc, Annotated +from typing_extensions import Annotated, Doc -from faststream.asyncapi.v2_6_0.schema.info import License, LicenseDict, Contact, ContactDict from faststream.asyncapi.version import AsyncAPIVersion -from faststream.specification.docs import ExternalDocs, ExternalDocsDict -from faststream.specification.tag import Tag, TagDict if TYPE_CHECKING: - from faststream.specification.channel import Channel from faststream.broker.core.usecase import BrokerUsecase + from faststream.specification.channel import Channel + from faststream.specification.docs import ExternalDocs, ExternalDocsDict + from faststream.specification.info import Contact, ContactDict, License, LicenseDict + from faststream.specification.tag import Tag, TagDict from faststream.types import ( AnyDict, AnyHttpUrl, diff --git a/faststream/asyncapi/v2_6_0/generate.py b/faststream/asyncapi/v2_6_0/generate.py index d42cf9c954..42a7cf4c01 100644 --- a/faststream/asyncapi/v2_6_0/generate.py +++ b/faststream/asyncapi/v2_6_0/generate.py @@ -7,8 +7,10 @@ from faststream.asyncapi.v2_6_0.schema import ( Channel, Components, + Contact, ExternalDocs, Info, + License, Operation, Reference, Schema, @@ -29,9 +31,9 @@ from faststream.constants import ContentTypes if TYPE_CHECKING: - from faststream.asyncapi.proto import AsyncAPIApplication from faststream.broker.core.usecase import BrokerUsecase from faststream.broker.types import ConnectionType, MsgType + from faststream.types import AnyDict def get_app_schema(app: AsyncAPIApplication) -> Schema: @@ -77,8 +79,10 @@ def get_app_schema(app: AsyncAPIApplication) -> Schema: version=app.version, description=app.description, termsOfService=app.terms_of_service, - contact=app.contact, - license=app.license, + contact=_specs_contact_to_asyncapi(app.contact) + if app.contact else None, + license=_specs_license_to_asyncapi(app.license) + if app.license else None, ), defaultContentType=ContentTypes.json.value, id=app.identifier, @@ -172,6 +176,25 @@ def get_broker_channels( return channels +def _specs_contact_to_asyncapi( + contact: Union["spec.info.Contact", "spec.info.ContactDict", "AnyDict"] +) -> Union["Contact", "AnyDict"]: + if isinstance(contact, spec.info.Contact): + return Contact(**contact.dict()) + + return dict(contact) + + +def _specs_license_to_asyncapi( + license: Union["spec.info.License", "spec.info.LicenseDict", "AnyDict"] +) -> Union["License", "AnyDict"]: + if isinstance(license, spec.info.License): + return License(**license.dict()) + + return dict(license) + + + def _specs_channel_to_asyncapi(channel: spec.channel.Channel) -> Channel: return Channel( description=channel.description, diff --git a/faststream/asyncapi/v3_0_0/generate.py b/faststream/asyncapi/v3_0_0/generate.py index 7e3ee30872..e6000e67ff 100644 --- a/faststream/asyncapi/v3_0_0/generate.py +++ b/faststream/asyncapi/v3_0_0/generate.py @@ -7,6 +7,8 @@ from faststream.asyncapi.proto import AsyncAPIApplication from faststream.asyncapi.v2_6_0.generate import ( _specs_channel_binding_to_asyncapi, + _specs_contact_to_asyncapi, + _specs_license_to_asyncapi, _specs_operation_binding_to_asyncapi, _specs_tags_to_asyncapi, ) @@ -28,7 +30,6 @@ from faststream.constants import ContentTypes if TYPE_CHECKING: - from faststream.asyncapi.proto import AsyncAPIApplication from faststream.broker.core.usecase import BrokerUsecase from faststream.broker.types import ConnectionType, MsgType @@ -70,8 +71,10 @@ def get_app_schema(app: AsyncAPIApplication) -> Schema: version=app.version, description=app.description, termsOfService=app.terms_of_service, - contact=app.contact, - license=app.license, + contact=_specs_contact_to_asyncapi(app.contact) + if app.contact else None, + license=_specs_license_to_asyncapi(app.license) + if app.license else None, tags=_specs_tags_to_asyncapi(list(app.asyncapi_tags)) if app.asyncapi_tags else None, externalDocs=_specs_external_docs_to_asyncapi(app.external_docs) if app.external_docs else None, ), diff --git a/faststream/specification/__init__.py b/faststream/specification/__init__.py index 164a74ca70..c04be659df 100644 --- a/faststream/specification/__init__.py +++ b/faststream/specification/__init__.py @@ -1,4 +1,4 @@ -from . import bindings, channel, docs, message, operation, tag +from . import bindings, channel, docs, message, operation, tag, info __all__ = ( "bindings", @@ -7,4 +7,5 @@ "message", "operation", "tag", + "info", ) diff --git a/faststream/specification/info.py b/faststream/specification/info.py new file mode 100644 index 0000000000..e3219176fd --- /dev/null +++ b/faststream/specification/info.py @@ -0,0 +1,183 @@ +from typing import ( + Any, + Callable, + Dict, + Iterable, + Optional, + Type, + Union, +) + +from pydantic import AnyHttpUrl, BaseModel +from typing_extensions import Required, TypedDict + +from faststream._compat import ( + PYDANTIC_V2, + CoreSchema, + GetJsonSchemaHandler, + JsonSchemaValue, + with_info_plain_validator_function, +) +from faststream.asyncapi.base import BaseInfo +from faststream.log import logger + +try: + import email_validator + + if email_validator is None: + raise ImportError + from pydantic import EmailStr + +except ImportError: # pragma: no cover + # NOTE: EmailStr mock was copied from the FastAPI + # https://github.com/tiangolo/fastapi/blob/master/fastapi/openapi/models.py#24 + class EmailStr(str): # type: ignore + """EmailStr is a string that should be an email. + + Note: EmailStr mock was copied from the FastAPI: + https://github.com/tiangolo/fastapi/blob/master/fastapi/openapi/models.py#24 + + """ + + @classmethod + def __get_validators__(cls) -> Iterable[Callable[..., Any]]: + """Returns the validators for the EmailStr class.""" + yield cls.validate + + @classmethod + def validate(cls, v: Any) -> str: + """Validates the EmailStr class.""" + logger.warning( + "email-validator bot installed, email fields will be treated as str.\n" + "To install, run: pip install email-validator" + ) + return str(v) + + @classmethod + def _validate(cls, __input_value: Any, _: Any) -> str: + logger.warning( + "email-validator bot installed, email fields will be treated as str.\n" + "To install, run: pip install email-validator" + ) + return str(__input_value) + + @classmethod + def __get_pydantic_json_schema__( + cls, + core_schema: CoreSchema, + handler: GetJsonSchemaHandler, + ) -> JsonSchemaValue: + """Returns the JSON schema for the EmailStr class. + + Args: + core_schema : the core schema + handler : the handler + """ + return {"type": "string", "format": "email"} + + @classmethod + def __get_pydantic_core_schema__( + cls, + source: Type[Any], + handler: Callable[[Any], CoreSchema], + ) -> JsonSchemaValue: + """Returns the core schema for the EmailStr class. + + Args: + source : the source + handler : the handler + """ + return with_info_plain_validator_function(cls._validate) # type: ignore[no-any-return] + + +class ContactDict(TypedDict, total=False): + """A class to represent a dictionary of contact information. + + Attributes: + name : required name of the contact (type: str) + url : URL of the contact (type: AnyHttpUrl) + email : email address of the contact (type: EmailStr) + + """ + + name: Required[str] + url: AnyHttpUrl + email: EmailStr + + +class Contact(BaseModel): + """A class to represent a contact. + + Attributes: + name : name of the contact (str) + url : URL of the contact (Optional[AnyHttpUrl]) + email : email of the contact (Optional[EmailStr]) + + """ + + name: str + url: Optional[AnyHttpUrl] = None + email: Optional[EmailStr] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" + + +class LicenseDict(TypedDict, total=False): + """A dictionary-like class to represent a license. + + Attributes: + name : required name of the license (type: str) + url : URL of the license (type: AnyHttpUrl) + + """ + + name: Required[str] + url: AnyHttpUrl + + +class License(BaseModel): + """A class to represent a license. + + Attributes: + name : name of the license + url : URL of the license (optional) + + Config: + extra : allow additional attributes in the model (PYDANTIC_V2) + + """ + + name: str + url: Optional[AnyHttpUrl] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" + + +class Info(BaseInfo): + """A class to represent information. + + Attributes: + title : title of the information + version : version of the information (default: "1.0.0") + description : description of the information (default: "") + termsOfService : terms of service for the information (default: None) + contact : contact information for the information (default: None) + license : license information for the information (default: None) + + """ + + termsOfService: Optional[AnyHttpUrl] = None + contact: Optional[Union[Contact, ContactDict, Dict[str, Any]]] = None + license: Optional[Union[License, LicenseDict, Dict[str, Any]]] = None From e324fb1afb4ae5c9ed21b9e505a9b992b3fd3d7e Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Tue, 13 Aug 2024 21:37:26 +0300 Subject: [PATCH 069/245] asyncapi base restructuring --- faststream/asyncapi/base/__init__.py | 6 +-- faststream/asyncapi/base/schema/__init__.py | 7 +++ faststream/asyncapi/base/{ => schema}/info.py | 0 .../asyncapi/base/{ => schema}/schema.py | 2 +- faststream/asyncapi/generate.py | 2 +- faststream/asyncapi/site.py | 2 +- faststream/asyncapi/v2_6_0/generate.py | 46 +++++++++---------- faststream/asyncapi/v2_6_0/schema/__init__.py | 4 -- faststream/asyncapi/v2_6_0/schema/info.py | 2 +- faststream/asyncapi/v2_6_0/schema/schema.py | 2 +- faststream/asyncapi/v3_0_0/generate.py | 36 +++++++-------- faststream/asyncapi/v3_0_0/schema/info.py | 2 +- faststream/asyncapi/v3_0_0/schema/schema.py | 2 +- faststream/specification/info.py | 2 +- .../schema => specification}/security.py | 0 15 files changed, 58 insertions(+), 57 deletions(-) create mode 100644 faststream/asyncapi/base/schema/__init__.py rename faststream/asyncapi/base/{ => schema}/info.py (100%) rename faststream/asyncapi/base/{ => schema}/schema.py (95%) rename faststream/{asyncapi/v2_6_0/schema => specification}/security.py (100%) diff --git a/faststream/asyncapi/base/__init__.py b/faststream/asyncapi/base/__init__.py index 9164dc3039..f9bfcf6e90 100644 --- a/faststream/asyncapi/base/__init__.py +++ b/faststream/asyncapi/base/__init__.py @@ -1,7 +1,5 @@ -from .info import BaseInfo -from .schema import BaseSchema +from faststream.asyncapi.base import schema __all__ = ( - "BaseInfo", - "BaseSchema", + "schema", ) diff --git a/faststream/asyncapi/base/schema/__init__.py b/faststream/asyncapi/base/schema/__init__.py new file mode 100644 index 0000000000..f8befed431 --- /dev/null +++ b/faststream/asyncapi/base/schema/__init__.py @@ -0,0 +1,7 @@ +from .schema import BaseSchema +from .info import BaseInfo + +__all__ = ( + "BaseSchema", + "BaseInfo", +) diff --git a/faststream/asyncapi/base/info.py b/faststream/asyncapi/base/schema/info.py similarity index 100% rename from faststream/asyncapi/base/info.py rename to faststream/asyncapi/base/schema/info.py diff --git a/faststream/asyncapi/base/schema.py b/faststream/asyncapi/base/schema/schema.py similarity index 95% rename from faststream/asyncapi/base/schema.py rename to faststream/asyncapi/base/schema/schema.py index 4584ef5092..4ca186972a 100644 --- a/faststream/asyncapi/base/schema.py +++ b/faststream/asyncapi/base/schema/schema.py @@ -3,7 +3,7 @@ from pydantic import BaseModel from faststream._compat import model_to_json, model_to_jsonable -from faststream.asyncapi.base.info import BaseInfo +from faststream.asyncapi.base.schema.info import BaseInfo class BaseSchema(BaseModel): diff --git a/faststream/asyncapi/generate.py b/faststream/asyncapi/generate.py index 8ed43a360d..79e8ced960 100644 --- a/faststream/asyncapi/generate.py +++ b/faststream/asyncapi/generate.py @@ -1,6 +1,6 @@ from typing import TYPE_CHECKING -from faststream.asyncapi.base import BaseSchema +from faststream.asyncapi.base.schema import BaseSchema from faststream.asyncapi.v2_6_0.generate import get_app_schema as get_app_schema_v2_6 from faststream.asyncapi.v3_0_0.generate import get_app_schema as get_app_schema_v3 from faststream.asyncapi.version import AsyncAPIVersion diff --git a/faststream/asyncapi/site.py b/faststream/asyncapi/site.py index 8afaedbd9c..9e4a76e816 100644 --- a/faststream/asyncapi/site.py +++ b/faststream/asyncapi/site.py @@ -7,7 +7,7 @@ from faststream.log import logger if TYPE_CHECKING: - from faststream.asyncapi.schema import BaseSchema + from faststream.asyncapi.base.schema import BaseSchema ASYNCAPI_JS_DEFAULT_URL = "https://unpkg.com/@asyncapi/react-component@1.0.0-next.54/browser/standalone/index.js" diff --git a/faststream/asyncapi/v2_6_0/generate.py b/faststream/asyncapi/v2_6_0/generate.py index 42a7cf4c01..f4199b04ee 100644 --- a/faststream/asyncapi/v2_6_0/generate.py +++ b/faststream/asyncapi/v2_6_0/generate.py @@ -79,15 +79,15 @@ def get_app_schema(app: AsyncAPIApplication) -> Schema: version=app.version, description=app.description, termsOfService=app.terms_of_service, - contact=_specs_contact_to_asyncapi(app.contact) + contact=specs_contact_to_asyncapi(app.contact) if app.contact else None, - license=_specs_license_to_asyncapi(app.license) + license=specs_license_to_asyncapi(app.license) if app.license else None, ), defaultContentType=ContentTypes.json.value, id=app.identifier, - tags=_specs_tags_to_asyncapi(list(app.asyncapi_tags)) if app.asyncapi_tags else None, - externalDocs=_specs_external_docs_to_asyncapi(app.external_docs) if app.external_docs else None, + tags=specs_tags_to_asyncapi(list(app.asyncapi_tags)) if app.asyncapi_tags else None, + externalDocs=specs_external_docs_to_asyncapi(app.external_docs) if app.external_docs else None, servers=servers, channels=channels, components=Components( @@ -162,21 +162,21 @@ def get_broker_channels( for h in broker._subscribers.values(): schema = h.schema() channels.update({ - key: _specs_channel_to_asyncapi(channel) + key: specs_channel_to_asyncapi(channel) for key, channel in schema.items() }) for p in broker._publishers.values(): schema = p.schema() channels.update({ - key: _specs_channel_to_asyncapi(channel) + key: specs_channel_to_asyncapi(channel) for key, channel in schema.items() }) return channels -def _specs_contact_to_asyncapi( +def specs_contact_to_asyncapi( contact: Union["spec.info.Contact", "spec.info.ContactDict", "AnyDict"] ) -> Union["Contact", "AnyDict"]: if isinstance(contact, spec.info.Contact): @@ -185,7 +185,7 @@ def _specs_contact_to_asyncapi( return dict(contact) -def _specs_license_to_asyncapi( +def specs_license_to_asyncapi( license: Union["spec.info.License", "spec.info.LicenseDict", "AnyDict"] ) -> Union["License", "AnyDict"]: if isinstance(license, spec.info.License): @@ -195,23 +195,23 @@ def _specs_license_to_asyncapi( -def _specs_channel_to_asyncapi(channel: spec.channel.Channel) -> Channel: +def specs_channel_to_asyncapi(channel: spec.channel.Channel) -> Channel: return Channel( description=channel.description, servers=channel.servers, - bindings=_specs_channel_binding_to_asyncapi(channel.bindings) + bindings=specs_channel_binding_to_asyncapi(channel.bindings) if channel.bindings else None, - subscribe=_specs_operation_to_asyncapi(channel.subscribe) + subscribe=specs_operation_to_asyncapi(channel.subscribe) if channel.subscribe else None, - publish=_specs_operation_to_asyncapi(channel.publish) + publish=specs_operation_to_asyncapi(channel.publish) if channel.publish else None, ) -def _specs_channel_binding_to_asyncapi(binding: spec.bindings.ChannelBinding) -> ChannelBinding: +def specs_channel_binding_to_asyncapi(binding: spec.bindings.ChannelBinding) -> ChannelBinding: return ChannelBinding( amqp=amqp.ChannelBinding(**{ "is": binding.amqp.is_, @@ -252,13 +252,13 @@ def _specs_channel_binding_to_asyncapi(binding: spec.bindings.ChannelBinding) -> ) -def _specs_operation_to_asyncapi(operation: spec.operation.Operation) -> Operation: +def specs_operation_to_asyncapi(operation: spec.operation.Operation) -> Operation: return Operation( operationId=operation.operationId, summary=operation.summary, description=operation.description, - bindings=_specs_operation_binding_to_asyncapi(operation.bindings) + bindings=specs_operation_binding_to_asyncapi(operation.bindings) if operation.bindings else None, message=Message( @@ -274,24 +274,24 @@ def _specs_operation_to_asyncapi(operation: spec.operation.Operation) -> Operati contentType=operation.message.contentType, - tags=_specs_tags_to_asyncapi(operation.tags) + tags=specs_tags_to_asyncapi(operation.tags) if operation.tags else None, - externalDocs=_specs_external_docs_to_asyncapi(operation.externalDocs) + externalDocs=specs_external_docs_to_asyncapi(operation.externalDocs) if operation.externalDocs else None, ), security=operation.security, - tags=_specs_tags_to_asyncapi(operation.tags) + tags=specs_tags_to_asyncapi(operation.tags) if operation.tags else None, - externalDocs=_specs_external_docs_to_asyncapi(operation.externalDocs) + externalDocs=specs_external_docs_to_asyncapi(operation.externalDocs) if operation.externalDocs else None, ) -def _specs_operation_binding_to_asyncapi(binding: spec.bindings.OperationBinding) -> OperationBinding: +def specs_operation_binding_to_asyncapi(binding: spec.bindings.OperationBinding) -> OperationBinding: return OperationBinding( amqp=amqp.OperationBinding(**asdict(binding.amqp)) if binding.amqp else None, @@ -310,7 +310,7 @@ def _specs_operation_binding_to_asyncapi(binding: spec.bindings.OperationBinding ) -def _specs_tags_to_asyncapi( +def specs_tags_to_asyncapi( tags: List[Union[spec.tag.Tag, spec.tag.TagDict, Dict[str, Any]]] ) -> List[Union[Tag, TagDict, Dict[str, Any]]]: asyncapi_tags: List[Union[Tag, TagDict, Dict[str, Any]]] = [] @@ -321,7 +321,7 @@ def _specs_tags_to_asyncapi( name=tag.name, description=tag.description, - externalDocs=_specs_external_docs_to_asyncapi(tag.externalDocs) + externalDocs=specs_external_docs_to_asyncapi(tag.externalDocs) if tag.externalDocs else None, )) elif isinstance(tag, dict): @@ -332,7 +332,7 @@ def _specs_tags_to_asyncapi( return asyncapi_tags -def _specs_external_docs_to_asyncapi( +def specs_external_docs_to_asyncapi( externalDocs: Union[spec.docs.ExternalDocs, spec.docs.ExternalDocsDict, Dict[str, Any]] ) -> Union[ExternalDocs, Dict[str, Any]]: if isinstance(externalDocs, spec.docs.ExternalDocs): diff --git a/faststream/asyncapi/v2_6_0/schema/__init__.py b/faststream/asyncapi/v2_6_0/schema/__init__.py index 846f5c3f88..a43ad3d13e 100644 --- a/faststream/asyncapi/v2_6_0/schema/__init__.py +++ b/faststream/asyncapi/v2_6_0/schema/__init__.py @@ -5,7 +5,6 @@ from .message import CorrelationId, Message from .operations import Operation from .schema import Schema -from .security import OauthFlowObj, OauthFlows, SecuritySchemaComponent from .servers import Server, ServerVariable from .utils import ExternalDocs, ExternalDocsDict, Parameter, Reference, Tag, TagDict @@ -19,9 +18,6 @@ "ContactDict", "Operation", "Schema", - "OauthFlowObj", - "OauthFlows", - "SecuritySchemaComponent", "Server", "ServerVariable", "Message", diff --git a/faststream/asyncapi/v2_6_0/schema/info.py b/faststream/asyncapi/v2_6_0/schema/info.py index e3219176fd..bf282fa762 100644 --- a/faststream/asyncapi/v2_6_0/schema/info.py +++ b/faststream/asyncapi/v2_6_0/schema/info.py @@ -18,7 +18,7 @@ JsonSchemaValue, with_info_plain_validator_function, ) -from faststream.asyncapi.base import BaseInfo +from faststream.asyncapi.base.schema import BaseInfo from faststream.log import logger try: diff --git a/faststream/asyncapi/v2_6_0/schema/schema.py b/faststream/asyncapi/v2_6_0/schema/schema.py index 143ed74288..a473c7543f 100644 --- a/faststream/asyncapi/v2_6_0/schema/schema.py +++ b/faststream/asyncapi/v2_6_0/schema/schema.py @@ -1,7 +1,7 @@ from typing import Any, Dict, List, Optional, Union from faststream._compat import model_to_json, model_to_jsonable -from faststream.asyncapi.base import BaseSchema +from faststream.asyncapi.base.schema import BaseSchema from faststream.asyncapi.v2_6_0.schema.channels import Channel from faststream.asyncapi.v2_6_0.schema.components import Components from faststream.asyncapi.v2_6_0.schema.info import Info diff --git a/faststream/asyncapi/v3_0_0/generate.py b/faststream/asyncapi/v3_0_0/generate.py index e6000e67ff..2353b39b73 100644 --- a/faststream/asyncapi/v3_0_0/generate.py +++ b/faststream/asyncapi/v3_0_0/generate.py @@ -6,11 +6,11 @@ from faststream._compat import DEF_KEY from faststream.asyncapi.proto import AsyncAPIApplication from faststream.asyncapi.v2_6_0.generate import ( - _specs_channel_binding_to_asyncapi, - _specs_contact_to_asyncapi, - _specs_license_to_asyncapi, - _specs_operation_binding_to_asyncapi, - _specs_tags_to_asyncapi, + specs_channel_binding_to_asyncapi, + specs_contact_to_asyncapi, + specs_license_to_asyncapi, + specs_operation_binding_to_asyncapi, + specs_tags_to_asyncapi, ) from faststream.asyncapi.v2_6_0.schema import ( ExternalDocs, @@ -71,12 +71,12 @@ def get_app_schema(app: AsyncAPIApplication) -> Schema: version=app.version, description=app.description, termsOfService=app.terms_of_service, - contact=_specs_contact_to_asyncapi(app.contact) + contact=specs_contact_to_asyncapi(app.contact) if app.contact else None, - license=_specs_license_to_asyncapi(app.license) + license=specs_license_to_asyncapi(app.license) if app.license else None, - tags=_specs_tags_to_asyncapi(list(app.asyncapi_tags)) if app.asyncapi_tags else None, - externalDocs=_specs_external_docs_to_asyncapi(app.external_docs) if app.external_docs else None, + tags=specs_tags_to_asyncapi(list(app.asyncapi_tags)) if app.asyncapi_tags else None, + externalDocs=specs_external_docs_to_asyncapi(app.external_docs) if app.external_docs else None, ), defaultContentType=ContentTypes.json.value, id=app.identifier, @@ -176,7 +176,7 @@ def get_broker_operations( action="receive", summary=specs_channel.subscribe.summary, description=specs_channel.subscribe.description, - bindings=_specs_operation_binding_to_asyncapi(specs_channel.subscribe.bindings) + bindings=specs_operation_binding_to_asyncapi(specs_channel.subscribe.bindings) if specs_channel.subscribe.bindings else None, messages=[ Reference( @@ -197,7 +197,7 @@ def get_broker_operations( action="send", summary=specs_channel.publish.summary, description=specs_channel.publish.description, - bindings=_specs_operation_binding_to_asyncapi(specs_channel.publish.bindings) + bindings=specs_operation_binding_to_asyncapi(specs_channel.publish.bindings) if specs_channel.publish.bindings else None, messages=[ Reference( @@ -240,16 +240,16 @@ def get_broker_channels( contentType=specs_channel.subscribe.message.contentType, - tags=_specs_tags_to_asyncapi(specs_channel.subscribe.message.tags) # type: ignore + tags=specs_tags_to_asyncapi(specs_channel.subscribe.message.tags) # type: ignore if specs_channel.subscribe.message.tags else None, - externalDocs=_specs_external_docs_to_asyncapi(specs_channel.subscribe.message.externalDocs) + externalDocs=specs_external_docs_to_asyncapi(specs_channel.subscribe.message.externalDocs) if specs_channel.subscribe.message.externalDocs else None, ), }, description=specs_channel.description, servers=specs_channel.servers, - bindings=_specs_channel_binding_to_asyncapi(specs_channel.bindings) + bindings=specs_channel_binding_to_asyncapi(specs_channel.bindings) if specs_channel.bindings else None, ) @@ -277,16 +277,16 @@ def get_broker_channels( contentType=specs_channel.publish.message.contentType, - tags=_specs_tags_to_asyncapi(specs_channel.publish.message.tags) # type: ignore + tags=specs_tags_to_asyncapi(specs_channel.publish.message.tags) # type: ignore if specs_channel.publish.message.tags else None, - externalDocs=_specs_external_docs_to_asyncapi(specs_channel.publish.message.externalDocs) + externalDocs=specs_external_docs_to_asyncapi(specs_channel.publish.message.externalDocs) if specs_channel.publish.message.externalDocs else None, ), }, description=specs_channel.description, servers=specs_channel.servers, - bindings=_specs_channel_binding_to_asyncapi(specs_channel.bindings) + bindings=specs_channel_binding_to_asyncapi(specs_channel.bindings) if specs_channel.bindings else None, ) @@ -297,7 +297,7 @@ def get_broker_channels( return channels -def _specs_external_docs_to_asyncapi( +def specs_external_docs_to_asyncapi( externalDocs: Union[spec.docs.ExternalDocs, spec.docs.ExternalDocsDict, Dict[str, Any]] ) -> Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]: if isinstance(externalDocs, spec.docs.ExternalDocs): diff --git a/faststream/asyncapi/v3_0_0/schema/info.py b/faststream/asyncapi/v3_0_0/schema/info.py index 13f7d1478b..87c2fd07a5 100644 --- a/faststream/asyncapi/v3_0_0/schema/info.py +++ b/faststream/asyncapi/v3_0_0/schema/info.py @@ -8,7 +8,7 @@ from pydantic import AnyHttpUrl -from faststream.asyncapi.base import BaseInfo +from faststream.asyncapi.base.schema import BaseInfo from faststream.asyncapi.v2_6_0.schema.info import ( Contact, ContactDict, diff --git a/faststream/asyncapi/v3_0_0/schema/schema.py b/faststream/asyncapi/v3_0_0/schema/schema.py index 75505ba368..8bc1c1fe41 100644 --- a/faststream/asyncapi/v3_0_0/schema/schema.py +++ b/faststream/asyncapi/v3_0_0/schema/schema.py @@ -1,7 +1,7 @@ from typing import Any, Dict, Optional from faststream._compat import model_to_json, model_to_jsonable -from faststream.asyncapi.base import BaseSchema +from faststream.asyncapi.base.schema import BaseSchema from faststream.asyncapi.v3_0_0.schema.channels import Channel from faststream.asyncapi.v3_0_0.schema.components import Components from faststream.asyncapi.v3_0_0.schema.info import Info diff --git a/faststream/specification/info.py b/faststream/specification/info.py index e3219176fd..bf282fa762 100644 --- a/faststream/specification/info.py +++ b/faststream/specification/info.py @@ -18,7 +18,7 @@ JsonSchemaValue, with_info_plain_validator_function, ) -from faststream.asyncapi.base import BaseInfo +from faststream.asyncapi.base.schema import BaseInfo from faststream.log import logger try: diff --git a/faststream/asyncapi/v2_6_0/schema/security.py b/faststream/specification/security.py similarity index 100% rename from faststream/asyncapi/v2_6_0/schema/security.py rename to faststream/specification/security.py From e1ad4763ec944efa79d2fe4c058116d46a002c73 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Tue, 13 Aug 2024 22:03:04 +0300 Subject: [PATCH 070/245] specification restructuring --- faststream/app.py | 16 +- faststream/asgi/app.py | 16 +- faststream/asyncapi/base/schema/__init__.py | 2 +- faststream/asyncapi/proto.py | 2 +- faststream/asyncapi/v2_6_0/generate.py | 22 +-- faststream/asyncapi/v3_0_0/generate.py | 6 +- faststream/specification/__init__.py | 56 ++++++- faststream/specification/contact.py | 125 +++++++++++++++ faststream/specification/info.py | 160 +------------------- faststream/specification/license.py | 47 ++++++ 10 files changed, 252 insertions(+), 200 deletions(-) create mode 100644 faststream/specification/contact.py create mode 100644 faststream/specification/license.py diff --git a/faststream/app.py b/faststream/app.py index fe76930a26..2c128125c9 100644 --- a/faststream/app.py +++ b/faststream/app.py @@ -30,19 +30,15 @@ if TYPE_CHECKING: from faststream.broker.core.usecase import BrokerUsecase - from faststream.specification.docs import ( - ExternalDocs, - ExternalDocsDict, - ) - from faststream.specification.info import ( - Contact, - ContactDict, + from faststream.specification import ( License, LicenseDict, - ) - from faststream.specification.tag import ( - Tag, + Contact, + ContactDict, TagDict, + Tag, + ExternalDocs, + ExternalDocsDict, ) from faststream.types import ( AnyCallable, diff --git a/faststream/asgi/app.py b/faststream/asgi/app.py index b2bff09d36..f40a2591bb 100644 --- a/faststream/asgi/app.py +++ b/faststream/asgi/app.py @@ -21,19 +21,15 @@ if TYPE_CHECKING: from faststream.asgi.types import ASGIApp, Receive, Scope, Send from faststream.broker.core.usecase import BrokerUsecase - from faststream.specification.docs import ( - ExternalDocs, - ExternalDocsDict, - ) - from faststream.specification.info import ( + from faststream.specification import ( + LicenseDict, + License, Contact, ContactDict, - License, - LicenseDict, - ) - from faststream.specification.tag import ( - Tag, TagDict, + Tag, + ExternalDocs, + ExternalDocsDict, ) from faststream.types import ( AnyCallable, diff --git a/faststream/asyncapi/base/schema/__init__.py b/faststream/asyncapi/base/schema/__init__.py index f8befed431..99107ebd15 100644 --- a/faststream/asyncapi/base/schema/__init__.py +++ b/faststream/asyncapi/base/schema/__init__.py @@ -1,5 +1,5 @@ -from .schema import BaseSchema from .info import BaseInfo +from .schema import BaseSchema __all__ = ( "BaseSchema", diff --git a/faststream/asyncapi/proto.py b/faststream/asyncapi/proto.py index 27b5c5bec1..ccf5f99bf7 100644 --- a/faststream/asyncapi/proto.py +++ b/faststream/asyncapi/proto.py @@ -4,12 +4,12 @@ from typing_extensions import Annotated, Doc from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification import License, LicenseDict, Contact, ContactDict if TYPE_CHECKING: from faststream.broker.core.usecase import BrokerUsecase from faststream.specification.channel import Channel from faststream.specification.docs import ExternalDocs, ExternalDocsDict - from faststream.specification.info import Contact, ContactDict, License, LicenseDict from faststream.specification.tag import Tag, TagDict from faststream.types import ( AnyDict, diff --git a/faststream/asyncapi/v2_6_0/generate.py b/faststream/asyncapi/v2_6_0/generate.py index f4199b04ee..f8c78674ba 100644 --- a/faststream/asyncapi/v2_6_0/generate.py +++ b/faststream/asyncapi/v2_6_0/generate.py @@ -111,7 +111,7 @@ def get_broker_server( if broker.tags: for tag in broker.tags: - if isinstance(tag, spec.tag.Tag): + if isinstance(tag, spec.Tag): tags.append(Tag(**asdict(tag))) elif isinstance(tag, dict): tags.append(dict(tag)) @@ -177,25 +177,25 @@ def get_broker_channels( def specs_contact_to_asyncapi( - contact: Union["spec.info.Contact", "spec.info.ContactDict", "AnyDict"] + contact: Union["spec.Contact", "spec.ContactDict", "AnyDict"] ) -> Union["Contact", "AnyDict"]: - if isinstance(contact, spec.info.Contact): + if isinstance(contact, spec.Contact): return Contact(**contact.dict()) return dict(contact) def specs_license_to_asyncapi( - license: Union["spec.info.License", "spec.info.LicenseDict", "AnyDict"] + license: Union["spec.License", "spec.LicenseDict", "AnyDict"] ) -> Union["License", "AnyDict"]: - if isinstance(license, spec.info.License): + if isinstance(license, spec.License): return License(**license.dict()) return dict(license) -def specs_channel_to_asyncapi(channel: spec.channel.Channel) -> Channel: +def specs_channel_to_asyncapi(channel: spec.Channel) -> Channel: return Channel( description=channel.description, servers=channel.servers, @@ -252,7 +252,7 @@ def specs_channel_binding_to_asyncapi(binding: spec.bindings.ChannelBinding) -> ) -def specs_operation_to_asyncapi(operation: spec.operation.Operation) -> Operation: +def specs_operation_to_asyncapi(operation: spec.Operation) -> Operation: return Operation( operationId=operation.operationId, summary=operation.summary, @@ -311,12 +311,12 @@ def specs_operation_binding_to_asyncapi(binding: spec.bindings.OperationBinding) def specs_tags_to_asyncapi( - tags: List[Union[spec.tag.Tag, spec.tag.TagDict, Dict[str, Any]]] + tags: List[Union[spec.Tag, spec.TagDict, Dict[str, Any]]] ) -> List[Union[Tag, TagDict, Dict[str, Any]]]: asyncapi_tags: List[Union[Tag, TagDict, Dict[str, Any]]] = [] for tag in tags: - if isinstance(tag, spec.tag.Tag): + if isinstance(tag, spec.Tag): asyncapi_tags.append(Tag( name=tag.name, description=tag.description, @@ -333,9 +333,9 @@ def specs_tags_to_asyncapi( def specs_external_docs_to_asyncapi( - externalDocs: Union[spec.docs.ExternalDocs, spec.docs.ExternalDocsDict, Dict[str, Any]] + externalDocs: Union[spec.ExternalDocs, spec.ExternalDocsDict, Dict[str, Any]] ) -> Union[ExternalDocs, Dict[str, Any]]: - if isinstance(externalDocs, spec.docs.ExternalDocs): + if isinstance(externalDocs, spec.ExternalDocs): return ExternalDocs( **asdict(externalDocs) ) diff --git a/faststream/asyncapi/v3_0_0/generate.py b/faststream/asyncapi/v3_0_0/generate.py index 2353b39b73..5d09e06b65 100644 --- a/faststream/asyncapi/v3_0_0/generate.py +++ b/faststream/asyncapi/v3_0_0/generate.py @@ -104,7 +104,7 @@ def get_broker_server( if broker.tags: for tag in broker.tags: - if isinstance(tag, spec.tag.Tag): + if isinstance(tag, spec.Tag): tags.append(Tag(**asdict(tag))) elif isinstance(tag, dict): tags.append(dict(tag)) @@ -298,9 +298,9 @@ def get_broker_channels( def specs_external_docs_to_asyncapi( - externalDocs: Union[spec.docs.ExternalDocs, spec.docs.ExternalDocsDict, Dict[str, Any]] + externalDocs: Union[spec.ExternalDocs, spec.ExternalDocsDict, Dict[str, Any]] ) -> Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]: - if isinstance(externalDocs, spec.docs.ExternalDocs): + if isinstance(externalDocs, spec.ExternalDocs): return ExternalDocs( **asdict(externalDocs) ) diff --git a/faststream/specification/__init__.py b/faststream/specification/__init__.py index c04be659df..14776c8df0 100644 --- a/faststream/specification/__init__.py +++ b/faststream/specification/__init__.py @@ -1,11 +1,53 @@ -from . import bindings, channel, docs, message, operation, tag, info +from . import bindings +from .channel import ( + Channel, +) +from .contact import ( + Contact, + ContactDict, +) +from .docs import ( + ExternalDocs, + ExternalDocsDict, +) +from .info import ( + Info, +) +from .license import ( + License, + LicenseDict, +) +from .message import ( + Message, +) +from .operation import ( + Operation +) +from .security import ( + SecuritySchemaComponent, + OauthFlows, + OauthFlowObj, +) +from .tag import ( + Tag, + TagDict, +) __all__ = ( "bindings", - "channel", - "docs", - "message", - "operation", - "tag", - "info", + "Channel", + "Contact", + "ContactDict", + "ExternalDocs", + "ExternalDocsDict", + "Info", + "License", + "LicenseDict", + "Message", + "Operation", + "SecuritySchemaComponent", + "OauthFlows", + "OauthFlowObj", + "Tag", + "TagDict", ) diff --git a/faststream/specification/contact.py b/faststream/specification/contact.py new file mode 100644 index 0000000000..3090f9a09b --- /dev/null +++ b/faststream/specification/contact.py @@ -0,0 +1,125 @@ +from typing import ( + Any, + Callable, + Iterable, + Optional, + Type, +) + +from pydantic import AnyHttpUrl, BaseModel +from typing_extensions import Required, TypedDict + +from faststream._compat import ( + PYDANTIC_V2, + CoreSchema, + GetJsonSchemaHandler, + JsonSchemaValue, + with_info_plain_validator_function, +) +from faststream.log import logger + +try: + import email_validator + + if email_validator is None: + raise ImportError + from pydantic import EmailStr + +except ImportError: # pragma: no cover + # NOTE: EmailStr mock was copied from the FastAPI + # https://github.com/tiangolo/fastapi/blob/master/fastapi/openapi/models.py#24 + class EmailStr(str): # type: ignore + """EmailStr is a string that should be an email. + + Note: EmailStr mock was copied from the FastAPI: + https://github.com/tiangolo/fastapi/blob/master/fastapi/openapi/models.py#24 + + """ + + @classmethod + def __get_validators__(cls) -> Iterable[Callable[..., Any]]: + """Returns the validators for the EmailStr class.""" + yield cls.validate + + @classmethod + def validate(cls, v: Any) -> str: + """Validates the EmailStr class.""" + logger.warning( + "email-validator bot installed, email fields will be treated as str.\n" + "To install, run: pip install email-validator" + ) + return str(v) + + @classmethod + def _validate(cls, __input_value: Any, _: Any) -> str: + logger.warning( + "email-validator bot installed, email fields will be treated as str.\n" + "To install, run: pip install email-validator" + ) + return str(__input_value) + + @classmethod + def __get_pydantic_json_schema__( + cls, + core_schema: CoreSchema, + handler: GetJsonSchemaHandler, + ) -> JsonSchemaValue: + """Returns the JSON schema for the EmailStr class. + + Args: + core_schema : the core schema + handler : the handler + """ + return {"type": "string", "format": "email"} + + @classmethod + def __get_pydantic_core_schema__( + cls, + source: Type[Any], + handler: Callable[[Any], CoreSchema], + ) -> JsonSchemaValue: + """Returns the core schema for the EmailStr class. + + Args: + source : the source + handler : the handler + """ + return with_info_plain_validator_function(cls._validate) # type: ignore[no-any-return] + + +class ContactDict(TypedDict, total=False): + """A class to represent a dictionary of contact information. + + Attributes: + name : required name of the contact (type: str) + url : URL of the contact (type: AnyHttpUrl) + email : email address of the contact (type: EmailStr) + + """ + + name: Required[str] + url: AnyHttpUrl + email: EmailStr + + +class Contact(BaseModel): + """A class to represent a contact. + + Attributes: + name : name of the contact (str) + url : URL of the contact (Optional[AnyHttpUrl]) + email : email of the contact (Optional[EmailStr]) + + """ + + name: str + url: Optional[AnyHttpUrl] = None + email: Optional[EmailStr] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" diff --git a/faststream/specification/info.py b/faststream/specification/info.py index bf282fa762..8c310b2d62 100644 --- a/faststream/specification/info.py +++ b/faststream/specification/info.py @@ -1,171 +1,17 @@ from typing import ( Any, - Callable, Dict, - Iterable, Optional, - Type, Union, ) from pydantic import AnyHttpUrl, BaseModel -from typing_extensions import Required, TypedDict -from faststream._compat import ( - PYDANTIC_V2, - CoreSchema, - GetJsonSchemaHandler, - JsonSchemaValue, - with_info_plain_validator_function, -) -from faststream.asyncapi.base.schema import BaseInfo -from faststream.log import logger - -try: - import email_validator - - if email_validator is None: - raise ImportError - from pydantic import EmailStr - -except ImportError: # pragma: no cover - # NOTE: EmailStr mock was copied from the FastAPI - # https://github.com/tiangolo/fastapi/blob/master/fastapi/openapi/models.py#24 - class EmailStr(str): # type: ignore - """EmailStr is a string that should be an email. - - Note: EmailStr mock was copied from the FastAPI: - https://github.com/tiangolo/fastapi/blob/master/fastapi/openapi/models.py#24 - - """ - - @classmethod - def __get_validators__(cls) -> Iterable[Callable[..., Any]]: - """Returns the validators for the EmailStr class.""" - yield cls.validate - - @classmethod - def validate(cls, v: Any) -> str: - """Validates the EmailStr class.""" - logger.warning( - "email-validator bot installed, email fields will be treated as str.\n" - "To install, run: pip install email-validator" - ) - return str(v) - - @classmethod - def _validate(cls, __input_value: Any, _: Any) -> str: - logger.warning( - "email-validator bot installed, email fields will be treated as str.\n" - "To install, run: pip install email-validator" - ) - return str(__input_value) - - @classmethod - def __get_pydantic_json_schema__( - cls, - core_schema: CoreSchema, - handler: GetJsonSchemaHandler, - ) -> JsonSchemaValue: - """Returns the JSON schema for the EmailStr class. - - Args: - core_schema : the core schema - handler : the handler - """ - return {"type": "string", "format": "email"} - - @classmethod - def __get_pydantic_core_schema__( - cls, - source: Type[Any], - handler: Callable[[Any], CoreSchema], - ) -> JsonSchemaValue: - """Returns the core schema for the EmailStr class. - - Args: - source : the source - handler : the handler - """ - return with_info_plain_validator_function(cls._validate) # type: ignore[no-any-return] - - -class ContactDict(TypedDict, total=False): - """A class to represent a dictionary of contact information. - - Attributes: - name : required name of the contact (type: str) - url : URL of the contact (type: AnyHttpUrl) - email : email address of the contact (type: EmailStr) - - """ - - name: Required[str] - url: AnyHttpUrl - email: EmailStr - - -class Contact(BaseModel): - """A class to represent a contact. - - Attributes: - name : name of the contact (str) - url : URL of the contact (Optional[AnyHttpUrl]) - email : email of the contact (Optional[EmailStr]) - - """ - - name: str - url: Optional[AnyHttpUrl] = None - email: Optional[EmailStr] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" - - -class LicenseDict(TypedDict, total=False): - """A dictionary-like class to represent a license. - - Attributes: - name : required name of the license (type: str) - url : URL of the license (type: AnyHttpUrl) - - """ - - name: Required[str] - url: AnyHttpUrl - - -class License(BaseModel): - """A class to represent a license. - - Attributes: - name : name of the license - url : URL of the license (optional) - - Config: - extra : allow additional attributes in the model (PYDANTIC_V2) - - """ - - name: str - url: Optional[AnyHttpUrl] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" +from faststream.specification.contact import Contact, ContactDict +from faststream.specification.license import License, LicenseDict -class Info(BaseInfo): +class Info(BaseModel): """A class to represent information. Attributes: diff --git a/faststream/specification/license.py b/faststream/specification/license.py new file mode 100644 index 0000000000..7bf7c20042 --- /dev/null +++ b/faststream/specification/license.py @@ -0,0 +1,47 @@ +from typing import ( + Optional, +) + +from pydantic import AnyHttpUrl, BaseModel +from typing_extensions import Required, TypedDict + +from faststream._compat import ( + PYDANTIC_V2, +) + + +class LicenseDict(TypedDict, total=False): + """A dictionary-like class to represent a license. + + Attributes: + name : required name of the license (type: str) + url : URL of the license (type: AnyHttpUrl) + + """ + + name: Required[str] + url: AnyHttpUrl + + +class License(BaseModel): + """A class to represent a license. + + Attributes: + name : name of the license + url : URL of the license (optional) + + Config: + extra : allow additional attributes in the model (PYDANTIC_V2) + + """ + + name: str + url: Optional[AnyHttpUrl] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" From 52db91f0a80b56cffd67d786ee2f8799207bba66 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 8 Sep 2024 11:52:44 +0300 Subject: [PATCH 071/245] refactoring --- faststream/app.py | 14 +- faststream/asgi/app.py | 15 +- faststream/asyncapi/proto.py | 3 +- faststream/asyncapi/v2_6_0/generate.py | 22 +-- faststream/asyncapi/v3_0_0/generate.py | 6 +- faststream/confluent/broker/registrator.py | 130 ++++++++--------- faststream/confluent/fastapi/fastapi.py | 134 +++++++++--------- .../publisher/{asyncapi.py => publisher.py} | 34 ++--- faststream/confluent/subscriber/factory.py | 30 ++-- .../subscriber/{asyncapi.py => subscriber.py} | 10 +- faststream/confluent/testing.py | 20 +-- faststream/kafka/broker/registrator.py | 130 ++++++++--------- faststream/kafka/fastapi/fastapi.py | 134 +++++++++--------- .../publisher/{asyncapi.py => publisher.py} | 34 ++--- faststream/kafka/subscriber/factory.py | 30 ++-- .../subscriber/{asyncapi.py => subscriber.py} | 10 +- faststream/kafka/testing.py | 22 +-- faststream/nats/broker/broker.py | 14 +- faststream/nats/broker/registrator.py | 18 +-- faststream/nats/fastapi/fastapi.py | 10 +- .../publisher/{asyncapi.py => publisher.py} | 4 +- faststream/nats/subscriber/factory.py | 72 +++++----- .../subscriber/{asyncapi.py => subscriber.py} | 42 +++--- faststream/nats/testing.py | 5 +- faststream/rabbit/broker/broker.py | 4 +- faststream/rabbit/broker/registrator.py | 18 +-- faststream/rabbit/fastapi/router.py | 10 +- .../publisher/{asyncapi.py => publisher.py} | 8 +- faststream/rabbit/subscriber/factory.py | 6 +- .../subscriber/{asyncapi.py => subscriber.py} | 2 +- faststream/rabbit/testing.py | 4 +- faststream/redis/broker/registrator.py | 16 +-- faststream/redis/fastapi/fastapi.py | 10 +- .../publisher/{asyncapi.py => publisher.py} | 8 +- faststream/redis/subscriber/factory.py | 2 +- .../subscriber/{asyncapi.py => subscriber.py} | 8 +- faststream/redis/testing.py | 4 +- faststream/specification/__init__.py | 68 +++------ 38 files changed, 540 insertions(+), 571 deletions(-) rename faststream/confluent/publisher/{asyncapi.py => publisher.py} (87%) rename faststream/confluent/subscriber/{asyncapi.py => subscriber.py} (87%) rename faststream/kafka/publisher/{asyncapi.py => publisher.py} (87%) rename faststream/kafka/subscriber/{asyncapi.py => subscriber.py} (87%) rename faststream/nats/publisher/{asyncapi.py => publisher.py} (96%) rename faststream/nats/subscriber/{asyncapi.py => subscriber.py} (56%) rename faststream/rabbit/publisher/{asyncapi.py => publisher.py} (96%) rename faststream/rabbit/subscriber/{asyncapi.py => subscriber.py} (98%) rename faststream/redis/publisher/{asyncapi.py => publisher.py} (95%) rename faststream/redis/subscriber/{asyncapi.py => subscriber.py} (91%) diff --git a/faststream/app.py b/faststream/app.py index 2c128125c9..0acdbf8b26 100644 --- a/faststream/app.py +++ b/faststream/app.py @@ -30,16 +30,10 @@ if TYPE_CHECKING: from faststream.broker.core.usecase import BrokerUsecase - from faststream.specification import ( - License, - LicenseDict, - Contact, - ContactDict, - TagDict, - Tag, - ExternalDocs, - ExternalDocsDict, - ) + from faststream.specification.contact import ContactDict, Contact + from faststream.specification.docs import ExternalDocs, ExternalDocsDict + from faststream.specification.license import License, LicenseDict + from faststream.specification.tag import TagDict, Tag from faststream.types import ( AnyCallable, AnyDict, diff --git a/faststream/asgi/app.py b/faststream/asgi/app.py index f40a2591bb..8ee7f2d580 100644 --- a/faststream/asgi/app.py +++ b/faststream/asgi/app.py @@ -18,19 +18,14 @@ from faststream.asgi.websocket import WebSocketClose from faststream.log.logging import logger + if TYPE_CHECKING: from faststream.asgi.types import ASGIApp, Receive, Scope, Send from faststream.broker.core.usecase import BrokerUsecase - from faststream.specification import ( - LicenseDict, - License, - Contact, - ContactDict, - TagDict, - Tag, - ExternalDocs, - ExternalDocsDict, - ) + from faststream.specification.contact import Contact, ContactDict + from faststream.specification.docs import ExternalDocs, ExternalDocsDict + from faststream.specification.license import License, LicenseDict + from faststream.specification.tag import Tag, TagDict from faststream.types import ( AnyCallable, AnyDict, diff --git a/faststream/asyncapi/proto.py b/faststream/asyncapi/proto.py index ccf5f99bf7..16c0f9f40b 100644 --- a/faststream/asyncapi/proto.py +++ b/faststream/asyncapi/proto.py @@ -4,7 +4,8 @@ from typing_extensions import Annotated, Doc from faststream.asyncapi.version import AsyncAPIVersion -from faststream.specification import License, LicenseDict, Contact, ContactDict +from faststream.specification.contact import Contact, ContactDict +from faststream.specification.license import License, LicenseDict if TYPE_CHECKING: from faststream.broker.core.usecase import BrokerUsecase diff --git a/faststream/asyncapi/v2_6_0/generate.py b/faststream/asyncapi/v2_6_0/generate.py index f8c78674ba..be1297a609 100644 --- a/faststream/asyncapi/v2_6_0/generate.py +++ b/faststream/asyncapi/v2_6_0/generate.py @@ -111,7 +111,7 @@ def get_broker_server( if broker.tags: for tag in broker.tags: - if isinstance(tag, spec.Tag): + if isinstance(tag, spec.tag.Tag): tags.append(Tag(**asdict(tag))) elif isinstance(tag, dict): tags.append(dict(tag)) @@ -177,25 +177,25 @@ def get_broker_channels( def specs_contact_to_asyncapi( - contact: Union["spec.Contact", "spec.ContactDict", "AnyDict"] + contact: Union["spec.contact.Contact", "spec.contact.ContactDict", "AnyDict"] ) -> Union["Contact", "AnyDict"]: - if isinstance(contact, spec.Contact): + if isinstance(contact, spec.contact.Contact): return Contact(**contact.dict()) return dict(contact) def specs_license_to_asyncapi( - license: Union["spec.License", "spec.LicenseDict", "AnyDict"] + license: Union["spec.license.License", "spec.license.LicenseDict", "AnyDict"] ) -> Union["License", "AnyDict"]: - if isinstance(license, spec.License): + if isinstance(license, spec.license.License): return License(**license.dict()) return dict(license) -def specs_channel_to_asyncapi(channel: spec.Channel) -> Channel: +def specs_channel_to_asyncapi(channel: spec.channel.Channel) -> Channel: return Channel( description=channel.description, servers=channel.servers, @@ -252,7 +252,7 @@ def specs_channel_binding_to_asyncapi(binding: spec.bindings.ChannelBinding) -> ) -def specs_operation_to_asyncapi(operation: spec.Operation) -> Operation: +def specs_operation_to_asyncapi(operation: spec.operation.Operation) -> Operation: return Operation( operationId=operation.operationId, summary=operation.summary, @@ -311,12 +311,12 @@ def specs_operation_binding_to_asyncapi(binding: spec.bindings.OperationBinding) def specs_tags_to_asyncapi( - tags: List[Union[spec.Tag, spec.TagDict, Dict[str, Any]]] + tags: List[Union[spec.tag.Tag, spec.tag.TagDict, Dict[str, Any]]] ) -> List[Union[Tag, TagDict, Dict[str, Any]]]: asyncapi_tags: List[Union[Tag, TagDict, Dict[str, Any]]] = [] for tag in tags: - if isinstance(tag, spec.Tag): + if isinstance(tag, spec.tag.Tag): asyncapi_tags.append(Tag( name=tag.name, description=tag.description, @@ -333,9 +333,9 @@ def specs_tags_to_asyncapi( def specs_external_docs_to_asyncapi( - externalDocs: Union[spec.ExternalDocs, spec.ExternalDocsDict, Dict[str, Any]] + externalDocs: Union[spec.docs.ExternalDocs, spec.docs.ExternalDocsDict, Dict[str, Any]] ) -> Union[ExternalDocs, Dict[str, Any]]: - if isinstance(externalDocs, spec.ExternalDocs): + if isinstance(externalDocs, spec.docs.ExternalDocs): return ExternalDocs( **asdict(externalDocs) ) diff --git a/faststream/asyncapi/v3_0_0/generate.py b/faststream/asyncapi/v3_0_0/generate.py index 5d09e06b65..2353b39b73 100644 --- a/faststream/asyncapi/v3_0_0/generate.py +++ b/faststream/asyncapi/v3_0_0/generate.py @@ -104,7 +104,7 @@ def get_broker_server( if broker.tags: for tag in broker.tags: - if isinstance(tag, spec.Tag): + if isinstance(tag, spec.tag.Tag): tags.append(Tag(**asdict(tag))) elif isinstance(tag, dict): tags.append(dict(tag)) @@ -298,9 +298,9 @@ def get_broker_channels( def specs_external_docs_to_asyncapi( - externalDocs: Union[spec.ExternalDocs, spec.ExternalDocsDict, Dict[str, Any]] + externalDocs: Union[spec.docs.ExternalDocs, spec.docs.ExternalDocsDict, Dict[str, Any]] ) -> Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]: - if isinstance(externalDocs, spec.ExternalDocs): + if isinstance(externalDocs, spec.docs.ExternalDocs): return ExternalDocs( **asdict(externalDocs) ) diff --git a/faststream/confluent/broker/registrator.py b/faststream/confluent/broker/registrator.py index 5f7d8e1354..e1a62a9eda 100644 --- a/faststream/confluent/broker/registrator.py +++ b/faststream/confluent/broker/registrator.py @@ -16,7 +16,7 @@ from faststream.broker.core.abc import ABCBroker from faststream.broker.utils import default_filter -from faststream.confluent.publisher.asyncapi import AsyncAPIPublisher +from faststream.confluent.publisher.publisher import SpecificationPublisher from faststream.confluent.subscriber.factory import create_subscriber from faststream.exceptions import SetupError @@ -31,14 +31,14 @@ SubscriberMiddleware, ) from faststream.confluent.message import KafkaMessage - from faststream.confluent.publisher.asyncapi import ( - AsyncAPIBatchPublisher, - AsyncAPIDefaultPublisher, + from faststream.confluent.publisher.publisher import ( + SpecificationBatchPublisher, + SpecificationDefaultPublisher, ) from faststream.confluent.schemas import TopicPartition - from faststream.confluent.subscriber.asyncapi import ( - AsyncAPIBatchSubscriber, - AsyncAPIDefaultSubscriber, + from faststream.confluent.subscriber.subscriber import ( + SpecificationBatchSubscriber, + SpecificationDefaultSubscriber, ) @@ -53,9 +53,9 @@ class KafkaRegistrator( """Includable to KafkaBroker router.""" _subscribers: Dict[ - int, Union["AsyncAPIBatchSubscriber", "AsyncAPIDefaultSubscriber"] + int, Union["SpecificationBatchSubscriber", "SpecificationDefaultSubscriber"] ] - _publishers: Dict[int, Union["AsyncAPIBatchPublisher", "AsyncAPIDefaultPublisher"]] + _publishers: Dict[int, Union["SpecificationBatchPublisher", "SpecificationDefaultPublisher"]] @overload # type: ignore[override] def subscriber( @@ -321,23 +321,23 @@ def subscriber( "Whether to disable **FastStream** RPC and Reply To auto responses or not." ), ] = False, - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI subscriber object title."), + Doc("Specification subscriber object title."), ] = None, description: Annotated[ Optional[str], Doc( - "AsyncAPI subscriber object description. " + "Specification subscriber object description. " "Uses decorated docstring as default." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, - ) -> "AsyncAPIBatchSubscriber": ... + ) -> "SpecificationBatchSubscriber": ... @overload def subscriber( @@ -603,23 +603,23 @@ def subscriber( "Whether to disable **FastStream** RPC and Reply To auto responses or not." ), ] = False, - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI subscriber object title."), + Doc("Specification subscriber object title."), ] = None, description: Annotated[ Optional[str], Doc( - "AsyncAPI subscriber object description. " + "Specification subscriber object description. " "Uses decorated docstring as default." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, - ) -> "AsyncAPIDefaultSubscriber": ... + ) -> "SpecificationDefaultSubscriber": ... @overload def subscriber( @@ -885,25 +885,25 @@ def subscriber( "Whether to disable **FastStream** RPC and Reply To auto responses or not." ), ] = False, - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI subscriber object title."), + Doc("Specification subscriber object title."), ] = None, description: Annotated[ Optional[str], Doc( - "AsyncAPI subscriber object description. " + "Specification subscriber object description. " "Uses decorated docstring as default." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, ) -> Union[ - "AsyncAPIDefaultSubscriber", - "AsyncAPIBatchSubscriber", + "SpecificationDefaultSubscriber", + "SpecificationBatchSubscriber", ]: ... @override @@ -1170,25 +1170,25 @@ def subscriber( "Whether to disable **FastStream** RPC and Reply To auto responses or not." ), ] = False, - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI subscriber object title."), + Doc("Specification subscriber object title."), ] = None, description: Annotated[ Optional[str], Doc( - "AsyncAPI subscriber object description. " + "Specification subscriber object description. " "Uses decorated docstring as default." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, ) -> Union[ - "AsyncAPIDefaultSubscriber", - "AsyncAPIBatchSubscriber", + "SpecificationDefaultSubscriber", + "SpecificationBatchSubscriber", ]: if not auto_commit and not group_id: raise SetupError("You should install `group_id` with manual commit mode") @@ -1224,7 +1224,7 @@ def subscriber( retry=retry, broker_middlewares=self._middlewares, broker_dependencies=self._dependencies, - # AsyncAPI + # Specification title_=title, description_=description, include_in_schema=self._solve_include_in_schema(include_in_schema), @@ -1232,7 +1232,7 @@ def subscriber( ) if batch: - return cast("AsyncAPIBatchSubscriber", subscriber).add_call( + return cast("SpecificationBatchSubscriber", subscriber).add_call( filter_=filter, parser_=parser or self._parser, decoder_=decoder or self._decoder, @@ -1240,7 +1240,7 @@ def subscriber( middlewares_=middlewares, ) else: - return cast("AsyncAPIDefaultSubscriber", subscriber).add_call( + return cast("SpecificationDefaultSubscriber", subscriber).add_call( filter_=filter, parser_=parser or self._parser, decoder_=decoder or self._decoder, @@ -1300,27 +1300,27 @@ def publisher( Iterable["PublisherMiddleware"], Doc("Publisher middlewares to wrap outgoing messages."), ] = (), - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI publisher object title."), + Doc("Specification publisher object title."), ] = None, description: Annotated[ Optional[str], - Doc("AsyncAPI publisher object description."), + Doc("Specification publisher object description."), ] = None, schema: Annotated[ Optional[Any], Doc( - "AsyncAPI publishing message type. " + "Specification publishing message type. " "Should be any python-native object annotation or `pydantic.BaseModel`." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, - ) -> "AsyncAPIDefaultPublisher": ... + ) -> "SpecificationDefaultPublisher": ... @overload def publisher( @@ -1374,27 +1374,27 @@ def publisher( Iterable["PublisherMiddleware"], Doc("Publisher middlewares to wrap outgoing messages."), ] = (), - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI publisher object title."), + Doc("Specification publisher object title."), ] = None, description: Annotated[ Optional[str], - Doc("AsyncAPI publisher object description."), + Doc("Specification publisher object description."), ] = None, schema: Annotated[ Optional[Any], Doc( - "AsyncAPI publishing message type. " + "Specification publishing message type. " "Should be any python-native object annotation or `pydantic.BaseModel`." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, - ) -> "AsyncAPIBatchPublisher": ... + ) -> "SpecificationBatchPublisher": ... @overload def publisher( @@ -1448,29 +1448,29 @@ def publisher( Iterable["PublisherMiddleware"], Doc("Publisher middlewares to wrap outgoing messages."), ] = (), - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI publisher object title."), + Doc("Specification publisher object title."), ] = None, description: Annotated[ Optional[str], - Doc("AsyncAPI publisher object description."), + Doc("Specification publisher object description."), ] = None, schema: Annotated[ Optional[Any], Doc( - "AsyncAPI publishing message type. " + "Specification publishing message type. " "Should be any python-native object annotation or `pydantic.BaseModel`." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, ) -> Union[ - "AsyncAPIBatchPublisher", - "AsyncAPIDefaultPublisher", + "SpecificationBatchPublisher", + "SpecificationDefaultPublisher", ]: ... @override @@ -1525,38 +1525,38 @@ def publisher( Iterable["PublisherMiddleware"], Doc("Publisher middlewares to wrap outgoing messages."), ] = (), - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI publisher object title."), + Doc("Specification publisher object title."), ] = None, description: Annotated[ Optional[str], - Doc("AsyncAPI publisher object description."), + Doc("Specification publisher object description."), ] = None, schema: Annotated[ Optional[Any], Doc( - "AsyncAPI publishing message type. " + "Specification publishing message type. " "Should be any python-native object annotation or `pydantic.BaseModel`." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, ) -> Union[ - "AsyncAPIBatchPublisher", - "AsyncAPIDefaultPublisher", + "SpecificationBatchPublisher", + "SpecificationDefaultPublisher", ]: - """Creates long-living and AsyncAPI-documented publisher object. + """Creates long-living and Specification-documented publisher object. You can use it as a handler decorator (handler should be decorated by `@broker.subscriber(...)` too) - `@broker.publisher(...)`. In such case publisher will publish your handler return value. Or you can create a publisher object to call it lately - `broker.publisher(...).publish(...)`. """ - publisher = AsyncAPIPublisher.create( + publisher = SpecificationPublisher.create( # batch flag batch=batch, # default args @@ -1569,7 +1569,7 @@ def publisher( # publisher-specific broker_middlewares=self._middlewares, middlewares=middlewares, - # AsyncAPI + # Specification title_=title, description_=description, schema_=schema, @@ -1577,6 +1577,6 @@ def publisher( ) if batch: - return cast("AsyncAPIBatchPublisher", super().publisher(publisher)) + return cast("SpecificationBatchPublisher", super().publisher(publisher)) else: - return cast("AsyncAPIDefaultPublisher", super().publisher(publisher)) + return cast("SpecificationDefaultPublisher", super().publisher(publisher)) diff --git a/faststream/confluent/fastapi/fastapi.py b/faststream/confluent/fastapi/fastapi.py index d4144c0f19..06c6aa8bdd 100644 --- a/faststream/confluent/fastapi/fastapi.py +++ b/faststream/confluent/fastapi/fastapi.py @@ -49,14 +49,14 @@ ) from faststream.confluent.config import ConfluentConfig from faststream.confluent.message import KafkaMessage - from faststream.confluent.publisher.asyncapi import ( - AsyncAPIBatchPublisher, - AsyncAPIDefaultPublisher, + from faststream.confluent.publisher.publisher import ( + SpecificationBatchPublisher, + SpecificationDefaultPublisher, ) from faststream.confluent.schemas import TopicPartition - from faststream.confluent.subscriber.asyncapi import ( - AsyncAPIBatchSubscriber, - AsyncAPIDefaultSubscriber, + from faststream.confluent.subscriber.subscriber import ( + SpecificationBatchSubscriber, + SpecificationDefaultSubscriber, ) from faststream.security import BaseSecurity from faststream.types import AnyDict, LoggerProto @@ -276,36 +276,36 @@ def __init__( ], Doc("Middlewares to apply to all broker publishers/subscribers."), ] = (), - # AsyncAPI args + # Specification args security: Annotated[ Optional["BaseSecurity"], Doc( - "Security options to connect broker and generate AsyncAPI server security information." + "Security options to connect broker and generate Specification server security information." ), ] = None, asyncapi_url: Annotated[ Optional[str], - Doc("AsyncAPI hardcoded server addresses. Use `servers` if not specified."), + Doc("Specification hardcoded server addresses. Use `servers` if not specified."), ] = None, protocol: Annotated[ Optional[str], - Doc("AsyncAPI server protocol."), + Doc("Specification server protocol."), ] = None, protocol_version: Annotated[ Optional[str], - Doc("AsyncAPI server protocol version."), + Doc("Specification server protocol version."), ] = "auto", description: Annotated[ Optional[str], - Doc("AsyncAPI server description."), + Doc("Specification server description."), ] = None, asyncapi_version: Annotated[ AsyncAPIVersion, - Doc("Version of AsyncAPI for schema generation") + Doc("Version of Specification for schema generation") ] = AsyncAPIVersion.v2_6, asyncapi_tags: Annotated[ Optional[Iterable[Union["asyncapi.Tag", "asyncapi.TagDict"]]], - Doc("AsyncAPI server tags."), + Doc("Specification server tags."), ] = None, # logging args logger: Annotated[ @@ -331,7 +331,7 @@ def __init__( schema_url: Annotated[ Optional[str], Doc( - "AsyncAPI schema url. You should set this option to `None` to disable AsyncAPI routes at all." + "Specification schema url. You should set this option to `None` to disable Specification routes at all." ), ] = "/asyncapi", # FastAPI args @@ -576,7 +576,7 @@ def __init__( logger=logger, log_level=log_level, log_fmt=log_fmt, - # AsyncAPI options + # Specification options security=security, protocol=protocol, description=description, @@ -868,21 +868,21 @@ def subscriber( "Whether to disable **FastStream** RPC and Reply To auto responses or not." ), ] = False, - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI subscriber object title."), + Doc("Specification subscriber object title."), ] = None, description: Annotated[ Optional[str], Doc( - "AsyncAPI subscriber object description. " + "Specification subscriber object description. " "Uses decorated docstring as default." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, # FastAPI args response_model: Annotated[ @@ -1007,7 +1007,7 @@ def subscriber( """ ), ] = False, - ) -> "AsyncAPIDefaultSubscriber": ... + ) -> "SpecificationDefaultSubscriber": ... @overload def subscriber( @@ -1259,21 +1259,21 @@ def subscriber( "Argument will be removed in **FastStream 0.6.0**." ), ] = default_filter, - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI subscriber object title."), + Doc("Specification subscriber object title."), ] = None, description: Annotated[ Optional[str], Doc( - "AsyncAPI subscriber object description. " + "Specification subscriber object description. " "Uses decorated docstring as default." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, # FastAPI args response_model: Annotated[ @@ -1398,7 +1398,7 @@ def subscriber( """ ), ] = False, - ) -> "AsyncAPIBatchSubscriber": ... + ) -> "SpecificationBatchSubscriber": ... @overload def subscriber( @@ -1664,21 +1664,21 @@ def subscriber( "Whether to disable **FastStream** RPC and Reply To auto responses or not." ), ] = False, - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI subscriber object title."), + Doc("Specification subscriber object title."), ] = None, description: Annotated[ Optional[str], Doc( - "AsyncAPI subscriber object description. " + "Specification subscriber object description. " "Uses decorated docstring as default." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, # FastAPI args response_model: Annotated[ @@ -1804,8 +1804,8 @@ def subscriber( ), ] = False, ) -> Union[ - "AsyncAPIBatchSubscriber", - "AsyncAPIDefaultSubscriber", + "SpecificationBatchSubscriber", + "SpecificationDefaultSubscriber", ]: ... @override @@ -2072,21 +2072,21 @@ def subscriber( "Whether to disable **FastStream** RPC and Reply To auto responses or not." ), ] = False, - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI subscriber object title."), + Doc("Specification subscriber object title."), ] = None, description: Annotated[ Optional[str], Doc( - "AsyncAPI subscriber object description. " + "Specification subscriber object description. " "Uses decorated docstring as default." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, # FastAPI args response_model: Annotated[ @@ -2212,8 +2212,8 @@ def subscriber( ), ] = False, ) -> Union[ - "AsyncAPIBatchSubscriber", - "AsyncAPIDefaultSubscriber", + "SpecificationBatchSubscriber", + "SpecificationDefaultSubscriber", ]: subscriber = super().subscriber( *topics, @@ -2259,9 +2259,9 @@ def subscriber( ) if batch: - return cast("AsyncAPIBatchSubscriber", subscriber) + return cast("SpecificationBatchSubscriber", subscriber) else: - return cast("AsyncAPIDefaultSubscriber", subscriber) + return cast("SpecificationDefaultSubscriber", subscriber) @overload # type: ignore[override] def publisher( @@ -2315,27 +2315,27 @@ def publisher( Iterable["PublisherMiddleware"], Doc("Publisher middlewares to wrap outgoing messages."), ] = (), - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI publisher object title."), + Doc("Specification publisher object title."), ] = None, description: Annotated[ Optional[str], - Doc("AsyncAPI publisher object description."), + Doc("Specification publisher object description."), ] = None, schema: Annotated[ Optional[Any], Doc( - "AsyncAPI publishing message type. " + "Specification publishing message type. " "Should be any python-native object annotation or `pydantic.BaseModel`." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, - ) -> "AsyncAPIDefaultPublisher": ... + ) -> "SpecificationDefaultPublisher": ... @overload def publisher( @@ -2389,27 +2389,27 @@ def publisher( Iterable["PublisherMiddleware"], Doc("Publisher middlewares to wrap outgoing messages."), ] = (), - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI publisher object title."), + Doc("Specification publisher object title."), ] = None, description: Annotated[ Optional[str], - Doc("AsyncAPI publisher object description."), + Doc("Specification publisher object description."), ] = None, schema: Annotated[ Optional[Any], Doc( - "AsyncAPI publishing message type. " + "Specification publishing message type. " "Should be any python-native object annotation or `pydantic.BaseModel`." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, - ) -> "AsyncAPIBatchPublisher": ... + ) -> "SpecificationBatchPublisher": ... @overload def publisher( @@ -2463,29 +2463,29 @@ def publisher( Iterable["PublisherMiddleware"], Doc("Publisher middlewares to wrap outgoing messages."), ] = (), - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI publisher object title."), + Doc("Specification publisher object title."), ] = None, description: Annotated[ Optional[str], - Doc("AsyncAPI publisher object description."), + Doc("Specification publisher object description."), ] = None, schema: Annotated[ Optional[Any], Doc( - "AsyncAPI publishing message type. " + "Specification publishing message type. " "Should be any python-native object annotation or `pydantic.BaseModel`." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, ) -> Union[ - "AsyncAPIBatchPublisher", - "AsyncAPIDefaultPublisher", + "SpecificationBatchPublisher", + "SpecificationDefaultPublisher", ]: ... @override @@ -2540,29 +2540,29 @@ def publisher( Iterable["PublisherMiddleware"], Doc("Publisher middlewares to wrap outgoing messages."), ] = (), - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI publisher object title."), + Doc("Specification publisher object title."), ] = None, description: Annotated[ Optional[str], - Doc("AsyncAPI publisher object description."), + Doc("Specification publisher object description."), ] = None, schema: Annotated[ Optional[Any], Doc( - "AsyncAPI publishing message type. " + "Specification publishing message type. " "Should be any python-native object annotation or `pydantic.BaseModel`." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, ) -> Union[ - "AsyncAPIBatchPublisher", - "AsyncAPIDefaultPublisher", + "SpecificationBatchPublisher", + "SpecificationDefaultPublisher", ]: return self.broker.publisher( topic=topic, @@ -2573,7 +2573,7 @@ def publisher( reply_to=reply_to, # broker options middlewares=middlewares, - # AsyncAPI options + # Specification options title=title, description=description, schema=schema, diff --git a/faststream/confluent/publisher/asyncapi.py b/faststream/confluent/publisher/publisher.py similarity index 87% rename from faststream/confluent/publisher/asyncapi.py rename to faststream/confluent/publisher/publisher.py index 577a752be7..2fd4e192e3 100644 --- a/faststream/confluent/publisher/asyncapi.py +++ b/faststream/confluent/publisher/publisher.py @@ -31,7 +31,7 @@ from faststream.broker.types import BrokerMiddleware, PublisherMiddleware -class AsyncAPIPublisher(LogicPublisher[MsgType]): +class SpecificationPublisher(LogicPublisher[MsgType]): """A class representing a publisher.""" def get_name(self) -> str: @@ -69,12 +69,12 @@ def create( # Publisher args broker_middlewares: Iterable["BrokerMiddleware[Tuple[ConfluentMsg, ...]]"], middlewares: Iterable["PublisherMiddleware"], - # AsyncAPI args + # Specification args schema_: Optional[Any], title_: Optional[str], description_: Optional[str], include_in_schema: bool, - ) -> "AsyncAPIBatchPublisher": ... + ) -> "SpecificationBatchPublisher": ... @overload @staticmethod @@ -89,12 +89,12 @@ def create( # Publisher args broker_middlewares: Iterable["BrokerMiddleware[ConfluentMsg]"], middlewares: Iterable["PublisherMiddleware"], - # AsyncAPI args + # Specification args schema_: Optional[Any], title_: Optional[str], description_: Optional[str], include_in_schema: bool, - ) -> "AsyncAPIDefaultPublisher": ... + ) -> "SpecificationDefaultPublisher": ... @overload @staticmethod @@ -111,14 +111,14 @@ def create( "BrokerMiddleware[Union[Tuple[ConfluentMsg, ...], ConfluentMsg]]" ], middlewares: Iterable["PublisherMiddleware"], - # AsyncAPI args + # Specification args schema_: Optional[Any], title_: Optional[str], description_: Optional[str], include_in_schema: bool, ) -> Union[ - "AsyncAPIBatchPublisher", - "AsyncAPIDefaultPublisher", + "SpecificationBatchPublisher", + "SpecificationDefaultPublisher", ]: ... @override @@ -136,20 +136,20 @@ def create( "BrokerMiddleware[Union[Tuple[ConfluentMsg, ...], ConfluentMsg]]" ], middlewares: Iterable["PublisherMiddleware"], - # AsyncAPI args + # Specification args schema_: Optional[Any], title_: Optional[str], description_: Optional[str], include_in_schema: bool, ) -> Union[ - "AsyncAPIBatchPublisher", - "AsyncAPIDefaultPublisher", + "SpecificationBatchPublisher", + "SpecificationDefaultPublisher", ]: if batch: if key: raise SetupError("You can't setup `key` with batch publisher") - return AsyncAPIBatchPublisher( + return SpecificationBatchPublisher( topic=topic, partition=partition, headers=headers, @@ -162,7 +162,7 @@ def create( include_in_schema=include_in_schema, ) else: - return AsyncAPIDefaultPublisher( + return SpecificationDefaultPublisher( key=key, # basic args topic=topic, @@ -178,15 +178,15 @@ def create( ) -class AsyncAPIBatchPublisher( +class SpecificationBatchPublisher( BatchPublisher, - AsyncAPIPublisher[Tuple["ConfluentMsg", ...]], + SpecificationPublisher[Tuple["ConfluentMsg", ...]], ): pass -class AsyncAPIDefaultPublisher( +class SpecificationDefaultPublisher( DefaultPublisher, - AsyncAPIPublisher["ConfluentMsg"], + SpecificationPublisher["ConfluentMsg"], ): pass diff --git a/faststream/confluent/subscriber/factory.py b/faststream/confluent/subscriber/factory.py index dcb7e414b3..d846f18861 100644 --- a/faststream/confluent/subscriber/factory.py +++ b/faststream/confluent/subscriber/factory.py @@ -9,9 +9,9 @@ overload, ) -from faststream.confluent.subscriber.asyncapi import ( - AsyncAPIBatchSubscriber, - AsyncAPIDefaultSubscriber, +from faststream.confluent.subscriber.subscriber import ( + SpecificationBatchSubscriber, + SpecificationDefaultSubscriber, ) if TYPE_CHECKING: @@ -40,11 +40,11 @@ def create_subscriber( retry: bool, broker_dependencies: Iterable["Depends"], broker_middlewares: Iterable["BrokerMiddleware[Tuple[ConfluentMsg, ...]]"], - # AsyncAPI args + # Specification args title_: Optional[str], description_: Optional[str], include_in_schema: bool, -) -> "AsyncAPIBatchSubscriber": ... +) -> "SpecificationBatchSubscriber": ... @overload @@ -64,11 +64,11 @@ def create_subscriber( retry: bool, broker_dependencies: Iterable["Depends"], broker_middlewares: Iterable["BrokerMiddleware[ConfluentMsg]"], - # AsyncAPI args + # Specification args title_: Optional[str], description_: Optional[str], include_in_schema: bool, -) -> "AsyncAPIDefaultSubscriber": ... +) -> "SpecificationDefaultSubscriber": ... @overload @@ -90,13 +90,13 @@ def create_subscriber( broker_middlewares: Iterable[ "BrokerMiddleware[Union[ConfluentMsg, Tuple[ConfluentMsg, ...]]]" ], - # AsyncAPI args + # Specification args title_: Optional[str], description_: Optional[str], include_in_schema: bool, ) -> Union[ - "AsyncAPIDefaultSubscriber", - "AsyncAPIBatchSubscriber", + "SpecificationDefaultSubscriber", + "SpecificationBatchSubscriber", ]: ... @@ -118,16 +118,16 @@ def create_subscriber( broker_middlewares: Iterable[ "BrokerMiddleware[Union[ConfluentMsg, Tuple[ConfluentMsg, ...]]]" ], - # AsyncAPI args + # Specification args title_: Optional[str], description_: Optional[str], include_in_schema: bool, ) -> Union[ - "AsyncAPIDefaultSubscriber", - "AsyncAPIBatchSubscriber", + "SpecificationDefaultSubscriber", + "SpecificationBatchSubscriber", ]: if batch: - return AsyncAPIBatchSubscriber( + return SpecificationBatchSubscriber( *topics, partitions=partitions, polling_interval=polling_interval, @@ -145,7 +145,7 @@ def create_subscriber( include_in_schema=include_in_schema, ) else: - return AsyncAPIDefaultSubscriber( + return SpecificationDefaultSubscriber( *topics, partitions=partitions, polling_interval=polling_interval, diff --git a/faststream/confluent/subscriber/asyncapi.py b/faststream/confluent/subscriber/subscriber.py similarity index 87% rename from faststream/confluent/subscriber/asyncapi.py rename to faststream/confluent/subscriber/subscriber.py index 615c4361c3..172e3f546c 100644 --- a/faststream/confluent/subscriber/asyncapi.py +++ b/faststream/confluent/subscriber/subscriber.py @@ -20,7 +20,7 @@ from confluent_kafka import Message as ConfluentMsg -class AsyncAPISubscriber(LogicSubscriber[MsgType]): +class SpecificationSubscriber(LogicSubscriber[MsgType]): """A class to handle logic and async API operations.""" def get_name(self) -> str: @@ -52,15 +52,15 @@ def get_schema(self) -> Dict[str, Channel]: return channels -class AsyncAPIDefaultSubscriber( +class SpecificationDefaultSubscriber( DefaultSubscriber, - AsyncAPISubscriber["ConfluentMsg"], + SpecificationSubscriber["ConfluentMsg"], ): pass -class AsyncAPIBatchSubscriber( +class SpecificationBatchSubscriber( BatchSubscriber, - AsyncAPISubscriber[Tuple["ConfluentMsg", ...]], + SpecificationSubscriber[Tuple["ConfluentMsg", ...]], ): pass diff --git a/faststream/confluent/testing.py b/faststream/confluent/testing.py index 10d0fd5b20..62ecb2923e 100644 --- a/faststream/confluent/testing.py +++ b/faststream/confluent/testing.py @@ -9,16 +9,18 @@ from faststream.broker.utils import resolve_custom_func from faststream.confluent.broker import KafkaBroker from faststream.confluent.parser import AsyncConfluentParser -from faststream.confluent.publisher.asyncapi import AsyncAPIBatchPublisher from faststream.confluent.publisher.producer import AsyncConfluentFastProducer +from faststream.confluent.publisher.publisher import SpecificationBatchPublisher from faststream.confluent.schemas import TopicPartition -from faststream.confluent.subscriber.asyncapi import AsyncAPIBatchSubscriber from faststream.exceptions import SubscriberNotFound from faststream.testing.broker import TestBroker from faststream.utils.functions import timeout_scope if TYPE_CHECKING: - from faststream.confluent.publisher.asyncapi import AsyncAPIPublisher + from faststream.confluent.subscriber.subscriber import SpecificationBatchSubscriber + from faststream.testing.broker import TestBroker, call_handler + from faststream.broker.wrapper.call import HandlerCallWrapper + from faststream.confluent.publisher.publisher import SpecificationPublisher from faststream.confluent.subscriber.usecase import LogicSubscriber from faststream.types import SendableMessage @@ -40,7 +42,7 @@ async def _fake_connect( # type: ignore[override] @staticmethod def create_publisher_fake_subscriber( broker: KafkaBroker, - publisher: "AsyncAPIPublisher[Any]", + publisher: "SpecificationPublisher[Any]", ) -> Tuple["LogicSubscriber[Any]", bool]: sub: Optional[LogicSubscriber[Any]] = None for handler in broker._subscribers.values(): @@ -59,13 +61,13 @@ def create_publisher_fake_subscriber( ) sub = broker.subscriber( partitions=[tp], - batch=isinstance(publisher, AsyncAPIBatchPublisher), + batch=isinstance(publisher, SpecificationBatchPublisher), auto_offset_reset="earliest", ) else: sub = broker.subscriber( publisher.topic, - batch=isinstance(publisher, AsyncAPIBatchPublisher), + batch=isinstance(publisher, SpecificationBatchPublisher), auto_offset_reset="earliest", ) @@ -124,7 +126,7 @@ async def publish( # type: ignore[override] if _is_handler_matches(handler, topic, partition): msg_to_send = ( [incoming] - if isinstance(handler, AsyncAPIBatchSubscriber) + if isinstance(handler, SpecificationBatchSubscriber) else incoming ) @@ -166,7 +168,7 @@ async def publish_batch( for message in msgs ) - if isinstance(handler, AsyncAPIBatchSubscriber): + if isinstance(handler, SpecificationBatchSubscriber): await self._execute_handler(list(messages), topic, handler) else: @@ -202,7 +204,7 @@ async def request( # type: ignore[override] if _is_handler_matches(handler, topic, partition): msg_to_send = ( [incoming] - if isinstance(handler, AsyncAPIBatchSubscriber) + if isinstance(handler, SpecificationBatchSubscriber) else incoming ) diff --git a/faststream/kafka/broker/registrator.py b/faststream/kafka/broker/registrator.py index 1cb3fa38e2..dba09de7eb 100644 --- a/faststream/kafka/broker/registrator.py +++ b/faststream/kafka/broker/registrator.py @@ -19,7 +19,7 @@ from faststream.broker.core.abc import ABCBroker from faststream.broker.utils import default_filter -from faststream.kafka.publisher.asyncapi import AsyncAPIPublisher +from faststream.kafka.publisher.publisher import SpecificationPublisher from faststream.kafka.subscriber.factory import create_subscriber if TYPE_CHECKING: @@ -35,13 +35,13 @@ SubscriberMiddleware, ) from faststream.kafka.message import KafkaMessage - from faststream.kafka.publisher.asyncapi import ( - AsyncAPIBatchPublisher, - AsyncAPIDefaultPublisher, + from faststream.kafka.publisher.publisher import ( + SpecificationBatchPublisher, + SpecificationDefaultPublisher, ) - from faststream.kafka.subscriber.asyncapi import ( - AsyncAPIBatchSubscriber, - AsyncAPIDefaultSubscriber, + from faststream.kafka.subscriber.subscriber import ( + SpecificationBatchSubscriber, + SpecificationDefaultSubscriber, ) @@ -57,11 +57,11 @@ class KafkaRegistrator( _subscribers: Dict[ int, - Union["AsyncAPIBatchSubscriber", "AsyncAPIDefaultSubscriber"], + Union["SpecificationBatchSubscriber", "SpecificationDefaultSubscriber"], ] _publishers: Dict[ int, - Union["AsyncAPIBatchPublisher", "AsyncAPIDefaultPublisher"], + Union["SpecificationBatchPublisher", "SpecificationDefaultPublisher"], ] @overload # type: ignore[override] @@ -427,23 +427,23 @@ def subscriber( "Whether to disable **FastStream** RPC and Reply To auto responses or not." ), ] = False, - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI subscriber object title."), + Doc("Specification subscriber object title."), ] = None, description: Annotated[ Optional[str], Doc( - "AsyncAPI subscriber object description. " + "Specification subscriber object description. " "Uses decorated docstring as default." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, - ) -> "AsyncAPIDefaultSubscriber": ... + ) -> "SpecificationDefaultSubscriber": ... @overload def subscriber( @@ -808,23 +808,23 @@ def subscriber( "Whether to disable **FastStream** RPC and Reply To auto responses or not." ), ] = False, - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI subscriber object title."), + Doc("Specification subscriber object title."), ] = None, description: Annotated[ Optional[str], Doc( - "AsyncAPI subscriber object description. " + "Specification subscriber object description. " "Uses decorated docstring as default." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, - ) -> "AsyncAPIBatchSubscriber": ... + ) -> "SpecificationBatchSubscriber": ... @overload def subscriber( @@ -1189,25 +1189,25 @@ def subscriber( "Whether to disable **FastStream** RPC and Reply To auto responses or not." ), ] = False, - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI subscriber object title."), + Doc("Specification subscriber object title."), ] = None, description: Annotated[ Optional[str], Doc( - "AsyncAPI subscriber object description. " + "Specification subscriber object description. " "Uses decorated docstring as default." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, ) -> Union[ - "AsyncAPIDefaultSubscriber", - "AsyncAPIBatchSubscriber", + "SpecificationDefaultSubscriber", + "SpecificationBatchSubscriber", ]: ... @override @@ -1573,25 +1573,25 @@ def subscriber( "Whether to disable **FastStream** RPC and Reply To auto responses or not." ), ] = False, - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI subscriber object title."), + Doc("Specification subscriber object title."), ] = None, description: Annotated[ Optional[str], Doc( - "AsyncAPI subscriber object description. " + "Specification subscriber object description. " "Uses decorated docstring as default." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, ) -> Union[ - "AsyncAPIDefaultSubscriber", - "AsyncAPIBatchSubscriber", + "SpecificationDefaultSubscriber", + "SpecificationBatchSubscriber", ]: subscriber = super().subscriber( create_subscriber( @@ -1631,7 +1631,7 @@ def subscriber( retry=retry, broker_middlewares=self._middlewares, broker_dependencies=self._dependencies, - # AsyncAPI + # Specification title_=title, description_=description, include_in_schema=self._solve_include_in_schema(include_in_schema), @@ -1639,7 +1639,7 @@ def subscriber( ) if batch: - return cast("AsyncAPIBatchSubscriber", subscriber).add_call( + return cast("SpecificationBatchSubscriber", subscriber).add_call( filter_=filter, parser_=parser or self._parser, decoder_=decoder or self._decoder, @@ -1648,7 +1648,7 @@ def subscriber( ) else: - return cast("AsyncAPIDefaultSubscriber", subscriber).add_call( + return cast("SpecificationDefaultSubscriber", subscriber).add_call( filter_=filter, parser_=parser or self._parser, decoder_=decoder or self._decoder, @@ -1708,27 +1708,27 @@ def publisher( Iterable["PublisherMiddleware"], Doc("Publisher middlewares to wrap outgoing messages."), ] = (), - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI publisher object title."), + Doc("Specification publisher object title."), ] = None, description: Annotated[ Optional[str], - Doc("AsyncAPI publisher object description."), + Doc("Specification publisher object description."), ] = None, schema: Annotated[ Optional[Any], Doc( - "AsyncAPI publishing message type. " + "Specification publishing message type. " "Should be any python-native object annotation or `pydantic.BaseModel`." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, - ) -> "AsyncAPIDefaultPublisher": ... + ) -> "SpecificationDefaultPublisher": ... @overload def publisher( @@ -1782,27 +1782,27 @@ def publisher( Iterable["PublisherMiddleware"], Doc("Publisher middlewares to wrap outgoing messages."), ] = (), - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI publisher object title."), + Doc("Specification publisher object title."), ] = None, description: Annotated[ Optional[str], - Doc("AsyncAPI publisher object description."), + Doc("Specification publisher object description."), ] = None, schema: Annotated[ Optional[Any], Doc( - "AsyncAPI publishing message type. " + "Specification publishing message type. " "Should be any python-native object annotation or `pydantic.BaseModel`." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, - ) -> "AsyncAPIBatchPublisher": ... + ) -> "SpecificationBatchPublisher": ... @overload def publisher( @@ -1856,29 +1856,29 @@ def publisher( Iterable["PublisherMiddleware"], Doc("Publisher middlewares to wrap outgoing messages."), ] = (), - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI publisher object title."), + Doc("Specification publisher object title."), ] = None, description: Annotated[ Optional[str], - Doc("AsyncAPI publisher object description."), + Doc("Specification publisher object description."), ] = None, schema: Annotated[ Optional[Any], Doc( - "AsyncAPI publishing message type. " + "Specification publishing message type. " "Should be any python-native object annotation or `pydantic.BaseModel`." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, ) -> Union[ - "AsyncAPIBatchPublisher", - "AsyncAPIDefaultPublisher", + "SpecificationBatchPublisher", + "SpecificationDefaultPublisher", ]: ... @override @@ -1933,38 +1933,38 @@ def publisher( Iterable["PublisherMiddleware"], Doc("Publisher middlewares to wrap outgoing messages."), ] = (), - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI publisher object title."), + Doc("Specification publisher object title."), ] = None, description: Annotated[ Optional[str], - Doc("AsyncAPI publisher object description."), + Doc("Specification publisher object description."), ] = None, schema: Annotated[ Optional[Any], Doc( - "AsyncAPI publishing message type. " + "Specification publishing message type. " "Should be any python-native object annotation or `pydantic.BaseModel`." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, ) -> Union[ - "AsyncAPIBatchPublisher", - "AsyncAPIDefaultPublisher", + "SpecificationBatchPublisher", + "SpecificationDefaultPublisher", ]: - """Creates long-living and AsyncAPI-documented publisher object. + """Creates long-living and Specification-documented publisher object. You can use it as a handler decorator (handler should be decorated by `@broker.subscriber(...)` too) - `@broker.publisher(...)`. In such case publisher will publish your handler return value. Or you can create a publisher object to call it lately - `broker.publisher(...).publish(...)`. """ - publisher = AsyncAPIPublisher.create( + publisher = SpecificationPublisher.create( # batch flag batch=batch, # default args @@ -1977,7 +1977,7 @@ def publisher( # publisher-specific broker_middlewares=self._middlewares, middlewares=middlewares, - # AsyncAPI + # Specification title_=title, description_=description, schema_=schema, @@ -1985,6 +1985,6 @@ def publisher( ) if batch: - return cast("AsyncAPIBatchPublisher", super().publisher(publisher)) + return cast("SpecificationBatchPublisher", super().publisher(publisher)) else: - return cast("AsyncAPIDefaultPublisher", super().publisher(publisher)) + return cast("SpecificationDefaultPublisher", super().publisher(publisher)) diff --git a/faststream/kafka/fastapi/fastapi.py b/faststream/kafka/fastapi/fastapi.py index a80320e534..169a5e1026 100644 --- a/faststream/kafka/fastapi/fastapi.py +++ b/faststream/kafka/fastapi/fastapi.py @@ -55,13 +55,13 @@ SubscriberMiddleware, ) from faststream.kafka.message import KafkaMessage - from faststream.kafka.publisher.asyncapi import ( - AsyncAPIBatchPublisher, - AsyncAPIDefaultPublisher, + from faststream.kafka.publisher.publisher import ( + SpecificationBatchPublisher, + SpecificationDefaultPublisher, ) - from faststream.kafka.subscriber.asyncapi import ( - AsyncAPIBatchSubscriber, - AsyncAPIDefaultSubscriber, + from faststream.kafka.subscriber.subscriber import ( + SpecificationBatchSubscriber, + SpecificationDefaultSubscriber, ) from faststream.security import BaseSecurity from faststream.types import AnyDict, LoggerProto @@ -284,36 +284,36 @@ def __init__( ], Doc("Middlewares to apply to all broker publishers/subscribers."), ] = (), - # AsyncAPI args + # Specification args security: Annotated[ Optional["BaseSecurity"], Doc( - "Security options to connect broker and generate AsyncAPI server security information." + "Security options to connect broker and generate Specification server security information." ), ] = None, asyncapi_url: Annotated[ Optional[str], - Doc("AsyncAPI hardcoded server addresses. Use `servers` if not specified."), + Doc("Specification hardcoded server addresses. Use `servers` if not specified."), ] = None, protocol: Annotated[ Optional[str], - Doc("AsyncAPI server protocol."), + Doc("Specification server protocol."), ] = None, protocol_version: Annotated[ Optional[str], - Doc("AsyncAPI server protocol version."), + Doc("Specification server protocol version."), ] = "auto", description: Annotated[ Optional[str], - Doc("AsyncAPI server description."), + Doc("Specification server description."), ] = None, asyncapi_version: Annotated[ AsyncAPIVersion, - Doc("Version of AsyncAPI for schema generation") + Doc("Version of Specification for schema generation") ] = AsyncAPIVersion.v2_6, asyncapi_tags: Annotated[ Optional[Iterable[Union["asyncapi.Tag", "asyncapi.TagDict"]]], - Doc("AsyncAPI server tags."), + Doc("Specification server tags."), ] = None, # logging args logger: Annotated[ @@ -339,7 +339,7 @@ def __init__( schema_url: Annotated[ Optional[str], Doc( - "AsyncAPI schema url. You should set this option to `None` to disable AsyncAPI routes at all." + "Specification schema url. You should set this option to `None` to disable Specification routes at all." ), ] = "/asyncapi", # FastAPI args @@ -591,7 +591,7 @@ def __init__( logger=logger, log_level=log_level, log_fmt=log_fmt, - # AsyncAPI args + # Specification args security=security, protocol=protocol, description=description, @@ -979,21 +979,21 @@ def subscriber( "Whether to disable **FastStream** RPC and Reply To auto responses or not." ), ] = False, - # AsyncAPI information + # Specification information title: Annotated[ Optional[str], - Doc("AsyncAPI subscriber object title."), + Doc("Specification subscriber object title."), ] = None, description: Annotated[ Optional[str], Doc( - "AsyncAPI subscriber object description. " + "Specification subscriber object description. " "Uses decorated docstring as default." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, # FastAPI args response_model: Annotated[ @@ -1118,7 +1118,7 @@ def subscriber( """ ), ] = False, - ) -> "AsyncAPIDefaultSubscriber": ... + ) -> "SpecificationDefaultSubscriber": ... @overload def subscriber( @@ -1480,21 +1480,21 @@ def subscriber( "Whether to disable **FastStream** RPC and Reply To auto responses or not." ), ] = False, - # AsyncAPI information + # Specification information title: Annotated[ Optional[str], - Doc("AsyncAPI subscriber object title."), + Doc("Specification subscriber object title."), ] = None, description: Annotated[ Optional[str], Doc( - "AsyncAPI subscriber object description. " + "Specification subscriber object description. " "Uses decorated docstring as default." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, # FastAPI args response_model: Annotated[ @@ -1619,7 +1619,7 @@ def subscriber( """ ), ] = False, - ) -> "AsyncAPIBatchSubscriber": ... + ) -> "SpecificationBatchSubscriber": ... @overload def subscriber( @@ -1981,21 +1981,21 @@ def subscriber( "Whether to disable **FastStream** RPC and Reply To auto responses or not." ), ] = False, - # AsyncAPI information + # Specification information title: Annotated[ Optional[str], - Doc("AsyncAPI subscriber object title."), + Doc("Specification subscriber object title."), ] = None, description: Annotated[ Optional[str], Doc( - "AsyncAPI subscriber object description. " + "Specification subscriber object description. " "Uses decorated docstring as default." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, # FastAPI args response_model: Annotated[ @@ -2121,8 +2121,8 @@ def subscriber( ), ] = False, ) -> Union[ - "AsyncAPIBatchSubscriber", - "AsyncAPIDefaultSubscriber", + "SpecificationBatchSubscriber", + "SpecificationDefaultSubscriber", ]: ... @override @@ -2485,21 +2485,21 @@ def subscriber( "Whether to disable **FastStream** RPC and Reply To auto responses or not." ), ] = False, - # AsyncAPI information + # Specification information title: Annotated[ Optional[str], - Doc("AsyncAPI subscriber object title."), + Doc("Specification subscriber object title."), ] = None, description: Annotated[ Optional[str], Doc( - "AsyncAPI subscriber object description. " + "Specification subscriber object description. " "Uses decorated docstring as default." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, # FastAPI args response_model: Annotated[ @@ -2625,8 +2625,8 @@ def subscriber( ), ] = False, ) -> Union[ - "AsyncAPIBatchSubscriber", - "AsyncAPIDefaultSubscriber", + "SpecificationBatchSubscriber", + "SpecificationDefaultSubscriber", ]: subscriber = super().subscriber( *topics, @@ -2679,9 +2679,9 @@ def subscriber( ) if batch: - return cast("AsyncAPIBatchSubscriber", subscriber) + return cast("SpecificationBatchSubscriber", subscriber) else: - return cast("AsyncAPIDefaultSubscriber", subscriber) + return cast("SpecificationDefaultSubscriber", subscriber) @overload # type: ignore[override] def publisher( @@ -2735,27 +2735,27 @@ def publisher( Iterable["PublisherMiddleware"], Doc("Publisher middlewares to wrap outgoing messages."), ] = (), - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI publisher object title."), + Doc("Specification publisher object title."), ] = None, description: Annotated[ Optional[str], - Doc("AsyncAPI publisher object description."), + Doc("Specification publisher object description."), ] = None, schema: Annotated[ Optional[Any], Doc( - "AsyncAPI publishing message type. " + "Specification publishing message type. " "Should be any python-native object annotation or `pydantic.BaseModel`." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, - ) -> "AsyncAPIDefaultPublisher": ... + ) -> "SpecificationDefaultPublisher": ... @overload def publisher( @@ -2809,27 +2809,27 @@ def publisher( Iterable["PublisherMiddleware"], Doc("Publisher middlewares to wrap outgoing messages."), ] = (), - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI publisher object title."), + Doc("Specification publisher object title."), ] = None, description: Annotated[ Optional[str], - Doc("AsyncAPI publisher object description."), + Doc("Specification publisher object description."), ] = None, schema: Annotated[ Optional[Any], Doc( - "AsyncAPI publishing message type. " + "Specification publishing message type. " "Should be any python-native object annotation or `pydantic.BaseModel`." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, - ) -> "AsyncAPIBatchPublisher": ... + ) -> "SpecificationBatchPublisher": ... @overload def publisher( @@ -2883,29 +2883,29 @@ def publisher( Iterable["PublisherMiddleware"], Doc("Publisher middlewares to wrap outgoing messages."), ] = (), - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI publisher object title."), + Doc("Specification publisher object title."), ] = None, description: Annotated[ Optional[str], - Doc("AsyncAPI publisher object description."), + Doc("Specification publisher object description."), ] = None, schema: Annotated[ Optional[Any], Doc( - "AsyncAPI publishing message type. " + "Specification publishing message type. " "Should be any python-native object annotation or `pydantic.BaseModel`." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, ) -> Union[ - "AsyncAPIBatchPublisher", - "AsyncAPIDefaultPublisher", + "SpecificationBatchPublisher", + "SpecificationDefaultPublisher", ]: ... @override @@ -2960,29 +2960,29 @@ def publisher( Iterable["PublisherMiddleware"], Doc("Publisher middlewares to wrap outgoing messages."), ] = (), - # AsyncAPI args + # Specification args title: Annotated[ Optional[str], - Doc("AsyncAPI publisher object title."), + Doc("Specification publisher object title."), ] = None, description: Annotated[ Optional[str], - Doc("AsyncAPI publisher object description."), + Doc("Specification publisher object description."), ] = None, schema: Annotated[ Optional[Any], Doc( - "AsyncAPI publishing message type. " + "Specification publishing message type. " "Should be any python-native object annotation or `pydantic.BaseModel`." ), ] = None, include_in_schema: Annotated[ bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), + Doc("Whetever to include operation in Specification schema or not."), ] = True, ) -> Union[ - "AsyncAPIBatchPublisher", - "AsyncAPIDefaultPublisher", + "SpecificationBatchPublisher", + "SpecificationDefaultPublisher", ]: return self.broker.publisher( topic=topic, @@ -2993,7 +2993,7 @@ def publisher( reply_to=reply_to, # broker options middlewares=middlewares, - # AsyncAPI options + # Specification options title=title, description=description, schema=schema, diff --git a/faststream/kafka/publisher/asyncapi.py b/faststream/kafka/publisher/publisher.py similarity index 87% rename from faststream/kafka/publisher/asyncapi.py rename to faststream/kafka/publisher/publisher.py index 386d08f5f3..7f9bb744e6 100644 --- a/faststream/kafka/publisher/asyncapi.py +++ b/faststream/kafka/publisher/publisher.py @@ -31,7 +31,7 @@ from faststream.broker.types import BrokerMiddleware, PublisherMiddleware -class AsyncAPIPublisher(LogicPublisher[MsgType]): +class SpecificationPublisher(LogicPublisher[MsgType]): """A class representing a publisher.""" def get_name(self) -> str: @@ -69,12 +69,12 @@ def create( # Publisher args broker_middlewares: Iterable["BrokerMiddleware[Tuple[ConsumerRecord, ...]]"], middlewares: Iterable["PublisherMiddleware"], - # AsyncAPI args + # Specification args schema_: Optional[Any], title_: Optional[str], description_: Optional[str], include_in_schema: bool, - ) -> "AsyncAPIBatchPublisher": ... + ) -> "SpecificationBatchPublisher": ... @overload @staticmethod @@ -89,12 +89,12 @@ def create( # Publisher args broker_middlewares: Iterable["BrokerMiddleware[ConsumerRecord]"], middlewares: Iterable["PublisherMiddleware"], - # AsyncAPI args + # Specification args schema_: Optional[Any], title_: Optional[str], description_: Optional[str], include_in_schema: bool, - ) -> "AsyncAPIDefaultPublisher": ... + ) -> "SpecificationDefaultPublisher": ... @overload @staticmethod @@ -111,14 +111,14 @@ def create( "BrokerMiddleware[Union[Tuple[ConsumerRecord, ...], ConsumerRecord]]" ], middlewares: Iterable["PublisherMiddleware"], - # AsyncAPI args + # Specification args schema_: Optional[Any], title_: Optional[str], description_: Optional[str], include_in_schema: bool, ) -> Union[ - "AsyncAPIBatchPublisher", - "AsyncAPIDefaultPublisher", + "SpecificationBatchPublisher", + "SpecificationDefaultPublisher", ]: ... @override @@ -136,20 +136,20 @@ def create( "BrokerMiddleware[Union[Tuple[ConsumerRecord, ...], ConsumerRecord]]" ], middlewares: Iterable["PublisherMiddleware"], - # AsyncAPI args + # Specification args schema_: Optional[Any], title_: Optional[str], description_: Optional[str], include_in_schema: bool, ) -> Union[ - "AsyncAPIBatchPublisher", - "AsyncAPIDefaultPublisher", + "SpecificationBatchPublisher", + "SpecificationDefaultPublisher", ]: if batch: if key: raise SetupError("You can't setup `key` with batch publisher") - return AsyncAPIBatchPublisher( + return SpecificationBatchPublisher( topic=topic, partition=partition, headers=headers, @@ -162,7 +162,7 @@ def create( include_in_schema=include_in_schema, ) else: - return AsyncAPIDefaultPublisher( + return SpecificationDefaultPublisher( key=key, # basic args topic=topic, @@ -178,15 +178,15 @@ def create( ) -class AsyncAPIBatchPublisher( +class SpecificationBatchPublisher( BatchPublisher, - AsyncAPIPublisher[Tuple["ConsumerRecord", ...]], + SpecificationPublisher[Tuple["ConsumerRecord", ...]], ): pass -class AsyncAPIDefaultPublisher( +class SpecificationDefaultPublisher( DefaultPublisher, - AsyncAPIPublisher["ConsumerRecord"], + SpecificationPublisher["ConsumerRecord"], ): pass diff --git a/faststream/kafka/subscriber/factory.py b/faststream/kafka/subscriber/factory.py index 0f504667f4..a58843d52f 100644 --- a/faststream/kafka/subscriber/factory.py +++ b/faststream/kafka/subscriber/factory.py @@ -9,9 +9,9 @@ ) from faststream.exceptions import SetupError -from faststream.kafka.subscriber.asyncapi import ( - AsyncAPIBatchSubscriber, - AsyncAPIDefaultSubscriber, +from faststream.kafka.subscriber.subscriber import ( + SpecificationBatchSubscriber, + SpecificationDefaultSubscriber, ) if TYPE_CHECKING: @@ -42,11 +42,11 @@ def create_subscriber( retry: bool, broker_dependencies: Iterable["Depends"], broker_middlewares: Iterable["BrokerMiddleware[Tuple[ConsumerRecord, ...]]"], - # AsyncAPI args + # Specification args title_: Optional[str], description_: Optional[str], include_in_schema: bool, -) -> "AsyncAPIBatchSubscriber": ... +) -> "SpecificationBatchSubscriber": ... @overload @@ -68,11 +68,11 @@ def create_subscriber( retry: bool, broker_dependencies: Iterable["Depends"], broker_middlewares: Iterable["BrokerMiddleware[ConsumerRecord]"], - # AsyncAPI args + # Specification args title_: Optional[str], description_: Optional[str], include_in_schema: bool, -) -> "AsyncAPIDefaultSubscriber": ... +) -> "SpecificationDefaultSubscriber": ... @overload @@ -96,13 +96,13 @@ def create_subscriber( broker_middlewares: Iterable[ "BrokerMiddleware[Union[ConsumerRecord, Tuple[ConsumerRecord, ...]]]" ], - # AsyncAPI args + # Specification args title_: Optional[str], description_: Optional[str], include_in_schema: bool, ) -> Union[ - "AsyncAPIDefaultSubscriber", - "AsyncAPIBatchSubscriber", + "SpecificationDefaultSubscriber", + "SpecificationBatchSubscriber", ]: ... @@ -126,13 +126,13 @@ def create_subscriber( broker_middlewares: Iterable[ "BrokerMiddleware[Union[ConsumerRecord, Tuple[ConsumerRecord, ...]]]" ], - # AsyncAPI args + # Specification args title_: Optional[str], description_: Optional[str], include_in_schema: bool, ) -> Union[ - "AsyncAPIDefaultSubscriber", - "AsyncAPIBatchSubscriber", + "SpecificationDefaultSubscriber", + "SpecificationBatchSubscriber", ]: if is_manual and not group_id: raise SetupError("You must use `group_id` with manual commit mode.") @@ -149,7 +149,7 @@ def create_subscriber( raise SetupError("You can't provide both `partitions` and `pattern`.") if batch: - return AsyncAPIBatchSubscriber( + return SpecificationBatchSubscriber( *topics, batch_timeout_ms=batch_timeout_ms, max_records=max_records, @@ -170,7 +170,7 @@ def create_subscriber( ) else: - return AsyncAPIDefaultSubscriber( + return SpecificationDefaultSubscriber( *topics, group_id=group_id, listener=listener, diff --git a/faststream/kafka/subscriber/asyncapi.py b/faststream/kafka/subscriber/subscriber.py similarity index 87% rename from faststream/kafka/subscriber/asyncapi.py rename to faststream/kafka/subscriber/subscriber.py index d0d33d13f6..aaa33d1428 100644 --- a/faststream/kafka/subscriber/asyncapi.py +++ b/faststream/kafka/subscriber/subscriber.py @@ -20,7 +20,7 @@ from aiokafka import ConsumerRecord -class AsyncAPISubscriber(LogicSubscriber[MsgType]): +class SpecificationSubscriber(LogicSubscriber[MsgType]): """A class to handle logic and async API operations.""" def get_name(self) -> str: @@ -53,15 +53,15 @@ def get_schema(self) -> Dict[str, Channel]: return channels -class AsyncAPIDefaultSubscriber( +class SpecificationDefaultSubscriber( DefaultSubscriber, - AsyncAPISubscriber["ConsumerRecord"], + SpecificationSubscriber["ConsumerRecord"], ): pass -class AsyncAPIBatchSubscriber( +class SpecificationBatchSubscriber( BatchSubscriber, - AsyncAPISubscriber[Tuple["ConsumerRecord", ...]], + SpecificationSubscriber[Tuple["ConsumerRecord", ...]], ): pass diff --git a/faststream/kafka/testing.py b/faststream/kafka/testing.py index e538fbb70d..37e77dcf3e 100755 --- a/faststream/kafka/testing.py +++ b/faststream/kafka/testing.py @@ -14,14 +14,18 @@ from faststream.kafka.broker import KafkaBroker from faststream.kafka.message import KafkaMessage from faststream.kafka.parser import AioKafkaParser -from faststream.kafka.publisher.asyncapi import AsyncAPIBatchPublisher from faststream.kafka.publisher.producer import AioKafkaFastProducer -from faststream.kafka.subscriber.asyncapi import AsyncAPIBatchSubscriber from faststream.testing.broker import TestBroker from faststream.utils.functions import timeout_scope if TYPE_CHECKING: - from faststream.kafka.publisher.asyncapi import AsyncAPIPublisher + from faststream.kafka.publisher.producer import AioKafkaFastProducer + from faststream.kafka.publisher.publisher import SpecificationBatchPublisher + from faststream.kafka.subscriber.subscriber import SpecificationBatchSubscriber + from faststream.testing.broker import TestBroker + +if TYPE_CHECKING: + from faststream.kafka.publisher.publisher import SpecificationPublisher from faststream.kafka.subscriber.usecase import LogicSubscriber from faststream.types import SendableMessage @@ -43,7 +47,7 @@ async def _fake_connect( # type: ignore[override] @staticmethod def create_publisher_fake_subscriber( broker: KafkaBroker, - publisher: "AsyncAPIPublisher[Any]", + publisher: "SpecificationPublisher[Any]", ) -> Tuple["LogicSubscriber[Any]", bool]: sub: Optional[LogicSubscriber[Any]] = None for handler in broker._subscribers.values(): @@ -60,12 +64,12 @@ def create_publisher_fake_subscriber( ) sub = broker.subscriber( partitions=[tp], - batch=isinstance(publisher, AsyncAPIBatchPublisher), + batch=isinstance(publisher, SpecificationBatchPublisher), ) else: sub = broker.subscriber( publisher.topic, - batch=isinstance(publisher, AsyncAPIBatchPublisher), + batch=isinstance(publisher, SpecificationBatchPublisher), ) else: is_real = True @@ -125,7 +129,7 @@ async def publish( # type: ignore[override] if _is_handler_matches(handler, topic, partition): msg_to_send = ( [incoming] - if isinstance(handler, AsyncAPIBatchSubscriber) + if isinstance(handler, SpecificationBatchSubscriber) else incoming ) @@ -167,7 +171,7 @@ async def request( # type: ignore[override] if _is_handler_matches(handler, topic, partition): msg_to_send = ( [incoming] - if isinstance(handler, AsyncAPIBatchSubscriber) + if isinstance(handler, SpecificationBatchSubscriber) else incoming ) @@ -203,7 +207,7 @@ async def publish_batch( for message in msgs ) - if isinstance(handler, AsyncAPIBatchSubscriber): + if isinstance(handler, SpecificationBatchSubscriber): await self._execute_handler(list(messages), topic, handler) else: diff --git a/faststream/nats/broker/broker.py b/faststream/nats/broker/broker.py index ae956d50e7..297822f8e5 100644 --- a/faststream/nats/broker/broker.py +++ b/faststream/nats/broker/broker.py @@ -36,7 +36,7 @@ from faststream.nats.helpers import KVBucketDeclarer, OSBucketDeclarer from faststream.nats.publisher.producer import NatsFastProducer, NatsJSFastProducer from faststream.nats.security import parse_security -from faststream.nats.subscriber.asyncapi import AsyncAPISubscriber +from faststream.nats.subscriber.subscriber import SpecificationSubscriber from faststream.types import EMPTY if TYPE_CHECKING: @@ -66,7 +66,7 @@ CustomCallable, ) from faststream.nats.message import NatsMessage - from faststream.nats.publisher.asyncapi import AsyncAPIPublisher + from faststream.nats.publisher.publisher import SpecificationPublisher from faststream.security import BaseSecurity from faststream.types import ( AnyDict, @@ -633,7 +633,7 @@ async def start(self) -> None: ) except BadRequestError as e: # noqa: PERF203 - log_context = AsyncAPISubscriber.build_log_context( + log_context = SpecificationSubscriber.build_log_context( message=None, subject="", queue="", @@ -844,7 +844,7 @@ async def request( # type: ignore[override] @override def setup_subscriber( # type: ignore[override] self, - subscriber: "AsyncAPISubscriber", + subscriber: "SpecificationSubscriber", ) -> None: connection: Union[ Client, @@ -874,7 +874,7 @@ def setup_subscriber( # type: ignore[override] @override def setup_publisher( # type: ignore[override] self, - publisher: "AsyncAPIPublisher", + publisher: "SpecificationPublisher", ) -> None: producer: Optional[ProducerProto] = None @@ -951,7 +951,7 @@ def _log_connection_broken( self, error_cb: Optional["ErrorCallback"] = None, ) -> "ErrorCallback": - c = AsyncAPISubscriber.build_log_context(None, "") + c = SpecificationSubscriber.build_log_context(None, "") async def wrapper(err: Exception) -> None: if error_cb is not None: @@ -969,7 +969,7 @@ def _log_reconnected( self, cb: Optional["Callback"] = None, ) -> "Callback": - c = AsyncAPISubscriber.build_log_context(None, "") + c = SpecificationSubscriber.build_log_context(None, "") async def wrapper() -> None: if cb is not None: diff --git a/faststream/nats/broker/registrator.py b/faststream/nats/broker/registrator.py index fb7aaf8e7f..42d8c0ca88 100644 --- a/faststream/nats/broker/registrator.py +++ b/faststream/nats/broker/registrator.py @@ -6,10 +6,10 @@ from faststream.broker.core.abc import ABCBroker from faststream.broker.utils import default_filter from faststream.nats.helpers import StreamBuilder -from faststream.nats.publisher.asyncapi import AsyncAPIPublisher +from faststream.nats.publisher.publisher import SpecificationPublisher from faststream.nats.schemas import JStream, KvWatch, ObjWatch, PullSub -from faststream.nats.subscriber.asyncapi import AsyncAPISubscriber from faststream.nats.subscriber.factory import create_subscriber +from faststream.nats.subscriber.subscriber import SpecificationSubscriber if TYPE_CHECKING: from fast_depends.dependencies import Depends @@ -28,8 +28,8 @@ class NatsRegistrator(ABCBroker["Msg"]): """Includable to NatsBroker router.""" - _subscribers: Dict[int, "AsyncAPISubscriber"] - _publishers: Dict[int, "AsyncAPIPublisher"] + _subscribers: Dict[int, "SpecificationSubscriber"] + _publishers: Dict[int, "SpecificationPublisher"] def __init__(self, **kwargs: Any) -> None: self._stream_builder = StreamBuilder() @@ -204,7 +204,7 @@ def subscriber( # type: ignore[override] bool, Doc("Whetever to include operation in AsyncAPI schema or not."), ] = True, - ) -> AsyncAPISubscriber: + ) -> SpecificationSubscriber: """Creates NATS subscriber object. You can use it as a handler decorator `@broker.subscriber(...)`. @@ -212,7 +212,7 @@ def subscriber( # type: ignore[override] stream = self._stream_builder.create(stream) subscriber = cast( - AsyncAPISubscriber, + SpecificationSubscriber, super().subscriber( create_subscriber( subject=subject, @@ -317,7 +317,7 @@ def publisher( # type: ignore[override] bool, Doc("Whetever to include operation in AsyncAPI schema or not."), ] = True, - ) -> "AsyncAPIPublisher": + ) -> "SpecificationPublisher": """Creates long-living and AsyncAPI-documented publisher object. You can use it as a handler decorator (handler should be decorated by `@broker.subscriber(...)` too) - `@broker.publisher(...)`. @@ -328,9 +328,9 @@ def publisher( # type: ignore[override] stream = self._stream_builder.create(stream) publisher = cast( - AsyncAPIPublisher, + SpecificationPublisher, super().publisher( - publisher=AsyncAPIPublisher.create( + publisher=SpecificationPublisher.create( subject=subject, headers=headers, # Core diff --git a/faststream/nats/fastapi/fastapi.py b/faststream/nats/fastapi/fastapi.py index db9152c433..c091b5e728 100644 --- a/faststream/nats/fastapi/fastapi.py +++ b/faststream/nats/fastapi/fastapi.py @@ -37,8 +37,8 @@ from faststream.broker.fastapi.router import StreamRouter from faststream.broker.utils import default_filter from faststream.nats.broker import NatsBroker -from faststream.nats.publisher.asyncapi import AsyncAPIPublisher -from faststream.nats.subscriber.asyncapi import AsyncAPISubscriber +from faststream.nats.publisher.publisher import SpecificationPublisher +from faststream.nats.subscriber.subscriber import SpecificationSubscriber from faststream.types import EMPTY if TYPE_CHECKING: @@ -868,9 +868,9 @@ def subscriber( # type: ignore[override] """ ), ] = False, - ) -> "AsyncAPISubscriber": + ) -> "SpecificationSubscriber": return cast( - AsyncAPISubscriber, + SpecificationSubscriber, super().subscriber( subject=subject, queue=queue, @@ -969,7 +969,7 @@ def publisher( # type: ignore[override] bool, Doc("Whetever to include operation in AsyncAPI schema or not."), ] = True, - ) -> AsyncAPIPublisher: + ) -> SpecificationPublisher: return self.broker.publisher( subject, headers=headers, diff --git a/faststream/nats/publisher/asyncapi.py b/faststream/nats/publisher/publisher.py similarity index 96% rename from faststream/nats/publisher/asyncapi.py rename to faststream/nats/publisher/publisher.py index 81bcfeccb5..135cefa19c 100644 --- a/faststream/nats/publisher/asyncapi.py +++ b/faststream/nats/publisher/publisher.py @@ -16,7 +16,7 @@ from faststream.nats.schemas.js_stream import JStream -class AsyncAPIPublisher(LogicPublisher): +class SpecificationPublisher(LogicPublisher): """A class to represent a NATS publisher.""" def get_name(self) -> str: @@ -63,7 +63,7 @@ def create( # type: ignore[override] title_: Optional[str], description_: Optional[str], include_in_schema: bool, - ) -> "AsyncAPIPublisher": + ) -> "SpecificationPublisher": return cls( subject=subject, reply_to=reply_to, diff --git a/faststream/nats/subscriber/factory.py b/faststream/nats/subscriber/factory.py index 1161c66550..51a7f84d8a 100644 --- a/faststream/nats/subscriber/factory.py +++ b/faststream/nats/subscriber/factory.py @@ -11,16 +11,16 @@ ) from faststream.exceptions import SetupError -from faststream.nats.subscriber.asyncapi import ( - AsyncAPIBatchPullStreamSubscriber, - AsyncAPIConcurrentCoreSubscriber, - AsyncAPIConcurrentPullStreamSubscriber, - AsyncAPIConcurrentPushStreamSubscriber, - AsyncAPICoreSubscriber, - AsyncAPIKeyValueWatchSubscriber, - AsyncAPIObjStoreWatchSubscriber, - AsyncAPIPullStreamSubscriber, - AsyncAPIStreamSubscriber, +from faststream.nats.subscriber.subscriber import ( + SpecificationBatchPullStreamSubscriber, + SpecificationConcurrentCoreSubscriber, + SpecificationConcurrentPullStreamSubscriber, + SpecificationConcurrentPushStreamSubscriber, + SpecificationCoreSubscriber, + SpecificationKeyValueWatchSubscriber, + SpecificationObjStoreWatchSubscriber, + SpecificationPullStreamSubscriber, + SpecificationStreamSubscriber, ) if TYPE_CHECKING: @@ -63,20 +63,20 @@ def create_subscriber( retry: Union[bool, int], broker_dependencies: Iterable["Depends"], broker_middlewares: Iterable["BrokerMiddleware[Any]"], - # AsyncAPI information + # Specification information title_: Optional[str], description_: Optional[str], include_in_schema: bool, ) -> Union[ - "AsyncAPICoreSubscriber", - "AsyncAPIConcurrentCoreSubscriber", - "AsyncAPIStreamSubscriber", - "AsyncAPIConcurrentPushStreamSubscriber", - "AsyncAPIPullStreamSubscriber", - "AsyncAPIConcurrentPullStreamSubscriber", - "AsyncAPIBatchPullStreamSubscriber", - "AsyncAPIKeyValueWatchSubscriber", - "AsyncAPIObjStoreWatchSubscriber", + "SpecificationCoreSubscriber", + "SpecificationConcurrentCoreSubscriber", + "SpecificationStreamSubscriber", + "SpecificationConcurrentPushStreamSubscriber", + "SpecificationPullStreamSubscriber", + "SpecificationConcurrentPullStreamSubscriber", + "SpecificationBatchPullStreamSubscriber", + "SpecificationKeyValueWatchSubscriber", + "SpecificationObjStoreWatchSubscriber", ]: if pull_sub is not None and stream is None: raise SetupError("Pull subscriber can be used only with a stream") @@ -123,7 +123,7 @@ def create_subscriber( } if obj_watch is not None: - return AsyncAPIObjStoreWatchSubscriber( + return SpecificationObjStoreWatchSubscriber( subject=subject, config=config, obj_watch=obj_watch, @@ -135,7 +135,7 @@ def create_subscriber( ) if kv_watch is not None: - return AsyncAPIKeyValueWatchSubscriber( + return SpecificationKeyValueWatchSubscriber( subject=subject, config=config, kv_watch=kv_watch, @@ -148,7 +148,7 @@ def create_subscriber( elif stream is None: if max_workers > 1: - return AsyncAPIConcurrentCoreSubscriber( + return SpecificationConcurrentCoreSubscriber( max_workers=max_workers, subject=subject, config=config, @@ -161,14 +161,14 @@ def create_subscriber( retry=retry, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, - # AsyncAPI information + # Specification title_=title_, description_=description_, include_in_schema=include_in_schema, ) else: - return AsyncAPICoreSubscriber( + return SpecificationCoreSubscriber( subject=subject, config=config, queue=queue, @@ -180,7 +180,7 @@ def create_subscriber( retry=retry, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, - # AsyncAPI information + # Specification title_=title_, description_=description_, include_in_schema=include_in_schema, @@ -189,7 +189,7 @@ def create_subscriber( else: if max_workers > 1: if pull_sub is not None: - return AsyncAPIConcurrentPullStreamSubscriber( + return SpecificationConcurrentPullStreamSubscriber( max_workers=max_workers, pull_sub=pull_sub, stream=stream, @@ -203,14 +203,14 @@ def create_subscriber( retry=retry, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, - # AsyncAPI information + # Specification title_=title_, description_=description_, include_in_schema=include_in_schema, ) else: - return AsyncAPIConcurrentPushStreamSubscriber( + return SpecificationConcurrentPushStreamSubscriber( max_workers=max_workers, stream=stream, subject=subject, @@ -224,7 +224,7 @@ def create_subscriber( retry=retry, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, - # AsyncAPI information + # Specification title_=title_, description_=description_, include_in_schema=include_in_schema, @@ -233,7 +233,7 @@ def create_subscriber( else: if pull_sub is not None: if pull_sub.batch: - return AsyncAPIBatchPullStreamSubscriber( + return SpecificationBatchPullStreamSubscriber( pull_sub=pull_sub, stream=stream, subject=subject, @@ -246,14 +246,14 @@ def create_subscriber( retry=retry, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, - # AsyncAPI information + # Specification title_=title_, description_=description_, include_in_schema=include_in_schema, ) else: - return AsyncAPIPullStreamSubscriber( + return SpecificationPullStreamSubscriber( pull_sub=pull_sub, stream=stream, subject=subject, @@ -266,14 +266,14 @@ def create_subscriber( retry=retry, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, - # AsyncAPI information + # Specification title_=title_, description_=description_, include_in_schema=include_in_schema, ) else: - return AsyncAPIStreamSubscriber( + return SpecificationStreamSubscriber( stream=stream, subject=subject, queue=queue, @@ -286,7 +286,7 @@ def create_subscriber( retry=retry, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, - # AsyncAPI information + # Specification information title_=title_, description_=description_, include_in_schema=include_in_schema, diff --git a/faststream/nats/subscriber/asyncapi.py b/faststream/nats/subscriber/subscriber.py similarity index 56% rename from faststream/nats/subscriber/asyncapi.py rename to faststream/nats/subscriber/subscriber.py index 3202c0abc1..9c279e0021 100644 --- a/faststream/nats/subscriber/asyncapi.py +++ b/faststream/nats/subscriber/subscriber.py @@ -21,7 +21,7 @@ from faststream.specification.operation import Operation -class AsyncAPISubscriber(LogicSubscriber[Any]): +class SpecificationSubscriber(LogicSubscriber[Any]): """A class to represent a NATS handler.""" def get_name(self) -> str: @@ -52,40 +52,40 @@ def get_schema(self) -> Dict[str, Channel]: } -class AsyncAPICoreSubscriber(AsyncAPISubscriber, CoreSubscriber): - """One-message core consumer with AsyncAPI methods.""" +class SpecificationCoreSubscriber(SpecificationSubscriber, CoreSubscriber): + """One-message core consumer with Specification methods.""" -class AsyncAPIConcurrentCoreSubscriber(AsyncAPISubscriber, ConcurrentCoreSubscriber): - """One-message core concurrent consumer with AsyncAPI methods.""" +class SpecificationConcurrentCoreSubscriber(SpecificationSubscriber, ConcurrentCoreSubscriber): + """One-message core concurrent consumer with Specification methods.""" -class AsyncAPIStreamSubscriber(AsyncAPISubscriber, PushStreamSubscription): - """One-message JS Push consumer with AsyncAPI methods.""" +class SpecificationStreamSubscriber(SpecificationSubscriber, PushStreamSubscription): + """One-message JS Push consumer with Specification methods.""" -class AsyncAPIConcurrentPushStreamSubscriber( - AsyncAPISubscriber, ConcurrentPushStreamSubscriber +class SpecificationConcurrentPushStreamSubscriber( + SpecificationSubscriber, ConcurrentPushStreamSubscriber ): - """One-message JS Push concurrent consumer with AsyncAPI methods.""" + """One-message JS Push concurrent consumer with Specification methods.""" -class AsyncAPIPullStreamSubscriber(AsyncAPISubscriber, PullStreamSubscriber): - """One-message JS Pull consumer with AsyncAPI methods.""" +class SpecificationPullStreamSubscriber(SpecificationSubscriber, PullStreamSubscriber): + """One-message JS Pull consumer with Specification methods.""" -class AsyncAPIConcurrentPullStreamSubscriber( - AsyncAPISubscriber, ConcurrentPullStreamSubscriber +class SpecificationConcurrentPullStreamSubscriber( + SpecificationSubscriber, ConcurrentPullStreamSubscriber ): - """One-message JS Pull concurrent consumer with AsyncAPI methods.""" + """One-message JS Pull concurrent consumer with Specification methods.""" -class AsyncAPIBatchPullStreamSubscriber(AsyncAPISubscriber, BatchPullStreamSubscriber): - """Batch-message Pull consumer with AsyncAPI methods.""" +class SpecificationBatchPullStreamSubscriber(SpecificationSubscriber, BatchPullStreamSubscriber): + """Batch-message Pull consumer with Specification methods.""" -class AsyncAPIKeyValueWatchSubscriber(AsyncAPISubscriber, KeyValueWatchSubscriber): - """KeyValueWatch consumer with AsyncAPI methods.""" +class SpecificationKeyValueWatchSubscriber(SpecificationSubscriber, KeyValueWatchSubscriber): + """KeyValueWatch consumer with Specification methods.""" @override def get_name(self) -> str: @@ -96,8 +96,8 @@ def get_schema(self) -> Dict[str, Channel]: return {} -class AsyncAPIObjStoreWatchSubscriber(AsyncAPISubscriber, ObjStoreWatchSubscriber): - """ObjStoreWatch consumer with AsyncAPI methods.""" +class SpecificationObjStoreWatchSubscriber(SpecificationSubscriber, ObjStoreWatchSubscriber): + """ObjStoreWatch consumer with Specification methods.""" @override def get_name(self) -> str: diff --git a/faststream/nats/testing.py b/faststream/nats/testing.py index 011629093b..1c9548cf81 100644 --- a/faststream/nats/testing.py +++ b/faststream/nats/testing.py @@ -16,8 +16,9 @@ from faststream.utils.functions import timeout_scope if TYPE_CHECKING: - from faststream.nats.publisher.asyncapi import AsyncAPIPublisher from faststream.nats.subscriber.usecase import LogicSubscriber + from faststream.broker.wrapper.call import HandlerCallWrapper + from faststream.nats.publisher.publisher import SpecificationPublisher from faststream.types import AnyDict, SendableMessage __all__ = ("TestNatsBroker",) @@ -29,7 +30,7 @@ class TestNatsBroker(TestBroker[NatsBroker]): @staticmethod def create_publisher_fake_subscriber( broker: NatsBroker, - publisher: "AsyncAPIPublisher", + publisher: "SpecificationPublisher", ) -> Tuple["LogicSubscriber[Any]", bool]: sub: Optional[LogicSubscriber[Any]] = None publisher_stream = publisher.stream.name if publisher.stream else None diff --git a/faststream/rabbit/broker/broker.py b/faststream/rabbit/broker/broker.py index 774a88665e..584bd8b3a5 100644 --- a/faststream/rabbit/broker/broker.py +++ b/faststream/rabbit/broker/broker.py @@ -28,7 +28,7 @@ RabbitQueue, ) from faststream.rabbit.security import parse_security -from faststream.rabbit.subscriber.asyncapi import AsyncAPISubscriber +from faststream.rabbit.subscriber.subscriber import SpecificationSubscriber from faststream.rabbit.utils import build_url from faststream.types import EMPTY @@ -472,7 +472,7 @@ async def _connect( # type: ignore[override] ) if max_consumers: - c = AsyncAPISubscriber.build_log_context( + c = SpecificationSubscriber.build_log_context( None, RabbitQueue(""), RabbitExchange(""), diff --git a/faststream/rabbit/broker/registrator.py b/faststream/rabbit/broker/registrator.py index 8c6b0ba99c..4be99d8caf 100644 --- a/faststream/rabbit/broker/registrator.py +++ b/faststream/rabbit/broker/registrator.py @@ -4,14 +4,14 @@ from faststream.broker.core.abc import ABCBroker from faststream.broker.utils import default_filter -from faststream.rabbit.publisher.asyncapi import AsyncAPIPublisher +from faststream.rabbit.publisher.publisher import SpecificationPublisher from faststream.rabbit.publisher.usecase import PublishKwargs from faststream.rabbit.schemas import ( RabbitExchange, RabbitQueue, ) -from faststream.rabbit.subscriber.asyncapi import AsyncAPISubscriber from faststream.rabbit.subscriber.factory import create_subscriber +from faststream.rabbit.subscriber.subscriber import SpecificationSubscriber if TYPE_CHECKING: from aio_pika import IncomingMessage # noqa: F401 @@ -32,8 +32,8 @@ class RabbitRegistrator(ABCBroker["IncomingMessage"]): """Includable to RabbitBroker router.""" - _subscribers: Dict[int, "AsyncAPISubscriber"] - _publishers: Dict[int, "AsyncAPIPublisher"] + _subscribers: Dict[int, "SpecificationSubscriber"] + _publishers: Dict[int, "SpecificationPublisher"] @override def subscriber( # type: ignore[override] @@ -125,9 +125,9 @@ def subscriber( # type: ignore[override] bool, Doc("Whetever to include operation in AsyncAPI schema or not."), ] = True, - ) -> AsyncAPISubscriber: + ) -> SpecificationSubscriber: subscriber = cast( - AsyncAPISubscriber, + SpecificationSubscriber, super().subscriber( create_subscriber( queue=RabbitQueue.validate(queue), @@ -264,7 +264,7 @@ def publisher( # type: ignore[override] Optional[str], Doc("Publisher connection User ID, validated if set."), ] = None, - ) -> AsyncAPIPublisher: + ) -> SpecificationPublisher: """Creates long-living and AsyncAPI-documented publisher object. You can use it as a handler decorator (handler should be decorated by `@broker.subscriber(...)` too) - `@broker.publisher(...)`. @@ -288,9 +288,9 @@ def publisher( # type: ignore[override] ) publisher = cast( - AsyncAPIPublisher, + SpecificationPublisher, super().publisher( - AsyncAPIPublisher.create( + SpecificationPublisher.create( routing_key=routing_key, queue=RabbitQueue.validate(queue), exchange=RabbitExchange.validate(exchange), diff --git a/faststream/rabbit/fastapi/router.py b/faststream/rabbit/fastapi/router.py index 9d0f0ff72d..689695aa3b 100644 --- a/faststream/rabbit/fastapi/router.py +++ b/faststream/rabbit/fastapi/router.py @@ -25,12 +25,12 @@ from faststream.broker.fastapi.router import StreamRouter from faststream.broker.utils import default_filter from faststream.rabbit.broker.broker import RabbitBroker as RB -from faststream.rabbit.publisher.asyncapi import AsyncAPIPublisher +from faststream.rabbit.publisher.publisher import SpecificationPublisher from faststream.rabbit.schemas import ( RabbitExchange, RabbitQueue, ) -from faststream.rabbit.subscriber.asyncapi import AsyncAPISubscriber +from faststream.rabbit.subscriber.subscriber import SpecificationSubscriber from faststream.types import EMPTY if TYPE_CHECKING: @@ -696,9 +696,9 @@ def subscriber( # type: ignore[override] """ ), ] = False, - ) -> AsyncAPISubscriber: + ) -> SpecificationSubscriber: return cast( - AsyncAPISubscriber, + SpecificationSubscriber, super().subscriber( queue=queue, exchange=exchange, @@ -834,7 +834,7 @@ def publisher( Optional[str], Doc("Publisher connection User ID, validated if set."), ] = None, - ) -> AsyncAPIPublisher: + ) -> SpecificationPublisher: return self.broker.publisher( queue=queue, exchange=exchange, diff --git a/faststream/rabbit/publisher/asyncapi.py b/faststream/rabbit/publisher/publisher.py similarity index 96% rename from faststream/rabbit/publisher/asyncapi.py rename to faststream/rabbit/publisher/publisher.py index 330b42b9f7..0a6ecc55ee 100644 --- a/faststream/rabbit/publisher/asyncapi.py +++ b/faststream/rabbit/publisher/publisher.py @@ -21,15 +21,15 @@ from faststream.rabbit.schemas import RabbitExchange, RabbitQueue -class AsyncAPIPublisher(LogicPublisher): +class SpecificationPublisher(LogicPublisher): """AsyncAPI-compatible Rabbit Publisher class. Creting by ```python - publisher: AsyncAPIPublisher = broker.publisher(...) + publisher: SpecificationPublisher = broker.publisher(...) # or - publisher: AsyncAPIPublisher = router.publisher(...) + publisher: SpecificationPublisher = router.publisher(...) ``` """ @@ -119,7 +119,7 @@ def create( # type: ignore[override] title_: Optional[str], description_: Optional[str], include_in_schema: bool, - ) -> "AsyncAPIPublisher": + ) -> "SpecificationPublisher": return cls( routing_key=routing_key, queue=queue, diff --git a/faststream/rabbit/subscriber/factory.py b/faststream/rabbit/subscriber/factory.py index e3a79bb3a7..39830f4d2d 100644 --- a/faststream/rabbit/subscriber/factory.py +++ b/faststream/rabbit/subscriber/factory.py @@ -1,7 +1,7 @@ import warnings from typing import TYPE_CHECKING, Iterable, Optional, Union -from faststream.rabbit.subscriber.asyncapi import AsyncAPISubscriber +from faststream.rabbit.subscriber.subscriber import SpecificationSubscriber if TYPE_CHECKING: from aio_pika import IncomingMessage @@ -28,7 +28,7 @@ def create_subscriber( title_: Optional[str], description_: Optional[str], include_in_schema: bool, -) -> AsyncAPISubscriber: +) -> SpecificationSubscriber: if reply_config: # pragma: no cover warnings.warn( ( @@ -40,7 +40,7 @@ def create_subscriber( stacklevel=2, ) - return AsyncAPISubscriber( + return SpecificationSubscriber( queue=queue, exchange=exchange, consume_args=consume_args, diff --git a/faststream/rabbit/subscriber/asyncapi.py b/faststream/rabbit/subscriber/subscriber.py similarity index 98% rename from faststream/rabbit/subscriber/asyncapi.py rename to faststream/rabbit/subscriber/subscriber.py index 35643e4542..ee592318c5 100644 --- a/faststream/rabbit/subscriber/asyncapi.py +++ b/faststream/rabbit/subscriber/subscriber.py @@ -13,7 +13,7 @@ from faststream.specification.operation import Operation -class AsyncAPISubscriber(LogicSubscriber): +class SpecificationSubscriber(LogicSubscriber): """AsyncAPI-compatible Rabbit Subscriber class.""" def get_name(self) -> str: diff --git a/faststream/rabbit/testing.py b/faststream/rabbit/testing.py index 6863008cc1..afc6ace2d7 100644 --- a/faststream/rabbit/testing.py +++ b/faststream/rabbit/testing.py @@ -15,8 +15,8 @@ from faststream.exceptions import WRONG_PUBLISH_ARGS, SubscriberNotFound from faststream.rabbit.broker.broker import RabbitBroker from faststream.rabbit.parser import AioPikaParser -from faststream.rabbit.publisher.asyncapi import AsyncAPIPublisher from faststream.rabbit.publisher.producer import AioPikaFastProducer +from faststream.rabbit.publisher.publisher import SpecificationPublisher from faststream.rabbit.schemas import ( ExchangeType, RabbitExchange, @@ -58,7 +58,7 @@ async def _fake_connect(broker: RabbitBroker, *args: Any, **kwargs: Any) -> None @staticmethod def create_publisher_fake_subscriber( broker: RabbitBroker, - publisher: AsyncAPIPublisher, + publisher: SpecificationPublisher, ) -> Tuple["LogicSubscriber", bool]: sub: Optional[LogicSubscriber] = None for handler in broker._subscribers.values(): diff --git a/faststream/redis/broker/registrator.py b/faststream/redis/broker/registrator.py index d02d1f1762..227d316fab 100644 --- a/faststream/redis/broker/registrator.py +++ b/faststream/redis/broker/registrator.py @@ -5,9 +5,9 @@ from faststream.broker.core.abc import ABCBroker from faststream.broker.utils import default_filter from faststream.redis.message import UnifyRedisDict -from faststream.redis.publisher.asyncapi import AsyncAPIPublisher -from faststream.redis.subscriber.asyncapi import AsyncAPISubscriber +from faststream.redis.publisher.publisher import SpecificationPublisher from faststream.redis.subscriber.factory import SubsciberType, create_subscriber +from faststream.redis.subscriber.subscriber import SpecificationSubscriber if TYPE_CHECKING: from fast_depends.dependencies import Depends @@ -19,7 +19,7 @@ SubscriberMiddleware, ) from faststream.redis.message import UnifyRedisMessage - from faststream.redis.publisher.asyncapi import PublisherType + from faststream.redis.publisher.publisher import PublisherType from faststream.redis.schemas import ListSub, PubSub, StreamSub from faststream.types import AnyDict @@ -106,9 +106,9 @@ def subscriber( # type: ignore[override] bool, Doc("Whetever to include operation in AsyncAPI schema or not."), ] = True, - ) -> AsyncAPISubscriber: + ) -> SpecificationSubscriber: subscriber = cast( - AsyncAPISubscriber, + SpecificationSubscriber, super().subscriber( create_subscriber( channel=channel, @@ -187,7 +187,7 @@ def publisher( # type: ignore[override] bool, Doc("Whetever to include operation in AsyncAPI schema or not."), ] = True, - ) -> AsyncAPIPublisher: + ) -> SpecificationPublisher: """Creates long-living and AsyncAPI-documented publisher object. You can use it as a handler decorator (handler should be decorated by `@broker.subscriber(...)` too) - `@broker.publisher(...)`. @@ -196,9 +196,9 @@ def publisher( # type: ignore[override] Or you can create a publisher object to call it lately - `broker.publisher(...).publish(...)`. """ return cast( - AsyncAPIPublisher, + SpecificationPublisher, super().publisher( - AsyncAPIPublisher.create( + SpecificationPublisher.create( channel=channel, list=list, stream=stream, diff --git a/faststream/redis/fastapi/fastapi.py b/faststream/redis/fastapi/fastapi.py index 93c61e4a0e..5c75528059 100644 --- a/faststream/redis/fastapi/fastapi.py +++ b/faststream/redis/fastapi/fastapi.py @@ -32,9 +32,9 @@ from faststream.broker.utils import default_filter from faststream.redis.broker.broker import RedisBroker as RB from faststream.redis.message import UnifyRedisDict -from faststream.redis.publisher.asyncapi import AsyncAPIPublisher +from faststream.redis.publisher.publisher import SpecificationPublisher from faststream.redis.schemas import ListSub, PubSub, StreamSub -from faststream.redis.subscriber.asyncapi import AsyncAPISubscriber +from faststream.redis.subscriber.subscriber import SpecificationSubscriber from faststream.types import EMPTY if TYPE_CHECKING: @@ -637,9 +637,9 @@ def subscriber( # type: ignore[override] """ ), ] = False, - ) -> AsyncAPISubscriber: + ) -> SpecificationSubscriber: return cast( - AsyncAPISubscriber, + SpecificationSubscriber, super().subscriber( channel=channel, list=list, @@ -716,7 +716,7 @@ def publisher( bool, Doc("Whetever to include operation in AsyncAPI schema or not."), ] = True, - ) -> AsyncAPIPublisher: + ) -> SpecificationPublisher: return self.broker.publisher( channel, list=list, diff --git a/faststream/redis/publisher/asyncapi.py b/faststream/redis/publisher/publisher.py similarity index 95% rename from faststream/redis/publisher/asyncapi.py rename to faststream/redis/publisher/publisher.py index a849c0a8d0..187e39c623 100644 --- a/faststream/redis/publisher/asyncapi.py +++ b/faststream/redis/publisher/publisher.py @@ -31,7 +31,7 @@ ] -class AsyncAPIPublisher(LogicPublisher, RedisAsyncAPIProtocol): +class SpecificationPublisher(LogicPublisher, RedisAsyncAPIProtocol): """A class to represent a Redis publisher.""" def get_schema(self) -> Dict[str, Channel]: @@ -138,7 +138,7 @@ def create( # type: ignore[override] raise SetupError(INCORRECT_SETUP_MSG) -class AsyncAPIChannelPublisher(ChannelPublisher, AsyncAPIPublisher): +class AsyncAPIChannelPublisher(ChannelPublisher, SpecificationPublisher): def get_name(self) -> str: return f"{self.channel.name}:Publisher" @@ -150,7 +150,7 @@ def channel_binding(self) -> "redis.ChannelBinding": ) -class _ListPublisherMixin(AsyncAPIPublisher): +class _ListPublisherMixin(SpecificationPublisher): list: "ListSub" def get_name(self) -> str: @@ -172,7 +172,7 @@ class AsyncAPIListBatchPublisher(ListBatchPublisher, _ListPublisherMixin): pass -class AsyncAPIStreamPublisher(StreamPublisher, AsyncAPIPublisher): +class AsyncAPIStreamPublisher(StreamPublisher, SpecificationPublisher): def get_name(self) -> str: return f"{self.stream.name}:Publisher" diff --git a/faststream/redis/subscriber/factory.py b/faststream/redis/subscriber/factory.py index ee0ae84c9b..7f387ab058 100644 --- a/faststream/redis/subscriber/factory.py +++ b/faststream/redis/subscriber/factory.py @@ -5,7 +5,7 @@ from faststream.exceptions import SetupError from faststream.redis.schemas import INCORRECT_SETUP_MSG, ListSub, PubSub, StreamSub from faststream.redis.schemas.proto import validate_options -from faststream.redis.subscriber.asyncapi import ( +from faststream.redis.subscriber.subscriber import ( AsyncAPIChannelSubscriber, AsyncAPIListBatchSubscriber, AsyncAPIListSubscriber, diff --git a/faststream/redis/subscriber/asyncapi.py b/faststream/redis/subscriber/subscriber.py similarity index 91% rename from faststream/redis/subscriber/asyncapi.py rename to faststream/redis/subscriber/subscriber.py index 622237d17b..45f39e2295 100644 --- a/faststream/redis/subscriber/asyncapi.py +++ b/faststream/redis/subscriber/subscriber.py @@ -17,7 +17,7 @@ from faststream.specification.operation import Operation -class AsyncAPISubscriber(LogicSubscriber, RedisAsyncAPIProtocol): +class SpecificationSubscriber(LogicSubscriber, RedisAsyncAPIProtocol): """A class to represent a Redis handler.""" def get_schema(self) -> Dict[str, Channel]: @@ -42,7 +42,7 @@ def get_schema(self) -> Dict[str, Channel]: } -class AsyncAPIChannelSubscriber(ChannelSubscriber, AsyncAPISubscriber): +class AsyncAPIChannelSubscriber(ChannelSubscriber, SpecificationSubscriber): def get_name(self) -> str: return f"{self.channel.name}:{self.call_name}" @@ -54,7 +54,7 @@ def channel_binding(self) -> "redis.ChannelBinding": ) -class _StreamSubscriberMixin(AsyncAPISubscriber): +class _StreamSubscriberMixin(SpecificationSubscriber): stream_sub: StreamSub def get_name(self) -> str: @@ -78,7 +78,7 @@ class AsyncAPIStreamBatchSubscriber(BatchStreamSubscriber, _StreamSubscriberMixi pass -class _ListSubscriberMixin(AsyncAPISubscriber): +class _ListSubscriberMixin(SpecificationSubscriber): list_sub: ListSub def get_name(self) -> str: diff --git a/faststream/redis/testing.py b/faststream/redis/testing.py index 16cf7f8abf..5ef5e1c360 100644 --- a/faststream/redis/testing.py +++ b/faststream/redis/testing.py @@ -40,7 +40,7 @@ from faststream.utils.functions import timeout_scope if TYPE_CHECKING: - from faststream.redis.publisher.asyncapi import AsyncAPIPublisher + from faststream.redis.publisher.publisher import SpecificationPublisher from faststream.types import AnyDict, SendableMessage __all__ = ("TestRedisBroker",) @@ -52,7 +52,7 @@ class TestRedisBroker(TestBroker[RedisBroker]): @staticmethod def create_publisher_fake_subscriber( broker: RedisBroker, - publisher: "AsyncAPIPublisher", + publisher: "SpecificationPublisher", ) -> Tuple["LogicSubscriber", bool]: sub: Optional[LogicSubscriber] = None diff --git a/faststream/specification/__init__.py b/faststream/specification/__init__.py index 14776c8df0..4e9a9ee5be 100644 --- a/faststream/specification/__init__.py +++ b/faststream/specification/__init__.py @@ -1,53 +1,25 @@ -from . import bindings -from .channel import ( - Channel, -) -from .contact import ( - Contact, - ContactDict, -) -from .docs import ( - ExternalDocs, - ExternalDocsDict, -) -from .info import ( - Info, -) -from .license import ( - License, - LicenseDict, -) -from .message import ( - Message, -) -from .operation import ( - Operation -) -from .security import ( - SecuritySchemaComponent, - OauthFlows, - OauthFlowObj, -) -from .tag import ( - Tag, - TagDict, +from . import ( + bindings, + channel, + contact, + docs, + info, + license, + message, + operation, + security, + tag, ) __all__ = ( "bindings", - "Channel", - "Contact", - "ContactDict", - "ExternalDocs", - "ExternalDocsDict", - "Info", - "License", - "LicenseDict", - "Message", - "Operation", - "SecuritySchemaComponent", - "OauthFlows", - "OauthFlowObj", - "Tag", - "TagDict", + "channel", + "contact", + "docs", + "info", + "license", + "message", + "operation", + "security", + "tag", ) From c31bc570370655f2bec54853fe564a03d13365ed Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Tue, 13 Aug 2024 22:59:30 +0300 Subject: [PATCH 072/245] ruff satisfied --- faststream/app.py | 4 ++-- faststream/asgi/app.py | 1 - faststream/asyncapi/proto.py | 4 ++-- faststream/confluent/testing.py | 4 +++- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/faststream/app.py b/faststream/app.py index 0acdbf8b26..d39d3a9014 100644 --- a/faststream/app.py +++ b/faststream/app.py @@ -30,10 +30,10 @@ if TYPE_CHECKING: from faststream.broker.core.usecase import BrokerUsecase - from faststream.specification.contact import ContactDict, Contact + from faststream.specification.contact import Contact, ContactDict from faststream.specification.docs import ExternalDocs, ExternalDocsDict from faststream.specification.license import License, LicenseDict - from faststream.specification.tag import TagDict, Tag + from faststream.specification.tag import Tag, TagDict from faststream.types import ( AnyCallable, AnyDict, diff --git a/faststream/asgi/app.py b/faststream/asgi/app.py index 8ee7f2d580..f496383dce 100644 --- a/faststream/asgi/app.py +++ b/faststream/asgi/app.py @@ -18,7 +18,6 @@ from faststream.asgi.websocket import WebSocketClose from faststream.log.logging import logger - if TYPE_CHECKING: from faststream.asgi.types import ASGIApp, Receive, Scope, Send from faststream.broker.core.usecase import BrokerUsecase diff --git a/faststream/asyncapi/proto.py b/faststream/asyncapi/proto.py index 16c0f9f40b..f081803c97 100644 --- a/faststream/asyncapi/proto.py +++ b/faststream/asyncapi/proto.py @@ -4,13 +4,13 @@ from typing_extensions import Annotated, Doc from faststream.asyncapi.version import AsyncAPIVersion -from faststream.specification.contact import Contact, ContactDict -from faststream.specification.license import License, LicenseDict if TYPE_CHECKING: from faststream.broker.core.usecase import BrokerUsecase from faststream.specification.channel import Channel + from faststream.specification.contact import Contact, ContactDict from faststream.specification.docs import ExternalDocs, ExternalDocsDict + from faststream.specification.license import License, LicenseDict from faststream.specification.tag import Tag, TagDict from faststream.types import ( AnyDict, diff --git a/faststream/confluent/testing.py b/faststream/confluent/testing.py index 62ecb2923e..b2945244a7 100644 --- a/faststream/confluent/testing.py +++ b/faststream/confluent/testing.py @@ -24,7 +24,9 @@ from faststream.confluent.subscriber.usecase import LogicSubscriber from faststream.types import SendableMessage -__all__ = ("TestKafkaBroker",) +__all__ = ( + "TestKafkaBroker", +) class TestKafkaBroker(TestBroker[KafkaBroker]): From 16c36be42249930fdb1b26ea48dbd6718b5b72c7 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 8 Sep 2024 11:53:40 +0300 Subject: [PATCH 073/245] fix --- faststream/app.py | 6 +++--- faststream/asgi/factories.py | 4 ++-- faststream/asyncapi/abc.py | 4 ++-- faststream/asyncapi/generate.py | 4 ++-- faststream/asyncapi/proto.py | 6 +++--- faststream/asyncapi/v2_6_0/generate.py | 6 +++--- faststream/asyncapi/v3_0_0/generate.py | 6 +++--- faststream/broker/fastapi/router.py | 8 ++++---- faststream/broker/publisher/proto.py | 4 ++-- faststream/broker/publisher/usecase.py | 4 ++-- faststream/broker/subscriber/proto.py | 4 ++-- faststream/broker/subscriber/usecase.py | 4 ++-- faststream/redis/schemas/proto.py | 4 ++-- 13 files changed, 32 insertions(+), 32 deletions(-) diff --git a/faststream/app.py b/faststream/app.py index d39d3a9014..4c561b2936 100644 --- a/faststream/app.py +++ b/faststream/app.py @@ -16,7 +16,7 @@ from typing_extensions import ParamSpec from faststream._compat import ExceptionGroup -from faststream.asyncapi.proto import AsyncAPIApplication +from faststream.asyncapi.proto import Application from faststream.asyncapi.version import AsyncAPIVersion from faststream.cli.supervisors.utils import set_exit from faststream.exceptions import ValidationError @@ -45,7 +45,7 @@ ) -class FastStream(AsyncAPIApplication): +class FastStream(Application): """A class representing a FastStream application.""" _on_startup_calling: List["AsyncFunc"] @@ -110,7 +110,7 @@ def __init__( self.license = license self.contact = contact self.identifier = identifier - self.asyncapi_tags = tags + self.tags = tags self.external_docs = external_docs def set_broker(self, broker: "BrokerUsecase[Any, Any]") -> None: diff --git a/faststream/asgi/factories.py b/faststream/asgi/factories.py index 54c6723e88..a14ba8a661 100644 --- a/faststream/asgi/factories.py +++ b/faststream/asgi/factories.py @@ -15,7 +15,7 @@ if TYPE_CHECKING: from faststream.asgi.types import ASGIApp, Scope - from faststream.asyncapi.proto import AsyncAPIApplication + from faststream.asyncapi.proto import Application from faststream.broker.core.usecase import BrokerUsecase @@ -38,7 +38,7 @@ async def ping(scope: "Scope") -> AsgiResponse: def make_asyncapi_asgi( - app: "AsyncAPIApplication", + app: "Application", sidebar: bool = True, info: bool = True, servers: bool = True, diff --git a/faststream/asyncapi/abc.py b/faststream/asyncapi/abc.py index 776952c357..84174b31c2 100644 --- a/faststream/asyncapi/abc.py +++ b/faststream/asyncapi/abc.py @@ -1,11 +1,11 @@ from abc import abstractmethod from typing import Any, Dict, Optional -from faststream.asyncapi.proto import AsyncAPIProto +from faststream.asyncapi.proto import SpecificationProto from faststream.specification.channel import Channel -class AsyncAPIOperation(AsyncAPIProto): +class SpecificationOperation(SpecificationProto): """A class representing an asynchronous API operation.""" @property diff --git a/faststream/asyncapi/generate.py b/faststream/asyncapi/generate.py index 79e8ced960..b70b130684 100644 --- a/faststream/asyncapi/generate.py +++ b/faststream/asyncapi/generate.py @@ -6,10 +6,10 @@ from faststream.asyncapi.version import AsyncAPIVersion if TYPE_CHECKING: - from faststream.asyncapi.proto import AsyncAPIApplication + from faststream.asyncapi.proto import Application -def get_app_schema(app: "AsyncAPIApplication") -> BaseSchema: +def get_app_schema(app: "Application") -> BaseSchema: if app.asyncapi_version == AsyncAPIVersion.v3_0: return get_app_schema_v3(app) diff --git a/faststream/asyncapi/proto.py b/faststream/asyncapi/proto.py index f081803c97..259ce54b4f 100644 --- a/faststream/asyncapi/proto.py +++ b/faststream/asyncapi/proto.py @@ -18,7 +18,7 @@ ) -class AsyncAPIApplication(Protocol): +class Application(Protocol): broker: Optional["BrokerUsecase[Any, Any]"] title: str @@ -27,13 +27,13 @@ class AsyncAPIApplication(Protocol): terms_of_service: Optional["AnyHttpUrl"] license: Optional[Union["License", "LicenseDict", "AnyDict"]] contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] - asyncapi_tags: Optional[Sequence[Union["Tag", "TagDict", "AnyDict"]]] + specs_tags: Optional[Sequence[Union["Tag", "TagDict", "AnyDict"]]] external_docs: Optional[Union["ExternalDocs", "ExternalDocsDict", "AnyDict"]] asyncapi_version: AsyncAPIVersion identifier: Optional[str] -class AsyncAPIProto(Protocol): +class SpecificationProto(Protocol): """A class representing an asynchronous API operation.""" title_: Annotated[ diff --git a/faststream/asyncapi/v2_6_0/generate.py b/faststream/asyncapi/v2_6_0/generate.py index be1297a609..1476170f34 100644 --- a/faststream/asyncapi/v2_6_0/generate.py +++ b/faststream/asyncapi/v2_6_0/generate.py @@ -3,7 +3,7 @@ from faststream import specification as spec from faststream._compat import DEF_KEY -from faststream.asyncapi.proto import AsyncAPIApplication +from faststream.asyncapi.proto import Application from faststream.asyncapi.v2_6_0.schema import ( Channel, Components, @@ -36,7 +36,7 @@ from faststream.types import AnyDict -def get_app_schema(app: AsyncAPIApplication) -> Schema: +def get_app_schema(app: Application) -> Schema: """Get the application schema.""" broker = app.broker if broker is None: # pragma: no cover @@ -86,7 +86,7 @@ def get_app_schema(app: AsyncAPIApplication) -> Schema: ), defaultContentType=ContentTypes.json.value, id=app.identifier, - tags=specs_tags_to_asyncapi(list(app.asyncapi_tags)) if app.asyncapi_tags else None, + tags=specs_tags_to_asyncapi(list(app.specs_tags)) if app.specs_tags else None, externalDocs=specs_external_docs_to_asyncapi(app.external_docs) if app.external_docs else None, servers=servers, channels=channels, diff --git a/faststream/asyncapi/v3_0_0/generate.py b/faststream/asyncapi/v3_0_0/generate.py index 2353b39b73..a088a28266 100644 --- a/faststream/asyncapi/v3_0_0/generate.py +++ b/faststream/asyncapi/v3_0_0/generate.py @@ -4,7 +4,7 @@ from faststream import specification as spec from faststream._compat import DEF_KEY -from faststream.asyncapi.proto import AsyncAPIApplication +from faststream.asyncapi.proto import Application from faststream.asyncapi.v2_6_0.generate import ( specs_channel_binding_to_asyncapi, specs_contact_to_asyncapi, @@ -34,7 +34,7 @@ from faststream.broker.types import ConnectionType, MsgType -def get_app_schema(app: AsyncAPIApplication) -> Schema: +def get_app_schema(app: Application) -> Schema: """Get the application schema.""" broker = app.broker if broker is None: # pragma: no cover @@ -75,7 +75,7 @@ def get_app_schema(app: AsyncAPIApplication) -> Schema: if app.contact else None, license=specs_license_to_asyncapi(app.license) if app.license else None, - tags=specs_tags_to_asyncapi(list(app.asyncapi_tags)) if app.asyncapi_tags else None, + tags=specs_tags_to_asyncapi(list(app.specs_tags)) if app.specs_tags else None, externalDocs=specs_external_docs_to_asyncapi(app.external_docs) if app.external_docs else None, ), defaultContentType=ContentTypes.json.value, diff --git a/faststream/broker/fastapi/router.py b/faststream/broker/fastapi/router.py index e8ae3b8347..09424dceae 100644 --- a/faststream/broker/fastapi/router.py +++ b/faststream/broker/fastapi/router.py @@ -30,7 +30,7 @@ from starlette.responses import JSONResponse, Response from starlette.routing import BaseRoute, _DefaultLifespan -from faststream.asyncapi.proto import AsyncAPIApplication +from faststream.asyncapi.proto import Application from faststream.asyncapi.site import get_asyncapi_html from faststream.asyncapi.version import AsyncAPIVersion from faststream.broker.fastapi.get_dependant import get_fastapi_dependant @@ -84,7 +84,7 @@ async def __aexit__( class StreamRouter( APIRouter, - AsyncAPIApplication, + Application, Generic[MsgType], ): """A class to route streams.""" @@ -153,11 +153,11 @@ def __init__( self.setup_state = setup_state - # AsyncAPI information + # Specification information # Empty self.terms_of_service = None self.identifier = None - self.asyncapi_tags = None + self.specs_tags = None self.external_docs = None # parse from FastAPI app on startup self.title = "" diff --git a/faststream/broker/publisher/proto.py b/faststream/broker/publisher/proto.py index 67ef329f19..1711aa974a 100644 --- a/faststream/broker/publisher/proto.py +++ b/faststream/broker/publisher/proto.py @@ -3,7 +3,7 @@ from typing_extensions import override -from faststream.asyncapi.proto import AsyncAPIProto +from faststream.asyncapi.proto import SpecificationProto from faststream.broker.proto import EndpointProto from faststream.broker.types import MsgType @@ -72,7 +72,7 @@ async def request( class PublisherProto( - AsyncAPIProto, + SpecificationProto, EndpointProto, BasePublisherProto, Generic[MsgType], diff --git a/faststream/broker/publisher/usecase.py b/faststream/broker/publisher/usecase.py index 34a192670d..2f8381135f 100644 --- a/faststream/broker/publisher/usecase.py +++ b/faststream/broker/publisher/usecase.py @@ -15,7 +15,7 @@ from fast_depends.core import CallModel, build_call_model from typing_extensions import Annotated, Doc, override -from faststream.asyncapi.abc import AsyncAPIOperation +from faststream.asyncapi.abc import SpecificationOperation from faststream.asyncapi.message import get_response_schema from faststream.asyncapi.utils import to_camelcase from faststream.broker.publisher.proto import PublisherProto @@ -37,7 +37,7 @@ class PublisherUsecase( ABC, - AsyncAPIOperation, + SpecificationOperation, PublisherProto[MsgType], ): """A base class for publishers in an asynchronous API.""" diff --git a/faststream/broker/subscriber/proto.py b/faststream/broker/subscriber/proto.py index 612d497196..0327f2304c 100644 --- a/faststream/broker/subscriber/proto.py +++ b/faststream/broker/subscriber/proto.py @@ -3,7 +3,7 @@ from typing_extensions import Self, override -from faststream.asyncapi.proto import AsyncAPIProto +from faststream.asyncapi.proto import SpecificationProto from faststream.broker.proto import EndpointProto from faststream.broker.types import MsgType from faststream.broker.wrapper.proto import WrapperProto @@ -25,7 +25,7 @@ class SubscriberProto( - AsyncAPIProto, + SpecificationProto, EndpointProto, WrapperProto[MsgType], ): diff --git a/faststream/broker/subscriber/usecase.py b/faststream/broker/subscriber/usecase.py index 4141ca17d5..aec1f0cdbd 100644 --- a/faststream/broker/subscriber/usecase.py +++ b/faststream/broker/subscriber/usecase.py @@ -17,7 +17,7 @@ from typing_extensions import Self, override -from faststream.asyncapi.abc import AsyncAPIOperation +from faststream.asyncapi.abc import SpecificationOperation from faststream.asyncapi.message import parse_handler_params from faststream.asyncapi.utils import to_camelcase from faststream.broker.response import ensure_response @@ -77,7 +77,7 @@ def __init__( class SubscriberUsecase( - AsyncAPIOperation, + SpecificationOperation, SubscriberProto[MsgType], ): """A class representing an asynchronous handler.""" diff --git a/faststream/redis/schemas/proto.py b/faststream/redis/schemas/proto.py index f69d11e883..af0dca83c5 100644 --- a/faststream/redis/schemas/proto.py +++ b/faststream/redis/schemas/proto.py @@ -1,7 +1,7 @@ from abc import abstractmethod from typing import TYPE_CHECKING, Any, Union -from faststream.asyncapi.abc import AsyncAPIOperation +from faststream.asyncapi.abc import SpecificationOperation from faststream.exceptions import SetupError if TYPE_CHECKING: @@ -9,7 +9,7 @@ from faststream.specification.bindings import redis -class RedisAsyncAPIProtocol(AsyncAPIOperation): +class RedisAsyncAPIProtocol(SpecificationOperation): @property @abstractmethod def channel_binding(self) -> "redis.ChannelBinding": ... From 0968a74f05d36e8dce55c74825158eb2f2093a91 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Tue, 13 Aug 2024 23:34:49 +0300 Subject: [PATCH 074/245] SpecificationProto and Application moved to specification from asyncapi --- faststream/app.py | 2 +- faststream/asyncapi/abc.py | 2 +- faststream/broker/fastapi/router.py | 2 +- faststream/broker/publisher/proto.py | 2 +- faststream/broker/subscriber/proto.py | 2 +- faststream/{asyncapi => specification}/proto.py | 0 6 files changed, 5 insertions(+), 5 deletions(-) rename faststream/{asyncapi => specification}/proto.py (100%) diff --git a/faststream/app.py b/faststream/app.py index 4c561b2936..5a94da44ce 100644 --- a/faststream/app.py +++ b/faststream/app.py @@ -16,11 +16,11 @@ from typing_extensions import ParamSpec from faststream._compat import ExceptionGroup -from faststream.asyncapi.proto import Application from faststream.asyncapi.version import AsyncAPIVersion from faststream.cli.supervisors.utils import set_exit from faststream.exceptions import ValidationError from faststream.log.logging import logger +from faststream.specification.proto import Application from faststream.utils import apply_types, context from faststream.utils.functions import drop_response_type, fake_context, to_async diff --git a/faststream/asyncapi/abc.py b/faststream/asyncapi/abc.py index 84174b31c2..b25e7e833b 100644 --- a/faststream/asyncapi/abc.py +++ b/faststream/asyncapi/abc.py @@ -1,8 +1,8 @@ from abc import abstractmethod from typing import Any, Dict, Optional -from faststream.asyncapi.proto import SpecificationProto from faststream.specification.channel import Channel +from faststream.specification.proto import SpecificationProto class SpecificationOperation(SpecificationProto): diff --git a/faststream/broker/fastapi/router.py b/faststream/broker/fastapi/router.py index 09424dceae..1fc7c2b939 100644 --- a/faststream/broker/fastapi/router.py +++ b/faststream/broker/fastapi/router.py @@ -30,7 +30,6 @@ from starlette.responses import JSONResponse, Response from starlette.routing import BaseRoute, _DefaultLifespan -from faststream.asyncapi.proto import Application from faststream.asyncapi.site import get_asyncapi_html from faststream.asyncapi.version import AsyncAPIVersion from faststream.broker.fastapi.get_dependant import get_fastapi_dependant @@ -42,6 +41,7 @@ P_HandlerParams, T_HandlerReturn, ) +from faststream.specification.proto import Application from faststream.utils.context.repository import context from faststream.utils.functions import fake_context, to_async diff --git a/faststream/broker/publisher/proto.py b/faststream/broker/publisher/proto.py index 1711aa974a..b268c2771a 100644 --- a/faststream/broker/publisher/proto.py +++ b/faststream/broker/publisher/proto.py @@ -3,9 +3,9 @@ from typing_extensions import override -from faststream.asyncapi.proto import SpecificationProto from faststream.broker.proto import EndpointProto from faststream.broker.types import MsgType +from faststream.specification.proto import SpecificationProto if TYPE_CHECKING: from faststream.broker.types import ( diff --git a/faststream/broker/subscriber/proto.py b/faststream/broker/subscriber/proto.py index 0327f2304c..274bad706b 100644 --- a/faststream/broker/subscriber/proto.py +++ b/faststream/broker/subscriber/proto.py @@ -3,10 +3,10 @@ from typing_extensions import Self, override -from faststream.asyncapi.proto import SpecificationProto from faststream.broker.proto import EndpointProto from faststream.broker.types import MsgType from faststream.broker.wrapper.proto import WrapperProto +from faststream.specification.proto import SpecificationProto if TYPE_CHECKING: from fast_depends.dependencies import Depends diff --git a/faststream/asyncapi/proto.py b/faststream/specification/proto.py similarity index 100% rename from faststream/asyncapi/proto.py rename to faststream/specification/proto.py From 9cc59d13ae7acf1b0952b4c8b42cfef87a8c5ba1 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Tue, 13 Aug 2024 23:36:57 +0300 Subject: [PATCH 075/245] errors fix --- faststream/app.py | 2 +- faststream/asyncapi/v2_6_0/generate.py | 2 +- faststream/asyncapi/v3_0_0/generate.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/faststream/app.py b/faststream/app.py index 5a94da44ce..19936e8182 100644 --- a/faststream/app.py +++ b/faststream/app.py @@ -110,7 +110,7 @@ def __init__( self.license = license self.contact = contact self.identifier = identifier - self.tags = tags + self.specs_tags = tags self.external_docs = external_docs def set_broker(self, broker: "BrokerUsecase[Any, Any]") -> None: diff --git a/faststream/asyncapi/v2_6_0/generate.py b/faststream/asyncapi/v2_6_0/generate.py index 1476170f34..44ae94b5c0 100644 --- a/faststream/asyncapi/v2_6_0/generate.py +++ b/faststream/asyncapi/v2_6_0/generate.py @@ -3,7 +3,6 @@ from faststream import specification as spec from faststream._compat import DEF_KEY -from faststream.asyncapi.proto import Application from faststream.asyncapi.v2_6_0.schema import ( Channel, Components, @@ -29,6 +28,7 @@ ) from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message from faststream.constants import ContentTypes +from faststream.specification.proto import Application if TYPE_CHECKING: from faststream.broker.core.usecase import BrokerUsecase diff --git a/faststream/asyncapi/v3_0_0/generate.py b/faststream/asyncapi/v3_0_0/generate.py index a088a28266..fd8f2948f7 100644 --- a/faststream/asyncapi/v3_0_0/generate.py +++ b/faststream/asyncapi/v3_0_0/generate.py @@ -4,7 +4,6 @@ from faststream import specification as spec from faststream._compat import DEF_KEY -from faststream.asyncapi.proto import Application from faststream.asyncapi.v2_6_0.generate import ( specs_channel_binding_to_asyncapi, specs_contact_to_asyncapi, @@ -28,6 +27,7 @@ Server, ) from faststream.constants import ContentTypes +from faststream.specification.proto import Application if TYPE_CHECKING: from faststream.broker.core.usecase import BrokerUsecase From ec7db2994e676bae1fd8baba4d4f1a49a43eb8cf Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Tue, 13 Aug 2024 23:38:54 +0300 Subject: [PATCH 076/245] comments fix --- faststream/app.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/faststream/app.py b/faststream/app.py index 19936e8182..df90f92595 100644 --- a/faststream/app.py +++ b/faststream/app.py @@ -58,7 +58,7 @@ def __init__( broker: Optional["BrokerUsecase[Any, Any]"] = None, logger: Optional["LoggerProto"] = logger, lifespan: Optional["Lifespan"] = None, - # AsyncAPI args, + # Specification args, title: str = "FastStream", version: str = "0.1.0", description: str = "", @@ -102,7 +102,7 @@ def __init__( self.should_exit = False - # AsyncAPI information + # Specification information self.title = title self.version = version self.description = description From 20b8d805de3961d798905d6eb860cc6c4df50da3 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 8 Sep 2024 11:54:56 +0300 Subject: [PATCH 077/245] fix --- faststream/app.py | 2 +- faststream/asgi/app.py | 2 +- faststream/asyncapi/generate.py | 2 +- faststream/asyncapi/v2_6_0/generate.py | 2 +- faststream/asyncapi/v3_0_0/generate.py | 2 +- faststream/broker/core/usecase.py | 2 +- faststream/broker/publisher/usecase.py | 2 +- faststream/broker/subscriber/usecase.py | 2 +- faststream/confluent/publisher/publisher.py | 8 +++--- faststream/confluent/subscriber/subscriber.py | 8 +++--- faststream/kafka/publisher/publisher.py | 8 +++--- faststream/kafka/subscriber/subscriber.py | 8 +++--- faststream/nats/publisher/publisher.py | 8 +++--- faststream/nats/subscriber/subscriber.py | 8 +++--- faststream/rabbit/publisher/publisher.py | 8 +++--- faststream/rabbit/subscriber/subscriber.py | 8 +++--- faststream/redis/publisher/publisher.py | 8 +++--- faststream/redis/schemas/proto.py | 4 +-- faststream/redis/subscriber/subscriber.py | 8 +++--- faststream/specification/__init__.py | 26 +++---------------- faststream/{asyncapi => specification}/abc.py | 2 +- faststream/specification/proto.py | 4 +-- faststream/specification/schema/__init__.py | 25 ++++++++++++++++++ .../{ => schema}/bindings/__init__.py | 0 .../{ => schema}/bindings/amqp.py | 0 .../{ => schema}/bindings/kafka.py | 0 .../{ => schema}/bindings/main.py | 10 +++---- .../{ => schema}/bindings/nats.py | 0 .../{ => schema}/bindings/redis.py | 0 .../{ => schema}/bindings/sqs.py | 0 .../specification/{ => schema}/channel.py | 4 +-- .../specification/{ => schema}/contact.py | 0 faststream/specification/{ => schema}/docs.py | 0 faststream/specification/{ => schema}/info.py | 4 +-- .../specification/{ => schema}/license.py | 0 .../specification/{ => schema}/message.py | 4 +-- .../specification/{ => schema}/operation.py | 8 +++--- .../specification/{ => schema}/security.py | 0 faststream/specification/{ => schema}/tag.py | 2 +- .../confluent/v2_6_0/test_connection.py | 2 +- .../confluent/v3_0_0/test_connection.py | 2 +- tests/asyncapi/kafka/v2_6_0/test_app.py | 4 +-- .../asyncapi/kafka/v2_6_0/test_connection.py | 2 +- .../asyncapi/kafka/v3_0_0/test_connection.py | 2 +- tests/asyncapi/nats/v2_6_0/test_connection.py | 2 +- tests/asyncapi/nats/v3_0_0/test_connection.py | 2 +- .../asyncapi/rabbit/v2_6_0/test_connection.py | 2 +- .../asyncapi/rabbit/v3_0_0/test_connection.py | 2 +- .../asyncapi/redis/v2_6_0/test_connection.py | 2 +- .../asyncapi/redis/v3_0_0/test_connection.py | 2 +- 50 files changed, 110 insertions(+), 103 deletions(-) rename faststream/{asyncapi => specification}/abc.py (95%) create mode 100644 faststream/specification/schema/__init__.py rename faststream/specification/{ => schema}/bindings/__init__.py (100%) rename faststream/specification/{ => schema}/bindings/amqp.py (100%) rename faststream/specification/{ => schema}/bindings/kafka.py (100%) rename faststream/specification/{ => schema}/bindings/main.py (78%) rename faststream/specification/{ => schema}/bindings/nats.py (100%) rename faststream/specification/{ => schema}/bindings/redis.py (100%) rename faststream/specification/{ => schema}/bindings/sqs.py (100%) rename faststream/specification/{ => schema}/channel.py (83%) rename faststream/specification/{ => schema}/contact.py (100%) rename faststream/specification/{ => schema}/docs.py (100%) rename faststream/specification/{ => schema}/info.py (84%) rename faststream/specification/{ => schema}/license.py (100%) rename faststream/specification/{ => schema}/message.py (92%) rename faststream/specification/{ => schema}/operation.py (78%) rename faststream/specification/{ => schema}/security.py (100%) rename faststream/specification/{ => schema}/tag.py (91%) diff --git a/faststream/app.py b/faststream/app.py index df90f92595..6073ba4248 100644 --- a/faststream/app.py +++ b/faststream/app.py @@ -33,7 +33,7 @@ from faststream.specification.contact import Contact, ContactDict from faststream.specification.docs import ExternalDocs, ExternalDocsDict from faststream.specification.license import License, LicenseDict - from faststream.specification.tag import Tag, TagDict + from faststream.specification.schema.tag import Tag, TagDict from faststream.types import ( AnyCallable, AnyDict, diff --git a/faststream/asgi/app.py b/faststream/asgi/app.py index f496383dce..f90e79a93f 100644 --- a/faststream/asgi/app.py +++ b/faststream/asgi/app.py @@ -24,7 +24,7 @@ from faststream.specification.contact import Contact, ContactDict from faststream.specification.docs import ExternalDocs, ExternalDocsDict from faststream.specification.license import License, LicenseDict - from faststream.specification.tag import Tag, TagDict + from faststream.specification.schema.tag import Tag, TagDict from faststream.types import ( AnyCallable, AnyDict, diff --git a/faststream/asyncapi/generate.py b/faststream/asyncapi/generate.py index b70b130684..b6a7935c63 100644 --- a/faststream/asyncapi/generate.py +++ b/faststream/asyncapi/generate.py @@ -6,7 +6,7 @@ from faststream.asyncapi.version import AsyncAPIVersion if TYPE_CHECKING: - from faststream.asyncapi.proto import Application + from faststream.specification.proto import Application def get_app_schema(app: "Application") -> BaseSchema: diff --git a/faststream/asyncapi/v2_6_0/generate.py b/faststream/asyncapi/v2_6_0/generate.py index 44ae94b5c0..f4141d3b49 100644 --- a/faststream/asyncapi/v2_6_0/generate.py +++ b/faststream/asyncapi/v2_6_0/generate.py @@ -1,7 +1,7 @@ from dataclasses import asdict from typing import TYPE_CHECKING, Any, Dict, List, Union -from faststream import specification as spec +from faststream.specification import schema as spec from faststream._compat import DEF_KEY from faststream.asyncapi.v2_6_0.schema import ( Channel, diff --git a/faststream/asyncapi/v3_0_0/generate.py b/faststream/asyncapi/v3_0_0/generate.py index fd8f2948f7..6287ffbf6a 100644 --- a/faststream/asyncapi/v3_0_0/generate.py +++ b/faststream/asyncapi/v3_0_0/generate.py @@ -2,7 +2,7 @@ from typing import TYPE_CHECKING, Any, Dict, List, Union from urllib.parse import urlparse -from faststream import specification as spec +from faststream.specification import schema as spec from faststream._compat import DEF_KEY from faststream.asyncapi.v2_6_0.generate import ( specs_channel_binding_to_asyncapi, diff --git a/faststream/broker/core/usecase.py b/faststream/broker/core/usecase.py index ea2fce1d16..cffda64077 100644 --- a/faststream/broker/core/usecase.py +++ b/faststream/broker/core/usecase.py @@ -43,7 +43,7 @@ from faststream.broker.message import StreamMessage from faststream.broker.publisher.proto import ProducerProto, PublisherProto from faststream.security import BaseSecurity - from faststream.specification.tag import Tag, TagDict + from faststream.specification.schema.tag import Tag, TagDict from faststream.types import AnyDict, Decorator, LoggerProto diff --git a/faststream/broker/publisher/usecase.py b/faststream/broker/publisher/usecase.py index 2f8381135f..57efb1ea58 100644 --- a/faststream/broker/publisher/usecase.py +++ b/faststream/broker/publisher/usecase.py @@ -15,7 +15,6 @@ from fast_depends.core import CallModel, build_call_model from typing_extensions import Annotated, Doc, override -from faststream.asyncapi.abc import SpecificationOperation from faststream.asyncapi.message import get_response_schema from faststream.asyncapi.utils import to_camelcase from faststream.broker.publisher.proto import PublisherProto @@ -25,6 +24,7 @@ T_HandlerReturn, ) from faststream.broker.wrapper.call import HandlerCallWrapper +from faststream.specification.abc import SpecificationOperation if TYPE_CHECKING: from faststream.broker.publisher.proto import ProducerProto diff --git a/faststream/broker/subscriber/usecase.py b/faststream/broker/subscriber/usecase.py index aec1f0cdbd..ecccf41d56 100644 --- a/faststream/broker/subscriber/usecase.py +++ b/faststream/broker/subscriber/usecase.py @@ -17,7 +17,6 @@ from typing_extensions import Self, override -from faststream.asyncapi.abc import SpecificationOperation from faststream.asyncapi.message import parse_handler_params from faststream.asyncapi.utils import to_camelcase from faststream.broker.response import ensure_response @@ -31,6 +30,7 @@ from faststream.broker.utils import MultiLock, get_watcher_context, resolve_custom_func from faststream.broker.wrapper.call import HandlerCallWrapper from faststream.exceptions import SetupError, StopConsume, SubscriberNotFound +from faststream.specification.abc import SpecificationOperation from faststream.utils.context.repository import context from faststream.utils.functions import sync_fake_context, to_async diff --git a/faststream/confluent/publisher/publisher.py b/faststream/confluent/publisher/publisher.py index 2fd4e192e3..dede2aceb7 100644 --- a/faststream/confluent/publisher/publisher.py +++ b/faststream/confluent/publisher/publisher.py @@ -20,10 +20,10 @@ LogicPublisher, ) from faststream.exceptions import SetupError -from faststream.specification.bindings import ChannelBinding, kafka -from faststream.specification.channel import Channel -from faststream.specification.message import CorrelationId, Message -from faststream.specification.operation import Operation +from faststream.specification.schema.bindings import ChannelBinding, kafka +from faststream.specification.schema.channel import Channel +from faststream.specification.schema.message import CorrelationId, Message +from faststream.specification.schema.operation import Operation if TYPE_CHECKING: from confluent_kafka import Message as ConfluentMsg diff --git a/faststream/confluent/subscriber/subscriber.py b/faststream/confluent/subscriber/subscriber.py index 172e3f546c..454d739906 100644 --- a/faststream/confluent/subscriber/subscriber.py +++ b/faststream/confluent/subscriber/subscriber.py @@ -11,10 +11,10 @@ DefaultSubscriber, LogicSubscriber, ) -from faststream.specification.bindings import ChannelBinding, kafka -from faststream.specification.channel import Channel -from faststream.specification.message import CorrelationId, Message -from faststream.specification.operation import Operation +from faststream.specification.schema.bindings import ChannelBinding, kafka +from faststream.specification.schema.channel import Channel +from faststream.specification.schema.message import CorrelationId, Message +from faststream.specification.schema.operation import Operation if TYPE_CHECKING: from confluent_kafka import Message as ConfluentMsg diff --git a/faststream/kafka/publisher/publisher.py b/faststream/kafka/publisher/publisher.py index 7f9bb744e6..e5e22616fb 100644 --- a/faststream/kafka/publisher/publisher.py +++ b/faststream/kafka/publisher/publisher.py @@ -20,10 +20,10 @@ DefaultPublisher, LogicPublisher, ) -from faststream.specification.bindings import ChannelBinding, kafka -from faststream.specification.channel import Channel -from faststream.specification.message import CorrelationId, Message -from faststream.specification.operation import Operation +from faststream.specification.schema.bindings import ChannelBinding, kafka +from faststream.specification.schema.channel import Channel +from faststream.specification.schema.message import CorrelationId, Message +from faststream.specification.schema.operation import Operation if TYPE_CHECKING: from aiokafka import ConsumerRecord diff --git a/faststream/kafka/subscriber/subscriber.py b/faststream/kafka/subscriber/subscriber.py index aaa33d1428..b695aac9d1 100644 --- a/faststream/kafka/subscriber/subscriber.py +++ b/faststream/kafka/subscriber/subscriber.py @@ -11,10 +11,10 @@ DefaultSubscriber, LogicSubscriber, ) -from faststream.specification.bindings import ChannelBinding, kafka -from faststream.specification.channel import Channel -from faststream.specification.message import CorrelationId, Message -from faststream.specification.operation import Operation +from faststream.specification.schema.bindings import ChannelBinding, kafka +from faststream.specification.schema.channel import Channel +from faststream.specification.schema.message import CorrelationId, Message +from faststream.specification.schema.operation import Operation if TYPE_CHECKING: from aiokafka import ConsumerRecord diff --git a/faststream/nats/publisher/publisher.py b/faststream/nats/publisher/publisher.py index 135cefa19c..3ef2317f24 100644 --- a/faststream/nats/publisher/publisher.py +++ b/faststream/nats/publisher/publisher.py @@ -4,10 +4,10 @@ from faststream.asyncapi.utils import resolve_payloads from faststream.nats.publisher.usecase import LogicPublisher -from faststream.specification.bindings import ChannelBinding, nats -from faststream.specification.channel import Channel -from faststream.specification.message import CorrelationId, Message -from faststream.specification.operation import Operation +from faststream.specification.schema.bindings import ChannelBinding, nats +from faststream.specification.schema.channel import Channel +from faststream.specification.schema.message import CorrelationId, Message +from faststream.specification.schema.operation import Operation if TYPE_CHECKING: from nats.aio.msg import Msg diff --git a/faststream/nats/subscriber/subscriber.py b/faststream/nats/subscriber/subscriber.py index 9c279e0021..6fbfb99d3c 100644 --- a/faststream/nats/subscriber/subscriber.py +++ b/faststream/nats/subscriber/subscriber.py @@ -15,10 +15,10 @@ PullStreamSubscriber, PushStreamSubscription, ) -from faststream.specification.bindings import ChannelBinding, nats -from faststream.specification.channel import Channel -from faststream.specification.message import CorrelationId, Message -from faststream.specification.operation import Operation +from faststream.specification.schema.bindings import ChannelBinding, nats +from faststream.specification.schema.channel import Channel +from faststream.specification.schema.message import CorrelationId, Message +from faststream.specification.schema.operation import Operation class SpecificationSubscriber(LogicSubscriber[Any]): diff --git a/faststream/rabbit/publisher/publisher.py b/faststream/rabbit/publisher/publisher.py index 0a6ecc55ee..c50fbce6bb 100644 --- a/faststream/rabbit/publisher/publisher.py +++ b/faststream/rabbit/publisher/publisher.py @@ -5,14 +5,14 @@ from faststream.asyncapi.utils import resolve_payloads from faststream.rabbit.publisher.usecase import LogicPublisher, PublishKwargs from faststream.rabbit.utils import is_routing_exchange -from faststream.specification.bindings import ( +from faststream.specification.schema.bindings import ( ChannelBinding, OperationBinding, amqp, ) -from faststream.specification.channel import Channel -from faststream.specification.message import CorrelationId, Message -from faststream.specification.operation import Operation +from faststream.specification.schema.channel import Channel +from faststream.specification.schema.message import CorrelationId, Message +from faststream.specification.schema.operation import Operation if TYPE_CHECKING: from aio_pika import IncomingMessage diff --git a/faststream/rabbit/subscriber/subscriber.py b/faststream/rabbit/subscriber/subscriber.py index ee592318c5..bc244d9eb1 100644 --- a/faststream/rabbit/subscriber/subscriber.py +++ b/faststream/rabbit/subscriber/subscriber.py @@ -3,14 +3,14 @@ from faststream.asyncapi.utils import resolve_payloads from faststream.rabbit.subscriber.usecase import LogicSubscriber from faststream.rabbit.utils import is_routing_exchange -from faststream.specification.bindings import ( +from faststream.specification.schema.bindings import ( ChannelBinding, OperationBinding, amqp, ) -from faststream.specification.channel import Channel -from faststream.specification.message import CorrelationId, Message -from faststream.specification.operation import Operation +from faststream.specification.schema.channel import Channel +from faststream.specification.schema.message import CorrelationId, Message +from faststream.specification.schema.operation import Operation class SpecificationSubscriber(LogicSubscriber): diff --git a/faststream/redis/publisher/publisher.py b/faststream/redis/publisher/publisher.py index 187e39c623..b43a8be91e 100644 --- a/faststream/redis/publisher/publisher.py +++ b/faststream/redis/publisher/publisher.py @@ -13,10 +13,10 @@ ) from faststream.redis.schemas import INCORRECT_SETUP_MSG, ListSub, PubSub, StreamSub from faststream.redis.schemas.proto import RedisAsyncAPIProtocol, validate_options -from faststream.specification.bindings import ChannelBinding, redis -from faststream.specification.channel import Channel -from faststream.specification.message import CorrelationId, Message -from faststream.specification.operation import Operation +from faststream.specification.schema.bindings import ChannelBinding, redis +from faststream.specification.schema.channel import Channel +from faststream.specification.schema.message import CorrelationId, Message +from faststream.specification.schema.operation import Operation if TYPE_CHECKING: from faststream.broker.types import BrokerMiddleware, PublisherMiddleware diff --git a/faststream/redis/schemas/proto.py b/faststream/redis/schemas/proto.py index af0dca83c5..3a1b8e215a 100644 --- a/faststream/redis/schemas/proto.py +++ b/faststream/redis/schemas/proto.py @@ -1,12 +1,12 @@ from abc import abstractmethod from typing import TYPE_CHECKING, Any, Union -from faststream.asyncapi.abc import SpecificationOperation from faststream.exceptions import SetupError +from faststream.specification.abc import SpecificationOperation if TYPE_CHECKING: from faststream.redis.schemas import ListSub, PubSub, StreamSub - from faststream.specification.bindings import redis + from faststream.specification.schema.bindings import redis class RedisAsyncAPIProtocol(SpecificationOperation): diff --git a/faststream/redis/subscriber/subscriber.py b/faststream/redis/subscriber/subscriber.py index 45f39e2295..67eec23533 100644 --- a/faststream/redis/subscriber/subscriber.py +++ b/faststream/redis/subscriber/subscriber.py @@ -11,10 +11,10 @@ LogicSubscriber, StreamSubscriber, ) -from faststream.specification.bindings import ChannelBinding, redis -from faststream.specification.channel import Channel -from faststream.specification.message import CorrelationId, Message -from faststream.specification.operation import Operation +from faststream.specification.schema.bindings import ChannelBinding, redis +from faststream.specification.schema.channel import Channel +from faststream.specification.schema.message import CorrelationId, Message +from faststream.specification.schema.operation import Operation class SpecificationSubscriber(LogicSubscriber, RedisAsyncAPIProtocol): diff --git a/faststream/specification/__init__.py b/faststream/specification/__init__.py index 4e9a9ee5be..8be0ec91a9 100644 --- a/faststream/specification/__init__.py +++ b/faststream/specification/__init__.py @@ -1,25 +1,7 @@ -from . import ( - bindings, - channel, - contact, - docs, - info, - license, - message, - operation, - security, - tag, -) +from . import abc, proto, schema __all__ = ( - "bindings", - "channel", - "contact", - "docs", - "info", - "license", - "message", - "operation", - "security", - "tag", + "schema", + "abc", + "proto", ) diff --git a/faststream/asyncapi/abc.py b/faststream/specification/abc.py similarity index 95% rename from faststream/asyncapi/abc.py rename to faststream/specification/abc.py index b25e7e833b..a94105a921 100644 --- a/faststream/asyncapi/abc.py +++ b/faststream/specification/abc.py @@ -1,7 +1,7 @@ from abc import abstractmethod from typing import Any, Dict, Optional -from faststream.specification.channel import Channel +from faststream.specification.schema.channel import Channel from faststream.specification.proto import SpecificationProto diff --git a/faststream/specification/proto.py b/faststream/specification/proto.py index 259ce54b4f..adda399cd4 100644 --- a/faststream/specification/proto.py +++ b/faststream/specification/proto.py @@ -7,11 +7,11 @@ if TYPE_CHECKING: from faststream.broker.core.usecase import BrokerUsecase - from faststream.specification.channel import Channel + from faststream.specification.schema.channel import Channel from faststream.specification.contact import Contact, ContactDict from faststream.specification.docs import ExternalDocs, ExternalDocsDict from faststream.specification.license import License, LicenseDict - from faststream.specification.tag import Tag, TagDict + from faststream.specification.schema.tag import Tag, TagDict from faststream.types import ( AnyDict, AnyHttpUrl, diff --git a/faststream/specification/schema/__init__.py b/faststream/specification/schema/__init__.py new file mode 100644 index 0000000000..4e9a9ee5be --- /dev/null +++ b/faststream/specification/schema/__init__.py @@ -0,0 +1,25 @@ +from . import ( + bindings, + channel, + contact, + docs, + info, + license, + message, + operation, + security, + tag, +) + +__all__ = ( + "bindings", + "channel", + "contact", + "docs", + "info", + "license", + "message", + "operation", + "security", + "tag", +) diff --git a/faststream/specification/bindings/__init__.py b/faststream/specification/schema/bindings/__init__.py similarity index 100% rename from faststream/specification/bindings/__init__.py rename to faststream/specification/schema/bindings/__init__.py diff --git a/faststream/specification/bindings/amqp.py b/faststream/specification/schema/bindings/amqp.py similarity index 100% rename from faststream/specification/bindings/amqp.py rename to faststream/specification/schema/bindings/amqp.py diff --git a/faststream/specification/bindings/kafka.py b/faststream/specification/schema/bindings/kafka.py similarity index 100% rename from faststream/specification/bindings/kafka.py rename to faststream/specification/schema/bindings/kafka.py diff --git a/faststream/specification/bindings/main.py b/faststream/specification/schema/bindings/main.py similarity index 78% rename from faststream/specification/bindings/main.py rename to faststream/specification/schema/bindings/main.py index 515c35ac74..65622aaa76 100644 --- a/faststream/specification/bindings/main.py +++ b/faststream/specification/schema/bindings/main.py @@ -1,11 +1,11 @@ from dataclasses import dataclass from typing import Optional -from faststream.specification.bindings import amqp as amqp_bindings -from faststream.specification.bindings import kafka as kafka_bindings -from faststream.specification.bindings import nats as nats_bindings -from faststream.specification.bindings import redis as redis_bindings -from faststream.specification.bindings import sqs as sqs_bindings +from faststream.specification.schema.bindings import amqp as amqp_bindings +from faststream.specification.schema.bindings import kafka as kafka_bindings +from faststream.specification.schema.bindings import nats as nats_bindings +from faststream.specification.schema.bindings import redis as redis_bindings +from faststream.specification.schema.bindings import sqs as sqs_bindings @dataclass diff --git a/faststream/specification/bindings/nats.py b/faststream/specification/schema/bindings/nats.py similarity index 100% rename from faststream/specification/bindings/nats.py rename to faststream/specification/schema/bindings/nats.py diff --git a/faststream/specification/bindings/redis.py b/faststream/specification/schema/bindings/redis.py similarity index 100% rename from faststream/specification/bindings/redis.py rename to faststream/specification/schema/bindings/redis.py diff --git a/faststream/specification/bindings/sqs.py b/faststream/specification/schema/bindings/sqs.py similarity index 100% rename from faststream/specification/bindings/sqs.py rename to faststream/specification/schema/bindings/sqs.py diff --git a/faststream/specification/channel.py b/faststream/specification/schema/channel.py similarity index 83% rename from faststream/specification/channel.py rename to faststream/specification/schema/channel.py index 54976da55e..d5649a5c36 100644 --- a/faststream/specification/channel.py +++ b/faststream/specification/schema/channel.py @@ -1,8 +1,8 @@ from dataclasses import dataclass from typing import List, Optional -from faststream.specification.bindings import ChannelBinding -from faststream.specification.operation import Operation +from faststream.specification.schema.bindings import ChannelBinding +from faststream.specification.schema.operation import Operation @dataclass diff --git a/faststream/specification/contact.py b/faststream/specification/schema/contact.py similarity index 100% rename from faststream/specification/contact.py rename to faststream/specification/schema/contact.py diff --git a/faststream/specification/docs.py b/faststream/specification/schema/docs.py similarity index 100% rename from faststream/specification/docs.py rename to faststream/specification/schema/docs.py diff --git a/faststream/specification/info.py b/faststream/specification/schema/info.py similarity index 84% rename from faststream/specification/info.py rename to faststream/specification/schema/info.py index 8c310b2d62..804f46e61c 100644 --- a/faststream/specification/info.py +++ b/faststream/specification/schema/info.py @@ -7,8 +7,8 @@ from pydantic import AnyHttpUrl, BaseModel -from faststream.specification.contact import Contact, ContactDict -from faststream.specification.license import License, LicenseDict +from faststream.specification.schema.contact import Contact, ContactDict +from faststream.specification.schema.license import License, LicenseDict class Info(BaseModel): diff --git a/faststream/specification/license.py b/faststream/specification/schema/license.py similarity index 100% rename from faststream/specification/license.py rename to faststream/specification/schema/license.py diff --git a/faststream/specification/message.py b/faststream/specification/schema/message.py similarity index 92% rename from faststream/specification/message.py rename to faststream/specification/schema/message.py index fc00da98b4..bb000bbb96 100644 --- a/faststream/specification/message.py +++ b/faststream/specification/schema/message.py @@ -1,8 +1,8 @@ from dataclasses import dataclass from typing import Any, Dict, List, Optional, Union -from faststream.specification.docs import ExternalDocs -from faststream.specification.tag import Tag +from faststream.specification.schema.docs import ExternalDocs +from faststream.specification.schema.tag import Tag @dataclass diff --git a/faststream/specification/operation.py b/faststream/specification/schema/operation.py similarity index 78% rename from faststream/specification/operation.py rename to faststream/specification/schema/operation.py index 85e219caa7..40409bdbf4 100644 --- a/faststream/specification/operation.py +++ b/faststream/specification/schema/operation.py @@ -1,10 +1,10 @@ from dataclasses import dataclass from typing import Any, Dict, List, Optional, Union -from faststream.specification.bindings import OperationBinding -from faststream.specification.docs import ExternalDocs, ExternalDocsDict -from faststream.specification.message import Message -from faststream.specification.tag import Tag, TagDict +from faststream.specification.schema.bindings import OperationBinding +from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict +from faststream.specification.schema.message import Message +from faststream.specification.schema.tag import Tag, TagDict @dataclass diff --git a/faststream/specification/security.py b/faststream/specification/schema/security.py similarity index 100% rename from faststream/specification/security.py rename to faststream/specification/schema/security.py diff --git a/faststream/specification/tag.py b/faststream/specification/schema/tag.py similarity index 91% rename from faststream/specification/tag.py rename to faststream/specification/schema/tag.py index 163aff1cfc..ff9509d2c8 100644 --- a/faststream/specification/tag.py +++ b/faststream/specification/schema/tag.py @@ -3,7 +3,7 @@ from typing_extensions import Required, TypedDict -from faststream.specification.docs import ExternalDocs, ExternalDocsDict +from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict class TagDict(TypedDict, total=False): diff --git a/tests/asyncapi/confluent/v2_6_0/test_connection.py b/tests/asyncapi/confluent/v2_6_0/test_connection.py index b2aad0a080..24ea94d6e8 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_connection.py +++ b/tests/asyncapi/confluent/v2_6_0/test_connection.py @@ -1,7 +1,7 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema from faststream.confluent import KafkaBroker -from faststream.specification.tag import Tag +from faststream.specification.schema.tag import Tag def test_base(): diff --git a/tests/asyncapi/confluent/v3_0_0/test_connection.py b/tests/asyncapi/confluent/v3_0_0/test_connection.py index f97aa8dcd1..d7ee0f0161 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_connection.py +++ b/tests/asyncapi/confluent/v3_0_0/test_connection.py @@ -2,7 +2,7 @@ from faststream.asyncapi.generate import get_app_schema from faststream.asyncapi.version import AsyncAPIVersion from faststream.confluent import KafkaBroker -from faststream.specification.tag import Tag +from faststream.specification.schema.tag import Tag def test_base(): diff --git a/tests/asyncapi/kafka/v2_6_0/test_app.py b/tests/asyncapi/kafka/v2_6_0/test_app.py index e848624c37..9e556d9230 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_app.py +++ b/tests/asyncapi/kafka/v2_6_0/test_app.py @@ -2,8 +2,8 @@ from faststream.asyncapi.generate import get_app_schema from faststream.asyncapi.v2_6_0.schema.info import Contact, License from faststream.kafka import KafkaBroker -from faststream.specification.docs import ExternalDocs -from faststream.specification.tag import Tag +from faststream.specification.schema.docs import ExternalDocs +from faststream.specification.schema.tag import Tag def test_base(): diff --git a/tests/asyncapi/kafka/v2_6_0/test_connection.py b/tests/asyncapi/kafka/v2_6_0/test_connection.py index 8e67a19d63..503f2592d5 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_connection.py +++ b/tests/asyncapi/kafka/v2_6_0/test_connection.py @@ -1,7 +1,7 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema from faststream.kafka import KafkaBroker -from faststream.specification.tag import Tag +from faststream.specification.schema.tag import Tag def test_base(): diff --git a/tests/asyncapi/kafka/v3_0_0/test_connection.py b/tests/asyncapi/kafka/v3_0_0/test_connection.py index da20f08b66..0d74af1b7b 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_connection.py +++ b/tests/asyncapi/kafka/v3_0_0/test_connection.py @@ -2,7 +2,7 @@ from faststream.asyncapi.generate import get_app_schema from faststream.asyncapi.version import AsyncAPIVersion from faststream.kafka import KafkaBroker -from faststream.specification.tag import Tag +from faststream.specification.schema.tag import Tag def test_base(): diff --git a/tests/asyncapi/nats/v2_6_0/test_connection.py b/tests/asyncapi/nats/v2_6_0/test_connection.py index 641f3bae22..00ed2d5ccb 100644 --- a/tests/asyncapi/nats/v2_6_0/test_connection.py +++ b/tests/asyncapi/nats/v2_6_0/test_connection.py @@ -1,7 +1,7 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker -from faststream.specification.tag import Tag +from faststream.specification.schema.tag import Tag def test_base(): diff --git a/tests/asyncapi/nats/v3_0_0/test_connection.py b/tests/asyncapi/nats/v3_0_0/test_connection.py index 44130a2ac9..1570dc9699 100644 --- a/tests/asyncapi/nats/v3_0_0/test_connection.py +++ b/tests/asyncapi/nats/v3_0_0/test_connection.py @@ -2,7 +2,7 @@ from faststream.asyncapi.generate import get_app_schema from faststream.asyncapi.version import AsyncAPIVersion from faststream.nats import NatsBroker -from faststream.specification.tag import Tag +from faststream.specification.schema.tag import Tag def test_base(): diff --git a/tests/asyncapi/rabbit/v2_6_0/test_connection.py b/tests/asyncapi/rabbit/v2_6_0/test_connection.py index 4512ea42ce..fc125c5df1 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_connection.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_connection.py @@ -1,7 +1,7 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema from faststream.rabbit import RabbitBroker -from faststream.specification.tag import Tag +from faststream.specification.schema.tag import Tag def test_base(): diff --git a/tests/asyncapi/rabbit/v3_0_0/test_connection.py b/tests/asyncapi/rabbit/v3_0_0/test_connection.py index 42bf1e2ce5..d6d47d774a 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_connection.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_connection.py @@ -2,7 +2,7 @@ from faststream.asyncapi.generate import get_app_schema from faststream.asyncapi.version import AsyncAPIVersion from faststream.rabbit import RabbitBroker -from faststream.specification.tag import Tag +from faststream.specification.schema.tag import Tag def test_base(): diff --git a/tests/asyncapi/redis/v2_6_0/test_connection.py b/tests/asyncapi/redis/v2_6_0/test_connection.py index dcd5f9c100..53b0c6b126 100644 --- a/tests/asyncapi/redis/v2_6_0/test_connection.py +++ b/tests/asyncapi/redis/v2_6_0/test_connection.py @@ -1,7 +1,7 @@ from faststream import FastStream from faststream.asyncapi.generate import get_app_schema from faststream.redis import RedisBroker -from faststream.specification.tag import Tag +from faststream.specification.schema.tag import Tag def test_base(): diff --git a/tests/asyncapi/redis/v3_0_0/test_connection.py b/tests/asyncapi/redis/v3_0_0/test_connection.py index b77b7dda70..f29c2fa808 100644 --- a/tests/asyncapi/redis/v3_0_0/test_connection.py +++ b/tests/asyncapi/redis/v3_0_0/test_connection.py @@ -2,7 +2,7 @@ from faststream.asyncapi.generate import get_app_schema from faststream.asyncapi.version import AsyncAPIVersion from faststream.redis import RedisBroker -from faststream.specification.tag import Tag +from faststream.specification.schema.tag import Tag def test_base(): From 7dc7447111e1f58260037dabff3618401e04153c Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 8 Sep 2024 11:57:23 +0300 Subject: [PATCH 078/245] fix --- faststream/asyncapi/v2_6_0/generate.py | 2 +- faststream/asyncapi/v3_0_0/generate.py | 2 +- faststream/broker/publisher/usecase.py | 4 --- faststream/broker/subscriber/usecase.py | 2 -- faststream/kafka/subscriber/usecase.py | 4 +-- faststream/redis/schemas/proto.py | 4 +-- faststream/specification/__init__.py | 7 ---- faststream/specification/abc.py | 45 ------------------------- faststream/specification/proto.py | 39 +++++++++++++++------ 9 files changed, 35 insertions(+), 74 deletions(-) delete mode 100644 faststream/specification/abc.py diff --git a/faststream/asyncapi/v2_6_0/generate.py b/faststream/asyncapi/v2_6_0/generate.py index f4141d3b49..b01f0acc0e 100644 --- a/faststream/asyncapi/v2_6_0/generate.py +++ b/faststream/asyncapi/v2_6_0/generate.py @@ -1,7 +1,6 @@ from dataclasses import asdict from typing import TYPE_CHECKING, Any, Dict, List, Union -from faststream.specification import schema as spec from faststream._compat import DEF_KEY from faststream.asyncapi.v2_6_0.schema import ( Channel, @@ -28,6 +27,7 @@ ) from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message from faststream.constants import ContentTypes +from faststream.specification import schema as spec from faststream.specification.proto import Application if TYPE_CHECKING: diff --git a/faststream/asyncapi/v3_0_0/generate.py b/faststream/asyncapi/v3_0_0/generate.py index 6287ffbf6a..fe7c9e64ff 100644 --- a/faststream/asyncapi/v3_0_0/generate.py +++ b/faststream/asyncapi/v3_0_0/generate.py @@ -2,7 +2,6 @@ from typing import TYPE_CHECKING, Any, Dict, List, Union from urllib.parse import urlparse -from faststream.specification import schema as spec from faststream._compat import DEF_KEY from faststream.asyncapi.v2_6_0.generate import ( specs_channel_binding_to_asyncapi, @@ -27,6 +26,7 @@ Server, ) from faststream.constants import ContentTypes +from faststream.specification import schema as spec from faststream.specification.proto import Application if TYPE_CHECKING: diff --git a/faststream/broker/publisher/usecase.py b/faststream/broker/publisher/usecase.py index 57efb1ea58..4ddabd32bd 100644 --- a/faststream/broker/publisher/usecase.py +++ b/faststream/broker/publisher/usecase.py @@ -1,4 +1,3 @@ -from abc import ABC from inspect import unwrap from typing import ( TYPE_CHECKING, @@ -24,7 +23,6 @@ T_HandlerReturn, ) from faststream.broker.wrapper.call import HandlerCallWrapper -from faststream.specification.abc import SpecificationOperation if TYPE_CHECKING: from faststream.broker.publisher.proto import ProducerProto @@ -36,8 +34,6 @@ class PublisherUsecase( - ABC, - SpecificationOperation, PublisherProto[MsgType], ): """A base class for publishers in an asynchronous API.""" diff --git a/faststream/broker/subscriber/usecase.py b/faststream/broker/subscriber/usecase.py index ecccf41d56..e8ec931af2 100644 --- a/faststream/broker/subscriber/usecase.py +++ b/faststream/broker/subscriber/usecase.py @@ -30,7 +30,6 @@ from faststream.broker.utils import MultiLock, get_watcher_context, resolve_custom_func from faststream.broker.wrapper.call import HandlerCallWrapper from faststream.exceptions import SetupError, StopConsume, SubscriberNotFound -from faststream.specification.abc import SpecificationOperation from faststream.utils.context.repository import context from faststream.utils.functions import sync_fake_context, to_async @@ -77,7 +76,6 @@ def __init__( class SubscriberUsecase( - SpecificationOperation, SubscriberProto[MsgType], ): """A class representing an asynchronous handler.""" diff --git a/faststream/kafka/subscriber/usecase.py b/faststream/kafka/subscriber/usecase.py index c1bcfa6511..f501eee9a4 100644 --- a/faststream/kafka/subscriber/usecase.py +++ b/faststream/kafka/subscriber/usecase.py @@ -1,5 +1,5 @@ import asyncio -from abc import ABC, abstractmethod +from abc import abstractmethod from itertools import chain from typing import ( TYPE_CHECKING, @@ -40,7 +40,7 @@ from faststream.types import AnyDict, Decorator, LoggerProto -class LogicSubscriber(ABC, SubscriberUsecase[MsgType]): +class LogicSubscriber(SubscriberUsecase[MsgType]): """A class to handle logic for consuming messages from Kafka.""" topics: Sequence[str] diff --git a/faststream/redis/schemas/proto.py b/faststream/redis/schemas/proto.py index 3a1b8e215a..c130e07a23 100644 --- a/faststream/redis/schemas/proto.py +++ b/faststream/redis/schemas/proto.py @@ -2,14 +2,14 @@ from typing import TYPE_CHECKING, Any, Union from faststream.exceptions import SetupError -from faststream.specification.abc import SpecificationOperation +from faststream.specification.proto import SpecificationProto if TYPE_CHECKING: from faststream.redis.schemas import ListSub, PubSub, StreamSub from faststream.specification.schema.bindings import redis -class RedisAsyncAPIProtocol(SpecificationOperation): +class RedisAsyncAPIProtocol(SpecificationProto): @property @abstractmethod def channel_binding(self) -> "redis.ChannelBinding": ... diff --git a/faststream/specification/__init__.py b/faststream/specification/__init__.py index 8be0ec91a9..e69de29bb2 100644 --- a/faststream/specification/__init__.py +++ b/faststream/specification/__init__.py @@ -1,7 +0,0 @@ -from . import abc, proto, schema - -__all__ = ( - "schema", - "abc", - "proto", -) diff --git a/faststream/specification/abc.py b/faststream/specification/abc.py deleted file mode 100644 index a94105a921..0000000000 --- a/faststream/specification/abc.py +++ /dev/null @@ -1,45 +0,0 @@ -from abc import abstractmethod -from typing import Any, Dict, Optional - -from faststream.specification.schema.channel import Channel -from faststream.specification.proto import SpecificationProto - - -class SpecificationOperation(SpecificationProto): - """A class representing an asynchronous API operation.""" - - @property - def name(self) -> str: - """Returns the name of the API operation.""" - return self.title_ or self.get_name() - - @abstractmethod - def get_name(self) -> str: - """Name property fallback.""" - raise NotImplementedError() - - @property - def description(self) -> Optional[str]: - """Returns the description of the API operation.""" - return self.description_ or self.get_description() - - def get_description(self) -> Optional[str]: - """Description property fallback.""" - return None - - def schema(self) -> Dict[str, Channel]: - """Returns the schema of the API operation as a dictionary of channel names and channel objects.""" - if self.include_in_schema: - return self.get_schema() - else: - return {} - - @abstractmethod - def get_schema(self) -> Dict[str, Channel]: - """Generate AsyncAPI schema.""" - raise NotImplementedError() - - @abstractmethod - def get_payloads(self) -> Any: - """Generate AsyncAPI payloads.""" - raise NotImplementedError() diff --git a/faststream/specification/proto.py b/faststream/specification/proto.py index adda399cd4..62734f7c71 100644 --- a/faststream/specification/proto.py +++ b/faststream/specification/proto.py @@ -4,13 +4,13 @@ from typing_extensions import Annotated, Doc from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.schema.channel import Channel if TYPE_CHECKING: from faststream.broker.core.usecase import BrokerUsecase - from faststream.specification.schema.channel import Channel - from faststream.specification.contact import Contact, ContactDict - from faststream.specification.docs import ExternalDocs, ExternalDocsDict - from faststream.specification.license import License, LicenseDict + from faststream.specification.schema.contact import Contact, ContactDict + from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict + from faststream.specification.schema.license import License, LicenseDict from faststream.specification.schema.tag import Tag, TagDict from faststream.types import ( AnyDict, @@ -50,18 +50,37 @@ class SpecificationProto(Protocol): ] @property - @abstractmethod def name(self) -> str: """Returns the name of the API operation.""" - ... + return self.title_ or self.get_name() - @property @abstractmethod + def get_name(self) -> str: + """Name property fallback.""" + raise NotImplementedError() + + @property def description(self) -> Optional[str]: """Returns the description of the API operation.""" - ... + return self.description_ or self.get_description() + + def get_description(self) -> Optional[str]: + """Description property fallback.""" + return None + + def schema(self) -> Dict[str, Channel]: + """Returns the schema of the API operation as a dictionary of channel names and channel objects.""" + if self.include_in_schema: + return self.get_schema() + else: + return {} @abstractmethod - def schema(self) -> Dict[str, "Channel"]: + def get_schema(self) -> Dict[str, Channel]: """Generate AsyncAPI schema.""" - ... + raise NotImplementedError() + + @abstractmethod + def get_payloads(self) -> Any: + """Generate AsyncAPI payloads.""" + raise NotImplementedError() From 133ad05d0bce31caaf3307566684ccaac65c72e4 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Wed, 14 Aug 2024 23:35:38 +0300 Subject: [PATCH 079/245] replace AsyncAPI 2.6.0 components via internal specs --- .../asyncapi_customization/custom_info.py | 2 +- faststream/app.py | 8 ++++---- faststream/asgi/factories.py | 6 +++--- faststream/asyncapi/__init__.py | 9 --------- faststream/asyncapi/base/__init__.py | 5 ----- faststream/broker/fastapi/router.py | 12 ++++++------ faststream/broker/publisher/usecase.py | 4 ++-- faststream/broker/subscriber/usecase.py | 4 ++-- faststream/cli/docs/app.py | 6 +++--- faststream/confluent/broker/broker.py | 4 ++-- faststream/confluent/fastapi/fastapi.py | 6 +++--- faststream/confluent/publisher/publisher.py | 2 +- faststream/confluent/subscriber/subscriber.py | 2 +- faststream/kafka/broker/broker.py | 4 ++-- faststream/kafka/fastapi/fastapi.py | 6 +++--- faststream/kafka/publisher/publisher.py | 2 +- faststream/kafka/subscriber/subscriber.py | 2 +- faststream/nats/broker/broker.py | 4 ++-- faststream/nats/fastapi/fastapi.py | 6 +++--- faststream/nats/publisher/publisher.py | 2 +- faststream/nats/subscriber/subscriber.py | 2 +- faststream/rabbit/broker/broker.py | 4 ++-- faststream/rabbit/fastapi/router.py | 6 +++--- faststream/rabbit/publisher/publisher.py | 2 +- faststream/rabbit/subscriber/subscriber.py | 2 +- faststream/redis/broker/broker.py | 4 ++-- faststream/redis/fastapi/fastapi.py | 6 +++--- faststream/redis/publisher/publisher.py | 2 +- faststream/redis/subscriber/subscriber.py | 2 +- faststream/specification/asyncapi/__init__.py | 9 +++++++++ .../specification/asyncapi/base/__init__.py | 5 +++++ .../asyncapi/base/schema/__init__.py | 0 .../asyncapi/base/schema/info.py | 0 .../asyncapi/base/schema/schema.py | 2 +- .../{ => specification}/asyncapi/generate.py | 12 ++++++++---- .../{ => specification}/asyncapi/message.py | 0 .../{ => specification}/asyncapi/site.py | 2 +- .../{ => specification}/asyncapi/utils.py | 0 .../asyncapi/v2_6_0/__init__.py | 0 .../asyncapi/v2_6_0/generate.py | 13 ++++++++----- .../asyncapi/v2_6_0/schema/__init__.py | 0 .../v2_6_0/schema/bindings/__init__.py | 0 .../asyncapi/v2_6_0/schema/bindings/amqp.py | 0 .../asyncapi/v2_6_0/schema/bindings/kafka.py | 0 .../asyncapi/v2_6_0/schema/bindings/main.py | 18 +++++++++++++----- .../asyncapi/v2_6_0/schema/bindings/nats.py | 0 .../asyncapi/v2_6_0/schema/bindings/redis.py | 0 .../asyncapi/v2_6_0/schema/bindings/sqs.py | 0 .../asyncapi/v2_6_0/schema/channels.py | 4 ++-- .../asyncapi/v2_6_0/schema/components.py | 2 +- .../asyncapi/v2_6_0/schema/info.py | 2 +- .../asyncapi/v2_6_0/schema/message.py | 2 +- .../asyncapi/v2_6_0/schema/operations.py | 6 +++--- .../asyncapi/v2_6_0/schema/schema.py | 14 +++++++------- .../asyncapi/v2_6_0/schema/servers.py | 8 ++++++-- .../asyncapi/v2_6_0/schema/utils.py | 0 .../asyncapi/v3_0_0/__init__.py | 0 .../asyncapi/v3_0_0/generate.py | 15 +++++++++------ .../asyncapi/v3_0_0/schema/__init__.py | 0 .../asyncapi/v3_0_0/schema/channels.py | 6 +++--- .../asyncapi/v3_0_0/schema/components.py | 2 +- .../asyncapi/v3_0_0/schema/info.py | 6 +++--- .../asyncapi/v3_0_0/schema/operations.py | 6 +++--- .../asyncapi/v3_0_0/schema/schema.py | 14 +++++++------- .../asyncapi/v3_0_0/schema/servers.py | 10 +++++++--- .../{ => specification}/asyncapi/version.py | 0 faststream/specification/proto.py | 2 +- .../asyncapi_customization/test_basic.py | 2 +- .../asyncapi_customization/test_broker.py | 2 +- .../asyncapi_customization/test_handler.py | 2 +- .../asyncapi_customization/test_info.py | 2 +- .../asyncapi_customization/test_payload.py | 2 +- tests/a_docs/rabbit/test_security.py | 2 +- tests/a_docs/redis/test_security.py | 2 +- tests/asyncapi/base/arguments.py | 2 +- tests/asyncapi/base/fastapi.py | 2 +- tests/asyncapi/base/naming.py | 2 +- tests/asyncapi/base/publisher.py | 2 +- tests/asyncapi/base/router.py | 2 +- tests/asyncapi/base/v3_0_0/arguments.py | 4 ++-- tests/asyncapi/base/v3_0_0/fastapi.py | 4 ++-- tests/asyncapi/base/v3_0_0/naming.py | 4 ++-- tests/asyncapi/base/v3_0_0/publisher.py | 4 ++-- tests/asyncapi/base/v3_0_0/router.py | 4 ++-- .../confluent/v2_6_0/test_arguments.py | 2 +- .../confluent/v2_6_0/test_connection.py | 2 +- .../asyncapi/confluent/v2_6_0/test_fastapi.py | 2 +- tests/asyncapi/confluent/v2_6_0/test_naming.py | 2 +- .../confluent/v2_6_0/test_publisher.py | 2 +- tests/asyncapi/confluent/v2_6_0/test_router.py | 2 +- .../asyncapi/confluent/v2_6_0/test_security.py | 2 +- .../confluent/v3_0_0/test_arguments.py | 2 +- .../confluent/v3_0_0/test_connection.py | 4 ++-- .../asyncapi/confluent/v3_0_0/test_fastapi.py | 4 ++-- tests/asyncapi/confluent/v3_0_0/test_naming.py | 4 ++-- .../confluent/v3_0_0/test_publisher.py | 2 +- tests/asyncapi/confluent/v3_0_0/test_router.py | 4 ++-- .../asyncapi/confluent/v3_0_0/test_security.py | 4 ++-- tests/asyncapi/kafka/v2_6_0/test_app.py | 4 ++-- tests/asyncapi/kafka/v2_6_0/test_arguments.py | 2 +- tests/asyncapi/kafka/v2_6_0/test_connection.py | 2 +- tests/asyncapi/kafka/v2_6_0/test_fastapi.py | 2 +- tests/asyncapi/kafka/v2_6_0/test_naming.py | 2 +- tests/asyncapi/kafka/v2_6_0/test_publisher.py | 2 +- tests/asyncapi/kafka/v2_6_0/test_router.py | 2 +- tests/asyncapi/kafka/v2_6_0/test_security.py | 2 +- tests/asyncapi/kafka/v3_0_0/test_arguments.py | 2 +- tests/asyncapi/kafka/v3_0_0/test_connection.py | 4 ++-- tests/asyncapi/kafka/v3_0_0/test_fastapi.py | 4 ++-- tests/asyncapi/kafka/v3_0_0/test_naming.py | 4 ++-- tests/asyncapi/kafka/v3_0_0/test_publisher.py | 2 +- tests/asyncapi/kafka/v3_0_0/test_router.py | 4 ++-- tests/asyncapi/kafka/v3_0_0/test_security.py | 4 ++-- tests/asyncapi/nats/v2_6_0/test_arguments.py | 2 +- tests/asyncapi/nats/v2_6_0/test_connection.py | 2 +- tests/asyncapi/nats/v2_6_0/test_kv_schema.py | 2 +- tests/asyncapi/nats/v2_6_0/test_naming.py | 2 +- tests/asyncapi/nats/v2_6_0/test_obj_schema.py | 2 +- tests/asyncapi/nats/v2_6_0/test_publisher.py | 2 +- tests/asyncapi/nats/v2_6_0/test_router.py | 2 +- tests/asyncapi/nats/v3_0_0/test_arguments.py | 2 +- tests/asyncapi/nats/v3_0_0/test_connection.py | 4 ++-- tests/asyncapi/nats/v3_0_0/test_fastapi.py | 2 +- tests/asyncapi/nats/v3_0_0/test_kv_schema.py | 4 ++-- tests/asyncapi/nats/v3_0_0/test_naming.py | 4 ++-- tests/asyncapi/nats/v3_0_0/test_obj_schema.py | 4 ++-- tests/asyncapi/nats/v3_0_0/test_publisher.py | 2 +- tests/asyncapi/nats/v3_0_0/test_router.py | 4 ++-- tests/asyncapi/rabbit/v2_6_0/test_arguments.py | 2 +- .../asyncapi/rabbit/v2_6_0/test_connection.py | 2 +- tests/asyncapi/rabbit/v2_6_0/test_fastapi.py | 2 +- tests/asyncapi/rabbit/v2_6_0/test_naming.py | 2 +- tests/asyncapi/rabbit/v2_6_0/test_publisher.py | 2 +- tests/asyncapi/rabbit/v2_6_0/test_router.py | 2 +- tests/asyncapi/rabbit/v2_6_0/test_security.py | 2 +- tests/asyncapi/rabbit/v3_0_0/test_arguments.py | 2 +- .../asyncapi/rabbit/v3_0_0/test_connection.py | 4 ++-- tests/asyncapi/rabbit/v3_0_0/test_fastapi.py | 4 ++-- tests/asyncapi/rabbit/v3_0_0/test_naming.py | 4 ++-- tests/asyncapi/rabbit/v3_0_0/test_publisher.py | 2 +- tests/asyncapi/rabbit/v3_0_0/test_router.py | 4 ++-- tests/asyncapi/rabbit/v3_0_0/test_security.py | 4 ++-- tests/asyncapi/redis/v2_6_0/test_arguments.py | 2 +- tests/asyncapi/redis/v2_6_0/test_connection.py | 2 +- tests/asyncapi/redis/v2_6_0/test_naming.py | 2 +- tests/asyncapi/redis/v2_6_0/test_publisher.py | 2 +- tests/asyncapi/redis/v2_6_0/test_router.py | 2 +- tests/asyncapi/redis/v2_6_0/test_security.py | 2 +- tests/asyncapi/redis/v3_0_0/test_arguments.py | 2 +- tests/asyncapi/redis/v3_0_0/test_connection.py | 4 ++-- tests/asyncapi/redis/v3_0_0/test_fastapi.py | 2 +- tests/asyncapi/redis/v3_0_0/test_naming.py | 4 ++-- tests/asyncapi/redis/v3_0_0/test_publisher.py | 2 +- tests/asyncapi/redis/v3_0_0/test_router.py | 4 ++-- tests/asyncapi/redis/v3_0_0/test_security.py | 4 ++-- 155 files changed, 274 insertions(+), 248 deletions(-) delete mode 100644 faststream/asyncapi/__init__.py delete mode 100644 faststream/asyncapi/base/__init__.py create mode 100644 faststream/specification/asyncapi/__init__.py create mode 100644 faststream/specification/asyncapi/base/__init__.py rename faststream/{ => specification}/asyncapi/base/schema/__init__.py (100%) rename faststream/{ => specification}/asyncapi/base/schema/info.py (100%) rename faststream/{ => specification}/asyncapi/base/schema/schema.py (94%) rename faststream/{ => specification}/asyncapi/generate.py (55%) rename faststream/{ => specification}/asyncapi/message.py (100%) rename faststream/{ => specification}/asyncapi/site.py (98%) rename faststream/{ => specification}/asyncapi/utils.py (100%) rename faststream/{ => specification}/asyncapi/v2_6_0/__init__.py (100%) rename faststream/{ => specification}/asyncapi/v2_6_0/generate.py (98%) rename faststream/{ => specification}/asyncapi/v2_6_0/schema/__init__.py (100%) rename faststream/{ => specification}/asyncapi/v2_6_0/schema/bindings/__init__.py (100%) rename faststream/{ => specification}/asyncapi/v2_6_0/schema/bindings/amqp.py (100%) rename faststream/{ => specification}/asyncapi/v2_6_0/schema/bindings/kafka.py (100%) rename faststream/{ => specification}/asyncapi/v2_6_0/schema/bindings/main.py (82%) rename faststream/{ => specification}/asyncapi/v2_6_0/schema/bindings/nats.py (100%) rename faststream/{ => specification}/asyncapi/v2_6_0/schema/bindings/redis.py (100%) rename faststream/{ => specification}/asyncapi/v2_6_0/schema/bindings/sqs.py (100%) rename faststream/{ => specification}/asyncapi/v2_6_0/schema/channels.py (87%) rename faststream/{ => specification}/asyncapi/v2_6_0/schema/components.py (94%) rename faststream/{ => specification}/asyncapi/v2_6_0/schema/info.py (98%) rename faststream/{ => specification}/asyncapi/v2_6_0/schema/message.py (96%) rename faststream/{ => specification}/asyncapi/v2_6_0/schema/operations.py (84%) rename faststream/{ => specification}/asyncapi/v2_6_0/schema/schema.py (79%) rename faststream/{ => specification}/asyncapi/v2_6_0/schema/servers.py (92%) rename faststream/{ => specification}/asyncapi/v2_6_0/schema/utils.py (100%) rename faststream/{ => specification}/asyncapi/v3_0_0/__init__.py (100%) rename faststream/{ => specification}/asyncapi/v3_0_0/generate.py (97%) rename faststream/{ => specification}/asyncapi/v3_0_0/schema/__init__.py (100%) rename faststream/{ => specification}/asyncapi/v3_0_0/schema/channels.py (82%) rename faststream/{ => specification}/asyncapi/v3_0_0/schema/components.py (94%) rename faststream/{ => specification}/asyncapi/v3_0_0/schema/info.py (83%) rename faststream/{ => specification}/asyncapi/v3_0_0/schema/operations.py (84%) rename faststream/{ => specification}/asyncapi/v3_0_0/schema/schema.py (76%) rename faststream/{ => specification}/asyncapi/v3_0_0/schema/servers.py (85%) rename faststream/{ => specification}/asyncapi/version.py (100%) diff --git a/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_info.py b/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_info.py index 621956bf15..1164cc4ba9 100644 --- a/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_info.py +++ b/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_info.py @@ -1,5 +1,5 @@ from faststream import FastStream -from faststream.asyncapi.v2_6_0.schema.info import License, Contact +from faststream.specification.asyncapi.v2_6_0.schema.info import License, Contact from faststream.kafka import KafkaBroker broker = KafkaBroker("localhost:9092") diff --git a/faststream/app.py b/faststream/app.py index 6073ba4248..6d871b913f 100644 --- a/faststream/app.py +++ b/faststream/app.py @@ -16,10 +16,10 @@ from typing_extensions import ParamSpec from faststream._compat import ExceptionGroup -from faststream.asyncapi.version import AsyncAPIVersion from faststream.cli.supervisors.utils import set_exit from faststream.exceptions import ValidationError from faststream.log.logging import logger +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.proto import Application from faststream.utils import apply_types, context from faststream.utils.functions import drop_response_type, fake_context, to_async @@ -30,9 +30,9 @@ if TYPE_CHECKING: from faststream.broker.core.usecase import BrokerUsecase - from faststream.specification.contact import Contact, ContactDict - from faststream.specification.docs import ExternalDocs, ExternalDocsDict - from faststream.specification.license import License, LicenseDict + from faststream.specification.schema.contact import Contact, ContactDict + from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict + from faststream.specification.schema.license import License, LicenseDict from faststream.specification.schema.tag import Tag, TagDict from faststream.types import ( AnyCallable, diff --git a/faststream/asgi/factories.py b/faststream/asgi/factories.py index a14ba8a661..41122b9db2 100644 --- a/faststream/asgi/factories.py +++ b/faststream/asgi/factories.py @@ -6,8 +6,8 @@ from faststream.asgi.handlers import get from faststream.asgi.response import AsgiResponse -from faststream.asyncapi import get_app_schema -from faststream.asyncapi.site import ( +from faststream.specification.asyncapi import get_app_schema +from faststream.specification.asyncapi.site import ( ASYNCAPI_CSS_DEFAULT_URL, ASYNCAPI_JS_DEFAULT_URL, get_asyncapi_html, @@ -15,8 +15,8 @@ if TYPE_CHECKING: from faststream.asgi.types import ASGIApp, Scope - from faststream.asyncapi.proto import Application from faststream.broker.core.usecase import BrokerUsecase + from faststream.specification.proto import Application def make_ping_asgi( diff --git a/faststream/asyncapi/__init__.py b/faststream/asyncapi/__init__.py deleted file mode 100644 index 07827b8101..0000000000 --- a/faststream/asyncapi/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -"""AsyncAPI related functions.""" - -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.site import get_asyncapi_html - -__all__ = ( - "get_asyncapi_html", - "get_app_schema", -) diff --git a/faststream/asyncapi/base/__init__.py b/faststream/asyncapi/base/__init__.py deleted file mode 100644 index f9bfcf6e90..0000000000 --- a/faststream/asyncapi/base/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from faststream.asyncapi.base import schema - -__all__ = ( - "schema", -) diff --git a/faststream/broker/fastapi/router.py b/faststream/broker/fastapi/router.py index 1fc7c2b939..fe42f29109 100644 --- a/faststream/broker/fastapi/router.py +++ b/faststream/broker/fastapi/router.py @@ -30,8 +30,6 @@ from starlette.responses import JSONResponse, Response from starlette.routing import BaseRoute, _DefaultLifespan -from faststream.asyncapi.site import get_asyncapi_html -from faststream.asyncapi.version import AsyncAPIVersion from faststream.broker.fastapi.get_dependant import get_fastapi_dependant from faststream.broker.fastapi.route import wrap_callable_to_fastapi_compatible from faststream.broker.middlewares import BaseMiddleware @@ -41,6 +39,8 @@ P_HandlerParams, T_HandlerReturn, ) +from faststream.specification.asyncapi.site import get_asyncapi_html +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.proto import Application from faststream.utils.context.repository import context from faststream.utils.functions import fake_context, to_async @@ -53,14 +53,14 @@ from starlette import routing from starlette.types import ASGIApp, AppType, Lifespan - from faststream.asyncapi import schema as asyncapi - from faststream.asyncapi.schema import BaseSchema from faststream.broker.core.usecase import BrokerUsecase from faststream.broker.message import StreamMessage from faststream.broker.publisher.proto import PublisherProto from faststream.broker.schemas import NameRequired from faststream.broker.types import BrokerMiddleware from faststream.broker.wrapper.call import HandlerCallWrapper + from faststream.specification.asyncapi.base.schema import BaseSchema + from faststream.specification.schema.tag import Tag, TagDict from faststream.types import AnyDict @@ -129,7 +129,7 @@ def __init__( # AsyncAPI information asyncapi_version: AsyncAPIVersion = AsyncAPIVersion.v2_6, asyncapi_tags: Optional[ - Iterable[Union["asyncapi.Tag", "asyncapi.TagDict"]] + Iterable[Union["Tag", "TagDict"]] ] = None, schema_url: Optional[str] = "/asyncapi", **connection_kwars: Any, @@ -303,7 +303,7 @@ async def start_broker_lifespan( self.contact = app.contact self.license = app.license_info - from faststream.asyncapi.generate import get_app_schema + from faststream.specification.asyncapi.generate import get_app_schema self.schema = get_app_schema(self) diff --git a/faststream/broker/publisher/usecase.py b/faststream/broker/publisher/usecase.py index 4ddabd32bd..1305aa169f 100644 --- a/faststream/broker/publisher/usecase.py +++ b/faststream/broker/publisher/usecase.py @@ -14,8 +14,6 @@ from fast_depends.core import CallModel, build_call_model from typing_extensions import Annotated, Doc, override -from faststream.asyncapi.message import get_response_schema -from faststream.asyncapi.utils import to_camelcase from faststream.broker.publisher.proto import PublisherProto from faststream.broker.types import ( MsgType, @@ -23,6 +21,8 @@ T_HandlerReturn, ) from faststream.broker.wrapper.call import HandlerCallWrapper +from faststream.specification.asyncapi.message import get_response_schema +from faststream.specification.asyncapi.utils import to_camelcase if TYPE_CHECKING: from faststream.broker.publisher.proto import ProducerProto diff --git a/faststream/broker/subscriber/usecase.py b/faststream/broker/subscriber/usecase.py index e8ec931af2..e5ed1399d4 100644 --- a/faststream/broker/subscriber/usecase.py +++ b/faststream/broker/subscriber/usecase.py @@ -17,8 +17,6 @@ from typing_extensions import Self, override -from faststream.asyncapi.message import parse_handler_params -from faststream.asyncapi.utils import to_camelcase from faststream.broker.response import ensure_response from faststream.broker.subscriber.call_item import HandlerItem from faststream.broker.subscriber.proto import SubscriberProto @@ -29,6 +27,8 @@ ) from faststream.broker.utils import MultiLock, get_watcher_context, resolve_custom_func from faststream.broker.wrapper.call import HandlerCallWrapper +from faststream.specification.asyncapi.message import parse_handler_params +from faststream.specification.asyncapi.utils import to_camelcase from faststream.exceptions import SetupError, StopConsume, SubscriberNotFound from faststream.utils.context.repository import context from faststream.utils.functions import sync_fake_context, to_async diff --git a/faststream/cli/docs/app.py b/faststream/cli/docs/app.py index 4ecaa05728..8e7170a3ff 100644 --- a/faststream/cli/docs/app.py +++ b/faststream/cli/docs/app.py @@ -7,11 +7,11 @@ import typer from faststream._compat import json_dumps, model_parse -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.site import serve_app -from faststream.asyncapi.v2_6_0.schema import Schema from faststream.cli.utils.imports import import_from_string from faststream.exceptions import INSTALL_WATCHFILES, INSTALL_YAML +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.site import serve_app +from faststream.specification.asyncapi.v2_6_0.schema import Schema docs_app = typer.Typer(pretty_exceptions_short=True) diff --git a/faststream/confluent/broker/broker.py b/faststream/confluent/broker/broker.py index e5facb8647..fe2dfcf814 100644 --- a/faststream/confluent/broker/broker.py +++ b/faststream/confluent/broker/broker.py @@ -40,13 +40,13 @@ from confluent_kafka import Message from fast_depends.dependencies import Depends - from faststream.asyncapi import schema as asyncapi from faststream.broker.types import ( BrokerMiddleware, CustomCallable, ) from faststream.confluent.config import ConfluentConfig from faststream.security import BaseSecurity + from faststream.specification.schema.tag import Tag, TagDict from faststream.types import ( AnyDict, AsyncFunc, @@ -298,7 +298,7 @@ def __init__( Doc("AsyncAPI server description."), ] = None, tags: Annotated[ - Optional[Iterable[Union["asyncapi.Tag", "asyncapi.TagDict"]]], + Optional[Iterable[Union["Tag", "TagDict"]]], Doc("AsyncAPI server tags."), ] = None, # logging args diff --git a/faststream/confluent/fastapi/fastapi.py b/faststream/confluent/fastapi/fastapi.py index 06c6aa8bdd..befa62665b 100644 --- a/faststream/confluent/fastapi/fastapi.py +++ b/faststream/confluent/fastapi/fastapi.py @@ -26,10 +26,10 @@ from typing_extensions import Annotated, Doc, deprecated, override from faststream.__about__ import SERVICE_NAME -from faststream.asyncapi.version import AsyncAPIVersion from faststream.broker.fastapi.router import StreamRouter from faststream.broker.utils import default_filter from faststream.confluent.broker.broker import KafkaBroker as KB +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.types import EMPTY if TYPE_CHECKING: @@ -39,7 +39,6 @@ from fastapi.types import IncEx from starlette.types import ASGIApp, Lifespan - from faststream.asyncapi import schema as asyncapi from faststream.broker.types import ( BrokerMiddleware, CustomCallable, @@ -59,6 +58,7 @@ SpecificationDefaultSubscriber, ) from faststream.security import BaseSecurity + from faststream.specification.schema.tag import Tag, TagDict from faststream.types import AnyDict, LoggerProto @@ -304,7 +304,7 @@ def __init__( Doc("Version of Specification for schema generation") ] = AsyncAPIVersion.v2_6, asyncapi_tags: Annotated[ - Optional[Iterable[Union["asyncapi.Tag", "asyncapi.TagDict"]]], + Optional[Iterable[Union["Tag", "TagDict"]]], Doc("Specification server tags."), ] = None, # logging args diff --git a/faststream/confluent/publisher/publisher.py b/faststream/confluent/publisher/publisher.py index dede2aceb7..7be876ddf8 100644 --- a/faststream/confluent/publisher/publisher.py +++ b/faststream/confluent/publisher/publisher.py @@ -12,7 +12,6 @@ from typing_extensions import override -from faststream.asyncapi.utils import resolve_payloads from faststream.broker.types import MsgType from faststream.confluent.publisher.usecase import ( BatchPublisher, @@ -20,6 +19,7 @@ LogicPublisher, ) from faststream.exceptions import SetupError +from faststream.specification.asyncapi.utils import resolve_payloads from faststream.specification.schema.bindings import ChannelBinding, kafka from faststream.specification.schema.channel import Channel from faststream.specification.schema.message import CorrelationId, Message diff --git a/faststream/confluent/subscriber/subscriber.py b/faststream/confluent/subscriber/subscriber.py index 454d739906..b706a075bb 100644 --- a/faststream/confluent/subscriber/subscriber.py +++ b/faststream/confluent/subscriber/subscriber.py @@ -4,13 +4,13 @@ Tuple, ) -from faststream.asyncapi.utils import resolve_payloads from faststream.broker.types import MsgType from faststream.confluent.subscriber.usecase import ( BatchSubscriber, DefaultSubscriber, LogicSubscriber, ) +from faststream.specification.asyncapi.utils import resolve_payloads from faststream.specification.schema.bindings import ChannelBinding, kafka from faststream.specification.schema.channel import Channel from faststream.specification.schema.message import CorrelationId, Message diff --git a/faststream/kafka/broker/broker.py b/faststream/kafka/broker/broker.py index e3a5ec4e67..c2ff0c1cca 100644 --- a/faststream/kafka/broker/broker.py +++ b/faststream/kafka/broker/broker.py @@ -43,12 +43,12 @@ from fast_depends.dependencies import Depends from typing_extensions import TypedDict, Unpack - from faststream.asyncapi import schema as asyncapi from faststream.broker.types import ( BrokerMiddleware, CustomCallable, ) from faststream.security import BaseSecurity + from faststream.specification.schema.tag import Tag, TagDict from faststream.types import ( AnyDict, AsyncFunc, @@ -472,7 +472,7 @@ def __init__( Doc("AsyncAPI server description."), ] = None, tags: Annotated[ - Optional[Iterable[Union["asyncapi.Tag", "asyncapi.TagDict"]]], + Optional[Iterable[Union["Tag", "TagDict"]]], Doc("AsyncAPI server tags."), ] = None, # logging args diff --git a/faststream/kafka/fastapi/fastapi.py b/faststream/kafka/fastapi/fastapi.py index 169a5e1026..6b1e962b1f 100644 --- a/faststream/kafka/fastapi/fastapi.py +++ b/faststream/kafka/fastapi/fastapi.py @@ -29,10 +29,10 @@ from typing_extensions import Annotated, Doc, deprecated, override from faststream.__about__ import SERVICE_NAME -from faststream.asyncapi.version import AsyncAPIVersion from faststream.broker.fastapi.router import StreamRouter from faststream.broker.utils import default_filter from faststream.kafka.broker.broker import KafkaBroker as KB +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.types import EMPTY if TYPE_CHECKING: @@ -46,7 +46,6 @@ from fastapi.types import IncEx from starlette.types import ASGIApp, Lifespan - from faststream.asyncapi import schema as asyncapi from faststream.broker.types import ( BrokerMiddleware, CustomCallable, @@ -64,6 +63,7 @@ SpecificationDefaultSubscriber, ) from faststream.security import BaseSecurity + from faststream.specification.schema.tag import Tag, TagDict from faststream.types import AnyDict, LoggerProto Partition = TypeVar("Partition") @@ -312,7 +312,7 @@ def __init__( Doc("Version of Specification for schema generation") ] = AsyncAPIVersion.v2_6, asyncapi_tags: Annotated[ - Optional[Iterable[Union["asyncapi.Tag", "asyncapi.TagDict"]]], + Optional[Iterable[Union["Tag", "TagDict"]]], Doc("Specification server tags."), ] = None, # logging args diff --git a/faststream/kafka/publisher/publisher.py b/faststream/kafka/publisher/publisher.py index e5e22616fb..f6ac82a709 100644 --- a/faststream/kafka/publisher/publisher.py +++ b/faststream/kafka/publisher/publisher.py @@ -12,7 +12,6 @@ from typing_extensions import override -from faststream.asyncapi.utils import resolve_payloads from faststream.broker.types import MsgType from faststream.exceptions import SetupError from faststream.kafka.publisher.usecase import ( @@ -20,6 +19,7 @@ DefaultPublisher, LogicPublisher, ) +from faststream.specification.asyncapi.utils import resolve_payloads from faststream.specification.schema.bindings import ChannelBinding, kafka from faststream.specification.schema.channel import Channel from faststream.specification.schema.message import CorrelationId, Message diff --git a/faststream/kafka/subscriber/subscriber.py b/faststream/kafka/subscriber/subscriber.py index b695aac9d1..8931fe14c9 100644 --- a/faststream/kafka/subscriber/subscriber.py +++ b/faststream/kafka/subscriber/subscriber.py @@ -4,13 +4,13 @@ Tuple, ) -from faststream.asyncapi.utils import resolve_payloads from faststream.broker.types import MsgType from faststream.kafka.subscriber.usecase import ( BatchSubscriber, DefaultSubscriber, LogicSubscriber, ) +from faststream.specification.asyncapi.utils import resolve_payloads from faststream.specification.schema.bindings import ChannelBinding, kafka from faststream.specification.schema.channel import Channel from faststream.specification.schema.message import CorrelationId, Message diff --git a/faststream/nats/broker/broker.py b/faststream/nats/broker/broker.py index 297822f8e5..5096b7dfe9 100644 --- a/faststream/nats/broker/broker.py +++ b/faststream/nats/broker/broker.py @@ -59,7 +59,6 @@ from nats.js.object_store import ObjectStore from typing_extensions import TypedDict, Unpack - from faststream.asyncapi import schema as asyncapi from faststream.broker.publisher.proto import ProducerProto from faststream.broker.types import ( BrokerMiddleware, @@ -68,6 +67,7 @@ from faststream.nats.message import NatsMessage from faststream.nats.publisher.publisher import SpecificationPublisher from faststream.security import BaseSecurity + from faststream.specification.schema.tag import Tag, TagDict from faststream.types import ( AnyDict, DecodedMessage, @@ -413,7 +413,7 @@ def __init__( Doc("AsyncAPI server description."), ] = None, tags: Annotated[ - Optional[Iterable[Union["asyncapi.Tag", "asyncapi.TagDict"]]], + Optional[Iterable[Union["Tag", "TagDict"]]], Doc("AsyncAPI server tags."), ] = None, # logging args diff --git a/faststream/nats/fastapi/fastapi.py b/faststream/nats/fastapi/fastapi.py index c091b5e728..010e757e2a 100644 --- a/faststream/nats/fastapi/fastapi.py +++ b/faststream/nats/fastapi/fastapi.py @@ -33,12 +33,12 @@ from typing_extensions import Annotated, Doc, deprecated, override from faststream.__about__ import SERVICE_NAME -from faststream.asyncapi.version import AsyncAPIVersion from faststream.broker.fastapi.router import StreamRouter from faststream.broker.utils import default_filter from faststream.nats.broker import NatsBroker from faststream.nats.publisher.publisher import SpecificationPublisher from faststream.nats.subscriber.subscriber import SpecificationSubscriber +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.types import EMPTY if TYPE_CHECKING: @@ -58,7 +58,6 @@ from starlette.responses import Response from starlette.types import ASGIApp, Lifespan - from faststream.asyncapi import schema as asyncapi from faststream.broker.types import ( BrokerMiddleware, CustomCallable, @@ -69,6 +68,7 @@ from faststream.nats.message import NatsBatchMessage, NatsMessage from faststream.nats.schemas import JStream, KvWatch, ObjWatch, PullSub from faststream.security import BaseSecurity + from faststream.specification.schema.tag import Tag, TagDict from faststream.types import AnyDict, LoggerProto @@ -265,7 +265,7 @@ def __init__( Doc("Version of AsyncAPI for schema generation") ] = AsyncAPIVersion.v2_6, asyncapi_tags: Annotated[ - Optional[Iterable[Union["asyncapi.Tag", "asyncapi.TagDict"]]], + Optional[Iterable[Union["Tag", "TagDict"]]], Doc("AsyncAPI server tags."), ] = None, # logging args diff --git a/faststream/nats/publisher/publisher.py b/faststream/nats/publisher/publisher.py index 3ef2317f24..f86c12e142 100644 --- a/faststream/nats/publisher/publisher.py +++ b/faststream/nats/publisher/publisher.py @@ -2,8 +2,8 @@ from typing_extensions import override -from faststream.asyncapi.utils import resolve_payloads from faststream.nats.publisher.usecase import LogicPublisher +from faststream.specification.asyncapi.utils import resolve_payloads from faststream.specification.schema.bindings import ChannelBinding, nats from faststream.specification.schema.channel import Channel from faststream.specification.schema.message import CorrelationId, Message diff --git a/faststream/nats/subscriber/subscriber.py b/faststream/nats/subscriber/subscriber.py index 6fbfb99d3c..c01705daeb 100644 --- a/faststream/nats/subscriber/subscriber.py +++ b/faststream/nats/subscriber/subscriber.py @@ -2,7 +2,6 @@ from typing_extensions import override -from faststream.asyncapi.utils import resolve_payloads from faststream.nats.subscriber.usecase import ( BatchPullStreamSubscriber, ConcurrentCoreSubscriber, @@ -15,6 +14,7 @@ PullStreamSubscriber, PushStreamSubscription, ) +from faststream.specification.asyncapi.utils import resolve_payloads from faststream.specification.schema.bindings import ChannelBinding, nats from faststream.specification.schema.channel import Channel from faststream.specification.schema.message import CorrelationId, Message diff --git a/faststream/rabbit/broker/broker.py b/faststream/rabbit/broker/broker.py index 584bd8b3a5..29d2a50486 100644 --- a/faststream/rabbit/broker/broker.py +++ b/faststream/rabbit/broker/broker.py @@ -48,7 +48,6 @@ from pamqp.common import FieldTable from yarl import URL - from faststream.asyncapi import schema as asyncapi from faststream.broker.types import ( BrokerMiddleware, CustomCallable, @@ -56,6 +55,7 @@ from faststream.rabbit.message import RabbitMessage from faststream.rabbit.types import AioPikaSendableMessage from faststream.security import BaseSecurity + from faststream.specification.schema.tag import Tag, TagDict from faststream.types import AnyDict, Decorator, LoggerProto @@ -192,7 +192,7 @@ def __init__( Doc("AsyncAPI server description."), ] = None, tags: Annotated[ - Optional[Iterable[Union["asyncapi.Tag", "asyncapi.TagDict"]]], + Optional[Iterable[Union["Tag", "TagDict"]]], Doc("AsyncAPI server tags."), ] = None, # logging args diff --git a/faststream/rabbit/fastapi/router.py b/faststream/rabbit/fastapi/router.py index 689695aa3b..e212b4b70c 100644 --- a/faststream/rabbit/fastapi/router.py +++ b/faststream/rabbit/fastapi/router.py @@ -21,7 +21,6 @@ from typing_extensions import Annotated, Doc, deprecated, override from faststream.__about__ import SERVICE_NAME -from faststream.asyncapi.version import AsyncAPIVersion from faststream.broker.fastapi.router import StreamRouter from faststream.broker.utils import default_filter from faststream.rabbit.broker.broker import RabbitBroker as RB @@ -31,6 +30,7 @@ RabbitQueue, ) from faststream.rabbit.subscriber.subscriber import SpecificationSubscriber +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.types import EMPTY if TYPE_CHECKING: @@ -45,7 +45,6 @@ from starlette.types import ASGIApp, Lifespan from yarl import URL - from faststream.asyncapi import schema as asyncapi from faststream.broker.types import ( BrokerMiddleware, CustomCallable, @@ -56,6 +55,7 @@ from faststream.rabbit.message import RabbitMessage from faststream.rabbit.schemas.reply import ReplyConfig from faststream.security import BaseSecurity + from faststream.specification.schema.tag import Tag, TagDict from faststream.types import AnyDict, LoggerProto @@ -186,7 +186,7 @@ def __init__( Doc("Version of AsyncAPI for schema generation") ] = AsyncAPIVersion.v2_6, asyncapi_tags: Annotated[ - Optional[Iterable[Union["asyncapi.Tag", "asyncapi.TagDict"]]], + Optional[Iterable[Union["Tag", "TagDict"]]], Doc("AsyncAPI server tags."), ] = None, # logging args diff --git a/faststream/rabbit/publisher/publisher.py b/faststream/rabbit/publisher/publisher.py index c50fbce6bb..ecf19536a8 100644 --- a/faststream/rabbit/publisher/publisher.py +++ b/faststream/rabbit/publisher/publisher.py @@ -2,9 +2,9 @@ from typing_extensions import override -from faststream.asyncapi.utils import resolve_payloads from faststream.rabbit.publisher.usecase import LogicPublisher, PublishKwargs from faststream.rabbit.utils import is_routing_exchange +from faststream.specification.asyncapi.utils import resolve_payloads from faststream.specification.schema.bindings import ( ChannelBinding, OperationBinding, diff --git a/faststream/rabbit/subscriber/subscriber.py b/faststream/rabbit/subscriber/subscriber.py index bc244d9eb1..61ff809790 100644 --- a/faststream/rabbit/subscriber/subscriber.py +++ b/faststream/rabbit/subscriber/subscriber.py @@ -1,8 +1,8 @@ from typing import Dict -from faststream.asyncapi.utils import resolve_payloads from faststream.rabbit.subscriber.usecase import LogicSubscriber from faststream.rabbit.utils import is_routing_exchange +from faststream.specification.asyncapi.utils import resolve_payloads from faststream.specification.schema.bindings import ( ChannelBinding, OperationBinding, diff --git a/faststream/redis/broker/broker.py b/faststream/redis/broker/broker.py index fdafa04c02..e26ce828c6 100644 --- a/faststream/redis/broker/broker.py +++ b/faststream/redis/broker/broker.py @@ -41,13 +41,13 @@ from redis.asyncio.connection import BaseParser from typing_extensions import TypedDict, Unpack - from faststream.asyncapi import schema as asyncapi from faststream.broker.types import ( BrokerMiddleware, CustomCallable, ) from faststream.redis.message import BaseMessage, RedisMessage from faststream.security import BaseSecurity + from faststream.specification.schema.tag import Tag, TagDict from faststream.types import ( AnyDict, AsyncFunc, @@ -161,7 +161,7 @@ def __init__( Doc("AsyncAPI server description."), ] = None, tags: Annotated[ - Optional[Iterable[Union["asyncapi.Tag", "asyncapi.TagDict"]]], + Optional[Iterable[Union["Tag", "TagDict"]]], Doc("AsyncAPI server tags."), ] = None, # logging args diff --git a/faststream/redis/fastapi/fastapi.py b/faststream/redis/fastapi/fastapi.py index 5c75528059..799d3bf439 100644 --- a/faststream/redis/fastapi/fastapi.py +++ b/faststream/redis/fastapi/fastapi.py @@ -27,7 +27,6 @@ from typing_extensions import Annotated, Doc, deprecated, override from faststream.__about__ import SERVICE_NAME -from faststream.asyncapi.version import AsyncAPIVersion from faststream.broker.fastapi.router import StreamRouter from faststream.broker.utils import default_filter from faststream.redis.broker.broker import RedisBroker as RB @@ -35,6 +34,7 @@ from faststream.redis.publisher.publisher import SpecificationPublisher from faststream.redis.schemas import ListSub, PubSub, StreamSub from faststream.redis.subscriber.subscriber import SpecificationSubscriber +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.types import EMPTY if TYPE_CHECKING: @@ -46,7 +46,6 @@ from starlette.responses import Response from starlette.types import ASGIApp, Lifespan - from faststream.asyncapi import schema as asyncapi from faststream.broker.types import ( BrokerMiddleware, CustomCallable, @@ -56,6 +55,7 @@ ) from faststream.redis.message import UnifyRedisMessage from faststream.security import BaseSecurity + from faststream.specification.schema.tag import Tag, TagDict from faststream.types import AnyDict, LoggerProto @@ -135,7 +135,7 @@ def __init__( Doc("Version of AsyncAPI for schema generation") ] = AsyncAPIVersion.v2_6, asyncapi_tags: Annotated[ - Optional[Iterable[Union["asyncapi.Tag", "asyncapi.TagDict"]]], + Optional[Iterable[Union["Tag", "TagDict"]]], Doc("AsyncAPI server tags."), ] = None, # logging args diff --git a/faststream/redis/publisher/publisher.py b/faststream/redis/publisher/publisher.py index b43a8be91e..759308872e 100644 --- a/faststream/redis/publisher/publisher.py +++ b/faststream/redis/publisher/publisher.py @@ -2,7 +2,6 @@ from typing_extensions import TypeAlias, override -from faststream.asyncapi.utils import resolve_payloads from faststream.exceptions import SetupError from faststream.redis.publisher.usecase import ( ChannelPublisher, @@ -13,6 +12,7 @@ ) from faststream.redis.schemas import INCORRECT_SETUP_MSG, ListSub, PubSub, StreamSub from faststream.redis.schemas.proto import RedisAsyncAPIProtocol, validate_options +from faststream.specification.asyncapi.utils import resolve_payloads from faststream.specification.schema.bindings import ChannelBinding, redis from faststream.specification.schema.channel import Channel from faststream.specification.schema.message import CorrelationId, Message diff --git a/faststream/redis/subscriber/subscriber.py b/faststream/redis/subscriber/subscriber.py index 67eec23533..54a9b57578 100644 --- a/faststream/redis/subscriber/subscriber.py +++ b/faststream/redis/subscriber/subscriber.py @@ -1,6 +1,5 @@ from typing import Dict -from faststream.asyncapi.utils import resolve_payloads from faststream.redis.schemas import ListSub, StreamSub from faststream.redis.schemas.proto import RedisAsyncAPIProtocol from faststream.redis.subscriber.usecase import ( @@ -11,6 +10,7 @@ LogicSubscriber, StreamSubscriber, ) +from faststream.specification.asyncapi.utils import resolve_payloads from faststream.specification.schema.bindings import ChannelBinding, redis from faststream.specification.schema.channel import Channel from faststream.specification.schema.message import CorrelationId, Message diff --git a/faststream/specification/asyncapi/__init__.py b/faststream/specification/asyncapi/__init__.py new file mode 100644 index 0000000000..5b5a564ce1 --- /dev/null +++ b/faststream/specification/asyncapi/__init__.py @@ -0,0 +1,9 @@ +"""AsyncAPI related functions.""" + +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.site import get_asyncapi_html + +__all__ = ( + "get_asyncapi_html", + "get_app_schema", +) diff --git a/faststream/specification/asyncapi/base/__init__.py b/faststream/specification/asyncapi/base/__init__.py new file mode 100644 index 0000000000..2e088681c2 --- /dev/null +++ b/faststream/specification/asyncapi/base/__init__.py @@ -0,0 +1,5 @@ +from faststream.specification.asyncapi.base import schema + +__all__ = ( + "schema", +) diff --git a/faststream/asyncapi/base/schema/__init__.py b/faststream/specification/asyncapi/base/schema/__init__.py similarity index 100% rename from faststream/asyncapi/base/schema/__init__.py rename to faststream/specification/asyncapi/base/schema/__init__.py diff --git a/faststream/asyncapi/base/schema/info.py b/faststream/specification/asyncapi/base/schema/info.py similarity index 100% rename from faststream/asyncapi/base/schema/info.py rename to faststream/specification/asyncapi/base/schema/info.py diff --git a/faststream/asyncapi/base/schema/schema.py b/faststream/specification/asyncapi/base/schema/schema.py similarity index 94% rename from faststream/asyncapi/base/schema/schema.py rename to faststream/specification/asyncapi/base/schema/schema.py index 4ca186972a..49e8c90fd1 100644 --- a/faststream/asyncapi/base/schema/schema.py +++ b/faststream/specification/asyncapi/base/schema/schema.py @@ -3,7 +3,7 @@ from pydantic import BaseModel from faststream._compat import model_to_json, model_to_jsonable -from faststream.asyncapi.base.schema.info import BaseInfo +from faststream.specification.asyncapi.base.schema.info import BaseInfo class BaseSchema(BaseModel): diff --git a/faststream/asyncapi/generate.py b/faststream/specification/asyncapi/generate.py similarity index 55% rename from faststream/asyncapi/generate.py rename to faststream/specification/asyncapi/generate.py index b6a7935c63..f8c8633b16 100644 --- a/faststream/asyncapi/generate.py +++ b/faststream/specification/asyncapi/generate.py @@ -1,9 +1,13 @@ from typing import TYPE_CHECKING -from faststream.asyncapi.base.schema import BaseSchema -from faststream.asyncapi.v2_6_0.generate import get_app_schema as get_app_schema_v2_6 -from faststream.asyncapi.v3_0_0.generate import get_app_schema as get_app_schema_v3 -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.base.schema import BaseSchema +from faststream.specification.asyncapi.v2_6_0.generate import ( + get_app_schema as get_app_schema_v2_6, +) +from faststream.specification.asyncapi.v3_0_0.generate import ( + get_app_schema as get_app_schema_v3, +) +from faststream.specification.asyncapi.version import AsyncAPIVersion if TYPE_CHECKING: from faststream.specification.proto import Application diff --git a/faststream/asyncapi/message.py b/faststream/specification/asyncapi/message.py similarity index 100% rename from faststream/asyncapi/message.py rename to faststream/specification/asyncapi/message.py diff --git a/faststream/asyncapi/site.py b/faststream/specification/asyncapi/site.py similarity index 98% rename from faststream/asyncapi/site.py rename to faststream/specification/asyncapi/site.py index 9e4a76e816..278b059e3a 100644 --- a/faststream/asyncapi/site.py +++ b/faststream/specification/asyncapi/site.py @@ -7,7 +7,7 @@ from faststream.log import logger if TYPE_CHECKING: - from faststream.asyncapi.base.schema import BaseSchema + from faststream.specification.asyncapi.base.schema import BaseSchema ASYNCAPI_JS_DEFAULT_URL = "https://unpkg.com/@asyncapi/react-component@1.0.0-next.54/browser/standalone/index.js" diff --git a/faststream/asyncapi/utils.py b/faststream/specification/asyncapi/utils.py similarity index 100% rename from faststream/asyncapi/utils.py rename to faststream/specification/asyncapi/utils.py diff --git a/faststream/asyncapi/v2_6_0/__init__.py b/faststream/specification/asyncapi/v2_6_0/__init__.py similarity index 100% rename from faststream/asyncapi/v2_6_0/__init__.py rename to faststream/specification/asyncapi/v2_6_0/__init__.py diff --git a/faststream/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py similarity index 98% rename from faststream/asyncapi/v2_6_0/generate.py rename to faststream/specification/asyncapi/v2_6_0/generate.py index b01f0acc0e..59b6d33a89 100644 --- a/faststream/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -2,7 +2,9 @@ from typing import TYPE_CHECKING, Any, Dict, List, Union from faststream._compat import DEF_KEY -from faststream.asyncapi.v2_6_0.schema import ( +from faststream.constants import ContentTypes +from faststream.specification import schema as spec +from faststream.specification.asyncapi.v2_6_0.schema import ( Channel, Components, Contact, @@ -16,7 +18,7 @@ Tag, TagDict, ) -from faststream.asyncapi.v2_6_0.schema.bindings import ( +from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( ChannelBinding, OperationBinding, amqp, @@ -25,9 +27,10 @@ redis, sqs, ) -from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message -from faststream.constants import ContentTypes -from faststream.specification import schema as spec +from faststream.specification.asyncapi.v2_6_0.schema.message import ( + CorrelationId, + Message, +) from faststream.specification.proto import Application if TYPE_CHECKING: diff --git a/faststream/asyncapi/v2_6_0/schema/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/__init__.py similarity index 100% rename from faststream/asyncapi/v2_6_0/schema/__init__.py rename to faststream/specification/asyncapi/v2_6_0/schema/__init__.py diff --git a/faststream/asyncapi/v2_6_0/schema/bindings/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/__init__.py similarity index 100% rename from faststream/asyncapi/v2_6_0/schema/bindings/__init__.py rename to faststream/specification/asyncapi/v2_6_0/schema/bindings/__init__.py diff --git a/faststream/asyncapi/v2_6_0/schema/bindings/amqp.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp.py similarity index 100% rename from faststream/asyncapi/v2_6_0/schema/bindings/amqp.py rename to faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp.py diff --git a/faststream/asyncapi/v2_6_0/schema/bindings/kafka.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka.py similarity index 100% rename from faststream/asyncapi/v2_6_0/schema/bindings/kafka.py rename to faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka.py diff --git a/faststream/asyncapi/v2_6_0/schema/bindings/main.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main.py similarity index 82% rename from faststream/asyncapi/v2_6_0/schema/bindings/main.py rename to faststream/specification/asyncapi/v2_6_0/schema/bindings/main.py index 0cd5c7abfb..4db8877b00 100644 --- a/faststream/asyncapi/v2_6_0/schema/bindings/main.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main.py @@ -3,11 +3,19 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.v2_6_0.schema.bindings import amqp as amqp_bindings -from faststream.asyncapi.v2_6_0.schema.bindings import kafka as kafka_bindings -from faststream.asyncapi.v2_6_0.schema.bindings import nats as nats_bindings -from faststream.asyncapi.v2_6_0.schema.bindings import redis as redis_bindings -from faststream.asyncapi.v2_6_0.schema.bindings import sqs as sqs_bindings +from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( + amqp as amqp_bindings, +) +from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( + kafka as kafka_bindings, +) +from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( + nats as nats_bindings, +) +from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( + redis as redis_bindings, +) +from faststream.specification.asyncapi.v2_6_0.schema.bindings import sqs as sqs_bindings class ServerBinding(BaseModel): diff --git a/faststream/asyncapi/v2_6_0/schema/bindings/nats.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats.py similarity index 100% rename from faststream/asyncapi/v2_6_0/schema/bindings/nats.py rename to faststream/specification/asyncapi/v2_6_0/schema/bindings/nats.py diff --git a/faststream/asyncapi/v2_6_0/schema/bindings/redis.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis.py similarity index 100% rename from faststream/asyncapi/v2_6_0/schema/bindings/redis.py rename to faststream/specification/asyncapi/v2_6_0/schema/bindings/redis.py diff --git a/faststream/asyncapi/v2_6_0/schema/bindings/sqs.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs.py similarity index 100% rename from faststream/asyncapi/v2_6_0/schema/bindings/sqs.py rename to faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs.py diff --git a/faststream/asyncapi/v2_6_0/schema/channels.py b/faststream/specification/asyncapi/v2_6_0/schema/channels.py similarity index 87% rename from faststream/asyncapi/v2_6_0/schema/channels.py rename to faststream/specification/asyncapi/v2_6_0/schema/channels.py index f06a0166e5..4521837c96 100644 --- a/faststream/asyncapi/v2_6_0/schema/channels.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/channels.py @@ -3,8 +3,8 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding -from faststream.asyncapi.v2_6_0.schema.operations import Operation +from faststream.specification.asyncapi.v2_6_0.schema.bindings import ChannelBinding +from faststream.specification.asyncapi.v2_6_0.schema.operations import Operation class Channel(BaseModel): diff --git a/faststream/asyncapi/v2_6_0/schema/components.py b/faststream/specification/asyncapi/v2_6_0/schema/components.py similarity index 94% rename from faststream/asyncapi/v2_6_0/schema/components.py rename to faststream/specification/asyncapi/v2_6_0/schema/components.py index bff01e61bf..02287bacd3 100644 --- a/faststream/asyncapi/v2_6_0/schema/components.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/components.py @@ -9,7 +9,7 @@ from faststream._compat import ( PYDANTIC_V2, ) -from faststream.asyncapi.v2_6_0.schema.message import Message +from faststream.specification.asyncapi.v2_6_0.schema.message import Message class Components(BaseModel): diff --git a/faststream/asyncapi/v2_6_0/schema/info.py b/faststream/specification/asyncapi/v2_6_0/schema/info.py similarity index 98% rename from faststream/asyncapi/v2_6_0/schema/info.py rename to faststream/specification/asyncapi/v2_6_0/schema/info.py index bf282fa762..bb03694c8d 100644 --- a/faststream/asyncapi/v2_6_0/schema/info.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/info.py @@ -18,8 +18,8 @@ JsonSchemaValue, with_info_plain_validator_function, ) -from faststream.asyncapi.base.schema import BaseInfo from faststream.log import logger +from faststream.specification.asyncapi.base.schema import BaseInfo try: import email_validator diff --git a/faststream/asyncapi/v2_6_0/schema/message.py b/faststream/specification/asyncapi/v2_6_0/schema/message.py similarity index 96% rename from faststream/asyncapi/v2_6_0/schema/message.py rename to faststream/specification/asyncapi/v2_6_0/schema/message.py index c462e6aa33..dc8333b98b 100644 --- a/faststream/asyncapi/v2_6_0/schema/message.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/message.py @@ -3,7 +3,7 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.v2_6_0.schema.utils import ( +from faststream.specification.asyncapi.v2_6_0.schema.utils import ( ExternalDocs, Tag, ) diff --git a/faststream/asyncapi/v2_6_0/schema/operations.py b/faststream/specification/asyncapi/v2_6_0/schema/operations.py similarity index 84% rename from faststream/asyncapi/v2_6_0/schema/operations.py rename to faststream/specification/asyncapi/v2_6_0/schema/operations.py index 54a2a2ac71..d674cb4a78 100644 --- a/faststream/asyncapi/v2_6_0/schema/operations.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/operations.py @@ -3,9 +3,9 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.v2_6_0.schema.bindings import OperationBinding -from faststream.asyncapi.v2_6_0.schema.message import Message -from faststream.asyncapi.v2_6_0.schema.utils import ( +from faststream.specification.asyncapi.v2_6_0.schema.bindings import OperationBinding +from faststream.specification.asyncapi.v2_6_0.schema.message import Message +from faststream.specification.asyncapi.v2_6_0.schema.utils import ( ExternalDocs, ExternalDocsDict, Reference, diff --git a/faststream/asyncapi/v2_6_0/schema/schema.py b/faststream/specification/asyncapi/v2_6_0/schema/schema.py similarity index 79% rename from faststream/asyncapi/v2_6_0/schema/schema.py rename to faststream/specification/asyncapi/v2_6_0/schema/schema.py index a473c7543f..5040a7cadd 100644 --- a/faststream/asyncapi/v2_6_0/schema/schema.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/schema.py @@ -1,18 +1,18 @@ from typing import Any, Dict, List, Optional, Union from faststream._compat import model_to_json, model_to_jsonable -from faststream.asyncapi.base.schema import BaseSchema -from faststream.asyncapi.v2_6_0.schema.channels import Channel -from faststream.asyncapi.v2_6_0.schema.components import Components -from faststream.asyncapi.v2_6_0.schema.info import Info -from faststream.asyncapi.v2_6_0.schema.servers import Server -from faststream.asyncapi.v2_6_0.schema.utils import ( +from faststream.specification.asyncapi.base.schema import BaseSchema +from faststream.specification.asyncapi.v2_6_0.schema.channels import Channel +from faststream.specification.asyncapi.v2_6_0.schema.components import Components +from faststream.specification.asyncapi.v2_6_0.schema.info import Info +from faststream.specification.asyncapi.v2_6_0.schema.servers import Server +from faststream.specification.asyncapi.v2_6_0.schema.utils import ( ExternalDocs, ExternalDocsDict, Tag, TagDict, ) -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.version import AsyncAPIVersion class Schema(BaseSchema): diff --git a/faststream/asyncapi/v2_6_0/schema/servers.py b/faststream/specification/asyncapi/v2_6_0/schema/servers.py similarity index 92% rename from faststream/asyncapi/v2_6_0/schema/servers.py rename to faststream/specification/asyncapi/v2_6_0/schema/servers.py index d6d2af2805..3bdcc7ed49 100644 --- a/faststream/asyncapi/v2_6_0/schema/servers.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/servers.py @@ -3,8 +3,12 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.v2_6_0.schema.bindings import ServerBinding -from faststream.asyncapi.v2_6_0.schema.utils import Reference, Tag, TagDict +from faststream.specification.asyncapi.v2_6_0.schema.bindings import ServerBinding +from faststream.specification.asyncapi.v2_6_0.schema.utils import ( + Reference, + Tag, + TagDict, +) SecurityRequirement = List[Dict[str, List[str]]] diff --git a/faststream/asyncapi/v2_6_0/schema/utils.py b/faststream/specification/asyncapi/v2_6_0/schema/utils.py similarity index 100% rename from faststream/asyncapi/v2_6_0/schema/utils.py rename to faststream/specification/asyncapi/v2_6_0/schema/utils.py diff --git a/faststream/asyncapi/v3_0_0/__init__.py b/faststream/specification/asyncapi/v3_0_0/__init__.py similarity index 100% rename from faststream/asyncapi/v3_0_0/__init__.py rename to faststream/specification/asyncapi/v3_0_0/__init__.py diff --git a/faststream/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py similarity index 97% rename from faststream/asyncapi/v3_0_0/generate.py rename to faststream/specification/asyncapi/v3_0_0/generate.py index fe7c9e64ff..4b2af00581 100644 --- a/faststream/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -3,21 +3,26 @@ from urllib.parse import urlparse from faststream._compat import DEF_KEY -from faststream.asyncapi.v2_6_0.generate import ( +from faststream.constants import ContentTypes +from faststream.specification import schema as spec +from faststream.specification.asyncapi.v2_6_0.generate import ( specs_channel_binding_to_asyncapi, specs_contact_to_asyncapi, specs_license_to_asyncapi, specs_operation_binding_to_asyncapi, specs_tags_to_asyncapi, ) -from faststream.asyncapi.v2_6_0.schema import ( +from faststream.specification.asyncapi.v2_6_0.schema import ( ExternalDocs, ExternalDocsDict, Reference, Tag, ) -from faststream.asyncapi.v2_6_0.schema.message import CorrelationId, Message -from faststream.asyncapi.v3_0_0.schema import ( +from faststream.specification.asyncapi.v2_6_0.schema.message import ( + CorrelationId, + Message, +) +from faststream.specification.asyncapi.v3_0_0.schema import ( Channel, Components, Info, @@ -25,8 +30,6 @@ Schema, Server, ) -from faststream.constants import ContentTypes -from faststream.specification import schema as spec from faststream.specification.proto import Application if TYPE_CHECKING: diff --git a/faststream/asyncapi/v3_0_0/schema/__init__.py b/faststream/specification/asyncapi/v3_0_0/schema/__init__.py similarity index 100% rename from faststream/asyncapi/v3_0_0/schema/__init__.py rename to faststream/specification/asyncapi/v3_0_0/schema/__init__.py diff --git a/faststream/asyncapi/v3_0_0/schema/channels.py b/faststream/specification/asyncapi/v3_0_0/schema/channels.py similarity index 82% rename from faststream/asyncapi/v3_0_0/schema/channels.py rename to faststream/specification/asyncapi/v3_0_0/schema/channels.py index 7fed29525e..56578e18c6 100644 --- a/faststream/asyncapi/v3_0_0/schema/channels.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/channels.py @@ -3,9 +3,9 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding -from faststream.asyncapi.v2_6_0.schema.message import Message -from faststream.asyncapi.v2_6_0.schema.utils import Reference +from faststream.specification.asyncapi.v2_6_0.schema.bindings import ChannelBinding +from faststream.specification.asyncapi.v2_6_0.schema.message import Message +from faststream.specification.asyncapi.v2_6_0.schema.utils import Reference class Channel(BaseModel): diff --git a/faststream/asyncapi/v3_0_0/schema/components.py b/faststream/specification/asyncapi/v3_0_0/schema/components.py similarity index 94% rename from faststream/asyncapi/v3_0_0/schema/components.py rename to faststream/specification/asyncapi/v3_0_0/schema/components.py index 73f5176b3f..a6cf796644 100644 --- a/faststream/asyncapi/v3_0_0/schema/components.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/components.py @@ -3,7 +3,7 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.v2_6_0.schema.message import Message +from faststream.specification.asyncapi.v2_6_0.schema.message import Message class Components(BaseModel): diff --git a/faststream/asyncapi/v3_0_0/schema/info.py b/faststream/specification/asyncapi/v3_0_0/schema/info.py similarity index 83% rename from faststream/asyncapi/v3_0_0/schema/info.py rename to faststream/specification/asyncapi/v3_0_0/schema/info.py index 87c2fd07a5..5efcdb94f6 100644 --- a/faststream/asyncapi/v3_0_0/schema/info.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/info.py @@ -8,14 +8,14 @@ from pydantic import AnyHttpUrl -from faststream.asyncapi.base.schema import BaseInfo -from faststream.asyncapi.v2_6_0.schema.info import ( +from faststream.specification.asyncapi.base.schema import BaseInfo +from faststream.specification.asyncapi.v2_6_0.schema.info import ( Contact, ContactDict, License, LicenseDict, ) -from faststream.asyncapi.v2_6_0.schema.utils import ( # noqa: TCH001 +from faststream.specification.asyncapi.v2_6_0.schema.utils import ( # noqa: TCH001 ExternalDocs, ExternalDocsDict, Tag, diff --git a/faststream/asyncapi/v3_0_0/schema/operations.py b/faststream/specification/asyncapi/v3_0_0/schema/operations.py similarity index 84% rename from faststream/asyncapi/v3_0_0/schema/operations.py rename to faststream/specification/asyncapi/v3_0_0/schema/operations.py index b727243713..43fe3ee09a 100644 --- a/faststream/asyncapi/v3_0_0/schema/operations.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/operations.py @@ -3,15 +3,15 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.v2_6_0.schema.bindings import OperationBinding -from faststream.asyncapi.v2_6_0.schema.utils import ( +from faststream.specification.asyncapi.v2_6_0.schema.bindings import OperationBinding +from faststream.specification.asyncapi.v2_6_0.schema.utils import ( ExternalDocs, ExternalDocsDict, Reference, Tag, TagDict, ) -from faststream.asyncapi.v3_0_0.schema.channels import Channel +from faststream.specification.asyncapi.v3_0_0.schema.channels import Channel class Operation(BaseModel): diff --git a/faststream/asyncapi/v3_0_0/schema/schema.py b/faststream/specification/asyncapi/v3_0_0/schema/schema.py similarity index 76% rename from faststream/asyncapi/v3_0_0/schema/schema.py rename to faststream/specification/asyncapi/v3_0_0/schema/schema.py index 8bc1c1fe41..6dbcff4c66 100644 --- a/faststream/asyncapi/v3_0_0/schema/schema.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/schema.py @@ -1,13 +1,13 @@ from typing import Any, Dict, Optional from faststream._compat import model_to_json, model_to_jsonable -from faststream.asyncapi.base.schema import BaseSchema -from faststream.asyncapi.v3_0_0.schema.channels import Channel -from faststream.asyncapi.v3_0_0.schema.components import Components -from faststream.asyncapi.v3_0_0.schema.info import Info -from faststream.asyncapi.v3_0_0.schema.operations import Operation -from faststream.asyncapi.v3_0_0.schema.servers import Server -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.base.schema import BaseSchema +from faststream.specification.asyncapi.v3_0_0.schema.channels import Channel +from faststream.specification.asyncapi.v3_0_0.schema.components import Components +from faststream.specification.asyncapi.v3_0_0.schema.info import Info +from faststream.specification.asyncapi.v3_0_0.schema.operations import Operation +from faststream.specification.asyncapi.v3_0_0.schema.servers import Server +from faststream.specification.asyncapi.version import AsyncAPIVersion class Schema(BaseSchema): diff --git a/faststream/asyncapi/v3_0_0/schema/servers.py b/faststream/specification/asyncapi/v3_0_0/schema/servers.py similarity index 85% rename from faststream/asyncapi/v3_0_0/schema/servers.py rename to faststream/specification/asyncapi/v3_0_0/schema/servers.py index 563e398318..53189f9962 100644 --- a/faststream/asyncapi/v3_0_0/schema/servers.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/servers.py @@ -3,9 +3,13 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.v2_6_0.schema import ServerVariable -from faststream.asyncapi.v2_6_0.schema.bindings import ServerBinding -from faststream.asyncapi.v2_6_0.schema.utils import Reference, Tag, TagDict +from faststream.specification.asyncapi.v2_6_0.schema import ServerVariable +from faststream.specification.asyncapi.v2_6_0.schema.bindings import ServerBinding +from faststream.specification.asyncapi.v2_6_0.schema.utils import ( + Reference, + Tag, + TagDict, +) SecurityRequirement = List[Dict[str, List[str]]] diff --git a/faststream/asyncapi/version.py b/faststream/specification/asyncapi/version.py similarity index 100% rename from faststream/asyncapi/version.py rename to faststream/specification/asyncapi/version.py diff --git a/faststream/specification/proto.py b/faststream/specification/proto.py index 62734f7c71..c5e64e581a 100644 --- a/faststream/specification/proto.py +++ b/faststream/specification/proto.py @@ -3,7 +3,7 @@ from typing_extensions import Annotated, Doc -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.schema.channel import Channel if TYPE_CHECKING: diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py index a2167425a5..1d1de980c9 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py @@ -1,5 +1,5 @@ from docs.docs_src.getting_started.asyncapi.asyncapi_customization.basic import app -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema def test_basic_customization(): diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_broker.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_broker.py index 25c886853d..3c9328135c 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_broker.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_broker.py @@ -1,7 +1,7 @@ from docs.docs_src.getting_started.asyncapi.asyncapi_customization.custom_broker import ( app, ) -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema def test_broker_customization(): diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py index 6453f5a8d8..f18660566e 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py @@ -1,7 +1,7 @@ from docs.docs_src.getting_started.asyncapi.asyncapi_customization.custom_handler import ( app, ) -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema def test_handler_customization(): diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_info.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_info.py index 7d7a02a886..17b7c23737 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_info.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_info.py @@ -1,7 +1,7 @@ from docs.docs_src.getting_started.asyncapi.asyncapi_customization.custom_info import ( app, ) -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema def test_info_customization(): diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_payload.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_payload.py index 5b4d693321..980674d67c 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_payload.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_payload.py @@ -1,7 +1,7 @@ from docs.docs_src.getting_started.asyncapi.asyncapi_customization.payload_info import ( app, ) -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema def test_payload_customization(): diff --git a/tests/a_docs/rabbit/test_security.py b/tests/a_docs/rabbit/test_security.py index 30572bf947..e8bd2ba610 100644 --- a/tests/a_docs/rabbit/test_security.py +++ b/tests/a_docs/rabbit/test_security.py @@ -2,7 +2,7 @@ from aiormq.exceptions import AMQPConnectionError from faststream.app import FastStream -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema @pytest.mark.asyncio diff --git a/tests/a_docs/redis/test_security.py b/tests/a_docs/redis/test_security.py index 1b7efecd3f..4507b9ca6b 100644 --- a/tests/a_docs/redis/test_security.py +++ b/tests/a_docs/redis/test_security.py @@ -6,7 +6,7 @@ from redis.exceptions import AuthenticationError from faststream.app import FastStream -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema @contextmanager diff --git a/tests/asyncapi/base/arguments.py b/tests/asyncapi/base/arguments.py index 4d5597f232..f1f19d778a 100644 --- a/tests/asyncapi/base/arguments.py +++ b/tests/asyncapi/base/arguments.py @@ -10,7 +10,7 @@ from faststream import Context, FastStream from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.broker.core.usecase import BrokerUsecase from tests.marks import pydantic_v2 diff --git a/tests/asyncapi/base/fastapi.py b/tests/asyncapi/base/fastapi.py index 58ded71515..a1561a135a 100644 --- a/tests/asyncapi/base/fastapi.py +++ b/tests/asyncapi/base/fastapi.py @@ -5,7 +5,7 @@ from fastapi import FastAPI from fastapi.testclient import TestClient -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.broker.core.usecase import BrokerUsecase from faststream.broker.fastapi.router import StreamRouter from faststream.broker.types import MsgType diff --git a/tests/asyncapi/base/naming.py b/tests/asyncapi/base/naming.py index 0c3fc9454c..526c2f2176 100644 --- a/tests/asyncapi/base/naming.py +++ b/tests/asyncapi/base/naming.py @@ -4,7 +4,7 @@ from pydantic import create_model from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.broker.core.usecase import BrokerUsecase diff --git a/tests/asyncapi/base/publisher.py b/tests/asyncapi/base/publisher.py index 7b2e4dce5c..3b0f2618ba 100644 --- a/tests/asyncapi/base/publisher.py +++ b/tests/asyncapi/base/publisher.py @@ -3,7 +3,7 @@ import pydantic from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.broker.core.usecase import BrokerUsecase diff --git a/tests/asyncapi/base/router.py b/tests/asyncapi/base/router.py index 84996ccb06..c5f7820c4f 100644 --- a/tests/asyncapi/base/router.py +++ b/tests/asyncapi/base/router.py @@ -3,7 +3,7 @@ from dirty_equals import IsStr from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.broker.core.usecase import BrokerUsecase from faststream.broker.router import ArgsContainer, BrokerRouter, SubscriberRoute diff --git a/tests/asyncapi/base/v3_0_0/arguments.py b/tests/asyncapi/base/v3_0_0/arguments.py index 8f94a9a622..de79bafc08 100644 --- a/tests/asyncapi/base/v3_0_0/arguments.py +++ b/tests/asyncapi/base/v3_0_0/arguments.py @@ -11,8 +11,8 @@ from faststream import Context, FastStream from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.broker.core.usecase import BrokerUsecase from faststream.broker.fastapi import StreamRouter from tests.marks import pydantic_v2 diff --git a/tests/asyncapi/base/v3_0_0/fastapi.py b/tests/asyncapi/base/v3_0_0/fastapi.py index 0c6617aff0..7e51449b41 100644 --- a/tests/asyncapi/base/v3_0_0/fastapi.py +++ b/tests/asyncapi/base/v3_0_0/fastapi.py @@ -5,8 +5,8 @@ from fastapi import FastAPI from fastapi.testclient import TestClient -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.broker.core.usecase import BrokerUsecase from faststream.broker.fastapi.router import StreamRouter from faststream.broker.types import MsgType diff --git a/tests/asyncapi/base/v3_0_0/naming.py b/tests/asyncapi/base/v3_0_0/naming.py index 106dd61309..8761da40c1 100644 --- a/tests/asyncapi/base/v3_0_0/naming.py +++ b/tests/asyncapi/base/v3_0_0/naming.py @@ -4,8 +4,8 @@ from pydantic import create_model from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.broker.core.usecase import BrokerUsecase diff --git a/tests/asyncapi/base/v3_0_0/publisher.py b/tests/asyncapi/base/v3_0_0/publisher.py index dc3086915b..5cff94a9cf 100644 --- a/tests/asyncapi/base/v3_0_0/publisher.py +++ b/tests/asyncapi/base/v3_0_0/publisher.py @@ -3,8 +3,8 @@ import pydantic from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.broker.core.usecase import BrokerUsecase from faststream.broker.fastapi import StreamRouter diff --git a/tests/asyncapi/base/v3_0_0/router.py b/tests/asyncapi/base/v3_0_0/router.py index b6f9bb5f5d..5dfc2451b1 100644 --- a/tests/asyncapi/base/v3_0_0/router.py +++ b/tests/asyncapi/base/v3_0_0/router.py @@ -3,8 +3,8 @@ from dirty_equals import IsStr from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.broker.core.usecase import BrokerUsecase from faststream.broker.router import ArgsContainer, BrokerRouter, SubscriberRoute diff --git a/tests/asyncapi/confluent/v2_6_0/test_arguments.py b/tests/asyncapi/confluent/v2_6_0/test_arguments.py index 9e3746e398..f1869494cb 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_arguments.py +++ b/tests/asyncapi/confluent/v2_6_0/test_arguments.py @@ -1,4 +1,4 @@ -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.confluent import KafkaBroker from tests.asyncapi.base.arguments import ArgumentsTestcase diff --git a/tests/asyncapi/confluent/v2_6_0/test_connection.py b/tests/asyncapi/confluent/v2_6_0/test_connection.py index 24ea94d6e8..55eff119f5 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_connection.py +++ b/tests/asyncapi/confluent/v2_6_0/test_connection.py @@ -1,5 +1,5 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.confluent import KafkaBroker from faststream.specification.schema.tag import Tag diff --git a/tests/asyncapi/confluent/v2_6_0/test_fastapi.py b/tests/asyncapi/confluent/v2_6_0/test_fastapi.py index adf7b5cb28..7f2ea525ab 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/confluent/v2_6_0/test_fastapi.py @@ -1,6 +1,6 @@ from typing import Type -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.confluent.fastapi import KafkaRouter from faststream.confluent.testing import TestKafkaBroker from faststream.security import SASLPlaintext diff --git a/tests/asyncapi/confluent/v2_6_0/test_naming.py b/tests/asyncapi/confluent/v2_6_0/test_naming.py index cdcd3dc17c..ae9455b78b 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_naming.py +++ b/tests/asyncapi/confluent/v2_6_0/test_naming.py @@ -1,5 +1,5 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.confluent import KafkaBroker from tests.asyncapi.base.naming import NamingTestCase diff --git a/tests/asyncapi/confluent/v2_6_0/test_publisher.py b/tests/asyncapi/confluent/v2_6_0/test_publisher.py index b6ee208854..96cccb621c 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_publisher.py +++ b/tests/asyncapi/confluent/v2_6_0/test_publisher.py @@ -1,4 +1,4 @@ -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.confluent import KafkaBroker from tests.asyncapi.base.publisher import PublisherTestcase diff --git a/tests/asyncapi/confluent/v2_6_0/test_router.py b/tests/asyncapi/confluent/v2_6_0/test_router.py index 44424190d8..f837b97c0d 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_router.py +++ b/tests/asyncapi/confluent/v2_6_0/test_router.py @@ -1,5 +1,5 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.confluent import KafkaBroker, KafkaPublisher, KafkaRoute, KafkaRouter from tests.asyncapi.base.arguments import ArgumentsTestcase from tests.asyncapi.base.publisher import PublisherTestcase diff --git a/tests/asyncapi/confluent/v2_6_0/test_security.py b/tests/asyncapi/confluent/v2_6_0/test_security.py index 0621cbf756..ec5a373cf7 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_security.py +++ b/tests/asyncapi/confluent/v2_6_0/test_security.py @@ -2,7 +2,7 @@ from copy import deepcopy from faststream.app import FastStream -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.confluent import KafkaBroker from faststream.security import ( SASLGSSAPI, diff --git a/tests/asyncapi/confluent/v3_0_0/test_arguments.py b/tests/asyncapi/confluent/v3_0_0/test_arguments.py index 2aed50c24e..fcf9eb7161 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_arguments.py +++ b/tests/asyncapi/confluent/v3_0_0/test_arguments.py @@ -1,4 +1,4 @@ -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.confluent import KafkaBroker from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase diff --git a/tests/asyncapi/confluent/v3_0_0/test_connection.py b/tests/asyncapi/confluent/v3_0_0/test_connection.py index d7ee0f0161..fb9ecce111 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_connection.py +++ b/tests/asyncapi/confluent/v3_0_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.confluent import KafkaBroker from faststream.specification.schema.tag import Tag diff --git a/tests/asyncapi/confluent/v3_0_0/test_fastapi.py b/tests/asyncapi/confluent/v3_0_0/test_fastapi.py index 2d08ca4917..1334dfb4f2 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/confluent/v3_0_0/test_fastapi.py @@ -1,6 +1,6 @@ -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.confluent.fastapi import KafkaRouter from faststream.confluent.testing import TestKafkaBroker from faststream.security import SASLPlaintext diff --git a/tests/asyncapi/confluent/v3_0_0/test_naming.py b/tests/asyncapi/confluent/v3_0_0/test_naming.py index 5a05a36058..10ab216247 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_naming.py +++ b/tests/asyncapi/confluent/v3_0_0/test_naming.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.confluent import KafkaBroker from tests.asyncapi.base.v3_0_0.naming import NamingTestCase diff --git a/tests/asyncapi/confluent/v3_0_0/test_publisher.py b/tests/asyncapi/confluent/v3_0_0/test_publisher.py index a4e89fdc42..f006220d21 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_publisher.py +++ b/tests/asyncapi/confluent/v3_0_0/test_publisher.py @@ -1,4 +1,4 @@ -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.confluent import KafkaBroker from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase diff --git a/tests/asyncapi/confluent/v3_0_0/test_router.py b/tests/asyncapi/confluent/v3_0_0/test_router.py index fc47bc9d58..6bf69fc1b4 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_router.py +++ b/tests/asyncapi/confluent/v3_0_0/test_router.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.confluent import KafkaBroker, KafkaPublisher, KafkaRoute, KafkaRouter from tests.asyncapi.base.arguments import ArgumentsTestcase from tests.asyncapi.base.publisher import PublisherTestcase diff --git a/tests/asyncapi/confluent/v3_0_0/test_security.py b/tests/asyncapi/confluent/v3_0_0/test_security.py index b1ee30ca73..71053882ca 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_security.py +++ b/tests/asyncapi/confluent/v3_0_0/test_security.py @@ -2,8 +2,8 @@ from copy import deepcopy from faststream.app import FastStream -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.confluent import KafkaBroker from faststream.security import ( BaseSecurity, diff --git a/tests/asyncapi/kafka/v2_6_0/test_app.py b/tests/asyncapi/kafka/v2_6_0/test_app.py index 9e556d9230..cadf2ed79f 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_app.py +++ b/tests/asyncapi/kafka/v2_6_0/test_app.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.v2_6_0.schema.info import Contact, License +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.v2_6_0.schema.info import Contact, License from faststream.kafka import KafkaBroker from faststream.specification.schema.docs import ExternalDocs from faststream.specification.schema.tag import Tag diff --git a/tests/asyncapi/kafka/v2_6_0/test_arguments.py b/tests/asyncapi/kafka/v2_6_0/test_arguments.py index 89595c0672..5926b45b8a 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_arguments.py +++ b/tests/asyncapi/kafka/v2_6_0/test_arguments.py @@ -1,4 +1,4 @@ -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.kafka import KafkaBroker from tests.asyncapi.base.arguments import ArgumentsTestcase diff --git a/tests/asyncapi/kafka/v2_6_0/test_connection.py b/tests/asyncapi/kafka/v2_6_0/test_connection.py index 503f2592d5..0c088210f3 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_connection.py +++ b/tests/asyncapi/kafka/v2_6_0/test_connection.py @@ -1,5 +1,5 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.kafka import KafkaBroker from faststream.specification.schema.tag import Tag diff --git a/tests/asyncapi/kafka/v2_6_0/test_fastapi.py b/tests/asyncapi/kafka/v2_6_0/test_fastapi.py index 0991c3586d..a6929a1526 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/kafka/v2_6_0/test_fastapi.py @@ -1,6 +1,6 @@ from typing import Type -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.kafka.fastapi import KafkaRouter from faststream.kafka.testing import TestKafkaBroker from faststream.security import SASLPlaintext diff --git a/tests/asyncapi/kafka/v2_6_0/test_naming.py b/tests/asyncapi/kafka/v2_6_0/test_naming.py index ed8f18bd98..a3039d2730 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_naming.py +++ b/tests/asyncapi/kafka/v2_6_0/test_naming.py @@ -1,5 +1,5 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.kafka import KafkaBroker from tests.asyncapi.base.naming import NamingTestCase diff --git a/tests/asyncapi/kafka/v2_6_0/test_publisher.py b/tests/asyncapi/kafka/v2_6_0/test_publisher.py index 0b90bd6f4f..d438f4d733 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_publisher.py +++ b/tests/asyncapi/kafka/v2_6_0/test_publisher.py @@ -1,4 +1,4 @@ -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.kafka import KafkaBroker from tests.asyncapi.base.publisher import PublisherTestcase diff --git a/tests/asyncapi/kafka/v2_6_0/test_router.py b/tests/asyncapi/kafka/v2_6_0/test_router.py index 5cb2cc8168..58fcca22ed 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_router.py +++ b/tests/asyncapi/kafka/v2_6_0/test_router.py @@ -1,5 +1,5 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.kafka import KafkaBroker, KafkaPublisher, KafkaRoute, KafkaRouter from tests.asyncapi.base.arguments import ArgumentsTestcase from tests.asyncapi.base.publisher import PublisherTestcase diff --git a/tests/asyncapi/kafka/v2_6_0/test_security.py b/tests/asyncapi/kafka/v2_6_0/test_security.py index 3201bf899c..91df21b257 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_security.py +++ b/tests/asyncapi/kafka/v2_6_0/test_security.py @@ -2,7 +2,7 @@ from copy import deepcopy from faststream.app import FastStream -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.kafka import KafkaBroker from faststream.security import ( SASLGSSAPI, diff --git a/tests/asyncapi/kafka/v3_0_0/test_arguments.py b/tests/asyncapi/kafka/v3_0_0/test_arguments.py index f146ef6f47..f18877b054 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_arguments.py +++ b/tests/asyncapi/kafka/v3_0_0/test_arguments.py @@ -1,4 +1,4 @@ -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.kafka import KafkaBroker from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase diff --git a/tests/asyncapi/kafka/v3_0_0/test_connection.py b/tests/asyncapi/kafka/v3_0_0/test_connection.py index 0d74af1b7b..1fbb02ecd4 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_connection.py +++ b/tests/asyncapi/kafka/v3_0_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.kafka import KafkaBroker from faststream.specification.schema.tag import Tag diff --git a/tests/asyncapi/kafka/v3_0_0/test_fastapi.py b/tests/asyncapi/kafka/v3_0_0/test_fastapi.py index 21cbb41e72..2b180b6263 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/kafka/v3_0_0/test_fastapi.py @@ -1,6 +1,6 @@ -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.kafka.fastapi import KafkaRouter from faststream.kafka.testing import TestKafkaBroker from faststream.security import SASLPlaintext diff --git a/tests/asyncapi/kafka/v3_0_0/test_naming.py b/tests/asyncapi/kafka/v3_0_0/test_naming.py index 7c7ccb6dc8..d68d81dcf2 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_naming.py +++ b/tests/asyncapi/kafka/v3_0_0/test_naming.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.kafka import KafkaBroker from tests.asyncapi.base.v3_0_0.naming import NamingTestCase diff --git a/tests/asyncapi/kafka/v3_0_0/test_publisher.py b/tests/asyncapi/kafka/v3_0_0/test_publisher.py index 3ad1f788c7..52710319c7 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_publisher.py +++ b/tests/asyncapi/kafka/v3_0_0/test_publisher.py @@ -1,4 +1,4 @@ -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.kafka import KafkaBroker from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase diff --git a/tests/asyncapi/kafka/v3_0_0/test_router.py b/tests/asyncapi/kafka/v3_0_0/test_router.py index cf1792dfda..cd9674959f 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_router.py +++ b/tests/asyncapi/kafka/v3_0_0/test_router.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.kafka import KafkaBroker, KafkaPublisher, KafkaRoute, KafkaRouter from tests.asyncapi.base.arguments import ArgumentsTestcase from tests.asyncapi.base.publisher import PublisherTestcase diff --git a/tests/asyncapi/kafka/v3_0_0/test_security.py b/tests/asyncapi/kafka/v3_0_0/test_security.py index a5729e1d2d..b177fb0717 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_security.py +++ b/tests/asyncapi/kafka/v3_0_0/test_security.py @@ -2,8 +2,8 @@ from copy import deepcopy from faststream.app import FastStream -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.kafka import KafkaBroker from faststream.security import ( BaseSecurity, diff --git a/tests/asyncapi/nats/v2_6_0/test_arguments.py b/tests/asyncapi/nats/v2_6_0/test_arguments.py index 4749b85b5a..4f227a5095 100644 --- a/tests/asyncapi/nats/v2_6_0/test_arguments.py +++ b/tests/asyncapi/nats/v2_6_0/test_arguments.py @@ -1,4 +1,4 @@ -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker from tests.asyncapi.base.arguments import ArgumentsTestcase diff --git a/tests/asyncapi/nats/v2_6_0/test_connection.py b/tests/asyncapi/nats/v2_6_0/test_connection.py index 00ed2d5ccb..4e8dd6eef3 100644 --- a/tests/asyncapi/nats/v2_6_0/test_connection.py +++ b/tests/asyncapi/nats/v2_6_0/test_connection.py @@ -1,5 +1,5 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker from faststream.specification.schema.tag import Tag diff --git a/tests/asyncapi/nats/v2_6_0/test_kv_schema.py b/tests/asyncapi/nats/v2_6_0/test_kv_schema.py index 4b0edc1847..58429f73bb 100644 --- a/tests/asyncapi/nats/v2_6_0/test_kv_schema.py +++ b/tests/asyncapi/nats/v2_6_0/test_kv_schema.py @@ -1,5 +1,5 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker diff --git a/tests/asyncapi/nats/v2_6_0/test_naming.py b/tests/asyncapi/nats/v2_6_0/test_naming.py index 833289e8db..d72360bc87 100644 --- a/tests/asyncapi/nats/v2_6_0/test_naming.py +++ b/tests/asyncapi/nats/v2_6_0/test_naming.py @@ -1,5 +1,5 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker from tests.asyncapi.base.naming import NamingTestCase diff --git a/tests/asyncapi/nats/v2_6_0/test_obj_schema.py b/tests/asyncapi/nats/v2_6_0/test_obj_schema.py index f7546cbc22..55d98219b2 100644 --- a/tests/asyncapi/nats/v2_6_0/test_obj_schema.py +++ b/tests/asyncapi/nats/v2_6_0/test_obj_schema.py @@ -1,5 +1,5 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker diff --git a/tests/asyncapi/nats/v2_6_0/test_publisher.py b/tests/asyncapi/nats/v2_6_0/test_publisher.py index 5263a0dd99..eb7ee2a01c 100644 --- a/tests/asyncapi/nats/v2_6_0/test_publisher.py +++ b/tests/asyncapi/nats/v2_6_0/test_publisher.py @@ -1,4 +1,4 @@ -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker from tests.asyncapi.base.publisher import PublisherTestcase diff --git a/tests/asyncapi/nats/v2_6_0/test_router.py b/tests/asyncapi/nats/v2_6_0/test_router.py index 19087d14de..1eb9dcc8ca 100644 --- a/tests/asyncapi/nats/v2_6_0/test_router.py +++ b/tests/asyncapi/nats/v2_6_0/test_router.py @@ -1,5 +1,5 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker, NatsPublisher, NatsRoute, NatsRouter from tests.asyncapi.base.arguments import ArgumentsTestcase from tests.asyncapi.base.publisher import PublisherTestcase diff --git a/tests/asyncapi/nats/v3_0_0/test_arguments.py b/tests/asyncapi/nats/v3_0_0/test_arguments.py index 7158237f74..a6d538b27f 100644 --- a/tests/asyncapi/nats/v3_0_0/test_arguments.py +++ b/tests/asyncapi/nats/v3_0_0/test_arguments.py @@ -1,4 +1,4 @@ -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase diff --git a/tests/asyncapi/nats/v3_0_0/test_connection.py b/tests/asyncapi/nats/v3_0_0/test_connection.py index 1570dc9699..8ee0f062a2 100644 --- a/tests/asyncapi/nats/v3_0_0/test_connection.py +++ b/tests/asyncapi/nats/v3_0_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.nats import NatsBroker from faststream.specification.schema.tag import Tag diff --git a/tests/asyncapi/nats/v3_0_0/test_fastapi.py b/tests/asyncapi/nats/v3_0_0/test_fastapi.py index 2c397f0dc9..ca493da280 100644 --- a/tests/asyncapi/nats/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/nats/v3_0_0/test_fastapi.py @@ -1,5 +1,5 @@ -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.nats import TestNatsBroker from faststream.nats.fastapi import NatsRouter from tests.asyncapi.base.v3_0_0.arguments import FastAPICompatible diff --git a/tests/asyncapi/nats/v3_0_0/test_kv_schema.py b/tests/asyncapi/nats/v3_0_0/test_kv_schema.py index bcda197f31..9fba249772 100644 --- a/tests/asyncapi/nats/v3_0_0/test_kv_schema.py +++ b/tests/asyncapi/nats/v3_0_0/test_kv_schema.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.nats import NatsBroker diff --git a/tests/asyncapi/nats/v3_0_0/test_naming.py b/tests/asyncapi/nats/v3_0_0/test_naming.py index 87d44e5d32..5f73321898 100644 --- a/tests/asyncapi/nats/v3_0_0/test_naming.py +++ b/tests/asyncapi/nats/v3_0_0/test_naming.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.nats import NatsBroker from tests.asyncapi.base.v3_0_0.naming import NamingTestCase diff --git a/tests/asyncapi/nats/v3_0_0/test_obj_schema.py b/tests/asyncapi/nats/v3_0_0/test_obj_schema.py index dd3907d73e..57d9547353 100644 --- a/tests/asyncapi/nats/v3_0_0/test_obj_schema.py +++ b/tests/asyncapi/nats/v3_0_0/test_obj_schema.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.nats import NatsBroker diff --git a/tests/asyncapi/nats/v3_0_0/test_publisher.py b/tests/asyncapi/nats/v3_0_0/test_publisher.py index 0d0adbc1bd..c67cb5fd8f 100644 --- a/tests/asyncapi/nats/v3_0_0/test_publisher.py +++ b/tests/asyncapi/nats/v3_0_0/test_publisher.py @@ -1,4 +1,4 @@ -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase diff --git a/tests/asyncapi/nats/v3_0_0/test_router.py b/tests/asyncapi/nats/v3_0_0/test_router.py index 7ebe5b99b3..83340eb043 100644 --- a/tests/asyncapi/nats/v3_0_0/test_router.py +++ b/tests/asyncapi/nats/v3_0_0/test_router.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.nats import NatsBroker, NatsPublisher, NatsRoute, NatsRouter from tests.asyncapi.base.arguments import ArgumentsTestcase from tests.asyncapi.base.publisher import PublisherTestcase diff --git a/tests/asyncapi/rabbit/v2_6_0/test_arguments.py b/tests/asyncapi/rabbit/v2_6_0/test_arguments.py index f192b43766..136d6bfd42 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_arguments.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_arguments.py @@ -1,4 +1,4 @@ -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.rabbit import ExchangeType, RabbitBroker, RabbitExchange, RabbitQueue from tests.asyncapi.base.arguments import ArgumentsTestcase diff --git a/tests/asyncapi/rabbit/v2_6_0/test_connection.py b/tests/asyncapi/rabbit/v2_6_0/test_connection.py index fc125c5df1..96b2c5f256 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_connection.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_connection.py @@ -1,5 +1,5 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.rabbit import RabbitBroker from faststream.specification.schema.tag import Tag diff --git a/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py b/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py index e205f9966e..69cb1894f4 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py @@ -1,6 +1,6 @@ from typing import Type -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.rabbit.fastapi import RabbitRouter from faststream.rabbit.testing import TestRabbitBroker from faststream.security import SASLPlaintext diff --git a/tests/asyncapi/rabbit/v2_6_0/test_naming.py b/tests/asyncapi/rabbit/v2_6_0/test_naming.py index b97965649c..bd555ac2df 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_naming.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_naming.py @@ -1,7 +1,7 @@ from typing import Type from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.rabbit import RabbitBroker from tests.asyncapi.base.naming import NamingTestCase diff --git a/tests/asyncapi/rabbit/v2_6_0/test_publisher.py b/tests/asyncapi/rabbit/v2_6_0/test_publisher.py index bbe4faf3c8..f5dd27c895 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_publisher.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_publisher.py @@ -1,4 +1,4 @@ -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.rabbit import ExchangeType, RabbitBroker, RabbitExchange, RabbitQueue from tests.asyncapi.base.publisher import PublisherTestcase diff --git a/tests/asyncapi/rabbit/v2_6_0/test_router.py b/tests/asyncapi/rabbit/v2_6_0/test_router.py index 386f4960f5..133b82ee84 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_router.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_router.py @@ -1,5 +1,5 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.rabbit import ( RabbitBroker, RabbitPublisher, diff --git a/tests/asyncapi/rabbit/v2_6_0/test_security.py b/tests/asyncapi/rabbit/v2_6_0/test_security.py index 88ea3f683c..2a3f825993 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_security.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_security.py @@ -1,7 +1,7 @@ import ssl from faststream.app import FastStream -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.rabbit import RabbitBroker from faststream.security import ( BaseSecurity, diff --git a/tests/asyncapi/rabbit/v3_0_0/test_arguments.py b/tests/asyncapi/rabbit/v3_0_0/test_arguments.py index 4e66f1d214..4321cc4861 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_arguments.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_arguments.py @@ -1,4 +1,4 @@ -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.rabbit import ExchangeType, RabbitBroker, RabbitExchange, RabbitQueue from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase diff --git a/tests/asyncapi/rabbit/v3_0_0/test_connection.py b/tests/asyncapi/rabbit/v3_0_0/test_connection.py index d6d47d774a..e070c32ba0 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_connection.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.rabbit import RabbitBroker from faststream.specification.schema.tag import Tag diff --git a/tests/asyncapi/rabbit/v3_0_0/test_fastapi.py b/tests/asyncapi/rabbit/v3_0_0/test_fastapi.py index 1cb3ae10a8..9d522340f9 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_fastapi.py @@ -1,5 +1,5 @@ -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.rabbit.fastapi import RabbitRouter from faststream.rabbit.testing import TestRabbitBroker from faststream.security import SASLPlaintext diff --git a/tests/asyncapi/rabbit/v3_0_0/test_naming.py b/tests/asyncapi/rabbit/v3_0_0/test_naming.py index c124ccd128..6bc06d5e28 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_naming.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_naming.py @@ -1,8 +1,8 @@ from typing import Type from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.rabbit import RabbitBroker from tests.asyncapi.base.v3_0_0.naming import NamingTestCase diff --git a/tests/asyncapi/rabbit/v3_0_0/test_publisher.py b/tests/asyncapi/rabbit/v3_0_0/test_publisher.py index f9b24c1e54..83fc8608e4 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_publisher.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_publisher.py @@ -1,4 +1,4 @@ -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.rabbit import ExchangeType, RabbitBroker, RabbitExchange, RabbitQueue from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase diff --git a/tests/asyncapi/rabbit/v3_0_0/test_router.py b/tests/asyncapi/rabbit/v3_0_0/test_router.py index ce77c35b92..941875a7be 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_router.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_router.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.rabbit import ( RabbitBroker, RabbitPublisher, diff --git a/tests/asyncapi/rabbit/v3_0_0/test_security.py b/tests/asyncapi/rabbit/v3_0_0/test_security.py index babe62d5ea..18d94f7d98 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_security.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_security.py @@ -1,8 +1,8 @@ import ssl from faststream.app import FastStream -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.rabbit import RabbitBroker from faststream.security import ( BaseSecurity, diff --git a/tests/asyncapi/redis/v2_6_0/test_arguments.py b/tests/asyncapi/redis/v2_6_0/test_arguments.py index 3f64aba9b6..5c29b11f93 100644 --- a/tests/asyncapi/redis/v2_6_0/test_arguments.py +++ b/tests/asyncapi/redis/v2_6_0/test_arguments.py @@ -1,4 +1,4 @@ -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.redis import RedisBroker, StreamSub from tests.asyncapi.base.arguments import ArgumentsTestcase diff --git a/tests/asyncapi/redis/v2_6_0/test_connection.py b/tests/asyncapi/redis/v2_6_0/test_connection.py index 53b0c6b126..3157597ba6 100644 --- a/tests/asyncapi/redis/v2_6_0/test_connection.py +++ b/tests/asyncapi/redis/v2_6_0/test_connection.py @@ -1,5 +1,5 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.redis import RedisBroker from faststream.specification.schema.tag import Tag diff --git a/tests/asyncapi/redis/v2_6_0/test_naming.py b/tests/asyncapi/redis/v2_6_0/test_naming.py index 92bcb5b0f9..c2bc889658 100644 --- a/tests/asyncapi/redis/v2_6_0/test_naming.py +++ b/tests/asyncapi/redis/v2_6_0/test_naming.py @@ -1,7 +1,7 @@ import pytest from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.redis import RedisBroker from tests.asyncapi.base.naming import NamingTestCase diff --git a/tests/asyncapi/redis/v2_6_0/test_publisher.py b/tests/asyncapi/redis/v2_6_0/test_publisher.py index 8a82bca90d..3861fa6bbf 100644 --- a/tests/asyncapi/redis/v2_6_0/test_publisher.py +++ b/tests/asyncapi/redis/v2_6_0/test_publisher.py @@ -1,4 +1,4 @@ -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.redis import RedisBroker from tests.asyncapi.base.publisher import PublisherTestcase diff --git a/tests/asyncapi/redis/v2_6_0/test_router.py b/tests/asyncapi/redis/v2_6_0/test_router.py index eff7d40003..adaab1e3b0 100644 --- a/tests/asyncapi/redis/v2_6_0/test_router.py +++ b/tests/asyncapi/redis/v2_6_0/test_router.py @@ -1,5 +1,5 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.redis import RedisBroker, RedisPublisher, RedisRoute, RedisRouter from tests.asyncapi.base.arguments import ArgumentsTestcase from tests.asyncapi.base.publisher import PublisherTestcase diff --git a/tests/asyncapi/redis/v2_6_0/test_security.py b/tests/asyncapi/redis/v2_6_0/test_security.py index b9ef40b41a..b71ce53f2c 100644 --- a/tests/asyncapi/redis/v2_6_0/test_security.py +++ b/tests/asyncapi/redis/v2_6_0/test_security.py @@ -1,7 +1,7 @@ import ssl from faststream.app import FastStream -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.redis import RedisBroker from faststream.security import ( BaseSecurity, diff --git a/tests/asyncapi/redis/v3_0_0/test_arguments.py b/tests/asyncapi/redis/v3_0_0/test_arguments.py index 77e41974f0..6acf2dc19d 100644 --- a/tests/asyncapi/redis/v3_0_0/test_arguments.py +++ b/tests/asyncapi/redis/v3_0_0/test_arguments.py @@ -1,4 +1,4 @@ -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.redis import RedisBroker, StreamSub from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase diff --git a/tests/asyncapi/redis/v3_0_0/test_connection.py b/tests/asyncapi/redis/v3_0_0/test_connection.py index f29c2fa808..20c388c091 100644 --- a/tests/asyncapi/redis/v3_0_0/test_connection.py +++ b/tests/asyncapi/redis/v3_0_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.redis import RedisBroker from faststream.specification.schema.tag import Tag diff --git a/tests/asyncapi/redis/v3_0_0/test_fastapi.py b/tests/asyncapi/redis/v3_0_0/test_fastapi.py index a588c33b54..c2b95ebb69 100644 --- a/tests/asyncapi/redis/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/redis/v3_0_0/test_fastapi.py @@ -1,4 +1,4 @@ -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.redis import TestRedisBroker from faststream.redis.fastapi import RedisRouter from tests.asyncapi.base.v3_0_0.arguments import FastAPICompatible diff --git a/tests/asyncapi/redis/v3_0_0/test_naming.py b/tests/asyncapi/redis/v3_0_0/test_naming.py index 373a3c82c2..9183eb0f5e 100644 --- a/tests/asyncapi/redis/v3_0_0/test_naming.py +++ b/tests/asyncapi/redis/v3_0_0/test_naming.py @@ -1,8 +1,8 @@ import pytest from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.redis import RedisBroker from tests.asyncapi.base.v3_0_0.naming import NamingTestCase diff --git a/tests/asyncapi/redis/v3_0_0/test_publisher.py b/tests/asyncapi/redis/v3_0_0/test_publisher.py index 20814d42bf..e36d2935fe 100644 --- a/tests/asyncapi/redis/v3_0_0/test_publisher.py +++ b/tests/asyncapi/redis/v3_0_0/test_publisher.py @@ -1,4 +1,4 @@ -from faststream.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.generate import get_app_schema from faststream.redis import RedisBroker from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase diff --git a/tests/asyncapi/redis/v3_0_0/test_router.py b/tests/asyncapi/redis/v3_0_0/test_router.py index b11ada430c..cffd2597d1 100644 --- a/tests/asyncapi/redis/v3_0_0/test_router.py +++ b/tests/asyncapi/redis/v3_0_0/test_router.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.redis import RedisBroker, RedisPublisher, RedisRoute, RedisRouter from tests.asyncapi.base.arguments import ArgumentsTestcase from tests.asyncapi.base.publisher import PublisherTestcase diff --git a/tests/asyncapi/redis/v3_0_0/test_security.py b/tests/asyncapi/redis/v3_0_0/test_security.py index ac3b12849d..9c6b717a8d 100644 --- a/tests/asyncapi/redis/v3_0_0/test_security.py +++ b/tests/asyncapi/redis/v3_0_0/test_security.py @@ -1,8 +1,8 @@ import ssl from faststream.app import FastStream -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.version import AsyncAPIVersion +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.redis import RedisBroker from faststream.security import ( BaseSecurity, From a22fa81212bd8c9c19701a1e1f2111dba84a2339 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Thu, 15 Aug 2024 21:25:46 +0300 Subject: [PATCH 080/245] Components and servers in internal specs --- .../specification/schema/bindings/__init__.py | 2 + .../specification/schema/bindings/main.py | 20 +++++ faststream/specification/schema/components.py | 41 ++++++++++ faststream/specification/schema/schema.py | 70 ++++++++++++++++++ faststream/specification/schema/servers.py | 74 +++++++++++++++++++ 5 files changed, 207 insertions(+) create mode 100644 faststream/specification/schema/components.py create mode 100644 faststream/specification/schema/schema.py create mode 100644 faststream/specification/schema/servers.py diff --git a/faststream/specification/schema/bindings/__init__.py b/faststream/specification/schema/bindings/__init__.py index c304608c5b..39ce4b993c 100644 --- a/faststream/specification/schema/bindings/__init__.py +++ b/faststream/specification/schema/bindings/__init__.py @@ -1,9 +1,11 @@ from .main import ( ChannelBinding, OperationBinding, + ServerBinding, ) __all__ = ( + "ServerBinding", "ChannelBinding", "OperationBinding", ) diff --git a/faststream/specification/schema/bindings/main.py b/faststream/specification/schema/bindings/main.py index 65622aaa76..9ccfb32714 100644 --- a/faststream/specification/schema/bindings/main.py +++ b/faststream/specification/schema/bindings/main.py @@ -8,6 +8,26 @@ from faststream.specification.schema.bindings import sqs as sqs_bindings +@dataclass +class ServerBinding: + """A class to represent server bindings. + + Attributes: + amqp : AMQP server binding (optional) + kafka : Kafka server binding (optional) + sqs : SQS server binding (optional) + nats : NATS server binding (optional) + redis : Redis server binding (optional) + + """ + + amqp: Optional[amqp_bindings.ServerBinding] = None + kafka: Optional[kafka_bindings.ServerBinding] = None + sqs: Optional[sqs_bindings.ServerBinding] = None + nats: Optional[nats_bindings.ServerBinding] = None + redis: Optional[redis_bindings.ServerBinding] = None + + @dataclass class ChannelBinding: """A class to represent channel bindings. diff --git a/faststream/specification/schema/components.py b/faststream/specification/schema/components.py new file mode 100644 index 0000000000..e7755c2748 --- /dev/null +++ b/faststream/specification/schema/components.py @@ -0,0 +1,41 @@ +from typing import ( + Any, + Dict, + Optional, +) + +from pydantic import BaseModel + +from faststream._compat import ( + PYDANTIC_V2, +) +from faststream.specification.schema.message import Message + + +class Components(BaseModel): + """A class to represent components in a system. + + Attributes: + messages : Optional dictionary of messages + schemas : Optional dictionary of schemas + + Note: + The following attributes are not implemented yet: + - servers + - serverVariables + - channels + - securitySchemes + + """ + + messages: Optional[Dict[str, Message]] = None + schemas: Optional[Dict[str, Dict[str, Any]]] = None + securitySchemes: Optional[Dict[str, Dict[str, Any]]] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" diff --git a/faststream/specification/schema/schema.py b/faststream/specification/schema/schema.py new file mode 100644 index 0000000000..dcdd190516 --- /dev/null +++ b/faststream/specification/schema/schema.py @@ -0,0 +1,70 @@ +from typing import Any, Dict, List, Optional, Union + +from pydantic import BaseModel + +from faststream._compat import model_to_json, model_to_jsonable +from faststream.specification.asyncapi.version import AsyncAPIVersion +from faststream.specification.schema.channel import Channel +from faststream.specification.schema.components import Components +from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict +from faststream.specification.schema.info import Info +from faststream.specification.schema.servers import Server +from faststream.specification.schema.tag import Tag, TagDict + + +class Schema(BaseModel): + """A class to represent a schema. + + Attributes: + asyncapi : version of the async API + id : optional ID + defaultContentType : optional default content type + info : information about the schema + servers : optional dictionary of servers + channels : dictionary of channels + components : optional components of the schema + tags : optional list of tags + externalDocs : optional external documentation + + Methods: + to_jsonable() -> Any: Convert the schema to a JSON-serializable object. + to_json() -> str: Convert the schema to a JSON string. + to_yaml() -> str: Convert the schema to a YAML string. + + """ + + asyncapi: AsyncAPIVersion = AsyncAPIVersion.v2_6 + id: Optional[str] = None + defaultContentType: Optional[str] = None + info: Info + servers: Optional[Dict[str, Server]] = None + channels: Dict[str, Channel] + components: Optional[Components] = None + tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = None + externalDocs: Optional[Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]] = None + + def to_jsonable(self) -> Any: + """Convert the schema to a JSON-serializable object.""" + return model_to_jsonable( + self, + by_alias=True, + exclude_none=True, + ) + + def to_json(self) -> str: + """Convert the schema to a JSON string.""" + return model_to_json( + self, + by_alias=True, + exclude_none=True, + ) + + def to_yaml(self) -> str: + """Convert the schema to a YAML string.""" + from io import StringIO + + import yaml + + io = StringIO(initial_value="", newline="\n") + yaml.dump(self.to_jsonable(), io, sort_keys=False) + return io.getvalue() diff --git a/faststream/specification/schema/servers.py b/faststream/specification/schema/servers.py new file mode 100644 index 0000000000..83086c920a --- /dev/null +++ b/faststream/specification/schema/servers.py @@ -0,0 +1,74 @@ +from typing import Any, Dict, List, Optional, Union + +from pydantic import BaseModel + +from faststream._compat import PYDANTIC_V2 +from faststream.specification.schema.bindings import ServerBinding +from faststream.specification.schema.tag import Tag, TagDict + +SecurityRequirement = List[Dict[str, List[str]]] + + +class ServerVariable(BaseModel): + """A class to represent a server variable. + + Attributes: + enum : list of possible values for the server variable (optional) + default : default value for the server variable (optional) + description : description of the server variable (optional) + examples : list of example values for the server variable (optional) + + """ + + enum: Optional[List[str]] = None + default: Optional[str] = None + description: Optional[str] = None + examples: Optional[List[str]] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" + + +class Server(BaseModel): + """A class to represent a server. + + Attributes: + url : URL of the server + protocol : protocol used by the server + description : optional description of the server + protocolVersion : optional version of the protocol used by the server + tags : optional list of tags associated with the server + security : optional security requirement for the server + variables : optional dictionary of server variables + bindings : optional server binding + + Note: + The attributes `description`, `protocolVersion`, `tags`, `security`, `variables`, and `bindings` are all optional. + + Configurations: + If `PYDANTIC_V2` is True, the model configuration is set to allow extra attributes. + Otherwise, the `Config` class is defined with the `extra` attribute set to "allow". + + """ + + url: str + protocol: str + description: Optional[str] = None + protocolVersion: Optional[str] = None + tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = None + security: Optional[SecurityRequirement] = None + variables: Optional[Dict[str, ServerVariable]] = None + bindings: Optional[ServerBinding] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" From 54593592576a0b497868b3b4d57e4d88536d6cb8 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Thu, 15 Aug 2024 21:28:10 +0300 Subject: [PATCH 081/245] Remove asyncapi attr from internal schema --- faststream/specification/schema/schema.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/faststream/specification/schema/schema.py b/faststream/specification/schema/schema.py index dcdd190516..6fbf39b284 100644 --- a/faststream/specification/schema/schema.py +++ b/faststream/specification/schema/schema.py @@ -16,7 +16,6 @@ class Schema(BaseModel): """A class to represent a schema. Attributes: - asyncapi : version of the async API id : optional ID defaultContentType : optional default content type info : information about the schema @@ -33,7 +32,6 @@ class Schema(BaseModel): """ - asyncapi: AsyncAPIVersion = AsyncAPIVersion.v2_6 id: Optional[str] = None defaultContentType: Optional[str] = None info: Info From ebc618adc8e993a80d69e421fabd19c3d1a7de11 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Thu, 15 Aug 2024 23:24:43 +0300 Subject: [PATCH 082/245] I forgot what I done here but I done a lot of good things i think --- faststream/app.py | 4 +- faststream/asgi/app.py | 4 +- .../specification/asyncapi/v2_6_0/generate.py | 79 +++++++++---------- .../asyncapi/v2_6_0/schema/__init__.py | 6 +- .../asyncapi/v2_6_0/schema/components.py | 8 -- .../asyncapi/v2_6_0/schema/docs.py | 57 +++++++++++++ .../asyncapi/v2_6_0/schema/message.py | 8 +- .../asyncapi/v2_6_0/schema/operations.py | 9 +-- .../asyncapi/v2_6_0/schema/schema.py | 12 +-- .../asyncapi/v2_6_0/schema/servers.py | 9 +-- .../asyncapi/v2_6_0/schema/tag.py | 54 +++++++++++++ .../asyncapi/v2_6_0/schema/utils.py | 79 +------------------ .../specification/asyncapi/v3_0_0/generate.py | 17 ++-- .../asyncapi/v3_0_0/schema/info.py | 12 +-- .../asyncapi/v3_0_0/schema/operations.py | 13 +-- .../asyncapi/v3_0_0/schema/servers.py | 10 +-- faststream/specification/proto.py | 4 +- faststream/specification/schema/operation.py | 8 +- faststream/specification/schema/schema.py | 5 +- faststream/specification/schema/servers.py | 4 +- 20 files changed, 198 insertions(+), 204 deletions(-) create mode 100644 faststream/specification/asyncapi/v2_6_0/schema/docs.py create mode 100644 faststream/specification/asyncapi/v2_6_0/schema/tag.py diff --git a/faststream/app.py b/faststream/app.py index 6d871b913f..ab20c73488 100644 --- a/faststream/app.py +++ b/faststream/app.py @@ -33,7 +33,7 @@ from faststream.specification.schema.contact import Contact, ContactDict from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict from faststream.specification.schema.license import License, LicenseDict - from faststream.specification.schema.tag import Tag, TagDict + from faststream.specification.schema.tag import Tag from faststream.types import ( AnyCallable, AnyDict, @@ -66,7 +66,7 @@ def __init__( terms_of_service: Optional["AnyHttpUrl"] = None, license: Optional[Union["License", "LicenseDict", "AnyDict"]] = None, contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] = None, - tags: Optional[Sequence[Union["Tag", "TagDict", "AnyDict"]]] = None, + tags: Optional[Sequence[Union["Tag", "AnyDict"]]] = None, external_docs: Optional[ Union["ExternalDocs", "ExternalDocsDict", "AnyDict"] ] = None, diff --git a/faststream/asgi/app.py b/faststream/asgi/app.py index f90e79a93f..1d3182a629 100644 --- a/faststream/asgi/app.py +++ b/faststream/asgi/app.py @@ -24,7 +24,7 @@ from faststream.specification.contact import Contact, ContactDict from faststream.specification.docs import ExternalDocs, ExternalDocsDict from faststream.specification.license import License, LicenseDict - from faststream.specification.schema.tag import Tag, TagDict + from faststream.specification.schema.tag import Tag from faststream.types import ( AnyCallable, AnyDict, @@ -51,7 +51,7 @@ def __init__( terms_of_service: Optional["AnyHttpUrl"] = None, license: Optional[Union["License", "LicenseDict", "AnyDict"]] = None, contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] = None, - tags: Optional[Sequence[Union["Tag", "TagDict", "AnyDict"]]] = None, + tags: Optional[Sequence[Union["Tag", "AnyDict"]]] = None, external_docs: Optional[ Union["ExternalDocs", "ExternalDocsDict", "AnyDict"] ] = None, diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index 59b6d33a89..f4e875c0a1 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -8,7 +8,6 @@ Channel, Components, Contact, - ExternalDocs, Info, License, Operation, @@ -16,7 +15,6 @@ Schema, Server, Tag, - TagDict, ) from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( ChannelBinding, @@ -27,10 +25,16 @@ redis, sqs, ) +from faststream.specification.asyncapi.v2_6_0.schema.docs import ( + from_spec as docs_from_spec, +) from faststream.specification.asyncapi.v2_6_0.schema.message import ( CorrelationId, Message, ) +from faststream.specification.asyncapi.v2_6_0.schema.tag import ( + from_spec as tag_from_spec, +) from faststream.specification.proto import Application if TYPE_CHECKING: @@ -89,8 +93,13 @@ def get_app_schema(app: Application) -> Schema: ), defaultContentType=ContentTypes.json.value, id=app.identifier, - tags=specs_tags_to_asyncapi(list(app.specs_tags)) if app.specs_tags else None, - externalDocs=specs_external_docs_to_asyncapi(app.external_docs) if app.external_docs else None, + + tags=[tag_from_spec(tag) for tag in app.specs_tags] + if app.specs_tags else None, + + externalDocs=docs_from_spec(app.external_docs) + if app.external_docs else None, + servers=servers, channels=channels, components=Components( @@ -277,20 +286,17 @@ def specs_operation_to_asyncapi(operation: spec.operation.Operation) -> Operatio contentType=operation.message.contentType, - tags=specs_tags_to_asyncapi(operation.tags) + tags=[tag_from_spec(tag) for tag in operation.tags] if operation.tags else None, - externalDocs=specs_external_docs_to_asyncapi(operation.externalDocs) - if operation.externalDocs else None, + externalDocs=docs_from_spec(operation.message.externalDocs) + if operation.message.externalDocs else None, ), security=operation.security, - tags=specs_tags_to_asyncapi(operation.tags) + tags=[tag_from_spec(tag) for tag in operation.tags] if operation.tags else None, - - externalDocs=specs_external_docs_to_asyncapi(operation.externalDocs) - if operation.externalDocs else None, ) @@ -313,37 +319,26 @@ def specs_operation_binding_to_asyncapi(binding: spec.bindings.OperationBinding) ) -def specs_tags_to_asyncapi( - tags: List[Union[spec.tag.Tag, spec.tag.TagDict, Dict[str, Any]]] -) -> List[Union[Tag, TagDict, Dict[str, Any]]]: - asyncapi_tags: List[Union[Tag, TagDict, Dict[str, Any]]] = [] - - for tag in tags: - if isinstance(tag, spec.tag.Tag): - asyncapi_tags.append(Tag( - name=tag.name, - description=tag.description, - - externalDocs=specs_external_docs_to_asyncapi(tag.externalDocs) - if tag.externalDocs else None, - )) - elif isinstance(tag, dict): - asyncapi_tags.append(dict(tag)) - else: - raise NotImplementedError - - return asyncapi_tags - - -def specs_external_docs_to_asyncapi( - externalDocs: Union[spec.docs.ExternalDocs, spec.docs.ExternalDocsDict, Dict[str, Any]] -) -> Union[ExternalDocs, Dict[str, Any]]: - if isinstance(externalDocs, spec.docs.ExternalDocs): - return ExternalDocs( - **asdict(externalDocs) - ) - else: - return dict(externalDocs) +# def specs_tags_to_asyncapi( +# tags: List[Union[spec.tag.Tag, spec.tag.TagDict, Dict[str, Any]]] +# ) -> List[Union[Tag, Dict[str, Any]]]: +# asyncapi_tags: List[Union[Tag, Dict[str, Any]]] = [] +# +# for tag in tags: +# if isinstance(tag, spec.tag.Tag): +# asyncapi_tags.append(Tag( +# name=tag.name, +# description=tag.description, +# +# externalDocs=docs_from_spec(tag.externalDocs) +# if tag.externalDocs else None, +# )) +# elif isinstance(tag, dict): +# asyncapi_tags.append(dict(tag)) +# else: +# raise NotImplementedError +# +# return asyncapi_tags def _resolve_msg_payloads( diff --git a/faststream/specification/asyncapi/v2_6_0/schema/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/__init__.py index a43ad3d13e..7c7808c592 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/__init__.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/__init__.py @@ -1,12 +1,14 @@ from . import bindings from .channels import Channel from .components import Components +from .docs import ExternalDocs from .info import Contact, ContactDict, Info, License, LicenseDict from .message import CorrelationId, Message from .operations import Operation from .schema import Schema from .servers import Server, ServerVariable -from .utils import ExternalDocs, ExternalDocsDict, Parameter, Reference, Tag, TagDict +from .tag import Tag +from .utils import Parameter, Reference __all__ = ( "Channel", @@ -22,9 +24,7 @@ "ServerVariable", "Message", "CorrelationId", - "ExternalDocsDict", "ExternalDocs", - "TagDict", "Tag", "Reference", "Parameter", diff --git a/faststream/specification/asyncapi/v2_6_0/schema/components.py b/faststream/specification/asyncapi/v2_6_0/schema/components.py index 02287bacd3..c26f3f8437 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/components.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/components.py @@ -43,14 +43,6 @@ class Components(BaseModel): messages: Optional[Dict[str, Message]] = None schemas: Optional[Dict[str, Dict[str, Any]]] = None securitySchemes: Optional[Dict[str, Dict[str, Any]]] = None - # parameters - # correlationIds - # operationTraits - # messageTraits - # serverBindings - # channelBindings - # operationBindings - # messageBindings if PYDANTIC_V2: model_config = {"extra": "allow"} diff --git a/faststream/specification/asyncapi/v2_6_0/schema/docs.py b/faststream/specification/asyncapi/v2_6_0/schema/docs.py new file mode 100644 index 0000000000..d86584d10e --- /dev/null +++ b/faststream/specification/asyncapi/v2_6_0/schema/docs.py @@ -0,0 +1,57 @@ +from dataclasses import asdict +from typing import Any, Dict, Optional, Union, overload + +import typing_extensions +from pydantic import AnyHttpUrl, BaseModel + +from faststream._compat import PYDANTIC_V2 +from faststream.specification import schema as spec + + +class ExternalDocs(BaseModel): + """A class to represent external documentation. + + Attributes: + url : URL of the external documentation + description : optional description of the external documentation + + """ + + url: AnyHttpUrl + description: Optional[str] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" + + @classmethod + def from_spec(cls, docs: spec.docs.ExternalDocs) -> typing_extensions.Self: + return cls( + url=docs.url, + description=docs.description + ) + + +@overload +def from_spec(docs: spec.docs.ExternalDocs) -> ExternalDocs: ... + + +@overload +def from_spec(docs: spec.docs.ExternalDocsDict) -> Dict[str, Any]: ... + + +@overload +def from_spec(docs: Dict[str, Any]) -> Dict[str, Any]: ... + + +def from_spec( + docs: Union[spec.docs.ExternalDocs, spec.docs.ExternalDocsDict, Dict[str, Any]] +) -> Union[ExternalDocs, Dict[str, Any]]: + if isinstance(docs, spec.docs.ExternalDocs): + return ExternalDocs(**asdict(docs)) + + return dict(docs) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/message.py b/faststream/specification/asyncapi/v2_6_0/schema/message.py index dc8333b98b..73879bb2c3 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/message.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/message.py @@ -3,10 +3,8 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.specification.asyncapi.v2_6_0.schema.utils import ( - ExternalDocs, - Tag, -) +from faststream.specification.asyncapi.v2_6_0.schema.docs import ExternalDocs +from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag class CorrelationId(BaseModel): @@ -67,7 +65,7 @@ class Message(BaseModel): # traits tags: Optional[List[Union[Tag, Dict[str, Any]]]] = ( - None # TODO: weird TagDict behavior + None ) externalDocs: Optional[Union[ExternalDocs, Dict[str, Any]]] = ( None # TODO: weird ExternalDocsDict behavior diff --git a/faststream/specification/asyncapi/v2_6_0/schema/operations.py b/faststream/specification/asyncapi/v2_6_0/schema/operations.py index d674cb4a78..b77642a28b 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/operations.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/operations.py @@ -5,12 +5,9 @@ from faststream._compat import PYDANTIC_V2 from faststream.specification.asyncapi.v2_6_0.schema.bindings import OperationBinding from faststream.specification.asyncapi.v2_6_0.schema.message import Message +from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag from faststream.specification.asyncapi.v2_6_0.schema.utils import ( - ExternalDocs, - ExternalDocsDict, Reference, - Tag, - TagDict, ) @@ -25,7 +22,6 @@ class Operation(BaseModel): message : message of the operation security : security details of the operation tags : tags associated with the operation - externalDocs : external documentation for the operation """ @@ -42,8 +38,7 @@ class Operation(BaseModel): # TODO # traits - tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = None - externalDocs: Optional[Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]] = None + tags: Optional[List[Union[Tag, Dict[str, Any]]]] = None if PYDANTIC_V2: model_config = {"extra": "allow"} diff --git a/faststream/specification/asyncapi/v2_6_0/schema/schema.py b/faststream/specification/asyncapi/v2_6_0/schema/schema.py index 5040a7cadd..a19a92b359 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/schema.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/schema.py @@ -4,14 +4,10 @@ from faststream.specification.asyncapi.base.schema import BaseSchema from faststream.specification.asyncapi.v2_6_0.schema.channels import Channel from faststream.specification.asyncapi.v2_6_0.schema.components import Components +from faststream.specification.asyncapi.v2_6_0.schema.docs import ExternalDocs from faststream.specification.asyncapi.v2_6_0.schema.info import Info from faststream.specification.asyncapi.v2_6_0.schema.servers import Server -from faststream.specification.asyncapi.v2_6_0.schema.utils import ( - ExternalDocs, - ExternalDocsDict, - Tag, - TagDict, -) +from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag from faststream.specification.asyncapi.version import AsyncAPIVersion @@ -43,8 +39,8 @@ class Schema(BaseSchema): servers: Optional[Dict[str, Server]] = None channels: Dict[str, Channel] components: Optional[Components] = None - tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = None - externalDocs: Optional[Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]] = None + tags: Optional[List[Union[Tag, Dict[str, Any]]]] = None + externalDocs: Optional[Union[ExternalDocs, Dict[str, Any]]] = None def to_jsonable(self) -> Any: """Convert the schema to a JSON-serializable object.""" diff --git a/faststream/specification/asyncapi/v2_6_0/schema/servers.py b/faststream/specification/asyncapi/v2_6_0/schema/servers.py index 3bdcc7ed49..e694c60246 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/servers.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/servers.py @@ -4,11 +4,8 @@ from faststream._compat import PYDANTIC_V2 from faststream.specification.asyncapi.v2_6_0.schema.bindings import ServerBinding -from faststream.specification.asyncapi.v2_6_0.schema.utils import ( - Reference, - Tag, - TagDict, -) +from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag +from faststream.specification.asyncapi.v2_6_0.schema.utils import Reference SecurityRequirement = List[Dict[str, List[str]]] @@ -65,7 +62,7 @@ class Server(BaseModel): protocol: str description: Optional[str] = None protocolVersion: Optional[str] = None - tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = None + tags: Optional[List[Union[Tag, Dict[str, Any]]]] = None security: Optional[SecurityRequirement] = None variables: Optional[Dict[str, Union[ServerVariable, Reference]]] = None bindings: Optional[Union[ServerBinding, Reference]] = None diff --git a/faststream/specification/asyncapi/v2_6_0/schema/tag.py b/faststream/specification/asyncapi/v2_6_0/schema/tag.py new file mode 100644 index 0000000000..7af76281e8 --- /dev/null +++ b/faststream/specification/asyncapi/v2_6_0/schema/tag.py @@ -0,0 +1,54 @@ +from dataclasses import asdict +from typing import Any, Dict, Optional, Union, overload + +from pydantic import BaseModel + +from faststream._compat import PYDANTIC_V2 +from faststream.specification import schema as spec +from faststream.specification.asyncapi.v2_6_0.schema.docs import ( + ExternalDocs, +) + + +class Tag(BaseModel): + """A class to represent a tag. + + Attributes: + name : name of the tag + description : description of the tag (optional) + externalDocs : external documentation for the tag (optional) + + """ + + name: str + description: Optional[str] = None + externalDocs: Optional[ExternalDocs] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" + + +@overload +def from_spec(tag: spec.tag.Tag) -> Tag: ... + + +@overload +def from_spec(tag: spec.tag.TagDict) -> Dict[str, Any]: ... + + +@overload +def from_spec(tag: Dict[str, Any]) -> Dict[str, Any]: ... + + +def from_spec( + tag: Union[spec.tag.Tag, spec.tag.TagDict, Dict[str, Any]] +) -> Union[Tag, Dict[str, Any]]: + if isinstance(tag, spec.tag.Tag): + return Tag(**asdict(tag)) + + return dict(tag) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/utils.py b/faststream/specification/asyncapi/v2_6_0/schema/utils.py index 6857f93552..250022631d 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/utils.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/utils.py @@ -1,81 +1,4 @@ -from typing import Optional, Union - -from pydantic import AnyHttpUrl, BaseModel, Field -from typing_extensions import Required, TypedDict - -from faststream._compat import PYDANTIC_V2 - - -class ExternalDocsDict(TypedDict, total=False): - """A dictionary type for representing external documentation. - - Attributes: - url : Required URL for the external documentation - description : Description of the external documentation - - """ - - url: Required[AnyHttpUrl] - description: str - - -class ExternalDocs(BaseModel): - """A class to represent external documentation. - - Attributes: - url : URL of the external documentation - description : optional description of the external documentation - - """ - - url: AnyHttpUrl - description: Optional[str] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" - - -class TagDict(TypedDict, total=False): - """A dictionary-like class for storing tags. - - Attributes: - name : required name of the tag - description : description of the tag - externalDocs : external documentation for the tag - - """ - - name: Required[str] - description: str - externalDocs: Union[ExternalDocs, ExternalDocsDict] - - -class Tag(BaseModel): - """A class to represent a tag. - - Attributes: - name : name of the tag - description : description of the tag (optional) - externalDocs : external documentation for the tag (optional) - - """ - - name: str - description: Optional[str] = None - externalDocs: Optional[Union[ExternalDocs, ExternalDocsDict]] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" +from pydantic import BaseModel, Field class Reference(BaseModel): diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index 4b2af00581..432cad94e1 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -10,11 +10,9 @@ specs_contact_to_asyncapi, specs_license_to_asyncapi, specs_operation_binding_to_asyncapi, - specs_tags_to_asyncapi, ) from faststream.specification.asyncapi.v2_6_0.schema import ( ExternalDocs, - ExternalDocsDict, Reference, Tag, ) @@ -22,6 +20,9 @@ CorrelationId, Message, ) +from faststream.specification.asyncapi.v2_6_0.schema.tag import ( + from_spec as tag_from_spec, +) from faststream.specification.asyncapi.v3_0_0.schema import ( Channel, Components, @@ -74,12 +75,18 @@ def get_app_schema(app: Application) -> Schema: version=app.version, description=app.description, termsOfService=app.terms_of_service, + contact=specs_contact_to_asyncapi(app.contact) if app.contact else None, + license=specs_license_to_asyncapi(app.license) if app.license else None, - tags=specs_tags_to_asyncapi(list(app.specs_tags)) if app.specs_tags else None, - externalDocs=specs_external_docs_to_asyncapi(app.external_docs) if app.external_docs else None, + + tags=[tag_from_spec(tag) for tag in app.specs_tags] + if app.specs_tags else None, + + externalDocs=specs_external_docs_to_asyncapi(app.external_docs) + if app.external_docs else None, ), defaultContentType=ContentTypes.json.value, id=app.identifier, @@ -302,7 +309,7 @@ def get_broker_channels( def specs_external_docs_to_asyncapi( externalDocs: Union[spec.docs.ExternalDocs, spec.docs.ExternalDocsDict, Dict[str, Any]] -) -> Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]: +) -> Union[ExternalDocs, Dict[str, Any]]: if isinstance(externalDocs, spec.docs.ExternalDocs): return ExternalDocs( **asdict(externalDocs) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/info.py b/faststream/specification/asyncapi/v3_0_0/schema/info.py index 5efcdb94f6..a406f876c7 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/info.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/info.py @@ -9,18 +9,14 @@ from pydantic import AnyHttpUrl from faststream.specification.asyncapi.base.schema import BaseInfo +from faststream.specification.asyncapi.v2_6_0.schema.docs import ExternalDocs from faststream.specification.asyncapi.v2_6_0.schema.info import ( Contact, ContactDict, License, LicenseDict, ) -from faststream.specification.asyncapi.v2_6_0.schema.utils import ( # noqa: TCH001 - ExternalDocs, - ExternalDocsDict, - Tag, - TagDict, -) +from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag from faststream.types import ( # noqa: TCH001 AnyDict, ) @@ -41,7 +37,7 @@ class Info(BaseInfo): termsOfService: Optional[AnyHttpUrl] = None contact: Optional[Union[Contact, ContactDict, Dict[str, Any]]] = None license: Optional[Union[License, LicenseDict, Dict[str, Any]]] = None - tags: Optional[List[Union["Tag", "TagDict", "AnyDict"]]] = None + tags: Optional[List[Union["Tag", "AnyDict"]]] = None externalDocs: Optional[ - Union["ExternalDocs", "ExternalDocsDict", "AnyDict"] + Union["ExternalDocs", "AnyDict"] ] = None diff --git a/faststream/specification/asyncapi/v3_0_0/schema/operations.py b/faststream/specification/asyncapi/v3_0_0/schema/operations.py index 43fe3ee09a..f79e19e253 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/operations.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/operations.py @@ -4,13 +4,8 @@ from faststream._compat import PYDANTIC_V2 from faststream.specification.asyncapi.v2_6_0.schema.bindings import OperationBinding -from faststream.specification.asyncapi.v2_6_0.schema.utils import ( - ExternalDocs, - ExternalDocsDict, - Reference, - Tag, - TagDict, -) +from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag +from faststream.specification.asyncapi.v2_6_0.schema.utils import Reference from faststream.specification.asyncapi.v3_0_0.schema.channels import Channel @@ -25,7 +20,6 @@ class Operation(BaseModel): message : message of the operation security : security details of the operation tags : tags associated with the operation - externalDocs : external documentation for the operation """ action: Literal["send", "receive"] @@ -42,8 +36,7 @@ class Operation(BaseModel): # TODO # traits - tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = None - externalDocs: Optional[Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]] = None + tags: Optional[List[Union[Tag, Dict[str, Any]]]] = None if PYDANTIC_V2: model_config = {"extra": "allow"} diff --git a/faststream/specification/asyncapi/v3_0_0/schema/servers.py b/faststream/specification/asyncapi/v3_0_0/schema/servers.py index 53189f9962..0b12f83445 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/servers.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/servers.py @@ -3,13 +3,9 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.specification.asyncapi.v2_6_0.schema import ServerVariable +from faststream.specification.asyncapi.v2_6_0.schema import ServerVariable, Tag from faststream.specification.asyncapi.v2_6_0.schema.bindings import ServerBinding -from faststream.specification.asyncapi.v2_6_0.schema.utils import ( - Reference, - Tag, - TagDict, -) +from faststream.specification.asyncapi.v2_6_0.schema.utils import Reference SecurityRequirement = List[Dict[str, List[str]]] @@ -42,7 +38,7 @@ class Server(BaseModel): protocol: str description: Optional[str] = None protocolVersion: Optional[str] = None - tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = None + tags: Optional[List[Union[Tag, Dict[str, Any]]]] = None security: Optional[SecurityRequirement] = None variables: Optional[Dict[str, Union[ServerVariable, Reference]]] = None bindings: Optional[Union[ServerBinding, Reference]] = None diff --git a/faststream/specification/proto.py b/faststream/specification/proto.py index c5e64e581a..00197c0677 100644 --- a/faststream/specification/proto.py +++ b/faststream/specification/proto.py @@ -11,7 +11,7 @@ from faststream.specification.schema.contact import Contact, ContactDict from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict from faststream.specification.schema.license import License, LicenseDict - from faststream.specification.schema.tag import Tag, TagDict + from faststream.specification.schema.tag import Tag from faststream.types import ( AnyDict, AnyHttpUrl, @@ -27,7 +27,7 @@ class Application(Protocol): terms_of_service: Optional["AnyHttpUrl"] license: Optional[Union["License", "LicenseDict", "AnyDict"]] contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] - specs_tags: Optional[Sequence[Union["Tag", "TagDict", "AnyDict"]]] + specs_tags: Optional[Sequence[Union["Tag", "AnyDict"]]] external_docs: Optional[Union["ExternalDocs", "ExternalDocsDict", "AnyDict"]] asyncapi_version: AsyncAPIVersion identifier: Optional[str] diff --git a/faststream/specification/schema/operation.py b/faststream/specification/schema/operation.py index 40409bdbf4..71b56c5d16 100644 --- a/faststream/specification/schema/operation.py +++ b/faststream/specification/schema/operation.py @@ -2,9 +2,8 @@ from typing import Any, Dict, List, Optional, Union from faststream.specification.schema.bindings import OperationBinding -from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict from faststream.specification.schema.message import Message -from faststream.specification.schema.tag import Tag, TagDict +from faststream.specification.schema.tag import Tag @dataclass @@ -19,7 +18,6 @@ class Operation: message : message of the operation security : security details of the operation tags : tags associated with the operation - externalDocs : external documentation for the operation """ @@ -33,6 +31,4 @@ class Operation: security: Optional[Dict[str, List[str]]] = None - tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = None - externalDocs: Optional[Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]] = None - + tags: Optional[List[Union[Tag, Dict[str, Any]]]] = None diff --git a/faststream/specification/schema/schema.py b/faststream/specification/schema/schema.py index 6fbf39b284..d3b89ad2ac 100644 --- a/faststream/specification/schema/schema.py +++ b/faststream/specification/schema/schema.py @@ -3,13 +3,12 @@ from pydantic import BaseModel from faststream._compat import model_to_json, model_to_jsonable -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.schema.channel import Channel from faststream.specification.schema.components import Components from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict from faststream.specification.schema.info import Info from faststream.specification.schema.servers import Server -from faststream.specification.schema.tag import Tag, TagDict +from faststream.specification.schema.tag import Tag class Schema(BaseModel): @@ -38,7 +37,7 @@ class Schema(BaseModel): servers: Optional[Dict[str, Server]] = None channels: Dict[str, Channel] components: Optional[Components] = None - tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = None + tags: Optional[List[Union[Tag, Dict[str, Any]]]] = None externalDocs: Optional[Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]] = None def to_jsonable(self) -> Any: diff --git a/faststream/specification/schema/servers.py b/faststream/specification/schema/servers.py index 83086c920a..887dde859c 100644 --- a/faststream/specification/schema/servers.py +++ b/faststream/specification/schema/servers.py @@ -4,7 +4,7 @@ from faststream._compat import PYDANTIC_V2 from faststream.specification.schema.bindings import ServerBinding -from faststream.specification.schema.tag import Tag, TagDict +from faststream.specification.schema.tag import Tag SecurityRequirement = List[Dict[str, List[str]]] @@ -60,7 +60,7 @@ class Server(BaseModel): protocol: str description: Optional[str] = None protocolVersion: Optional[str] = None - tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = None + tags: Optional[List[Union[Tag, Dict[str, Any]]]] = None security: Optional[SecurityRequirement] = None variables: Optional[Dict[str, ServerVariable]] = None bindings: Optional[ServerBinding] = None From e3e62976cc6d005bf1e773b791667816f9e8570b Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 16 Aug 2024 00:23:33 +0300 Subject: [PATCH 083/245] AsyncAPI schema generation from specs refactoring - message --- .../specification/asyncapi/v2_6_0/generate.py | 47 ++----------------- .../asyncapi/v2_6_0/schema/docs.py | 3 +- .../asyncapi/v2_6_0/schema/message.py | 39 +++++++++++++-- .../asyncapi/v2_6_0/schema/tag.py | 16 ++++++- .../specification/asyncapi/v3_0_0/generate.py | 44 ++--------------- 5 files changed, 58 insertions(+), 91 deletions(-) diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index f4e875c0a1..76463aac95 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -29,9 +29,11 @@ from_spec as docs_from_spec, ) from faststream.specification.asyncapi.v2_6_0.schema.message import ( - CorrelationId, Message, ) +from faststream.specification.asyncapi.v2_6_0.schema.message import ( + from_spec as message_from_spec, +) from faststream.specification.asyncapi.v2_6_0.schema.tag import ( from_spec as tag_from_spec, ) @@ -273,26 +275,7 @@ def specs_operation_to_asyncapi(operation: spec.operation.Operation) -> Operatio bindings=specs_operation_binding_to_asyncapi(operation.bindings) if operation.bindings else None, - message=Message( - title=operation.message.title, - name=operation.message.name, - summary=operation.message.summary, - description=operation.message.description, - messageId=operation.message.messageId, - payload=operation.message.payload, - - correlationId=CorrelationId(**asdict(operation.message.correlationId)) - if operation.message.correlationId else None, - - contentType=operation.message.contentType, - - tags=[tag_from_spec(tag) for tag in operation.tags] - if operation.tags else None, - - externalDocs=docs_from_spec(operation.message.externalDocs) - if operation.message.externalDocs else None, - ), - + message=message_from_spec(operation.message), security=operation.security, tags=[tag_from_spec(tag) for tag in operation.tags] @@ -319,28 +302,6 @@ def specs_operation_binding_to_asyncapi(binding: spec.bindings.OperationBinding) ) -# def specs_tags_to_asyncapi( -# tags: List[Union[spec.tag.Tag, spec.tag.TagDict, Dict[str, Any]]] -# ) -> List[Union[Tag, Dict[str, Any]]]: -# asyncapi_tags: List[Union[Tag, Dict[str, Any]]] = [] -# -# for tag in tags: -# if isinstance(tag, spec.tag.Tag): -# asyncapi_tags.append(Tag( -# name=tag.name, -# description=tag.description, -# -# externalDocs=docs_from_spec(tag.externalDocs) -# if tag.externalDocs else None, -# )) -# elif isinstance(tag, dict): -# asyncapi_tags.append(dict(tag)) -# else: -# raise NotImplementedError -# -# return asyncapi_tags - - def _resolve_msg_payloads( m: Message, channel_name: str, diff --git a/faststream/specification/asyncapi/v2_6_0/schema/docs.py b/faststream/specification/asyncapi/v2_6_0/schema/docs.py index d86584d10e..a50991874a 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/docs.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/docs.py @@ -1,4 +1,3 @@ -from dataclasses import asdict from typing import Any, Dict, Optional, Union, overload import typing_extensions @@ -52,6 +51,6 @@ def from_spec( docs: Union[spec.docs.ExternalDocs, spec.docs.ExternalDocsDict, Dict[str, Any]] ) -> Union[ExternalDocs, Dict[str, Any]]: if isinstance(docs, spec.docs.ExternalDocs): - return ExternalDocs(**asdict(docs)) + return ExternalDocs.from_spec(docs) return dict(docs) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/message.py b/faststream/specification/asyncapi/v2_6_0/schema/message.py index 73879bb2c3..1fc625bc03 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/message.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/message.py @@ -1,10 +1,14 @@ from typing import Any, Dict, List, Optional, Union +import typing_extensions from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.specification.asyncapi.v2_6_0.schema.docs import ExternalDocs +from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag +from faststream.specification.asyncapi.v2_6_0.schema.tag import ( + from_spec as tag_from_spec, +) class CorrelationId(BaseModel): @@ -30,6 +34,13 @@ class CorrelationId(BaseModel): class Config: extra = "allow" + @classmethod + def from_spec(cls, cor_id: spec.message.CorrelationId) -> typing_extensions.Self: + return cls( + description=cor_id.description, + location=cor_id.location, + ) + class Message(BaseModel): """A class to represent a message. @@ -44,7 +55,6 @@ class Message(BaseModel): contentType : content type of the message payload : dictionary representing the payload of the message tags : list of tags associated with the message - externalDocs : external documentation associated with the message """ @@ -67,9 +77,6 @@ class Message(BaseModel): tags: Optional[List[Union[Tag, Dict[str, Any]]]] = ( None ) - externalDocs: Optional[Union[ExternalDocs, Dict[str, Any]]] = ( - None # TODO: weird ExternalDocsDict behavior - ) if PYDANTIC_V2: model_config = {"extra": "allow"} @@ -78,3 +85,25 @@ class Message(BaseModel): class Config: extra = "allow" + + @classmethod + def from_spec(cls, message: spec.message.Message) -> typing_extensions.Self: + return cls( + title=message.title, + name=message.name, + summary=message.summary, + description=message.description, + messageId=message.messageId, + + correlationId=CorrelationId.from_spec(message.correlationId) + if message.correlationId is not None else None, + + contentType=message.contentType, + payload=message.payload, + tags=[tag_from_spec(tag) for tag in message.tags] + if message.tags is not None else None, + ) + + +def from_spec(message: spec.message.Message) -> Message: + return Message.from_spec(message) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/tag.py b/faststream/specification/asyncapi/v2_6_0/schema/tag.py index 7af76281e8..30ffe5c3fd 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/tag.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/tag.py @@ -1,6 +1,6 @@ -from dataclasses import asdict from typing import Any, Dict, Optional, Union, overload +import typing_extensions from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 @@ -8,6 +8,9 @@ from faststream.specification.asyncapi.v2_6_0.schema.docs import ( ExternalDocs, ) +from faststream.specification.asyncapi.v2_6_0.schema.docs import ( + from_spec as docs_from_spec, +) class Tag(BaseModel): @@ -32,6 +35,15 @@ class Tag(BaseModel): class Config: extra = "allow" + @classmethod + def from_spec(cls, tag: spec.tag.Tag) -> typing_extensions.Self: + return cls( + name=tag.name, + description=tag.description, + externalDocs=docs_from_spec(tag.externalDocs) + if tag.externalDocs else None + ) + @overload def from_spec(tag: spec.tag.Tag) -> Tag: ... @@ -49,6 +61,6 @@ def from_spec( tag: Union[spec.tag.Tag, spec.tag.TagDict, Dict[str, Any]] ) -> Union[Tag, Dict[str, Any]]: if isinstance(tag, spec.tag.Tag): - return Tag(**asdict(tag)) + return Tag.from_spec(tag) return dict(tag) diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index 432cad94e1..f0a9b7ddf4 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -17,9 +17,11 @@ Tag, ) from faststream.specification.asyncapi.v2_6_0.schema.message import ( - CorrelationId, Message, ) +from faststream.specification.asyncapi.v2_6_0.schema.message import ( + from_spec as message_from_spec, +) from faststream.specification.asyncapi.v2_6_0.schema.tag import ( from_spec as tag_from_spec, ) @@ -237,25 +239,7 @@ def get_broker_channels( channel_v3_0 = Channel( address=channel_name, messages={ - "SubscribeMessage": Message( - title=specs_channel.subscribe.message.title, - name=specs_channel.subscribe.message.name, - summary=specs_channel.subscribe.message.summary, - description=specs_channel.subscribe.message.description, - messageId=specs_channel.subscribe.message.messageId, - payload=specs_channel.subscribe.message.payload, - - correlationId=CorrelationId(**asdict(specs_channel.subscribe.message.correlationId)) - if specs_channel.subscribe.message.correlationId else None, - - contentType=specs_channel.subscribe.message.contentType, - - tags=specs_tags_to_asyncapi(specs_channel.subscribe.message.tags) # type: ignore - if specs_channel.subscribe.message.tags else None, - - externalDocs=specs_external_docs_to_asyncapi(specs_channel.subscribe.message.externalDocs) - if specs_channel.subscribe.message.externalDocs else None, - ), + "SubscribeMessage": message_from_spec(specs_channel.subscribe.message), }, description=specs_channel.description, servers=specs_channel.servers, @@ -274,25 +258,7 @@ def get_broker_channels( channel_v3_0 = Channel( address=channel_name, messages={ - "Message": Message( - title=specs_channel.publish.message.title, - name=specs_channel.publish.message.name, - summary=specs_channel.publish.message.summary, - description=specs_channel.publish.message.description, - messageId=specs_channel.publish.message.messageId, - payload=specs_channel.publish.message.payload, - - correlationId=CorrelationId(**asdict(specs_channel.publish.message.correlationId)) - if specs_channel.publish.message.correlationId else None, - - contentType=specs_channel.publish.message.contentType, - - tags=specs_tags_to_asyncapi(specs_channel.publish.message.tags) # type: ignore - if specs_channel.publish.message.tags else None, - - externalDocs=specs_external_docs_to_asyncapi(specs_channel.publish.message.externalDocs) - if specs_channel.publish.message.externalDocs else None, - ), + "Message": message_from_spec(specs_channel.publish.message), }, description=specs_channel.description, servers=specs_channel.servers, From 7bd26fefd40d5e5980130fe7b2eb323ae3413428 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 16 Aug 2024 10:38:23 +0300 Subject: [PATCH 084/245] Remove unused ServerBinding and more refactoring --- .../specification/asyncapi/v2_6_0/generate.py | 4 +-- .../v2_6_0/schema/bindings/__init__.py | 2 -- .../asyncapi/v2_6_0/schema/bindings/amqp.py | 10 ------ .../asyncapi/v2_6_0/schema/bindings/kafka.py | 33 ++++++++++++------- .../asyncapi/v2_6_0/schema/bindings/main.py | 27 --------------- .../asyncapi/v2_6_0/schema/bindings/nats.py | 10 ------ .../asyncapi/v2_6_0/schema/bindings/redis.py | 10 ------ .../asyncapi/v2_6_0/schema/bindings/sqs.py | 10 ------ .../asyncapi/v2_6_0/schema/servers.py | 2 -- .../asyncapi/v3_0_0/schema/servers.py | 3 -- .../specification/schema/bindings/__init__.py | 2 -- .../specification/schema/bindings/amqp.py | 11 ------- .../specification/schema/bindings/kafka.py | 11 ------- .../specification/schema/bindings/main.py | 20 ----------- .../specification/schema/bindings/nats.py | 11 ------- .../specification/schema/bindings/redis.py | 11 ------- .../specification/schema/bindings/sqs.py | 11 ------- faststream/specification/schema/servers.py | 3 -- 18 files changed, 24 insertions(+), 167 deletions(-) diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index 76463aac95..e07b1181d5 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -252,7 +252,7 @@ def specs_channel_binding_to_asyncapi(binding: spec.bindings.ChannelBinding) -> ) if binding.amqp else None, - kafka=kafka.ChannelBinding(**asdict(binding.kafka)) + kafka=kafka.ChannelBinding.from_spec(binding.kafka) if binding.kafka else None, sqs=sqs.ChannelBinding(**asdict(binding.sqs)) @@ -288,7 +288,7 @@ def specs_operation_binding_to_asyncapi(binding: spec.bindings.OperationBinding) amqp=amqp.OperationBinding(**asdict(binding.amqp)) if binding.amqp else None, - kafka=kafka.OperationBinding(**asdict(binding.kafka)) + kafka=kafka.OperationBinding.from_spec(binding.kafka) if binding.kafka else None, sqs=kafka.OperationBinding(**asdict(binding.sqs)) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/__init__.py index 39ce4b993c..c304608c5b 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/__init__.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/__init__.py @@ -1,11 +1,9 @@ from .main import ( ChannelBinding, OperationBinding, - ServerBinding, ) __all__ = ( - "ServerBinding", "ChannelBinding", "OperationBinding", ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp.py index 8d9ead8dd0..cf9d5bd4d7 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp.py @@ -54,16 +54,6 @@ class Exchange(BaseModel): vhost: str = "/" -class ServerBinding(BaseModel): - """A class to represent a server binding. - - Attributes: - bindingVersion : version of the binding (default: "0.2.0") - """ - - bindingVersion: str = "0.2.0" - - class ChannelBinding(BaseModel): """A class to represent channel binding. diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka.py index 8f54abb0aa..e5e6eb58e3 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka.py @@ -2,20 +2,12 @@ References: https://github.com/asyncapi/bindings/tree/master/kafka """ - +import typing_extensions from typing import Any, Dict, Optional from pydantic import BaseModel, PositiveInt - -class ServerBinding(BaseModel): - """A class to represent a server binding. - - Attributes: - bindingVersion : version of the binding (default: "0.4.0") - """ - - bindingVersion: str = "0.4.0" +from faststream.specification import schema as spec class ChannelBinding(BaseModel): @@ -31,9 +23,19 @@ class ChannelBinding(BaseModel): topic: Optional[str] = None partitions: Optional[PositiveInt] = None replicas: Optional[PositiveInt] = None + bindingVersion: str = "0.4.0" + # TODO: # topicConfiguration - bindingVersion: str = "0.4.0" + + @classmethod + def from_spec(cls, binding: spec.bindings.kafka.ChannelBinding) -> typing_extensions.Self: + return cls( + topic=binding.topic, + partitions=binding.partitions, + replicas=binding.replicas, + bindingVersion=binding.bindingVersion, + ) class OperationBinding(BaseModel): @@ -50,3 +52,12 @@ class OperationBinding(BaseModel): clientId: Optional[Dict[str, Any]] = None replyTo: Optional[Dict[str, Any]] = None bindingVersion: str = "0.4.0" + + @classmethod + def from_spec(cls, binding: spec.bindings.kafka.OperationBinding) -> typing_extensions.Self: + return cls( + groupId=binding.groupId, + clientId=binding.clientId, + replyTo=binding.replyTo, + bindingVersion=binding.bindingVersion, + ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main.py index 4db8877b00..eb57100a32 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main.py @@ -18,33 +18,6 @@ from faststream.specification.asyncapi.v2_6_0.schema.bindings import sqs as sqs_bindings -class ServerBinding(BaseModel): - """A class to represent server bindings. - - Attributes: - amqp : AMQP server binding (optional) - kafka : Kafka server binding (optional) - sqs : SQS server binding (optional) - nats : NATS server binding (optional) - redis : Redis server binding (optional) - - """ - - amqp: Optional[amqp_bindings.ServerBinding] = None - kafka: Optional[kafka_bindings.ServerBinding] = None - sqs: Optional[sqs_bindings.ServerBinding] = None - nats: Optional[nats_bindings.ServerBinding] = None - redis: Optional[redis_bindings.ServerBinding] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" - - class ChannelBinding(BaseModel): """A class to represent channel bindings. diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats.py index 3016c91075..350c3981a2 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats.py @@ -8,16 +8,6 @@ from pydantic import BaseModel -class ServerBinding(BaseModel): - """A class to represent a server binding. - - Attributes: - bindingVersion : version of the binding (default: "custom") - """ - - bindingVersion: str = "custom" - - class ChannelBinding(BaseModel): """A class to represent channel binding. diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis.py index fe82e94d1f..cd639a6c2b 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis.py @@ -8,16 +8,6 @@ from pydantic import BaseModel -class ServerBinding(BaseModel): - """A class to represent a server binding. - - Attributes: - bindingVersion : version of the binding (default: "custom") - """ - - bindingVersion: str = "custom" - - class ChannelBinding(BaseModel): """A class to represent channel binding. diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs.py index 0aba239d8c..242cf19772 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs.py @@ -8,16 +8,6 @@ from pydantic import BaseModel -class ServerBinding(BaseModel): - """A class to represent a server binding. - - Attributes: - bindingVersion : version of the binding (default: "custom") - """ - - bindingVersion: str = "custom" - - class ChannelBinding(BaseModel): """A class to represent channel binding. diff --git a/faststream/specification/asyncapi/v2_6_0/schema/servers.py b/faststream/specification/asyncapi/v2_6_0/schema/servers.py index e694c60246..82e43b9fb2 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/servers.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/servers.py @@ -3,7 +3,6 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.specification.asyncapi.v2_6_0.schema.bindings import ServerBinding from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag from faststream.specification.asyncapi.v2_6_0.schema.utils import Reference @@ -65,7 +64,6 @@ class Server(BaseModel): tags: Optional[List[Union[Tag, Dict[str, Any]]]] = None security: Optional[SecurityRequirement] = None variables: Optional[Dict[str, Union[ServerVariable, Reference]]] = None - bindings: Optional[Union[ServerBinding, Reference]] = None if PYDANTIC_V2: model_config = {"extra": "allow"} diff --git a/faststream/specification/asyncapi/v3_0_0/schema/servers.py b/faststream/specification/asyncapi/v3_0_0/schema/servers.py index 0b12f83445..f3dfaa5a11 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/servers.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/servers.py @@ -4,7 +4,6 @@ from faststream._compat import PYDANTIC_V2 from faststream.specification.asyncapi.v2_6_0.schema import ServerVariable, Tag -from faststream.specification.asyncapi.v2_6_0.schema.bindings import ServerBinding from faststream.specification.asyncapi.v2_6_0.schema.utils import Reference SecurityRequirement = List[Dict[str, List[str]]] @@ -22,7 +21,6 @@ class Server(BaseModel): tags : optional list of tags associated with the server security : optional security requirement for the server variables : optional dictionary of server variables - bindings : optional server binding Note: The attributes `description`, `protocolVersion`, `tags`, `security`, `variables`, and `bindings` are all optional. @@ -41,7 +39,6 @@ class Server(BaseModel): tags: Optional[List[Union[Tag, Dict[str, Any]]]] = None security: Optional[SecurityRequirement] = None variables: Optional[Dict[str, Union[ServerVariable, Reference]]] = None - bindings: Optional[Union[ServerBinding, Reference]] = None if PYDANTIC_V2: model_config = {"extra": "allow"} diff --git a/faststream/specification/schema/bindings/__init__.py b/faststream/specification/schema/bindings/__init__.py index 39ce4b993c..c304608c5b 100644 --- a/faststream/specification/schema/bindings/__init__.py +++ b/faststream/specification/schema/bindings/__init__.py @@ -1,11 +1,9 @@ from .main import ( ChannelBinding, OperationBinding, - ServerBinding, ) __all__ = ( - "ServerBinding", "ChannelBinding", "OperationBinding", ) diff --git a/faststream/specification/schema/bindings/amqp.py b/faststream/specification/schema/bindings/amqp.py index 3702a7c80e..9af5566f51 100644 --- a/faststream/specification/schema/bindings/amqp.py +++ b/faststream/specification/schema/bindings/amqp.py @@ -44,17 +44,6 @@ class Exchange: vhost: str = "/" -@dataclass -class ServerBinding: - """A class to represent a server binding. - - Attributes: - bindingVersion : version of the binding (default: "0.2.0") - """ - - bindingVersion: str = "0.2.0" - - @dataclass class ChannelBinding: """A class to represent channel binding. diff --git a/faststream/specification/schema/bindings/kafka.py b/faststream/specification/schema/bindings/kafka.py index cbef7120e8..957ea31e42 100644 --- a/faststream/specification/schema/bindings/kafka.py +++ b/faststream/specification/schema/bindings/kafka.py @@ -6,17 +6,6 @@ from typing import Any, Dict, Optional -@dataclass -class ServerBinding: - """A class to represent a server binding. - - Attributes: - bindingVersion : version of the binding (default: "0.4.0") - """ - - bindingVersion: str = "0.4.0" - - @dataclass class ChannelBinding: """A class to represent a channel binding. diff --git a/faststream/specification/schema/bindings/main.py b/faststream/specification/schema/bindings/main.py index 9ccfb32714..65622aaa76 100644 --- a/faststream/specification/schema/bindings/main.py +++ b/faststream/specification/schema/bindings/main.py @@ -8,26 +8,6 @@ from faststream.specification.schema.bindings import sqs as sqs_bindings -@dataclass -class ServerBinding: - """A class to represent server bindings. - - Attributes: - amqp : AMQP server binding (optional) - kafka : Kafka server binding (optional) - sqs : SQS server binding (optional) - nats : NATS server binding (optional) - redis : Redis server binding (optional) - - """ - - amqp: Optional[amqp_bindings.ServerBinding] = None - kafka: Optional[kafka_bindings.ServerBinding] = None - sqs: Optional[sqs_bindings.ServerBinding] = None - nats: Optional[nats_bindings.ServerBinding] = None - redis: Optional[redis_bindings.ServerBinding] = None - - @dataclass class ChannelBinding: """A class to represent channel bindings. diff --git a/faststream/specification/schema/bindings/nats.py b/faststream/specification/schema/bindings/nats.py index ee6b40ee5b..8450321bc8 100644 --- a/faststream/specification/schema/bindings/nats.py +++ b/faststream/specification/schema/bindings/nats.py @@ -6,17 +6,6 @@ from typing import Any, Dict, Optional -@dataclass -class ServerBinding: - """A class to represent a server binding. - - Attributes: - bindingVersion : version of the binding (default: "custom") - """ - - bindingVersion: str = "custom" - - @dataclass class ChannelBinding: """A class to represent channel binding. diff --git a/faststream/specification/schema/bindings/redis.py b/faststream/specification/schema/bindings/redis.py index ae3e0922a6..7f96a84440 100644 --- a/faststream/specification/schema/bindings/redis.py +++ b/faststream/specification/schema/bindings/redis.py @@ -6,17 +6,6 @@ from typing import Any, Dict, Optional -@dataclass -class ServerBinding: - """A class to represent a server binding. - - Attributes: - bindingVersion : version of the binding (default: "custom") - """ - - bindingVersion: str = "custom" - - @dataclass class ChannelBinding: """A class to represent channel binding. diff --git a/faststream/specification/schema/bindings/sqs.py b/faststream/specification/schema/bindings/sqs.py index fdc58288bf..bd9b3e150b 100644 --- a/faststream/specification/schema/bindings/sqs.py +++ b/faststream/specification/schema/bindings/sqs.py @@ -6,17 +6,6 @@ from typing import Any, Dict, Optional -@dataclass -class ServerBinding: - """A class to represent a server binding. - - Attributes: - bindingVersion : version of the binding (default: "custom") - """ - - bindingVersion: str = "custom" - - @dataclass class ChannelBinding: """A class to represent channel binding. diff --git a/faststream/specification/schema/servers.py b/faststream/specification/schema/servers.py index 887dde859c..92e87f1ec3 100644 --- a/faststream/specification/schema/servers.py +++ b/faststream/specification/schema/servers.py @@ -3,7 +3,6 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.specification.schema.bindings import ServerBinding from faststream.specification.schema.tag import Tag SecurityRequirement = List[Dict[str, List[str]]] @@ -45,7 +44,6 @@ class Server(BaseModel): tags : optional list of tags associated with the server security : optional security requirement for the server variables : optional dictionary of server variables - bindings : optional server binding Note: The attributes `description`, `protocolVersion`, `tags`, `security`, `variables`, and `bindings` are all optional. @@ -63,7 +61,6 @@ class Server(BaseModel): tags: Optional[List[Union[Tag, Dict[str, Any]]]] = None security: Optional[SecurityRequirement] = None variables: Optional[Dict[str, ServerVariable]] = None - bindings: Optional[ServerBinding] = None if PYDANTIC_V2: model_config = {"extra": "allow"} From 75b1cd369bc1e58160270bc8d356148b2b54b9f3 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 16 Aug 2024 10:56:55 +0300 Subject: [PATCH 085/245] Bindings building from generate.py to schemas methods --- .../specification/asyncapi/v2_6_0/generate.py | 32 ++----------- .../asyncapi/v2_6_0/schema/bindings/amqp.py | 48 +++++++++++++++++++ .../asyncapi/v2_6_0/schema/bindings/kafka.py | 6 +-- .../asyncapi/v2_6_0/schema/bindings/nats.py | 18 +++++++ .../asyncapi/v2_6_0/schema/bindings/redis.py | 20 ++++++++ .../asyncapi/v2_6_0/schema/bindings/sqs.py | 18 +++++++ 6 files changed, 112 insertions(+), 30 deletions(-) diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index e07b1181d5..0d742194ec 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -227,41 +227,19 @@ def specs_channel_to_asyncapi(channel: spec.channel.Channel) -> Channel: def specs_channel_binding_to_asyncapi(binding: spec.bindings.ChannelBinding) -> ChannelBinding: return ChannelBinding( - amqp=amqp.ChannelBinding(**{ - "is": binding.amqp.is_, - "bindingVersion": binding.amqp.bindingVersion, - - "queue": amqp.Queue( - name=binding.amqp.queue.name, - durable=binding.amqp.queue.durable, - exclusive=binding.amqp.queue.exclusive, - autoDelete=binding.amqp.queue.autoDelete, - vhost=binding.amqp.queue.vhost, - ) - if binding.amqp.queue else None, - - "exchange": amqp.Exchange( - name=binding.amqp.exchange.name, - type=binding.amqp.exchange.type, - durable=binding.amqp.exchange.durable, - autoDelete=binding.amqp.exchange.autoDelete, - vhost=binding.amqp.exchange.vhost - ) - if binding.amqp.exchange else None, - } - ) - if binding.amqp else None, + amqp=amqp.ChannelBinding.from_spec(binding.amqp) + if binding.amqp is not None else None, kafka=kafka.ChannelBinding.from_spec(binding.kafka) if binding.kafka else None, - sqs=sqs.ChannelBinding(**asdict(binding.sqs)) + sqs=sqs.ChannelBinding.from_spec(binding.sqs) if binding.sqs else None, - nats=nats.ChannelBinding(**asdict(binding.nats)) + nats=nats.ChannelBinding.from_spec(binding.nats) if binding.nats else None, - redis=redis.ChannelBinding(**asdict(binding.redis)) + redis=redis.ChannelBinding.from_spec(binding.redis) if binding.redis else None, ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp.py index cf9d5bd4d7..6b3f2970dc 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp.py @@ -6,6 +6,9 @@ from typing import Literal, Optional from pydantic import BaseModel, Field, PositiveInt +from typing_extensions import Self + +from faststream.specification import schema as spec class Queue(BaseModel): @@ -25,6 +28,16 @@ class Queue(BaseModel): autoDelete: bool vhost: str = "/" + @classmethod + def from_spec(cls, binding: spec.bindings.amqp.Queue) -> Self: + return cls( + name=binding.name, + durable=binding.durable, + exclusive=binding.exclusive, + autoDelete=binding.autoDelete, + vhost=binding.vhost, + ) + class Exchange(BaseModel): """A class to represent an exchange. @@ -53,6 +66,16 @@ class Exchange(BaseModel): autoDelete: Optional[bool] = None vhost: str = "/" + @classmethod + def from_spec(cls, binding: spec.bindings.amqp.Exchange) -> Self: + return cls( + name=binding.name, + type=binding.type, + durable=binding.durable, + autoDelete=binding.autoDelete, + vhost=binding.vhost, + ) + class ChannelBinding(BaseModel): """A class to represent channel binding. @@ -69,6 +92,19 @@ class ChannelBinding(BaseModel): queue: Optional[Queue] = None exchange: Optional[Exchange] = None + @classmethod + def from_spec(cls, binding: spec.bindings.amqp.ChannelBinding) -> Self: + return cls(**{ + "is": binding.is_, + "bindingVersion": binding.bindingVersion, + + "queue": Queue.from_spec(binding.queue) + if binding.queue is not None else None, + + "exchange": Exchange.from_spec(binding.exchange) + if binding.exchange is not None else None, + }) + class OperationBinding(BaseModel): """A class to represent an operation binding. @@ -87,3 +123,15 @@ class OperationBinding(BaseModel): mandatory: Optional[bool] = None priority: Optional[PositiveInt] = None bindingVersion: str = "0.2.0" + + @classmethod + def from_spec(cls, binding: spec.bindings.amqp.OperationBinding) -> Self: + return cls( + cc=binding.cc, + ack=binding.ack, + replyTo=binding.replyTo, + deliveryMode=binding.deliveryMode, + mandatory=binding.mandatory, + priority=binding.priority, + bindingVersion=binding.bindingVersion, + ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka.py index e5e6eb58e3..3030119339 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka.py @@ -2,10 +2,10 @@ References: https://github.com/asyncapi/bindings/tree/master/kafka """ -import typing_extensions from typing import Any, Dict, Optional from pydantic import BaseModel, PositiveInt +from typing_extensions import Self from faststream.specification import schema as spec @@ -29,7 +29,7 @@ class ChannelBinding(BaseModel): # topicConfiguration @classmethod - def from_spec(cls, binding: spec.bindings.kafka.ChannelBinding) -> typing_extensions.Self: + def from_spec(cls, binding: spec.bindings.kafka.ChannelBinding) -> Self: return cls( topic=binding.topic, partitions=binding.partitions, @@ -54,7 +54,7 @@ class OperationBinding(BaseModel): bindingVersion: str = "0.4.0" @classmethod - def from_spec(cls, binding: spec.bindings.kafka.OperationBinding) -> typing_extensions.Self: + def from_spec(cls, binding: spec.bindings.kafka.OperationBinding) -> Self: return cls( groupId=binding.groupId, clientId=binding.clientId, diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats.py index 350c3981a2..8ff5997c18 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats.py @@ -6,6 +6,9 @@ from typing import Any, Dict, Optional from pydantic import BaseModel +from typing_extensions import Self + +from faststream.specification import schema as spec class ChannelBinding(BaseModel): @@ -21,6 +24,14 @@ class ChannelBinding(BaseModel): queue: Optional[str] = None bindingVersion: str = "custom" + @classmethod + def from_spec(cls, binding: spec.bindings.nats.ChannelBinding) -> Self: + return cls( + subject=binding.subject, + queue=binding.queue, + bindingVersion=binding.bindingVersion, + ) + class OperationBinding(BaseModel): """A class to represent an operation binding. @@ -32,3 +43,10 @@ class OperationBinding(BaseModel): replyTo: Optional[Dict[str, Any]] = None bindingVersion: str = "custom" + + @classmethod + def from_spec(cls, binding: spec.bindings.nats.OperationBinding) -> Self: + return cls( + replyTo=binding.replyTo, + bindingVersion=binding.bindingVersion, + ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis.py index cd639a6c2b..db82795099 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis.py @@ -6,6 +6,9 @@ from typing import Any, Dict, Optional from pydantic import BaseModel +from typing_extensions import Self + +from faststream.specification import schema as spec class ChannelBinding(BaseModel): @@ -23,6 +26,16 @@ class ChannelBinding(BaseModel): consumer_name: Optional[str] = None bindingVersion: str = "custom" + @classmethod + def from_spec(cls, binding: spec.bindings.redis.ChannelBinding) -> Self: + return cls( + channel=binding.channel, + method=binding.method, + group_name=binding.group_name, + consumer_name=binding.consumer_name, + bindingVersion=binding.bindingVersion, + ) + class OperationBinding(BaseModel): """A class to represent an operation binding. @@ -34,3 +47,10 @@ class OperationBinding(BaseModel): replyTo: Optional[Dict[str, Any]] = None bindingVersion: str = "custom" + + @classmethod + def from_spec(cls, binding: spec.bindings.redis.OperationBinding) -> Self: + return cls( + replyTo=binding.replyTo, + bindingVersion=binding.bindingVersion, + ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs.py index 242cf19772..dcc8ad4816 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs.py @@ -6,6 +6,9 @@ from typing import Any, Dict, Optional from pydantic import BaseModel +from typing_extensions import Self + +from faststream.specification import schema as spec class ChannelBinding(BaseModel): @@ -19,6 +22,13 @@ class ChannelBinding(BaseModel): queue: Dict[str, Any] bindingVersion: str = "custom" + @classmethod + def from_spec(cls, binding: spec.bindings.sqs.ChannelBinding) -> Self: + return cls( + queue=binding.queue, + bindingVersion=binding.bindingVersion, + ) + class OperationBinding(BaseModel): """A class to represent an operation binding. @@ -30,3 +40,11 @@ class OperationBinding(BaseModel): replyTo: Optional[Dict[str, Any]] = None bindingVersion: str = "custom" + + @classmethod + def from_spec(cls, binding: spec.bindings.sqs.OperationBinding) -> Self: + return cls( + replyTo=binding.replyTo, + bindingVersion=binding.bindingVersion, + ) + From 954f677a3a4e824c85dc3288ad8a253ed23e1c01 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 16 Aug 2024 12:02:06 +0300 Subject: [PATCH 086/245] AsyncAPI 2.6.0 general ChannelBinding building refactoring --- .../specification/asyncapi/v2_6_0/generate.py | 24 +------------------ .../asyncapi/v2_6_0/schema/bindings/main.py | 21 ++++++++++++++++ .../specification/asyncapi/v3_0_0/generate.py | 6 ++--- 3 files changed, 25 insertions(+), 26 deletions(-) diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index 0d742194ec..f94b1bffad 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -21,9 +21,6 @@ OperationBinding, amqp, kafka, - nats, - redis, - sqs, ) from faststream.specification.asyncapi.v2_6_0.schema.docs import ( from_spec as docs_from_spec, @@ -214,7 +211,7 @@ def specs_channel_to_asyncapi(channel: spec.channel.Channel) -> Channel: description=channel.description, servers=channel.servers, - bindings=specs_channel_binding_to_asyncapi(channel.bindings) + bindings=ChannelBinding.from_spec(channel.bindings) if channel.bindings else None, subscribe=specs_operation_to_asyncapi(channel.subscribe) @@ -225,25 +222,6 @@ def specs_channel_to_asyncapi(channel: spec.channel.Channel) -> Channel: ) -def specs_channel_binding_to_asyncapi(binding: spec.bindings.ChannelBinding) -> ChannelBinding: - return ChannelBinding( - amqp=amqp.ChannelBinding.from_spec(binding.amqp) - if binding.amqp is not None else None, - - kafka=kafka.ChannelBinding.from_spec(binding.kafka) - if binding.kafka else None, - - sqs=sqs.ChannelBinding.from_spec(binding.sqs) - if binding.sqs else None, - - nats=nats.ChannelBinding.from_spec(binding.nats) - if binding.nats else None, - - redis=redis.ChannelBinding.from_spec(binding.redis) - if binding.redis else None, - ) - - def specs_operation_to_asyncapi(operation: spec.operation.Operation) -> Operation: return Operation( operationId=operation.operationId, diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main.py index eb57100a32..49367905cf 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main.py @@ -1,8 +1,10 @@ from typing import Optional from pydantic import BaseModel +from typing_extensions import Self from faststream._compat import PYDANTIC_V2 +from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( amqp as amqp_bindings, ) @@ -44,6 +46,25 @@ class ChannelBinding(BaseModel): class Config: extra = "allow" + @classmethod + def from_spec(cls, binding: spec.bindings.ChannelBinding) -> Self: + return cls( + amqp=amqp_bindings.ChannelBinding.from_spec(binding.amqp) + if binding.amqp is not None else None, + + kafka=kafka_bindings.ChannelBinding.from_spec(binding.kafka) + if binding.kafka is not None else None, + + sqs=sqs_bindings.ChannelBinding.from_spec(binding.sqs) + if binding.sqs is not None else None, + + nats=nats_bindings.ChannelBinding.from_spec(binding.nats) + if binding.nats is not None else None, + + redis=redis_bindings.ChannelBinding.from_spec(binding.redis) + if binding.redis is not None else None, + ) + class OperationBinding(BaseModel): """A class to represent an operation binding. diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index f0a9b7ddf4..12457f2909 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -6,7 +6,6 @@ from faststream.constants import ContentTypes from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.generate import ( - specs_channel_binding_to_asyncapi, specs_contact_to_asyncapi, specs_license_to_asyncapi, specs_operation_binding_to_asyncapi, @@ -16,6 +15,7 @@ Reference, Tag, ) +from faststream.specification.asyncapi.v2_6_0.schema.bindings import ChannelBinding from faststream.specification.asyncapi.v2_6_0.schema.message import ( Message, ) @@ -243,7 +243,7 @@ def get_broker_channels( }, description=specs_channel.description, servers=specs_channel.servers, - bindings=specs_channel_binding_to_asyncapi(specs_channel.bindings) + bindings=ChannelBinding.from_spec(specs_channel.bindings) if specs_channel.bindings else None, ) @@ -262,7 +262,7 @@ def get_broker_channels( }, description=specs_channel.description, servers=specs_channel.servers, - bindings=specs_channel_binding_to_asyncapi(specs_channel.bindings) + bindings=ChannelBinding.from_spec(specs_channel.bindings) if specs_channel.bindings else None, ) From d57297bbb8b58256a60218195b6ef3913227be07 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 16 Aug 2024 12:05:42 +0300 Subject: [PATCH 087/245] AsyncAPI 2.6.0 general OperationBinding building refactoring --- .../specification/asyncapi/v2_6_0/generate.py | 38 +++++++++---------- .../asyncapi/v2_6_0/schema/bindings/main.py | 19 ++++++++++ .../specification/asyncapi/v3_0_0/generate.py | 10 +++-- 3 files changed, 43 insertions(+), 24 deletions(-) diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index f94b1bffad..e2d6905e38 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -19,8 +19,6 @@ from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( ChannelBinding, OperationBinding, - amqp, - kafka, ) from faststream.specification.asyncapi.v2_6_0.schema.docs import ( from_spec as docs_from_spec, @@ -228,7 +226,7 @@ def specs_operation_to_asyncapi(operation: spec.operation.Operation) -> Operatio summary=operation.summary, description=operation.description, - bindings=specs_operation_binding_to_asyncapi(operation.bindings) + bindings=OperationBinding.from_spec(operation.bindings) if operation.bindings else None, message=message_from_spec(operation.message), @@ -239,23 +237,23 @@ def specs_operation_to_asyncapi(operation: spec.operation.Operation) -> Operatio ) -def specs_operation_binding_to_asyncapi(binding: spec.bindings.OperationBinding) -> OperationBinding: - return OperationBinding( - amqp=amqp.OperationBinding(**asdict(binding.amqp)) - if binding.amqp else None, - - kafka=kafka.OperationBinding.from_spec(binding.kafka) - if binding.kafka else None, - - sqs=kafka.OperationBinding(**asdict(binding.sqs)) - if binding.sqs else None, - - nats=kafka.OperationBinding(**asdict(binding.nats)) - if binding.nats else None, - - redis=kafka.OperationBinding(**asdict(binding.redis)) - if binding.redis else None, - ) +# def specs_operation_binding_to_asyncapi(binding: spec.bindings.OperationBinding) -> OperationBinding: +# return OperationBinding( +# amqp=amqp.OperationBinding(**asdict(binding.amqp)) +# if binding.amqp else None, +# +# kafka=kafka.OperationBinding.from_spec(binding.kafka) +# if binding.kafka else None, +# +# sqs=kafka.OperationBinding(**asdict(binding.sqs)) +# if binding.sqs else None, +# +# nats=kafka.OperationBinding(**asdict(binding.nats)) +# if binding.nats else None, +# +# redis=kafka.OperationBinding(**asdict(binding.redis)) +# if binding.redis else None, +# ) def _resolve_msg_payloads( diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main.py index 49367905cf..6f63c57604 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main.py @@ -91,3 +91,22 @@ class OperationBinding(BaseModel): class Config: extra = "allow" + + @classmethod + def from_spec(cls, binding: spec.bindings.OperationBinding) -> Self: + return cls( + amqp=amqp_bindings.OperationBinding.from_spec(binding.amqp) + if binding.amqp is not None else None, + + kafka=kafka_bindings.OperationBinding.from_spec(binding.kafka) + if binding.kafka is not None else None, + + sqs=sqs_bindings.OperationBinding.from_spec(binding.sqs) + if binding.sqs is not None else None, + + nats=nats_bindings.OperationBinding.from_spec(binding.nats) + if binding.nats is not None else None, + + redis=redis_bindings.OperationBinding.from_spec(binding.redis) + if binding.redis is not None else None, + ) diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index 12457f2909..4943adf28b 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -8,14 +8,16 @@ from faststream.specification.asyncapi.v2_6_0.generate import ( specs_contact_to_asyncapi, specs_license_to_asyncapi, - specs_operation_binding_to_asyncapi, ) from faststream.specification.asyncapi.v2_6_0.schema import ( ExternalDocs, Reference, Tag, ) -from faststream.specification.asyncapi.v2_6_0.schema.bindings import ChannelBinding +from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( + ChannelBinding, + OperationBinding, +) from faststream.specification.asyncapi.v2_6_0.schema.message import ( Message, ) @@ -188,7 +190,7 @@ def get_broker_operations( action="receive", summary=specs_channel.subscribe.summary, description=specs_channel.subscribe.description, - bindings=specs_operation_binding_to_asyncapi(specs_channel.subscribe.bindings) + bindings=OperationBinding.from_spec(specs_channel.subscribe.bindings) if specs_channel.subscribe.bindings else None, messages=[ Reference( @@ -209,7 +211,7 @@ def get_broker_operations( action="send", summary=specs_channel.publish.summary, description=specs_channel.publish.description, - bindings=specs_operation_binding_to_asyncapi(specs_channel.publish.bindings) + bindings=OperationBinding.from_spec(specs_channel.publish.bindings) if specs_channel.publish.bindings else None, messages=[ Reference( From 2f4d22093e4b51483cde25a623919e27540fb648 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 16 Aug 2024 12:06:00 +0300 Subject: [PATCH 088/245] Remove commented code --- .../specification/asyncapi/v2_6_0/generate.py | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index e2d6905e38..5b6f660ddc 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -237,25 +237,6 @@ def specs_operation_to_asyncapi(operation: spec.operation.Operation) -> Operatio ) -# def specs_operation_binding_to_asyncapi(binding: spec.bindings.OperationBinding) -> OperationBinding: -# return OperationBinding( -# amqp=amqp.OperationBinding(**asdict(binding.amqp)) -# if binding.amqp else None, -# -# kafka=kafka.OperationBinding.from_spec(binding.kafka) -# if binding.kafka else None, -# -# sqs=kafka.OperationBinding(**asdict(binding.sqs)) -# if binding.sqs else None, -# -# nats=kafka.OperationBinding(**asdict(binding.nats)) -# if binding.nats else None, -# -# redis=kafka.OperationBinding(**asdict(binding.redis)) -# if binding.redis else None, -# ) - - def _resolve_msg_payloads( m: Message, channel_name: str, From a3393d8ca4eb89c700c80748a34954e0f9d920df Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 16 Aug 2024 12:23:29 +0300 Subject: [PATCH 089/245] AsyncAPI license generation refactoring + little things --- faststream/specification/asyncapi/message.py | 19 +++--- .../specification/asyncapi/v2_6_0/generate.py | 28 ++++---- .../asyncapi/v2_6_0/schema/bindings/kafka.py | 9 +-- .../asyncapi/v2_6_0/schema/bindings/nats.py | 5 +- .../asyncapi/v2_6_0/schema/bindings/redis.py | 5 +- .../asyncapi/v2_6_0/schema/bindings/sqs.py | 7 +- .../asyncapi/v2_6_0/schema/channels.py | 1 - .../asyncapi/v2_6_0/schema/components.py | 6 +- .../asyncapi/v2_6_0/schema/docs.py | 15 +++-- .../asyncapi/v2_6_0/schema/info.py | 6 +- .../asyncapi/v2_6_0/schema/license.py | 66 +++++++++++++++++++ .../asyncapi/v2_6_0/schema/message.py | 7 +- .../asyncapi/v2_6_0/schema/operations.py | 5 +- .../asyncapi/v2_6_0/schema/schema.py | 5 +- .../asyncapi/v2_6_0/schema/servers.py | 5 +- .../asyncapi/v2_6_0/schema/tag.py | 11 ++-- .../specification/asyncapi/v3_0_0/generate.py | 23 ++++--- .../asyncapi/v3_0_0/schema/components.py | 7 +- .../asyncapi/v3_0_0/schema/info.py | 8 +-- .../asyncapi/v3_0_0/schema/operations.py | 5 +- .../asyncapi/v3_0_0/schema/servers.py | 5 +- 21 files changed, 161 insertions(+), 87 deletions(-) create mode 100644 faststream/specification/asyncapi/v2_6_0/schema/license.py diff --git a/faststream/specification/asyncapi/message.py b/faststream/specification/asyncapi/message.py index b37415dedc..a1ae7cb5d5 100644 --- a/faststream/specification/asyncapi/message.py +++ b/faststream/specification/asyncapi/message.py @@ -1,9 +1,10 @@ from inspect import isclass -from typing import TYPE_CHECKING, Any, Dict, Optional, Sequence, Type, overload +from typing import TYPE_CHECKING, Any, Optional, Sequence, Type, overload from pydantic import BaseModel, create_model from faststream._compat import DEF_KEY, PYDANTIC_V2, get_model_fields, model_schema +from faststream.types import AnyDict if TYPE_CHECKING: from fast_depends.core import CallModel @@ -11,7 +12,7 @@ def parse_handler_params( call: "CallModel[Any, Any]", prefix: str = "" -) -> Dict[str, Any]: +) -> AnyDict: """Parses the handler parameters.""" model = call.model assert model # nosec B101 @@ -38,13 +39,13 @@ def get_response_schema(call: None, prefix: str = "") -> None: ... @overload def get_response_schema( call: "CallModel[Any, Any]", prefix: str = "" -) -> Dict[str, Any]: ... +) -> AnyDict: ... def get_response_schema( call: Optional["CallModel[Any, Any]"], prefix: str = "", -) -> Optional[Dict[str, Any]]: +) -> Optional[AnyDict]: """Get the response schema for a given call.""" return get_model_schema( getattr( @@ -67,14 +68,14 @@ def get_model_schema( call: Type[BaseModel], prefix: str = "", exclude: Sequence[str] = (), -) -> Dict[str, Any]: ... +) -> AnyDict: ... def get_model_schema( call: Optional[Type[BaseModel]], prefix: str = "", exclude: Sequence[str] = (), -) -> Optional[Dict[str, Any]]: +) -> Optional[AnyDict]: """Get the schema of a model.""" if call is None: return None @@ -100,7 +101,7 @@ def get_model_schema( if model is None: model = call - body: Dict[str, Any] = model_schema(model) + body: AnyDict = model_schema(model) body["properties"] = body.get("properties", {}) for i in exclude: body["properties"].pop(i, None) @@ -108,13 +109,13 @@ def get_model_schema( body["required"] = list(filter(lambda x: x not in exclude, required)) if params_number == 1 and not use_original_model: - param_body: Dict[str, Any] = body.get("properties", {}) + param_body: AnyDict = body.get("properties", {}) param_body = param_body[name] if defs := body.get(DEF_KEY): # single argument with useless reference if param_body.get("$ref"): - ref_obj: Dict[str, Any] = next(iter(defs.values())) + ref_obj: AnyDict = next(iter(defs.values())) return ref_obj else: param_body[DEF_KEY] = defs diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index 5b6f660ddc..2d34400bed 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -9,7 +9,6 @@ Components, Contact, Info, - License, Operation, Reference, Schema, @@ -23,6 +22,9 @@ from faststream.specification.asyncapi.v2_6_0.schema.docs import ( from_spec as docs_from_spec, ) +from faststream.specification.asyncapi.v2_6_0.schema.license import ( + from_spec as license_from_spec, +) from faststream.specification.asyncapi.v2_6_0.schema.message import ( Message, ) @@ -34,10 +36,11 @@ ) from faststream.specification.proto import Application +from faststream.types import AnyDict + if TYPE_CHECKING: from faststream.broker.core.usecase import BrokerUsecase from faststream.broker.types import ConnectionType, MsgType - from faststream.types import AnyDict def get_app_schema(app: Application) -> Schema: @@ -51,7 +54,7 @@ def get_app_schema(app: Application) -> Schema: channels = get_broker_channels(broker) messages: Dict[str, Message] = {} - payloads: Dict[str, Dict[str, Any]] = {} + payloads: Dict[str, AnyDict] = {} for channel_name, ch in channels.items(): ch.servers = list(servers.keys()) @@ -85,7 +88,7 @@ def get_app_schema(app: Application) -> Schema: termsOfService=app.terms_of_service, contact=specs_contact_to_asyncapi(app.contact) if app.contact else None, - license=specs_license_to_asyncapi(app.license) + license=license_from_spec(app.license) if app.license else None, ), defaultContentType=ContentTypes.json.value, @@ -116,7 +119,7 @@ def get_broker_server( """Get the broker server for an application.""" servers = {} - tags: List[Union[Tag, Dict[str, Any]]] = [] + tags: List[Union[Tag, AnyDict]] = [] if broker.tags: for tag in broker.tags: @@ -127,7 +130,7 @@ def get_broker_server( else: raise NotImplementedError(f"Unsupported tag type: {tag}; {type(tag)}") - broker_meta: Dict[str, Any] = { + broker_meta: AnyDict = { "protocol": broker.protocol, "protocolVersion": broker.protocol_version, "description": broker.description, @@ -194,15 +197,6 @@ def specs_contact_to_asyncapi( return dict(contact) -def specs_license_to_asyncapi( - license: Union["spec.license.License", "spec.license.LicenseDict", "AnyDict"] -) -> Union["License", "AnyDict"]: - if isinstance(license, spec.license.License): - return License(**license.dict()) - - return dict(license) - - def specs_channel_to_asyncapi(channel: spec.channel.Channel) -> Channel: return Channel( @@ -240,8 +234,8 @@ def specs_operation_to_asyncapi(operation: spec.operation.Operation) -> Operatio def _resolve_msg_payloads( m: Message, channel_name: str, - payloads: Dict[str, Any], - messages: Dict[str, Any], + payloads: AnyDict, + messages: AnyDict, ) -> Reference: """Replace message payload by reference and normalize payloads. diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka.py index 3030119339..766fa773ce 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka.py @@ -2,12 +2,13 @@ References: https://github.com/asyncapi/bindings/tree/master/kafka """ -from typing import Any, Dict, Optional +from typing import Optional from pydantic import BaseModel, PositiveInt from typing_extensions import Self from faststream.specification import schema as spec +from faststream.types import AnyDict class ChannelBinding(BaseModel): @@ -48,9 +49,9 @@ class OperationBinding(BaseModel): bindingVersion : version of the binding (default: "0.4.0") """ - groupId: Optional[Dict[str, Any]] = None - clientId: Optional[Dict[str, Any]] = None - replyTo: Optional[Dict[str, Any]] = None + groupId: Optional[AnyDict] = None + clientId: Optional[AnyDict] = None + replyTo: Optional[AnyDict] = None bindingVersion: str = "0.4.0" @classmethod diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats.py index 8ff5997c18..e380e26911 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats.py @@ -3,12 +3,13 @@ References: https://github.com/asyncapi/bindings/tree/master/nats """ -from typing import Any, Dict, Optional +from typing import Optional from pydantic import BaseModel from typing_extensions import Self from faststream.specification import schema as spec +from faststream.types import AnyDict class ChannelBinding(BaseModel): @@ -41,7 +42,7 @@ class OperationBinding(BaseModel): bindingVersion : version of the binding (default is "custom") """ - replyTo: Optional[Dict[str, Any]] = None + replyTo: Optional[AnyDict] = None bindingVersion: str = "custom" @classmethod diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis.py index db82795099..bcafadb791 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis.py @@ -3,12 +3,13 @@ References: https://github.com/asyncapi/bindings/tree/master/redis """ -from typing import Any, Dict, Optional +from typing import Optional from pydantic import BaseModel from typing_extensions import Self from faststream.specification import schema as spec +from faststream.types import AnyDict class ChannelBinding(BaseModel): @@ -45,7 +46,7 @@ class OperationBinding(BaseModel): bindingVersion : version of the binding (default is "custom") """ - replyTo: Optional[Dict[str, Any]] = None + replyTo: Optional[AnyDict] = None bindingVersion: str = "custom" @classmethod diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs.py index dcc8ad4816..81562726f6 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs.py @@ -3,12 +3,13 @@ References: https://github.com/asyncapi/bindings/tree/master/sqs """ -from typing import Any, Dict, Optional +from typing import Optional from pydantic import BaseModel from typing_extensions import Self from faststream.specification import schema as spec +from faststream.types import AnyDict class ChannelBinding(BaseModel): @@ -19,7 +20,7 @@ class ChannelBinding(BaseModel): bindingVersion : a string representing the binding version (default: "custom") """ - queue: Dict[str, Any] + queue: AnyDict bindingVersion: str = "custom" @classmethod @@ -38,7 +39,7 @@ class OperationBinding(BaseModel): bindingVersion : version of the binding, default is "custom" """ - replyTo: Optional[Dict[str, Any]] = None + replyTo: Optional[AnyDict] = None bindingVersion: str = "custom" @classmethod diff --git a/faststream/specification/asyncapi/v2_6_0/schema/channels.py b/faststream/specification/asyncapi/v2_6_0/schema/channels.py index 4521837c96..aca3cb90bf 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/channels.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/channels.py @@ -16,7 +16,6 @@ class Channel(BaseModel): bindings : optional channel binding subscribe : optional operation for subscribing to the channel publish : optional operation for publishing to the channel - parameters : optional parameters associated with the channel Configurations: model_config : configuration for the model (only applicable for Pydantic version 2) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/components.py b/faststream/specification/asyncapi/v2_6_0/schema/components.py index c26f3f8437..ea8840e16b 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/components.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/components.py @@ -1,5 +1,4 @@ from typing import ( - Any, Dict, Optional, ) @@ -10,6 +9,7 @@ PYDANTIC_V2, ) from faststream.specification.asyncapi.v2_6_0.schema.message import Message +from faststream.types import AnyDict class Components(BaseModel): @@ -41,8 +41,8 @@ class Components(BaseModel): """ messages: Optional[Dict[str, Message]] = None - schemas: Optional[Dict[str, Dict[str, Any]]] = None - securitySchemes: Optional[Dict[str, Dict[str, Any]]] = None + schemas: Optional[Dict[str, AnyDict]] = None + securitySchemes: Optional[Dict[str, AnyDict]] = None if PYDANTIC_V2: model_config = {"extra": "allow"} diff --git a/faststream/specification/asyncapi/v2_6_0/schema/docs.py b/faststream/specification/asyncapi/v2_6_0/schema/docs.py index a50991874a..82d23191e7 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/docs.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/docs.py @@ -1,10 +1,11 @@ -from typing import Any, Dict, Optional, Union, overload +from typing import Optional, Union, overload -import typing_extensions from pydantic import AnyHttpUrl, BaseModel +from typing_extensions import Self from faststream._compat import PYDANTIC_V2 from faststream.specification import schema as spec +from faststream.types import AnyDict class ExternalDocs(BaseModel): @@ -28,7 +29,7 @@ class Config: extra = "allow" @classmethod - def from_spec(cls, docs: spec.docs.ExternalDocs) -> typing_extensions.Self: + def from_spec(cls, docs: spec.docs.ExternalDocs) -> Self: return cls( url=docs.url, description=docs.description @@ -40,16 +41,16 @@ def from_spec(docs: spec.docs.ExternalDocs) -> ExternalDocs: ... @overload -def from_spec(docs: spec.docs.ExternalDocsDict) -> Dict[str, Any]: ... +def from_spec(docs: spec.docs.ExternalDocsDict) -> AnyDict: ... @overload -def from_spec(docs: Dict[str, Any]) -> Dict[str, Any]: ... +def from_spec(docs: AnyDict) -> AnyDict: ... def from_spec( - docs: Union[spec.docs.ExternalDocs, spec.docs.ExternalDocsDict, Dict[str, Any]] -) -> Union[ExternalDocs, Dict[str, Any]]: + docs: Union[spec.docs.ExternalDocs, spec.docs.ExternalDocsDict, AnyDict] +) -> Union[ExternalDocs, AnyDict]: if isinstance(docs, spec.docs.ExternalDocs): return ExternalDocs.from_spec(docs) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/info.py b/faststream/specification/asyncapi/v2_6_0/schema/info.py index bb03694c8d..b6c8b94f7d 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/info.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/info.py @@ -1,7 +1,6 @@ from typing import ( Any, Callable, - Dict, Iterable, Optional, Type, @@ -20,6 +19,7 @@ ) from faststream.log import logger from faststream.specification.asyncapi.base.schema import BaseInfo +from faststream.types import AnyDict try: import email_validator @@ -179,5 +179,5 @@ class Info(BaseInfo): """ termsOfService: Optional[AnyHttpUrl] = None - contact: Optional[Union[Contact, ContactDict, Dict[str, Any]]] = None - license: Optional[Union[License, LicenseDict, Dict[str, Any]]] = None + contact: Optional[Union[Contact, ContactDict, AnyDict]] = None + license: Optional[Union[License, LicenseDict, AnyDict]] = None diff --git a/faststream/specification/asyncapi/v2_6_0/schema/license.py b/faststream/specification/asyncapi/v2_6_0/schema/license.py new file mode 100644 index 0000000000..d5fbc3756d --- /dev/null +++ b/faststream/specification/asyncapi/v2_6_0/schema/license.py @@ -0,0 +1,66 @@ +from typing import ( + Optional, + Union, + overload, +) + +from pydantic import AnyHttpUrl, BaseModel +from typing_extensions import Self + +from faststream._compat import ( + PYDANTIC_V2, +) +from faststream.specification import schema as spec +from faststream.types import AnyDict + + +class License(BaseModel): + """A class to represent a license. + + Attributes: + name : name of the license + url : URL of the license (optional) + + Config: + extra : allow additional attributes in the model (PYDANTIC_V2) + + """ + + name: str + url: Optional[AnyHttpUrl] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" + + @classmethod + def from_spec(cls, license: spec.license.License) -> Self: + return cls( + name=license.name, + url=license.url, + ) + + +@overload +def from_spec(license: spec.license.License) -> License: ... + + +@overload +def from_spec(license: spec.license.LicenseDict) -> AnyDict: ... + + +@overload +def from_spec(license: AnyDict) -> AnyDict: ... + + +def from_spec( + license: Union[spec.license.License, spec.license.LicenseDict, AnyDict] +) -> Union[License, AnyDict]: + if isinstance(license, spec.license.License): + return License.from_spec(license) + + return dict(license) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/message.py b/faststream/specification/asyncapi/v2_6_0/schema/message.py index 1fc625bc03..4523bf3091 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/message.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/message.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, List, Optional, Union +from typing import List, Optional, Union import typing_extensions from pydantic import BaseModel @@ -9,6 +9,7 @@ from faststream.specification.asyncapi.v2_6_0.schema.tag import ( from_spec as tag_from_spec, ) +from faststream.types import AnyDict class CorrelationId(BaseModel): @@ -66,7 +67,7 @@ class Message(BaseModel): correlationId: Optional[CorrelationId] = None contentType: Optional[str] = None - payload: Dict[str, Any] + payload: AnyDict # TODO: # headers # schemaFormat @@ -74,7 +75,7 @@ class Message(BaseModel): # examples # traits - tags: Optional[List[Union[Tag, Dict[str, Any]]]] = ( + tags: Optional[List[Union[Tag, AnyDict]]] = ( None ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/operations.py b/faststream/specification/asyncapi/v2_6_0/schema/operations.py index b77642a28b..f19a9809a8 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/operations.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/operations.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, List, Optional, Union +from typing import Dict, List, Optional, Union from pydantic import BaseModel @@ -9,6 +9,7 @@ from faststream.specification.asyncapi.v2_6_0.schema.utils import ( Reference, ) +from faststream.types import AnyDict class Operation(BaseModel): @@ -38,7 +39,7 @@ class Operation(BaseModel): # TODO # traits - tags: Optional[List[Union[Tag, Dict[str, Any]]]] = None + tags: Optional[List[Union[Tag, AnyDict]]] = None if PYDANTIC_V2: model_config = {"extra": "allow"} diff --git a/faststream/specification/asyncapi/v2_6_0/schema/schema.py b/faststream/specification/asyncapi/v2_6_0/schema/schema.py index a19a92b359..83df8f7929 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/schema.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/schema.py @@ -9,6 +9,7 @@ from faststream.specification.asyncapi.v2_6_0.schema.servers import Server from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag from faststream.specification.asyncapi.version import AsyncAPIVersion +from faststream.types import AnyDict class Schema(BaseSchema): @@ -39,8 +40,8 @@ class Schema(BaseSchema): servers: Optional[Dict[str, Server]] = None channels: Dict[str, Channel] components: Optional[Components] = None - tags: Optional[List[Union[Tag, Dict[str, Any]]]] = None - externalDocs: Optional[Union[ExternalDocs, Dict[str, Any]]] = None + tags: Optional[List[Union[Tag, AnyDict]]] = None + externalDocs: Optional[Union[ExternalDocs, AnyDict]] = None def to_jsonable(self) -> Any: """Convert the schema to a JSON-serializable object.""" diff --git a/faststream/specification/asyncapi/v2_6_0/schema/servers.py b/faststream/specification/asyncapi/v2_6_0/schema/servers.py index 82e43b9fb2..daca856bc1 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/servers.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/servers.py @@ -1,10 +1,11 @@ -from typing import Any, Dict, List, Optional, Union +from typing import Dict, List, Optional, Union from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag from faststream.specification.asyncapi.v2_6_0.schema.utils import Reference +from faststream.types import AnyDict SecurityRequirement = List[Dict[str, List[str]]] @@ -61,7 +62,7 @@ class Server(BaseModel): protocol: str description: Optional[str] = None protocolVersion: Optional[str] = None - tags: Optional[List[Union[Tag, Dict[str, Any]]]] = None + tags: Optional[List[Union[Tag, AnyDict]]] = None security: Optional[SecurityRequirement] = None variables: Optional[Dict[str, Union[ServerVariable, Reference]]] = None diff --git a/faststream/specification/asyncapi/v2_6_0/schema/tag.py b/faststream/specification/asyncapi/v2_6_0/schema/tag.py index 30ffe5c3fd..6f3490973f 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/tag.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/tag.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, Optional, Union, overload +from typing import Optional, Union, overload import typing_extensions from pydantic import BaseModel @@ -11,6 +11,7 @@ from faststream.specification.asyncapi.v2_6_0.schema.docs import ( from_spec as docs_from_spec, ) +from faststream.types import AnyDict class Tag(BaseModel): @@ -50,16 +51,16 @@ def from_spec(tag: spec.tag.Tag) -> Tag: ... @overload -def from_spec(tag: spec.tag.TagDict) -> Dict[str, Any]: ... +def from_spec(tag: spec.tag.TagDict) -> AnyDict: ... @overload -def from_spec(tag: Dict[str, Any]) -> Dict[str, Any]: ... +def from_spec(tag: AnyDict) -> AnyDict: ... def from_spec( - tag: Union[spec.tag.Tag, spec.tag.TagDict, Dict[str, Any]] -) -> Union[Tag, Dict[str, Any]]: + tag: Union[spec.tag.Tag, spec.tag.TagDict, AnyDict] +) -> Union[Tag, AnyDict]: if isinstance(tag, spec.tag.Tag): return Tag.from_spec(tag) diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index 4943adf28b..4dfca42789 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -7,7 +7,6 @@ from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.generate import ( specs_contact_to_asyncapi, - specs_license_to_asyncapi, ) from faststream.specification.asyncapi.v2_6_0.schema import ( ExternalDocs, @@ -18,6 +17,9 @@ ChannelBinding, OperationBinding, ) +from faststream.specification.asyncapi.v2_6_0.schema.license import ( + from_spec as license_from_spec, +) from faststream.specification.asyncapi.v2_6_0.schema.message import ( Message, ) @@ -36,6 +38,7 @@ Server, ) from faststream.specification.proto import Application +from faststream.types import AnyDict if TYPE_CHECKING: from faststream.broker.core.usecase import BrokerUsecase @@ -54,7 +57,7 @@ def get_app_schema(app: Application) -> Schema: operations = get_broker_operations(broker) messages: Dict[str, Message] = {} - payloads: Dict[str, Dict[str, Any]] = {} + payloads: Dict[str, AnyDict] = {} for channel_name, channel in channels.items(): msgs: Dict[str, Union[Message, Reference]] = {} @@ -83,7 +86,7 @@ def get_app_schema(app: Application) -> Schema: contact=specs_contact_to_asyncapi(app.contact) if app.contact else None, - license=specs_license_to_asyncapi(app.license) + license=license_from_spec(app.license) if app.license else None, tags=[tag_from_spec(tag) for tag in app.specs_tags] @@ -114,7 +117,7 @@ def get_broker_server( """Get the broker server for an application.""" servers = {} - tags: List[Union[Tag, Dict[str, Any]]] = [] + tags: List[Union[Tag, AnyDict]] = [] if broker.tags: for tag in broker.tags: @@ -125,7 +128,7 @@ def get_broker_server( else: raise NotImplementedError(f"Unsupported tag type: {tag}; {type(tag)}") - broker_meta: Dict[str, Any] = { + broker_meta: AnyDict = { "protocol": broker.protocol, "protocolVersion": broker.protocol_version, "description": broker.description, @@ -276,8 +279,8 @@ def get_broker_channels( def specs_external_docs_to_asyncapi( - externalDocs: Union[spec.docs.ExternalDocs, spec.docs.ExternalDocsDict, Dict[str, Any]] -) -> Union[ExternalDocs, Dict[str, Any]]: + externalDocs: Union[spec.docs.ExternalDocs, spec.docs.ExternalDocsDict, AnyDict] +) -> Union[ExternalDocs, AnyDict]: if isinstance(externalDocs, spec.docs.ExternalDocs): return ExternalDocs( **asdict(externalDocs) @@ -290,8 +293,8 @@ def _resolve_msg_payloads( message_name: str, m: Message, channel_name: str, - payloads: Dict[str, Any], - messages: Dict[str, Any], + payloads: AnyDict, + messages: AnyDict, ) -> Reference: assert isinstance(m.payload, dict) @@ -303,7 +306,7 @@ def _resolve_msg_payloads( one_of = m.payload.get("oneOf", None) if isinstance(one_of, dict): one_of_list = [] - processed_payloads: Dict[str, Dict[str, Any]] = {} + processed_payloads: Dict[str, AnyDict] = {} for name, payload in one_of.items(): processed_payloads[name] = payload one_of_list.append(Reference(**{"$ref": f"#/components/schemas/{name}"})) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/components.py b/faststream/specification/asyncapi/v3_0_0/schema/components.py index a6cf796644..57d0e1b03f 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/components.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/components.py @@ -1,9 +1,10 @@ -from typing import Any, Dict, Optional +from typing import Dict, Optional from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 from faststream.specification.asyncapi.v2_6_0.schema.message import Message +from faststream.types import AnyDict class Components(BaseModel): @@ -35,8 +36,8 @@ class Components(BaseModel): """ messages: Optional[Dict[str, Message]] = None - schemas: Optional[Dict[str, Dict[str, Any]]] = None - securitySchemes: Optional[Dict[str, Dict[str, Any]]] = None + schemas: Optional[Dict[str, AnyDict]] = None + securitySchemes: Optional[Dict[str, AnyDict]] = None # parameters # correlationIds # operationTraits diff --git a/faststream/specification/asyncapi/v3_0_0/schema/info.py b/faststream/specification/asyncapi/v3_0_0/schema/info.py index a406f876c7..4ab774a24d 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/info.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/info.py @@ -1,6 +1,4 @@ from typing import ( - Any, - Dict, List, Optional, Union, @@ -17,7 +15,7 @@ LicenseDict, ) from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag -from faststream.types import ( # noqa: TCH001 +from faststream.types import ( AnyDict, ) @@ -35,8 +33,8 @@ class Info(BaseInfo): """ termsOfService: Optional[AnyHttpUrl] = None - contact: Optional[Union[Contact, ContactDict, Dict[str, Any]]] = None - license: Optional[Union[License, LicenseDict, Dict[str, Any]]] = None + contact: Optional[Union[Contact, ContactDict, AnyDict]] = None + license: Optional[Union[License, LicenseDict, AnyDict]] = None tags: Optional[List[Union["Tag", "AnyDict"]]] = None externalDocs: Optional[ Union["ExternalDocs", "AnyDict"] diff --git a/faststream/specification/asyncapi/v3_0_0/schema/operations.py b/faststream/specification/asyncapi/v3_0_0/schema/operations.py index f79e19e253..81d71e8210 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/operations.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/operations.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, List, Literal, Optional, Union +from typing import Dict, List, Literal, Optional, Union from pydantic import BaseModel @@ -7,6 +7,7 @@ from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag from faststream.specification.asyncapi.v2_6_0.schema.utils import Reference from faststream.specification.asyncapi.v3_0_0.schema.channels import Channel +from faststream.types import AnyDict class Operation(BaseModel): @@ -36,7 +37,7 @@ class Operation(BaseModel): # TODO # traits - tags: Optional[List[Union[Tag, Dict[str, Any]]]] = None + tags: Optional[List[Union[Tag, AnyDict]]] = None if PYDANTIC_V2: model_config = {"extra": "allow"} diff --git a/faststream/specification/asyncapi/v3_0_0/schema/servers.py b/faststream/specification/asyncapi/v3_0_0/schema/servers.py index f3dfaa5a11..d8edab9180 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/servers.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/servers.py @@ -1,10 +1,11 @@ -from typing import Any, Dict, List, Optional, Union +from typing import Dict, List, Optional, Union from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 from faststream.specification.asyncapi.v2_6_0.schema import ServerVariable, Tag from faststream.specification.asyncapi.v2_6_0.schema.utils import Reference +from faststream.types import AnyDict SecurityRequirement = List[Dict[str, List[str]]] @@ -36,7 +37,7 @@ class Server(BaseModel): protocol: str description: Optional[str] = None protocolVersion: Optional[str] = None - tags: Optional[List[Union[Tag, Dict[str, Any]]]] = None + tags: Optional[List[Union[Tag, AnyDict]]] = None security: Optional[SecurityRequirement] = None variables: Optional[Dict[str, Union[ServerVariable, Reference]]] = None From 83080225efa2b17fa973a39cc8e5862f0672ad0b Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 16 Aug 2024 13:52:17 +0300 Subject: [PATCH 090/245] AsyncAPI contact generation refactoring + little things --- .../asyncapi_customization/custom_info.py | 3 +- .../specification/asyncapi/v2_6_0/generate.py | 17 +- .../asyncapi/v2_6_0/schema/__init__.py | 6 +- .../asyncapi/v2_6_0/schema/contact.py | 143 +++++++++++++++ .../asyncapi/v2_6_0/schema/info.py | 164 +----------------- .../specification/asyncapi/v3_0_0/generate.py | 8 +- .../asyncapi/v3_0_0/schema/info.py | 12 +- faststream/specification/schema/contact.py | 2 +- tests/asyncapi/kafka/v2_6_0/test_app.py | 3 +- 9 files changed, 169 insertions(+), 189 deletions(-) create mode 100644 faststream/specification/asyncapi/v2_6_0/schema/contact.py diff --git a/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_info.py b/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_info.py index 1164cc4ba9..b72cad1946 100644 --- a/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_info.py +++ b/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_info.py @@ -1,5 +1,6 @@ from faststream import FastStream -from faststream.specification.asyncapi.v2_6_0.schema.info import License, Contact +from faststream.specification.schema.license import License +from faststream.specification.schema.contact import Contact from faststream.kafka import KafkaBroker broker = KafkaBroker("localhost:9092") diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index 2d34400bed..36ca1b2fa8 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -7,7 +7,6 @@ from faststream.specification.asyncapi.v2_6_0.schema import ( Channel, Components, - Contact, Info, Operation, Reference, @@ -19,6 +18,9 @@ ChannelBinding, OperationBinding, ) +from faststream.specification.asyncapi.v2_6_0.schema.contact import ( + from_spec as contact_from_spec, +) from faststream.specification.asyncapi.v2_6_0.schema.docs import ( from_spec as docs_from_spec, ) @@ -35,7 +37,6 @@ from_spec as tag_from_spec, ) from faststream.specification.proto import Application - from faststream.types import AnyDict if TYPE_CHECKING: @@ -79,14 +80,13 @@ def get_app_schema(app: Application) -> Schema: payloads, messages, ) - schema = Schema( info=Info( title=app.title, version=app.version, description=app.description, termsOfService=app.terms_of_service, - contact=specs_contact_to_asyncapi(app.contact) + contact=contact_from_spec(app.contact) if app.contact else None, license=license_from_spec(app.license) if app.license else None, @@ -188,15 +188,6 @@ def get_broker_channels( return channels -def specs_contact_to_asyncapi( - contact: Union["spec.contact.Contact", "spec.contact.ContactDict", "AnyDict"] -) -> Union["Contact", "AnyDict"]: - if isinstance(contact, spec.contact.Contact): - return Contact(**contact.dict()) - - return dict(contact) - - def specs_channel_to_asyncapi(channel: spec.channel.Channel) -> Channel: return Channel( diff --git a/faststream/specification/asyncapi/v2_6_0/schema/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/__init__.py index 7c7808c592..20aeb02dc1 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/__init__.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/__init__.py @@ -1,8 +1,10 @@ from . import bindings from .channels import Channel from .components import Components +from .contact import Contact from .docs import ExternalDocs -from .info import Contact, ContactDict, Info, License, LicenseDict +from .info import Info +from .license import License from .message import CorrelationId, Message from .operations import Operation from .schema import Schema @@ -15,9 +17,7 @@ "Components", "Info", "License", - "LicenseDict", "Contact", - "ContactDict", "Operation", "Schema", "Server", diff --git a/faststream/specification/asyncapi/v2_6_0/schema/contact.py b/faststream/specification/asyncapi/v2_6_0/schema/contact.py new file mode 100644 index 0000000000..8a4652d877 --- /dev/null +++ b/faststream/specification/asyncapi/v2_6_0/schema/contact.py @@ -0,0 +1,143 @@ +from typing import ( + Any, + Callable, + Iterable, + Optional, + Type, + Union, + overload, +) + +from pydantic import AnyHttpUrl, BaseModel +from typing_extensions import Self + +from faststream._compat import ( + PYDANTIC_V2, + CoreSchema, + GetJsonSchemaHandler, + JsonSchemaValue, + with_info_plain_validator_function, +) +from faststream.log import logger +from faststream.specification import schema as spec +from faststream.types import AnyDict + +try: + import email_validator + + if email_validator is None: + raise ImportError + from pydantic import EmailStr + +except ImportError: # pragma: no cover + # NOTE: EmailStr mock was copied from the FastAPI + # https://github.com/tiangolo/fastapi/blob/master/fastapi/openapi/models.py#24 + class EmailStr(str): # type: ignore + """EmailStr is a string that should be an email. + + Note: EmailStr mock was copied from the FastAPI: + https://github.com/tiangolo/fastapi/blob/master/fastapi/openapi/models.py#24 + + """ + + @classmethod + def __get_validators__(cls) -> Iterable[Callable[..., Any]]: + """Returns the validators for the EmailStr class.""" + yield cls.validate + + @classmethod + def validate(cls, v: Any) -> str: + """Validates the EmailStr class.""" + logger.warning( + "email-validator bot installed, email fields will be treated as str.\n" + "To install, run: pip install email-validator" + ) + return str(v) + + @classmethod + def _validate(cls, __input_value: Any, _: Any) -> str: + logger.warning( + "email-validator bot installed, email fields will be treated as str.\n" + "To install, run: pip install email-validator" + ) + return str(__input_value) + + @classmethod + def __get_pydantic_json_schema__( + cls, + core_schema: CoreSchema, + handler: GetJsonSchemaHandler, + ) -> JsonSchemaValue: + """Returns the JSON schema for the EmailStr class. + + Args: + core_schema : the core schema + handler : the handler + """ + return {"type": "string", "format": "email"} + + @classmethod + def __get_pydantic_core_schema__( + cls, + source: Type[Any], + handler: Callable[[Any], CoreSchema], + ) -> JsonSchemaValue: + """Returns the core schema for the EmailStr class. + + Args: + source : the source + handler : the handler + """ + return with_info_plain_validator_function(cls._validate) # type: ignore[no-any-return] + + +class Contact(BaseModel): + """A class to represent a contact. + + Attributes: + name : name of the contact (str) + url : URL of the contact (Optional[AnyHttpUrl]) + email : email of the contact (Optional[EmailStr]) + + """ + + name: str + url: Optional[AnyHttpUrl] = None + email: Optional[EmailStr] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" + + @classmethod + def from_spec(cls, contact: spec.contact.Contact) -> Self: + return cls( + name=contact.name, + url=contact.url, + email=contact.email, + ) + + +@overload +def from_spec(contact: spec.contact.Contact) -> Contact: ... + + +@overload +def from_spec(contact: spec.contact.ContactDict) -> AnyDict: ... + + +@overload +def from_spec(contact: AnyDict) -> AnyDict: ... + + +def from_spec( + contact: Union[spec.contact.Contact, spec.contact.ContactDict, AnyDict] +) -> Union[Contact, AnyDict]: + if isinstance(contact, spec.contact.Contact): + return Contact.from_spec(contact) + + return dict(contact) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/info.py b/faststream/specification/asyncapi/v2_6_0/schema/info.py index b6c8b94f7d..f9030fa05f 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/info.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/info.py @@ -1,169 +1,15 @@ from typing import ( - Any, - Callable, - Iterable, Optional, - Type, Union, ) -from pydantic import AnyHttpUrl, BaseModel -from typing_extensions import Required, TypedDict +from pydantic import AnyHttpUrl -from faststream._compat import ( - PYDANTIC_V2, - CoreSchema, - GetJsonSchemaHandler, - JsonSchemaValue, - with_info_plain_validator_function, -) -from faststream.log import logger from faststream.specification.asyncapi.base.schema import BaseInfo +from faststream.specification.asyncapi.v2_6_0.schema.contact import Contact +from faststream.specification.asyncapi.v2_6_0.schema.license import License from faststream.types import AnyDict -try: - import email_validator - - if email_validator is None: - raise ImportError - from pydantic import EmailStr - -except ImportError: # pragma: no cover - # NOTE: EmailStr mock was copied from the FastAPI - # https://github.com/tiangolo/fastapi/blob/master/fastapi/openapi/models.py#24 - class EmailStr(str): # type: ignore - """EmailStr is a string that should be an email. - - Note: EmailStr mock was copied from the FastAPI: - https://github.com/tiangolo/fastapi/blob/master/fastapi/openapi/models.py#24 - - """ - - @classmethod - def __get_validators__(cls) -> Iterable[Callable[..., Any]]: - """Returns the validators for the EmailStr class.""" - yield cls.validate - - @classmethod - def validate(cls, v: Any) -> str: - """Validates the EmailStr class.""" - logger.warning( - "email-validator bot installed, email fields will be treated as str.\n" - "To install, run: pip install email-validator" - ) - return str(v) - - @classmethod - def _validate(cls, __input_value: Any, _: Any) -> str: - logger.warning( - "email-validator bot installed, email fields will be treated as str.\n" - "To install, run: pip install email-validator" - ) - return str(__input_value) - - @classmethod - def __get_pydantic_json_schema__( - cls, - core_schema: CoreSchema, - handler: GetJsonSchemaHandler, - ) -> JsonSchemaValue: - """Returns the JSON schema for the EmailStr class. - - Args: - core_schema : the core schema - handler : the handler - """ - return {"type": "string", "format": "email"} - - @classmethod - def __get_pydantic_core_schema__( - cls, - source: Type[Any], - handler: Callable[[Any], CoreSchema], - ) -> JsonSchemaValue: - """Returns the core schema for the EmailStr class. - - Args: - source : the source - handler : the handler - """ - return with_info_plain_validator_function(cls._validate) # type: ignore[no-any-return] - - -class ContactDict(TypedDict, total=False): - """A class to represent a dictionary of contact information. - - Attributes: - name : required name of the contact (type: str) - url : URL of the contact (type: AnyHttpUrl) - email : email address of the contact (type: EmailStr) - - """ - - name: Required[str] - url: AnyHttpUrl - email: EmailStr - - -class Contact(BaseModel): - """A class to represent a contact. - - Attributes: - name : name of the contact (str) - url : URL of the contact (Optional[AnyHttpUrl]) - email : email of the contact (Optional[EmailStr]) - - """ - - name: str - url: Optional[AnyHttpUrl] = None - email: Optional[EmailStr] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" - - -class LicenseDict(TypedDict, total=False): - """A dictionary-like class to represent a license. - - Attributes: - name : required name of the license (type: str) - url : URL of the license (type: AnyHttpUrl) - - """ - - name: Required[str] - url: AnyHttpUrl - - -class License(BaseModel): - """A class to represent a license. - - Attributes: - name : name of the license - url : URL of the license (optional) - - Config: - extra : allow additional attributes in the model (PYDANTIC_V2) - - """ - - name: str - url: Optional[AnyHttpUrl] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" - class Info(BaseInfo): """A class to represent information. @@ -179,5 +25,5 @@ class Info(BaseInfo): """ termsOfService: Optional[AnyHttpUrl] = None - contact: Optional[Union[Contact, ContactDict, AnyDict]] = None - license: Optional[Union[License, LicenseDict, AnyDict]] = None + contact: Optional[Union[Contact, AnyDict]] = None + license: Optional[Union[License, AnyDict]] = None diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index 4dfca42789..f13c026c42 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -5,9 +5,6 @@ from faststream._compat import DEF_KEY from faststream.constants import ContentTypes from faststream.specification import schema as spec -from faststream.specification.asyncapi.v2_6_0.generate import ( - specs_contact_to_asyncapi, -) from faststream.specification.asyncapi.v2_6_0.schema import ( ExternalDocs, Reference, @@ -17,6 +14,9 @@ ChannelBinding, OperationBinding, ) +from faststream.specification.asyncapi.v2_6_0.schema.contact import ( + from_spec as contact_from_spec, +) from faststream.specification.asyncapi.v2_6_0.schema.license import ( from_spec as license_from_spec, ) @@ -83,7 +83,7 @@ def get_app_schema(app: Application) -> Schema: description=app.description, termsOfService=app.terms_of_service, - contact=specs_contact_to_asyncapi(app.contact) + contact=contact_from_spec(app.contact) if app.contact else None, license=license_from_spec(app.license) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/info.py b/faststream/specification/asyncapi/v3_0_0/schema/info.py index 4ab774a24d..f3fef0c614 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/info.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/info.py @@ -7,14 +7,12 @@ from pydantic import AnyHttpUrl from faststream.specification.asyncapi.base.schema import BaseInfo -from faststream.specification.asyncapi.v2_6_0.schema.docs import ExternalDocs -from faststream.specification.asyncapi.v2_6_0.schema.info import ( +from faststream.specification.asyncapi.v2_6_0.schema import ( Contact, - ContactDict, + ExternalDocs, License, - LicenseDict, + Tag, ) -from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag from faststream.types import ( AnyDict, ) @@ -33,8 +31,8 @@ class Info(BaseInfo): """ termsOfService: Optional[AnyHttpUrl] = None - contact: Optional[Union[Contact, ContactDict, AnyDict]] = None - license: Optional[Union[License, LicenseDict, AnyDict]] = None + contact: Optional[Union[Contact, AnyDict]] = None + license: Optional[Union[License, AnyDict]] = None tags: Optional[List[Union["Tag", "AnyDict"]]] = None externalDocs: Optional[ Union["ExternalDocs", "AnyDict"] diff --git a/faststream/specification/schema/contact.py b/faststream/specification/schema/contact.py index 3090f9a09b..b098d441bc 100644 --- a/faststream/specification/schema/contact.py +++ b/faststream/specification/schema/contact.py @@ -99,7 +99,7 @@ class ContactDict(TypedDict, total=False): name: Required[str] url: AnyHttpUrl - email: EmailStr + # email: EmailStr class Contact(BaseModel): diff --git a/tests/asyncapi/kafka/v2_6_0/test_app.py b/tests/asyncapi/kafka/v2_6_0/test_app.py index cadf2ed79f..4ce84b875b 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_app.py +++ b/tests/asyncapi/kafka/v2_6_0/test_app.py @@ -1,6 +1,7 @@ from faststream import FastStream from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.v2_6_0.schema.info import Contact, License +from faststream.specification.schema.contact import Contact +from faststream.specification.schema.license import License from faststream.kafka import KafkaBroker from faststream.specification.schema.docs import ExternalDocs from faststream.specification.schema.tag import Tag From a960394e9b2e01c579c55675479d28154a1e6658 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 16 Aug 2024 14:07:57 +0300 Subject: [PATCH 091/245] AsyncAPI 2.6.0 Channel and Operation building refactoring --- .../specification/asyncapi/v2_6_0/generate.py | 46 +------------------ .../asyncapi/v2_6_0/schema/channels.py | 18 ++++++++ .../asyncapi/v2_6_0/schema/operations.py | 26 +++++++++++ 3 files changed, 46 insertions(+), 44 deletions(-) diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index 36ca1b2fa8..08f1c15ca1 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -8,16 +8,11 @@ Channel, Components, Info, - Operation, Reference, Schema, Server, Tag, ) -from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( - ChannelBinding, - OperationBinding, -) from faststream.specification.asyncapi.v2_6_0.schema.contact import ( from_spec as contact_from_spec, ) @@ -30,9 +25,6 @@ from faststream.specification.asyncapi.v2_6_0.schema.message import ( Message, ) -from faststream.specification.asyncapi.v2_6_0.schema.message import ( - from_spec as message_from_spec, -) from faststream.specification.asyncapi.v2_6_0.schema.tag import ( from_spec as tag_from_spec, ) @@ -174,54 +166,20 @@ def get_broker_channels( for h in broker._subscribers.values(): schema = h.schema() channels.update({ - key: specs_channel_to_asyncapi(channel) + key: Channel.from_spec(channel) for key, channel in schema.items() }) for p in broker._publishers.values(): schema = p.schema() channels.update({ - key: specs_channel_to_asyncapi(channel) + key: Channel.from_spec(channel) for key, channel in schema.items() }) return channels - -def specs_channel_to_asyncapi(channel: spec.channel.Channel) -> Channel: - return Channel( - description=channel.description, - servers=channel.servers, - - bindings=ChannelBinding.from_spec(channel.bindings) - if channel.bindings else None, - - subscribe=specs_operation_to_asyncapi(channel.subscribe) - if channel.subscribe else None, - - publish=specs_operation_to_asyncapi(channel.publish) - if channel.publish else None, - ) - - -def specs_operation_to_asyncapi(operation: spec.operation.Operation) -> Operation: - return Operation( - operationId=operation.operationId, - summary=operation.summary, - description=operation.description, - - bindings=OperationBinding.from_spec(operation.bindings) - if operation.bindings else None, - - message=message_from_spec(operation.message), - security=operation.security, - - tags=[tag_from_spec(tag) for tag in operation.tags] - if operation.tags else None, - ) - - def _resolve_msg_payloads( m: Message, channel_name: str, diff --git a/faststream/specification/asyncapi/v2_6_0/schema/channels.py b/faststream/specification/asyncapi/v2_6_0/schema/channels.py index aca3cb90bf..8a016ecd38 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/channels.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/channels.py @@ -1,8 +1,10 @@ from typing import List, Optional from pydantic import BaseModel +from typing_extensions import Self from faststream._compat import PYDANTIC_V2 +from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.schema.bindings import ChannelBinding from faststream.specification.asyncapi.v2_6_0.schema.operations import Operation @@ -39,3 +41,19 @@ class Channel(BaseModel): class Config: extra = "allow" + + @classmethod + def from_spec(cls, channel: spec.channel.Channel) -> Self: + return cls( + description=channel.description, + servers=channel.servers, + + bindings=ChannelBinding.from_spec(channel.bindings) + if channel.bindings is not None else None, + + subscribe=Operation.from_spec(channel.subscribe) + if channel.subscribe is not None else None, + + publish=Operation.from_spec(channel.publish) + if channel.publish is not None else None, + ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/operations.py b/faststream/specification/asyncapi/v2_6_0/schema/operations.py index f19a9809a8..a38d61ec0c 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/operations.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/operations.py @@ -1,11 +1,19 @@ from typing import Dict, List, Optional, Union from pydantic import BaseModel +from typing_extensions import Self from faststream._compat import PYDANTIC_V2 +from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.schema.bindings import OperationBinding from faststream.specification.asyncapi.v2_6_0.schema.message import Message +from faststream.specification.asyncapi.v2_6_0.schema.message import ( + from_spec as message_from_spec, +) from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag +from faststream.specification.asyncapi.v2_6_0.schema.tag import ( + from_spec as tag_from_spec, +) from faststream.specification.asyncapi.v2_6_0.schema.utils import ( Reference, ) @@ -48,3 +56,21 @@ class Operation(BaseModel): class Config: extra = "allow" + + @classmethod + def from_spec(cls, operation: spec.operation.Operation) -> Self: + return cls( + operationId=operation.operationId, + summary=operation.summary, + description=operation.description, + + bindings=OperationBinding.from_spec(operation.bindings) + if operation.bindings is not None else None, + + message=message_from_spec(operation.message) + if operation.message is not None else None, + + tags=[tag_from_spec(tag) for tag in operation.tags] + if operation.tags is not None else None, + ) + From 2cc80861496b52aa6f18a2bf0788720ba9d498a4 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 16 Aug 2024 14:12:41 +0300 Subject: [PATCH 092/245] AsyncAPI 3.0.0 generation refactoring --- .../specification/asyncapi/v2_6_0/generate.py | 12 ++--- .../specification/asyncapi/v3_0_0/generate.py | 52 +++---------------- 2 files changed, 12 insertions(+), 52 deletions(-) diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index 08f1c15ca1..498d461926 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -22,9 +22,7 @@ from faststream.specification.asyncapi.v2_6_0.schema.license import ( from_spec as license_from_spec, ) -from faststream.specification.asyncapi.v2_6_0.schema.message import ( - Message, -) +from faststream.specification.asyncapi.v2_6_0.schema.message import Message from faststream.specification.asyncapi.v2_6_0.schema.tag import ( from_spec as tag_from_spec, ) @@ -191,7 +189,7 @@ def _resolve_msg_payloads( Payloads and messages are editable dicts to store schemas for reference in AsyncAPI. """ one_of_list: List[Reference] = [] - m.payload = _move_pydantic_refs(m.payload, DEF_KEY) + m.payload = move_pydantic_refs(m.payload, DEF_KEY) if DEF_KEY in m.payload: payloads.update(m.payload.pop(DEF_KEY)) @@ -226,7 +224,7 @@ def _resolve_msg_payloads( return Reference(**{"$ref": f"#/components/messages/{m.title}"}) -def _move_pydantic_refs( +def move_pydantic_refs( original: Any, key: str, ) -> Any: @@ -244,11 +242,11 @@ def _move_pydantic_refs( data[k] = data[k].replace(key, "components/schemas") elif isinstance(item, dict): - data[k] = _move_pydantic_refs(data[k], key) + data[k] = move_pydantic_refs(data[k], key) elif isinstance(item, List): for i in range(len(data[k])): - data[k][i] = _move_pydantic_refs(item[i], key) + data[k][i] = move_pydantic_refs(item[i], key) if isinstance(discriminator := data.get("discriminator"), dict): data["discriminator"] = discriminator["propertyName"] diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index f13c026c42..a33bef9cfe 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -1,12 +1,12 @@ from dataclasses import asdict -from typing import TYPE_CHECKING, Any, Dict, List, Union +from typing import TYPE_CHECKING, Dict, List, Union from urllib.parse import urlparse from faststream._compat import DEF_KEY from faststream.constants import ContentTypes from faststream.specification import schema as spec +from faststream.specification.asyncapi.v2_6_0.generate import move_pydantic_refs from faststream.specification.asyncapi.v2_6_0.schema import ( - ExternalDocs, Reference, Tag, ) @@ -17,6 +17,9 @@ from faststream.specification.asyncapi.v2_6_0.schema.contact import ( from_spec as contact_from_spec, ) +from faststream.specification.asyncapi.v2_6_0.schema.docs import ( + from_spec as docs_from_spec, +) from faststream.specification.asyncapi.v2_6_0.schema.license import ( from_spec as license_from_spec, ) @@ -92,7 +95,7 @@ def get_app_schema(app: Application) -> Schema: tags=[tag_from_spec(tag) for tag in app.specs_tags] if app.specs_tags else None, - externalDocs=specs_external_docs_to_asyncapi(app.external_docs) + externalDocs=docs_from_spec(app.external_docs) if app.external_docs else None, ), defaultContentType=ContentTypes.json.value, @@ -278,17 +281,6 @@ def get_broker_channels( return channels -def specs_external_docs_to_asyncapi( - externalDocs: Union[spec.docs.ExternalDocs, spec.docs.ExternalDocsDict, AnyDict] -) -> Union[ExternalDocs, AnyDict]: - if isinstance(externalDocs, spec.docs.ExternalDocs): - return ExternalDocs( - **asdict(externalDocs) - ) - else: - return dict(externalDocs) - - def _resolve_msg_payloads( message_name: str, m: Message, @@ -298,7 +290,7 @@ def _resolve_msg_payloads( ) -> Reference: assert isinstance(m.payload, dict) - m.payload = _move_pydantic_refs(m.payload, DEF_KEY) + m.payload = move_pydantic_refs(m.payload, DEF_KEY) if DEF_KEY in m.payload: payloads.update(m.payload.pop(DEF_KEY)) @@ -325,33 +317,3 @@ def _resolve_msg_payloads( assert m.title messages[m.title] = m return Reference(**{"$ref": f"#/components/messages/{channel_name}:{message_name}"}) - - -def _move_pydantic_refs( - original: Any, - key: str, -) -> Any: - """Remove pydantic references and replace them by real schemas.""" - if not isinstance(original, Dict): - return original - - data = original.copy() - - for k in data: - item = data[k] - - if isinstance(item, str): - if key in item: - data[k] = data[k].replace(key, "components/schemas") - - elif isinstance(item, dict): - data[k] = _move_pydantic_refs(data[k], key) - - elif isinstance(item, List): - for i in range(len(data[k])): - data[k][i] = _move_pydantic_refs(item[i], key) - - if isinstance(discriminator := data.get("discriminator"), dict): - data["discriminator"] = discriminator["propertyName"] - - return data From c50f04accb05ff01f267e3d90a35e9b4f54d4d2b Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 16 Aug 2024 15:48:17 +0300 Subject: [PATCH 093/245] refactoring --- .../specification/asyncapi/v2_6_0/generate.py | 7 +++++-- .../asyncapi/v2_6_0/schema/bindings/main.py | 11 ++++++++++- .../asyncapi/v2_6_0/schema/channels.py | 16 +++++++++++++--- .../asyncapi/v2_6_0/schema/operations.py | 8 +++++++- .../asyncapi/v2_6_0/schema/servers.py | 1 - .../specification/asyncapi/v3_0_0/generate.py | 17 +++++++---------- 6 files changed, 42 insertions(+), 18 deletions(-) diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index 498d461926..1946b7f57a 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -13,6 +13,9 @@ Server, Tag, ) +from faststream.specification.asyncapi.v2_6_0.schema.channels import ( + from_spec as channel_from_spec, +) from faststream.specification.asyncapi.v2_6_0.schema.contact import ( from_spec as contact_from_spec, ) @@ -164,14 +167,14 @@ def get_broker_channels( for h in broker._subscribers.values(): schema = h.schema() channels.update({ - key: Channel.from_spec(channel) + key: channel_from_spec(channel) for key, channel in schema.items() }) for p in broker._publishers.values(): schema = p.schema() channels.update({ - key: Channel.from_spec(channel) + key: channel_from_spec(channel) for key, channel in schema.items() }) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main.py index 6f63c57604..b2e7148202 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main.py @@ -1,4 +1,4 @@ -from typing import Optional +from typing import Optional, Union from pydantic import BaseModel from typing_extensions import Self @@ -110,3 +110,12 @@ def from_spec(cls, binding: spec.bindings.OperationBinding) -> Self: redis=redis_bindings.OperationBinding.from_spec(binding.redis) if binding.redis is not None else None, ) + + +def from_spec( + binding: Union[spec.bindings.ChannelBinding, spec.bindings.OperationBinding] +) -> Union[ChannelBinding, OperationBinding]: + if isinstance(binding, spec.bindings.ChannelBinding): + return ChannelBinding.from_spec(binding) + + return OperationBinding.from_spec(binding) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/channels.py b/faststream/specification/asyncapi/v2_6_0/schema/channels.py index 8a016ecd38..20dc5c929a 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/channels.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/channels.py @@ -6,7 +6,13 @@ from faststream._compat import PYDANTIC_V2 from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.schema.bindings import ChannelBinding +from faststream.specification.asyncapi.v2_6_0.schema.bindings.main import ( + from_spec as channel_or_operation_binding_from_spec, +) from faststream.specification.asyncapi.v2_6_0.schema.operations import Operation +from faststream.specification.asyncapi.v2_6_0.schema.operations import ( + from_spec as operation_from_spec, +) class Channel(BaseModel): @@ -48,12 +54,16 @@ def from_spec(cls, channel: spec.channel.Channel) -> Self: description=channel.description, servers=channel.servers, - bindings=ChannelBinding.from_spec(channel.bindings) + bindings=channel_or_operation_binding_from_spec(channel.bindings) if channel.bindings is not None else None, - subscribe=Operation.from_spec(channel.subscribe) + subscribe=operation_from_spec(channel.subscribe) if channel.subscribe is not None else None, - publish=Operation.from_spec(channel.publish) + publish=operation_from_spec(channel.publish) if channel.publish is not None else None, ) + + +def from_spec(channel: spec.channel.Channel) -> Channel: + return Channel.from_spec(channel) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/operations.py b/faststream/specification/asyncapi/v2_6_0/schema/operations.py index a38d61ec0c..eed0da9a22 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/operations.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/operations.py @@ -6,6 +6,9 @@ from faststream._compat import PYDANTIC_V2 from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.schema.bindings import OperationBinding +from faststream.specification.asyncapi.v2_6_0.schema.bindings.main import ( + from_spec as channel_or_operation_binding_from_spec, +) from faststream.specification.asyncapi.v2_6_0.schema.message import Message from faststream.specification.asyncapi.v2_6_0.schema.message import ( from_spec as message_from_spec, @@ -64,7 +67,7 @@ def from_spec(cls, operation: spec.operation.Operation) -> Self: summary=operation.summary, description=operation.description, - bindings=OperationBinding.from_spec(operation.bindings) + bindings=channel_or_operation_binding_from_spec(operation.bindings) if operation.bindings is not None else None, message=message_from_spec(operation.message) @@ -74,3 +77,6 @@ def from_spec(cls, operation: spec.operation.Operation) -> Self: if operation.tags is not None else None, ) + +def from_spec(operation: spec.operation.Operation) -> Operation: + return Operation.from_spec(operation) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/servers.py b/faststream/specification/asyncapi/v2_6_0/schema/servers.py index daca856bc1..318e2a40c9 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/servers.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/servers.py @@ -35,7 +35,6 @@ class Config: extra = "allow" - class Server(BaseModel): """A class to represent a server. diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index a33bef9cfe..5f9eb8809c 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -10,9 +10,8 @@ Reference, Tag, ) -from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( - ChannelBinding, - OperationBinding, +from faststream.specification.asyncapi.v2_6_0.schema.bindings.main import ( + from_spec as channel_or_operation_binding_from_spec, ) from faststream.specification.asyncapi.v2_6_0.schema.contact import ( from_spec as contact_from_spec, @@ -23,9 +22,7 @@ from faststream.specification.asyncapi.v2_6_0.schema.license import ( from_spec as license_from_spec, ) -from faststream.specification.asyncapi.v2_6_0.schema.message import ( - Message, -) +from faststream.specification.asyncapi.v2_6_0.schema.message import Message from faststream.specification.asyncapi.v2_6_0.schema.message import ( from_spec as message_from_spec, ) @@ -196,7 +193,7 @@ def get_broker_operations( action="receive", summary=specs_channel.subscribe.summary, description=specs_channel.subscribe.description, - bindings=OperationBinding.from_spec(specs_channel.subscribe.bindings) + bindings=channel_or_operation_binding_from_spec(specs_channel.subscribe.bindings) if specs_channel.subscribe.bindings else None, messages=[ Reference( @@ -217,7 +214,7 @@ def get_broker_operations( action="send", summary=specs_channel.publish.summary, description=specs_channel.publish.description, - bindings=OperationBinding.from_spec(specs_channel.publish.bindings) + bindings=channel_or_operation_binding_from_spec(specs_channel.publish.bindings) if specs_channel.publish.bindings else None, messages=[ Reference( @@ -251,7 +248,7 @@ def get_broker_channels( }, description=specs_channel.description, servers=specs_channel.servers, - bindings=ChannelBinding.from_spec(specs_channel.bindings) + bindings=channel_or_operation_binding_from_spec(specs_channel.bindings) if specs_channel.bindings else None, ) @@ -270,7 +267,7 @@ def get_broker_channels( }, description=specs_channel.description, servers=specs_channel.servers, - bindings=ChannelBinding.from_spec(specs_channel.bindings) + bindings=channel_or_operation_binding_from_spec(specs_channel.bindings) if specs_channel.bindings else None, ) From 7719ca1a34b1b0a1132116f698db8378b4c69626 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 16 Aug 2024 19:14:08 +0300 Subject: [PATCH 094/245] AsyncAPI 2.6.0 bindings refactoring --- .../v2_6_0/schema/bindings/__init__.py | 5 ++ .../v2_6_0/schema/bindings/amqp/__init__.py | 20 ++++++ .../bindings/{amqp.py => amqp/channel.py} | 33 +-------- .../v2_6_0/schema/bindings/amqp/operation.py | 46 ++++++++++++ .../v2_6_0/schema/bindings/kafka/__init__.py | 20 ++++++ .../bindings/{kafka.py => kafka/channel.py} | 26 +------ .../v2_6_0/schema/bindings/kafka/operation.py | 40 +++++++++++ .../v2_6_0/schema/bindings/main/__init__.py | 20 ++++++ .../v2_6_0/schema/bindings/main/channel.py | 70 +++++++++++++++++++ .../bindings/{main.py => main/operation.py} | 55 +-------------- .../v2_6_0/schema/bindings/nats/__init__.py | 20 ++++++ .../bindings/{nats.py => nats/channel.py} | 20 +----- .../v2_6_0/schema/bindings/nats/operation.py | 35 ++++++++++ .../v2_6_0/schema/bindings/redis/__init__.py | 20 ++++++ .../bindings/{redis.py => redis/channel.py} | 20 +----- .../v2_6_0/schema/bindings/redis/operation.py | 35 ++++++++++ .../v2_6_0/schema/bindings/sqs/__init__.py | 20 ++++++ .../v2_6_0/schema/bindings/sqs/channel.py | 34 +++++++++ .../v2_6_0/schema/bindings/sqs/operation.py | 35 ++++++++++ .../asyncapi/v2_6_0/schema/channels.py | 8 +-- .../asyncapi/v2_6_0/schema/operations.py | 4 +- .../specification/asyncapi/v3_0_0/generate.py | 13 ++-- 22 files changed, 444 insertions(+), 155 deletions(-) create mode 100644 faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/__init__.py rename faststream/specification/asyncapi/v2_6_0/schema/bindings/{amqp.py => amqp/channel.py} (73%) create mode 100644 faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation.py create mode 100644 faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/__init__.py rename faststream/specification/asyncapi/v2_6_0/schema/bindings/{kafka.py => kafka/channel.py} (57%) create mode 100644 faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation.py create mode 100644 faststream/specification/asyncapi/v2_6_0/schema/bindings/main/__init__.py create mode 100644 faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel.py rename faststream/specification/asyncapi/v2_6_0/schema/bindings/{main.py => main/operation.py} (55%) create mode 100644 faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/__init__.py rename faststream/specification/asyncapi/v2_6_0/schema/bindings/{nats.py => nats/channel.py} (60%) create mode 100644 faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation.py create mode 100644 faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/__init__.py rename faststream/specification/asyncapi/v2_6_0/schema/bindings/{redis.py => redis/channel.py} (64%) create mode 100644 faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation.py create mode 100644 faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/__init__.py create mode 100644 faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel.py create mode 100644 faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation.py diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/__init__.py index c304608c5b..1216010554 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/__init__.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/__init__.py @@ -1,9 +1,14 @@ from .main import ( ChannelBinding, OperationBinding, + channel_binding_from_spec, + operation_binding_from_spec, ) __all__ = ( "ChannelBinding", + "channel_binding_from_spec", + "OperationBinding", + "operation_binding_from_spec", ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/__init__.py new file mode 100644 index 0000000000..871cd25007 --- /dev/null +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/__init__.py @@ -0,0 +1,20 @@ +from .channel import ( + ChannelBinding, +) +from .channel import ( + from_spec as channel_binding_from_spec, +) +from .operation import ( + OperationBinding, +) +from .operation import ( + from_spec as operation_binding_from_spec, +) + +__all__ = ( + "ChannelBinding", + "channel_binding_from_spec", + + "OperationBinding", + "operation_binding_from_spec", +) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py similarity index 73% rename from faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp.py rename to faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py index 6b3f2970dc..87c6bb8d2b 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py @@ -5,7 +5,7 @@ from typing import Literal, Optional -from pydantic import BaseModel, Field, PositiveInt +from pydantic import BaseModel, Field from typing_extensions import Self from faststream.specification import schema as spec @@ -106,32 +106,5 @@ def from_spec(cls, binding: spec.bindings.amqp.ChannelBinding) -> Self: }) -class OperationBinding(BaseModel): - """A class to represent an operation binding. - - Attributes: - cc : optional string representing the cc - ack : boolean indicating if the operation is acknowledged - replyTo : optional dictionary representing the replyTo - bindingVersion : string representing the binding version - """ - - cc: Optional[str] = None - ack: bool = True - replyTo: Optional[str] = None - deliveryMode: Optional[int] = None - mandatory: Optional[bool] = None - priority: Optional[PositiveInt] = None - bindingVersion: str = "0.2.0" - - @classmethod - def from_spec(cls, binding: spec.bindings.amqp.OperationBinding) -> Self: - return cls( - cc=binding.cc, - ack=binding.ack, - replyTo=binding.replyTo, - deliveryMode=binding.deliveryMode, - mandatory=binding.mandatory, - priority=binding.priority, - bindingVersion=binding.bindingVersion, - ) +def from_spec(binding: spec.bindings.amqp.ChannelBinding) -> ChannelBinding: + return ChannelBinding.from_spec(binding) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation.py new file mode 100644 index 0000000000..de52f0fbb8 --- /dev/null +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation.py @@ -0,0 +1,46 @@ +"""AsyncAPI AMQP bindings. + +References: https://github.com/asyncapi/bindings/tree/master/amqp +""" + +from typing import Optional + +from pydantic import BaseModel, PositiveInt +from typing_extensions import Self + +from faststream.specification import schema as spec + + +class OperationBinding(BaseModel): + """A class to represent an operation binding. + + Attributes: + cc : optional string representing the cc + ack : boolean indicating if the operation is acknowledged + replyTo : optional dictionary representing the replyTo + bindingVersion : string representing the binding version + """ + + cc: Optional[str] = None + ack: bool = True + replyTo: Optional[str] = None + deliveryMode: Optional[int] = None + mandatory: Optional[bool] = None + priority: Optional[PositiveInt] = None + bindingVersion: str = "0.2.0" + + @classmethod + def from_spec(cls, binding: spec.bindings.amqp.OperationBinding) -> Self: + return cls( + cc=binding.cc, + ack=binding.ack, + replyTo=binding.replyTo, + deliveryMode=binding.deliveryMode, + mandatory=binding.mandatory, + priority=binding.priority, + bindingVersion=binding.bindingVersion, + ) + + +def from_spec(binding: spec.bindings.amqp.OperationBinding) -> OperationBinding: + return OperationBinding.from_spec(binding) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/__init__.py new file mode 100644 index 0000000000..871cd25007 --- /dev/null +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/__init__.py @@ -0,0 +1,20 @@ +from .channel import ( + ChannelBinding, +) +from .channel import ( + from_spec as channel_binding_from_spec, +) +from .operation import ( + OperationBinding, +) +from .operation import ( + from_spec as operation_binding_from_spec, +) + +__all__ = ( + "ChannelBinding", + "channel_binding_from_spec", + + "OperationBinding", + "operation_binding_from_spec", +) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel.py similarity index 57% rename from faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka.py rename to faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel.py index 766fa773ce..2c1465c4d2 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel.py @@ -8,7 +8,6 @@ from typing_extensions import Self from faststream.specification import schema as spec -from faststream.types import AnyDict class ChannelBinding(BaseModel): @@ -39,26 +38,5 @@ def from_spec(cls, binding: spec.bindings.kafka.ChannelBinding) -> Self: ) -class OperationBinding(BaseModel): - """A class to represent an operation binding. - - Attributes: - groupId : optional dictionary representing the group ID - clientId : optional dictionary representing the client ID - replyTo : optional dictionary representing the reply-to - bindingVersion : version of the binding (default: "0.4.0") - """ - - groupId: Optional[AnyDict] = None - clientId: Optional[AnyDict] = None - replyTo: Optional[AnyDict] = None - bindingVersion: str = "0.4.0" - - @classmethod - def from_spec(cls, binding: spec.bindings.kafka.OperationBinding) -> Self: - return cls( - groupId=binding.groupId, - clientId=binding.clientId, - replyTo=binding.replyTo, - bindingVersion=binding.bindingVersion, - ) +def from_spec(binding: spec.bindings.kafka.ChannelBinding) -> ChannelBinding: + return ChannelBinding.from_spec(binding) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation.py new file mode 100644 index 0000000000..d40d23d759 --- /dev/null +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation.py @@ -0,0 +1,40 @@ +"""AsyncAPI Kafka bindings. + +References: https://github.com/asyncapi/bindings/tree/master/kafka +""" +from typing import Optional + +from pydantic import BaseModel +from typing_extensions import Self + +from faststream.specification import schema as spec +from faststream.types import AnyDict + + +class OperationBinding(BaseModel): + """A class to represent an operation binding. + + Attributes: + groupId : optional dictionary representing the group ID + clientId : optional dictionary representing the client ID + replyTo : optional dictionary representing the reply-to + bindingVersion : version of the binding (default: "0.4.0") + """ + + groupId: Optional[AnyDict] = None + clientId: Optional[AnyDict] = None + replyTo: Optional[AnyDict] = None + bindingVersion: str = "0.4.0" + + @classmethod + def from_spec(cls, binding: spec.bindings.kafka.OperationBinding) -> Self: + return cls( + groupId=binding.groupId, + clientId=binding.clientId, + replyTo=binding.replyTo, + bindingVersion=binding.bindingVersion, + ) + + +def from_spec(binding: spec.bindings.kafka.OperationBinding) -> OperationBinding: + return OperationBinding.from_spec(binding) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/__init__.py new file mode 100644 index 0000000000..871cd25007 --- /dev/null +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/__init__.py @@ -0,0 +1,20 @@ +from .channel import ( + ChannelBinding, +) +from .channel import ( + from_spec as channel_binding_from_spec, +) +from .operation import ( + OperationBinding, +) +from .operation import ( + from_spec as operation_binding_from_spec, +) + +__all__ = ( + "ChannelBinding", + "channel_binding_from_spec", + + "OperationBinding", + "operation_binding_from_spec", +) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel.py new file mode 100644 index 0000000000..208f0912c3 --- /dev/null +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel.py @@ -0,0 +1,70 @@ +from typing import Optional + +from pydantic import BaseModel +from typing_extensions import Self + +from faststream._compat import PYDANTIC_V2 +from faststream.specification import schema as spec +from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( + amqp as amqp_bindings, +) +from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( + kafka as kafka_bindings, +) +from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( + nats as nats_bindings, +) +from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( + redis as redis_bindings, +) +from faststream.specification.asyncapi.v2_6_0.schema.bindings import sqs as sqs_bindings + + +class ChannelBinding(BaseModel): + """A class to represent channel bindings. + + Attributes: + amqp : AMQP channel binding (optional) + kafka : Kafka channel binding (optional) + sqs : SQS channel binding (optional) + nats : NATS channel binding (optional) + redis : Redis channel binding (optional) + + """ + + amqp: Optional[amqp_bindings.ChannelBinding] = None + kafka: Optional[kafka_bindings.ChannelBinding] = None + sqs: Optional[sqs_bindings.ChannelBinding] = None + nats: Optional[nats_bindings.ChannelBinding] = None + redis: Optional[redis_bindings.ChannelBinding] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" + + @classmethod + def from_spec(cls, binding: spec.bindings.ChannelBinding) -> Self: + return cls( + amqp=amqp_bindings.ChannelBinding.from_spec(binding.amqp) + if binding.amqp is not None else None, + + kafka=kafka_bindings.ChannelBinding.from_spec(binding.kafka) + if binding.kafka is not None else None, + + sqs=sqs_bindings.ChannelBinding.from_spec(binding.sqs) + if binding.sqs is not None else None, + + nats=nats_bindings.ChannelBinding.from_spec(binding.nats) + if binding.nats is not None else None, + + redis=redis_bindings.ChannelBinding.from_spec(binding.redis) + if binding.redis is not None else None, + ) + + +def from_spec(binding: spec.bindings.ChannelBinding) -> ChannelBinding: + return ChannelBinding.from_spec(binding) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation.py similarity index 55% rename from faststream/specification/asyncapi/v2_6_0/schema/bindings/main.py rename to faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation.py index b2e7148202..87c228e461 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation.py @@ -1,4 +1,4 @@ -from typing import Optional, Union +from typing import Optional from pydantic import BaseModel from typing_extensions import Self @@ -20,52 +20,6 @@ from faststream.specification.asyncapi.v2_6_0.schema.bindings import sqs as sqs_bindings -class ChannelBinding(BaseModel): - """A class to represent channel bindings. - - Attributes: - amqp : AMQP channel binding (optional) - kafka : Kafka channel binding (optional) - sqs : SQS channel binding (optional) - nats : NATS channel binding (optional) - redis : Redis channel binding (optional) - - """ - - amqp: Optional[amqp_bindings.ChannelBinding] = None - kafka: Optional[kafka_bindings.ChannelBinding] = None - sqs: Optional[sqs_bindings.ChannelBinding] = None - nats: Optional[nats_bindings.ChannelBinding] = None - redis: Optional[redis_bindings.ChannelBinding] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" - - @classmethod - def from_spec(cls, binding: spec.bindings.ChannelBinding) -> Self: - return cls( - amqp=amqp_bindings.ChannelBinding.from_spec(binding.amqp) - if binding.amqp is not None else None, - - kafka=kafka_bindings.ChannelBinding.from_spec(binding.kafka) - if binding.kafka is not None else None, - - sqs=sqs_bindings.ChannelBinding.from_spec(binding.sqs) - if binding.sqs is not None else None, - - nats=nats_bindings.ChannelBinding.from_spec(binding.nats) - if binding.nats is not None else None, - - redis=redis_bindings.ChannelBinding.from_spec(binding.redis) - if binding.redis is not None else None, - ) - - class OperationBinding(BaseModel): """A class to represent an operation binding. @@ -112,10 +66,5 @@ def from_spec(cls, binding: spec.bindings.OperationBinding) -> Self: ) -def from_spec( - binding: Union[spec.bindings.ChannelBinding, spec.bindings.OperationBinding] -) -> Union[ChannelBinding, OperationBinding]: - if isinstance(binding, spec.bindings.ChannelBinding): - return ChannelBinding.from_spec(binding) - +def from_spec(binding: spec.bindings.OperationBinding) -> OperationBinding: return OperationBinding.from_spec(binding) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/__init__.py new file mode 100644 index 0000000000..871cd25007 --- /dev/null +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/__init__.py @@ -0,0 +1,20 @@ +from .channel import ( + ChannelBinding, +) +from .channel import ( + from_spec as channel_binding_from_spec, +) +from .operation import ( + OperationBinding, +) +from .operation import ( + from_spec as operation_binding_from_spec, +) + +__all__ = ( + "ChannelBinding", + "channel_binding_from_spec", + + "OperationBinding", + "operation_binding_from_spec", +) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel.py similarity index 60% rename from faststream/specification/asyncapi/v2_6_0/schema/bindings/nats.py rename to faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel.py index e380e26911..ba39c7569b 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel.py @@ -9,7 +9,6 @@ from typing_extensions import Self from faststream.specification import schema as spec -from faststream.types import AnyDict class ChannelBinding(BaseModel): @@ -34,20 +33,5 @@ def from_spec(cls, binding: spec.bindings.nats.ChannelBinding) -> Self: ) -class OperationBinding(BaseModel): - """A class to represent an operation binding. - - Attributes: - replyTo : optional dictionary containing reply information - bindingVersion : version of the binding (default is "custom") - """ - - replyTo: Optional[AnyDict] = None - bindingVersion: str = "custom" - - @classmethod - def from_spec(cls, binding: spec.bindings.nats.OperationBinding) -> Self: - return cls( - replyTo=binding.replyTo, - bindingVersion=binding.bindingVersion, - ) +def from_spec(binding: spec.bindings.nats.ChannelBinding) -> ChannelBinding: + return ChannelBinding.from_spec(binding) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation.py new file mode 100644 index 0000000000..7911763747 --- /dev/null +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation.py @@ -0,0 +1,35 @@ +"""AsyncAPI NATS bindings. + +References: https://github.com/asyncapi/bindings/tree/master/nats +""" + +from typing import Optional + +from pydantic import BaseModel +from typing_extensions import Self + +from faststream.specification import schema as spec +from faststream.types import AnyDict + + +class OperationBinding(BaseModel): + """A class to represent an operation binding. + + Attributes: + replyTo : optional dictionary containing reply information + bindingVersion : version of the binding (default is "custom") + """ + + replyTo: Optional[AnyDict] = None + bindingVersion: str = "custom" + + @classmethod + def from_spec(cls, binding: spec.bindings.nats.OperationBinding) -> Self: + return cls( + replyTo=binding.replyTo, + bindingVersion=binding.bindingVersion, + ) + + +def from_spec(binding: spec.bindings.nats.OperationBinding) -> OperationBinding: + return OperationBinding.from_spec(binding) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/__init__.py new file mode 100644 index 0000000000..871cd25007 --- /dev/null +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/__init__.py @@ -0,0 +1,20 @@ +from .channel import ( + ChannelBinding, +) +from .channel import ( + from_spec as channel_binding_from_spec, +) +from .operation import ( + OperationBinding, +) +from .operation import ( + from_spec as operation_binding_from_spec, +) + +__all__ = ( + "ChannelBinding", + "channel_binding_from_spec", + + "OperationBinding", + "operation_binding_from_spec", +) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel.py similarity index 64% rename from faststream/specification/asyncapi/v2_6_0/schema/bindings/redis.py rename to faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel.py index bcafadb791..579f9170ea 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel.py @@ -9,7 +9,6 @@ from typing_extensions import Self from faststream.specification import schema as spec -from faststream.types import AnyDict class ChannelBinding(BaseModel): @@ -38,20 +37,5 @@ def from_spec(cls, binding: spec.bindings.redis.ChannelBinding) -> Self: ) -class OperationBinding(BaseModel): - """A class to represent an operation binding. - - Attributes: - replyTo : optional dictionary containing reply information - bindingVersion : version of the binding (default is "custom") - """ - - replyTo: Optional[AnyDict] = None - bindingVersion: str = "custom" - - @classmethod - def from_spec(cls, binding: spec.bindings.redis.OperationBinding) -> Self: - return cls( - replyTo=binding.replyTo, - bindingVersion=binding.bindingVersion, - ) +def from_spec(binding: spec.bindings.redis.ChannelBinding) -> ChannelBinding: + return ChannelBinding.from_spec(binding) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation.py new file mode 100644 index 0000000000..a6a28678bd --- /dev/null +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation.py @@ -0,0 +1,35 @@ +"""AsyncAPI Redis bindings. + +References: https://github.com/asyncapi/bindings/tree/master/redis +""" + +from typing import Optional + +from pydantic import BaseModel +from typing_extensions import Self + +from faststream.specification import schema as spec +from faststream.types import AnyDict + + +class OperationBinding(BaseModel): + """A class to represent an operation binding. + + Attributes: + replyTo : optional dictionary containing reply information + bindingVersion : version of the binding (default is "custom") + """ + + replyTo: Optional[AnyDict] = None + bindingVersion: str = "custom" + + @classmethod + def from_spec(cls, binding: spec.bindings.redis.OperationBinding) -> Self: + return cls( + replyTo=binding.replyTo, + bindingVersion=binding.bindingVersion, + ) + + +def from_spec(binding: spec.bindings.redis.OperationBinding) -> OperationBinding: + return OperationBinding.from_spec(binding) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/__init__.py new file mode 100644 index 0000000000..871cd25007 --- /dev/null +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/__init__.py @@ -0,0 +1,20 @@ +from .channel import ( + ChannelBinding, +) +from .channel import ( + from_spec as channel_binding_from_spec, +) +from .operation import ( + OperationBinding, +) +from .operation import ( + from_spec as operation_binding_from_spec, +) + +__all__ = ( + "ChannelBinding", + "channel_binding_from_spec", + + "OperationBinding", + "operation_binding_from_spec", +) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel.py new file mode 100644 index 0000000000..5ac2f8fac3 --- /dev/null +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel.py @@ -0,0 +1,34 @@ +"""AsyncAPI SQS bindings. + +References: https://github.com/asyncapi/bindings/tree/master/sqs +""" + + +from pydantic import BaseModel +from typing_extensions import Self + +from faststream.specification import schema as spec +from faststream.types import AnyDict + + +class ChannelBinding(BaseModel): + """A class to represent channel binding. + + Attributes: + queue : a dictionary representing the queue + bindingVersion : a string representing the binding version (default: "custom") + """ + + queue: AnyDict + bindingVersion: str = "custom" + + @classmethod + def from_spec(cls, binding: spec.bindings.sqs.ChannelBinding) -> Self: + return cls( + queue=binding.queue, + bindingVersion=binding.bindingVersion, + ) + + +def from_spec(binding: spec.bindings.sqs.ChannelBinding) -> ChannelBinding: + return ChannelBinding.from_spec(binding) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation.py new file mode 100644 index 0000000000..ee55d78cdd --- /dev/null +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation.py @@ -0,0 +1,35 @@ +"""AsyncAPI SQS bindings. + +References: https://github.com/asyncapi/bindings/tree/master/sqs +""" + +from typing import Optional + +from pydantic import BaseModel +from typing_extensions import Self + +from faststream.specification import schema as spec +from faststream.types import AnyDict + + +class OperationBinding(BaseModel): + """A class to represent an operation binding. + + Attributes: + replyTo : optional dictionary containing reply information + bindingVersion : version of the binding, default is "custom" + """ + + replyTo: Optional[AnyDict] = None + bindingVersion: str = "custom" + + @classmethod + def from_spec(cls, binding: spec.bindings.sqs.OperationBinding) -> Self: + return cls( + replyTo=binding.replyTo, + bindingVersion=binding.bindingVersion, + ) + + +def from_spec(binding: spec.bindings.sqs.OperationBinding) -> OperationBinding: + return OperationBinding.from_spec(binding) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/channels.py b/faststream/specification/asyncapi/v2_6_0/schema/channels.py index 20dc5c929a..2a2ae4ca6e 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/channels.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/channels.py @@ -5,9 +5,9 @@ from faststream._compat import PYDANTIC_V2 from faststream.specification import schema as spec -from faststream.specification.asyncapi.v2_6_0.schema.bindings import ChannelBinding -from faststream.specification.asyncapi.v2_6_0.schema.bindings.main import ( - from_spec as channel_or_operation_binding_from_spec, +from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( + ChannelBinding, + channel_binding_from_spec, ) from faststream.specification.asyncapi.v2_6_0.schema.operations import Operation from faststream.specification.asyncapi.v2_6_0.schema.operations import ( @@ -54,7 +54,7 @@ def from_spec(cls, channel: spec.channel.Channel) -> Self: description=channel.description, servers=channel.servers, - bindings=channel_or_operation_binding_from_spec(channel.bindings) + bindings=channel_binding_from_spec(channel.bindings) if channel.bindings is not None else None, subscribe=operation_from_spec(channel.subscribe) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/operations.py b/faststream/specification/asyncapi/v2_6_0/schema/operations.py index eed0da9a22..d907faf026 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/operations.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/operations.py @@ -7,7 +7,7 @@ from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.schema.bindings import OperationBinding from faststream.specification.asyncapi.v2_6_0.schema.bindings.main import ( - from_spec as channel_or_operation_binding_from_spec, + operation_binding_from_spec, ) from faststream.specification.asyncapi.v2_6_0.schema.message import Message from faststream.specification.asyncapi.v2_6_0.schema.message import ( @@ -67,7 +67,7 @@ def from_spec(cls, operation: spec.operation.Operation) -> Self: summary=operation.summary, description=operation.description, - bindings=channel_or_operation_binding_from_spec(operation.bindings) + bindings=operation_binding_from_spec(operation.bindings) if operation.bindings is not None else None, message=message_from_spec(operation.message) diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index 5f9eb8809c..fe67de0f5c 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -10,8 +10,9 @@ Reference, Tag, ) -from faststream.specification.asyncapi.v2_6_0.schema.bindings.main import ( - from_spec as channel_or_operation_binding_from_spec, +from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( + channel_binding_from_spec, + operation_binding_from_spec, ) from faststream.specification.asyncapi.v2_6_0.schema.contact import ( from_spec as contact_from_spec, @@ -193,7 +194,7 @@ def get_broker_operations( action="receive", summary=specs_channel.subscribe.summary, description=specs_channel.subscribe.description, - bindings=channel_or_operation_binding_from_spec(specs_channel.subscribe.bindings) + bindings=operation_binding_from_spec(specs_channel.subscribe.bindings) if specs_channel.subscribe.bindings else None, messages=[ Reference( @@ -214,7 +215,7 @@ def get_broker_operations( action="send", summary=specs_channel.publish.summary, description=specs_channel.publish.description, - bindings=channel_or_operation_binding_from_spec(specs_channel.publish.bindings) + bindings=operation_binding_from_spec(specs_channel.publish.bindings) if specs_channel.publish.bindings else None, messages=[ Reference( @@ -248,7 +249,7 @@ def get_broker_channels( }, description=specs_channel.description, servers=specs_channel.servers, - bindings=channel_or_operation_binding_from_spec(specs_channel.bindings) + bindings=channel_binding_from_spec(specs_channel.bindings) if specs_channel.bindings else None, ) @@ -267,7 +268,7 @@ def get_broker_channels( }, description=specs_channel.description, servers=specs_channel.servers, - bindings=channel_or_operation_binding_from_spec(specs_channel.bindings) + bindings=channel_binding_from_spec(specs_channel.bindings) if specs_channel.bindings else None, ) From 2d0b78d9030f5bca46acadf9bf0afb6a4bef4b5b Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 16 Aug 2024 21:13:17 +0300 Subject: [PATCH 095/245] AsyncAPI 2.6.0 bindings refactoring --- .../asyncapi/v2_6_0/schema/bindings/main/channel.py | 10 +++++----- .../asyncapi/v2_6_0/schema/bindings/main/operation.py | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel.py index 208f0912c3..c489d5cb6e 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel.py @@ -49,19 +49,19 @@ class Config: @classmethod def from_spec(cls, binding: spec.bindings.ChannelBinding) -> Self: return cls( - amqp=amqp_bindings.ChannelBinding.from_spec(binding.amqp) + amqp=amqp_bindings.channel_binding_from_spec(binding.amqp) if binding.amqp is not None else None, - kafka=kafka_bindings.ChannelBinding.from_spec(binding.kafka) + kafka=kafka_bindings.channel_binding_from_spec(binding.kafka) if binding.kafka is not None else None, - sqs=sqs_bindings.ChannelBinding.from_spec(binding.sqs) + sqs=sqs_bindings.channel_binding_from_spec(binding.sqs) if binding.sqs is not None else None, - nats=nats_bindings.ChannelBinding.from_spec(binding.nats) + nats=nats_bindings.channel_binding_from_spec(binding.nats) if binding.nats is not None else None, - redis=redis_bindings.ChannelBinding.from_spec(binding.redis) + redis=redis_bindings.channel_binding_from_spec(binding.redis) if binding.redis is not None else None, ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation.py index 87c228e461..52b316178f 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation.py @@ -49,19 +49,19 @@ class Config: @classmethod def from_spec(cls, binding: spec.bindings.OperationBinding) -> Self: return cls( - amqp=amqp_bindings.OperationBinding.from_spec(binding.amqp) + amqp=amqp_bindings.operation_binding_from_spec(binding.amqp) if binding.amqp is not None else None, - kafka=kafka_bindings.OperationBinding.from_spec(binding.kafka) + kafka=kafka_bindings.operation_binding_from_spec(binding.kafka) if binding.kafka is not None else None, - sqs=sqs_bindings.OperationBinding.from_spec(binding.sqs) + sqs=sqs_bindings.operation_binding_from_spec(binding.sqs) if binding.sqs is not None else None, - nats=nats_bindings.OperationBinding.from_spec(binding.nats) + nats=nats_bindings.operation_binding_from_spec(binding.nats) if binding.nats is not None else None, - redis=redis_bindings.OperationBinding.from_spec(binding.redis) + redis=redis_bindings.operation_binding_from_spec(binding.redis) if binding.redis is not None else None, ) From ae428b479fcbfae7c7bc89281d22a61354255116 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 16 Aug 2024 22:35:16 +0300 Subject: [PATCH 096/245] AsyncAPI 3.0.0 operations building refactoring --- .../specification/asyncapi/v3_0_0/generate.py | 47 ++++++----------- .../asyncapi/v3_0_0/schema/operations.py | 50 +++++++++++++++++-- 2 files changed, 61 insertions(+), 36 deletions(-) diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index fe67de0f5c..ef59e1da50 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -12,7 +12,6 @@ ) from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( channel_binding_from_spec, - operation_binding_from_spec, ) from faststream.specification.asyncapi.v2_6_0.schema.contact import ( from_spec as contact_from_spec, @@ -38,6 +37,12 @@ Schema, Server, ) +from faststream.specification.asyncapi.v3_0_0.schema.operations import ( + Action, +) +from faststream.specification.asyncapi.v3_0_0.schema.operations import ( + from_spec as operation_from_spec, +) from faststream.specification.proto import Application from faststream.types import AnyDict @@ -190,44 +195,20 @@ def get_broker_operations( for h in broker._subscribers.values(): for channel_name, specs_channel in h.schema().items(): if specs_channel.subscribe is not None: - op = Operation( - action="receive", - summary=specs_channel.subscribe.summary, - description=specs_channel.subscribe.description, - bindings=operation_binding_from_spec(specs_channel.subscribe.bindings) - if specs_channel.subscribe.bindings else None, - messages=[ - Reference( - **{"$ref": f"#/channels/{channel_name}/messages/SubscribeMessage"}, - ) - ], - channel=Reference( - **{"$ref": f"#/channels/{channel_name}"}, - ), - security=specs_channel.subscribe.security, + operations[f"{channel_name}Subscribe"] = operation_from_spec( + specs_channel.subscribe, + Action.RECEIVE, + channel_name ) - operations[f"{channel_name}Subscribe"] = op for p in broker._publishers.values(): for channel_name, specs_channel in p.schema().items(): if specs_channel.publish is not None: - op = Operation( - action="send", - summary=specs_channel.publish.summary, - description=specs_channel.publish.description, - bindings=operation_binding_from_spec(specs_channel.publish.bindings) - if specs_channel.publish.bindings else None, - messages=[ - Reference( - **{"$ref": f"#/channels/{channel_name}/messages/Message"}, - ) - ], - channel=Reference( - **{"$ref": f"#/channels/{channel_name}"}, - ), - security=specs_channel.publish.security, + operations[f"{channel_name}"] = operation_from_spec( + specs_channel.publish, + Action.SEND, + channel_name ) - operations[f"{channel_name}"] = op return operations diff --git a/faststream/specification/asyncapi/v3_0_0/schema/operations.py b/faststream/specification/asyncapi/v3_0_0/schema/operations.py index 81d71e8210..b5ce4d5b0f 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/operations.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/operations.py @@ -1,15 +1,28 @@ -from typing import Dict, List, Literal, Optional, Union +from enum import Enum +from typing import Dict, List, Optional, Union from pydantic import BaseModel +from typing_extensions import Self from faststream._compat import PYDANTIC_V2 +from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.schema.bindings import OperationBinding +from faststream.specification.asyncapi.v2_6_0.schema.bindings.main import ( + operation_binding_from_spec, +) from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag -from faststream.specification.asyncapi.v2_6_0.schema.utils import Reference +from faststream.specification.asyncapi.v2_6_0.schema.utils import ( + Reference, +) from faststream.specification.asyncapi.v3_0_0.schema.channels import Channel from faststream.types import AnyDict +class Action(str, Enum): + SEND = "send" + RECEIVE = "receive" + + class Operation(BaseModel): """A class to represent an operation. @@ -23,7 +36,7 @@ class Operation(BaseModel): tags : tags associated with the operation """ - action: Literal["send", "receive"] + action: Action summary: Optional[str] = None description: Optional[str] = None @@ -46,3 +59,34 @@ class Operation(BaseModel): class Config: extra = "allow" + + @classmethod + def from_spec(cls, operation: spec.operation.Operation, action: Action, channel_name: str) -> Self: + return cls( + action=action, + summary=operation.summary, + description=operation.description, + + bindings=operation_binding_from_spec(operation.bindings) + if operation.bindings else None, + + messages=[ + Reference( + **{ + "$ref": f"#/channels/{channel_name}/messages/SubscribeMessage" + if action is Action.RECEIVE else + f"#/channels/{channel_name}/messages/Message" + }, + ) + ], + + channel=Reference( + **{"$ref": f"#/channels/{channel_name}"}, + ), + + security=operation.security, + ) + + +def from_spec(operation: spec.operation.Operation, action: Action, channel_name: str) -> Operation: + return Operation.from_spec(operation, action, channel_name) From 9592cd173e81828e3de373fa28bd7bdbfbef0585 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 16 Aug 2024 23:09:15 +0300 Subject: [PATCH 097/245] AsyncAPI 3.0.0 channels building refactoring --- .../specification/asyncapi/v3_0_0/generate.py | 41 ++++++------------- .../asyncapi/v3_0_0/schema/channels.py | 36 ++++++++++++++++ 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index ef59e1da50..9da86d31bc 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -10,9 +10,6 @@ Reference, Tag, ) -from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( - channel_binding_from_spec, -) from faststream.specification.asyncapi.v2_6_0.schema.contact import ( from_spec as contact_from_spec, ) @@ -23,9 +20,6 @@ from_spec as license_from_spec, ) from faststream.specification.asyncapi.v2_6_0.schema.message import Message -from faststream.specification.asyncapi.v2_6_0.schema.message import ( - from_spec as message_from_spec, -) from faststream.specification.asyncapi.v2_6_0.schema.tag import ( from_spec as tag_from_spec, ) @@ -37,6 +31,9 @@ Schema, Server, ) +from faststream.specification.asyncapi.v3_0_0.schema.channels import ( + from_spec as channel_from_spec, +) from faststream.specification.asyncapi.v3_0_0.schema.operations import ( Action, ) @@ -223,38 +220,26 @@ def get_broker_channels( channels_schema_v3_0 = {} for channel_name, specs_channel in h.schema().items(): if specs_channel.subscribe: - channel_v3_0 = Channel( - address=channel_name, - messages={ - "SubscribeMessage": message_from_spec(specs_channel.subscribe.message), - }, - description=specs_channel.description, - servers=specs_channel.servers, - bindings=channel_binding_from_spec(specs_channel.bindings) - if specs_channel.bindings else None, + channels_schema_v3_0[channel_name] = channel_from_spec( + specs_channel, + specs_channel.subscribe.message, + channel_name, + "SubscribeMessage", ) - channels_schema_v3_0[channel_name] = channel_v3_0 - channels.update(channels_schema_v3_0) for p in broker._publishers.values(): channels_schema_v3_0 = {} for channel_name, specs_channel in p.schema().items(): if specs_channel.publish: - channel_v3_0 = Channel( - address=channel_name, - messages={ - "Message": message_from_spec(specs_channel.publish.message), - }, - description=specs_channel.description, - servers=specs_channel.servers, - bindings=channel_binding_from_spec(specs_channel.bindings) - if specs_channel.bindings else None, + channels_schema_v3_0[channel_name] = channel_from_spec( + specs_channel, + specs_channel.publish.message, + channel_name, + "Message", ) - channels_schema_v3_0[channel_name] = channel_v3_0 - channels.update(channels_schema_v3_0) return channels diff --git a/faststream/specification/asyncapi/v3_0_0/schema/channels.py b/faststream/specification/asyncapi/v3_0_0/schema/channels.py index 56578e18c6..782fada49d 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/channels.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/channels.py @@ -1,10 +1,18 @@ from typing import Dict, List, Optional, Union from pydantic import BaseModel +from typing_extensions import Self from faststream._compat import PYDANTIC_V2 +from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.schema.bindings import ChannelBinding +from faststream.specification.asyncapi.v2_6_0.schema.bindings.main import ( + channel_binding_from_spec, +) from faststream.specification.asyncapi.v2_6_0.schema.message import Message +from faststream.specification.asyncapi.v2_6_0.schema.message import ( + from_spec as message_from_spec, +) from faststream.specification.asyncapi.v2_6_0.schema.utils import Reference @@ -40,3 +48,31 @@ class Channel(BaseModel): class Config: extra = "allow" + + @classmethod + def from_spec( + cls, + channel: spec.channel.Channel, + message: spec.message.Message, + channel_name: str, + message_name: str + ) -> Self: + return cls( + address=channel_name, + messages={ + message_name: message_from_spec(message), + }, + description=channel.description, + servers=channel.servers, + bindings=channel_binding_from_spec(channel.bindings) + if channel.bindings else None, + ) + + +def from_spec( + channel: spec.channel.Channel, + message: spec.message.Message, + channel_name: str, + message_name: str +) -> Channel: + return Channel.from_spec(channel, message, channel_name, message_name) From 1120c897ce5581f4f67abe03eee1f52657fe182a Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 16 Aug 2024 23:47:33 +0300 Subject: [PATCH 098/245] Names fix --- .../asyncapi_customization/custom_broker.py | 2 +- faststream/broker/core/usecase.py | 4 ++-- faststream/confluent/broker/broker.py | 14 +++++++------- faststream/confluent/fastapi/fastapi.py | 4 ++-- faststream/kafka/broker/broker.py | 14 +++++++------- faststream/kafka/fastapi/fastapi.py | 4 ++-- faststream/nats/broker/broker.py | 14 +++++++------- faststream/nats/fastapi/fastapi.py | 4 ++-- faststream/rabbit/broker/broker.py | 16 ++++++++-------- faststream/rabbit/fastapi/router.py | 4 ++-- faststream/redis/broker/broker.py | 10 +++++----- faststream/redis/fastapi/fastapi.py | 4 ++-- .../specification/asyncapi/v3_0_0/generate.py | 17 ++++------------- .../confluent/v2_6_0/test_connection.py | 2 +- .../confluent/v3_0_0/test_connection.py | 2 +- tests/asyncapi/kafka/v2_6_0/test_connection.py | 2 +- tests/asyncapi/kafka/v3_0_0/test_connection.py | 2 +- tests/asyncapi/nats/v2_6_0/test_connection.py | 2 +- tests/asyncapi/nats/v3_0_0/test_connection.py | 2 +- tests/asyncapi/rabbit/v2_6_0/test_connection.py | 2 +- tests/asyncapi/rabbit/v3_0_0/test_connection.py | 2 +- tests/asyncapi/redis/v2_6_0/test_connection.py | 2 +- tests/asyncapi/redis/v3_0_0/test_connection.py | 2 +- 23 files changed, 61 insertions(+), 70 deletions(-) diff --git a/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_broker.py b/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_broker.py index 74247b6d10..4ddcc20cb8 100644 --- a/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_broker.py +++ b/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_broker.py @@ -4,7 +4,7 @@ broker = KafkaBroker( "localhost:9092", description="Kafka broker running locally", - asyncapi_url="non-sensitive-url:9092", + specification_url="non-sensitive-url:9092", ) app = FastStream(broker) diff --git a/faststream/broker/core/usecase.py b/faststream/broker/core/usecase.py index cffda64077..e6d7ea2f09 100644 --- a/faststream/broker/core/usecase.py +++ b/faststream/broker/core/usecase.py @@ -134,7 +134,7 @@ def __init__( Optional[Iterable[Union["Tag", "TagDict"]]], Doc("AsyncAPI server tags."), ], - asyncapi_url: Annotated[ + specification_url: Annotated[ Union[str, List[str]], Doc("AsyncAPI hardcoded server addresses."), ], @@ -192,7 +192,7 @@ def __init__( self._call_decorators = _call_decorators # AsyncAPI information - self.url = asyncapi_url + self.url = specification_url self.protocol = protocol self.protocol_version = protocol_version self.description = description diff --git a/faststream/confluent/broker/broker.py b/faststream/confluent/broker/broker.py index fe2dfcf814..15b9814f45 100644 --- a/faststream/confluent/broker/broker.py +++ b/faststream/confluent/broker/broker.py @@ -281,7 +281,7 @@ def __init__( "Security options to connect broker and generate AsyncAPI server security information." ), ] = None, - asyncapi_url: Annotated[ + specification_url: Annotated[ Union[str, Iterable[str], None], Doc("AsyncAPI hardcoded server addresses. Use `servers` if not specified."), ] = None, @@ -344,13 +344,13 @@ def __init__( else list(bootstrap_servers) ) - if asyncapi_url is not None: - if isinstance(asyncapi_url, str): - asyncapi_url = [asyncapi_url] + if specification_url is not None: + if isinstance(specification_url, str): + specification_url = [specification_url] else: - asyncapi_url = list(asyncapi_url) + specification_url = list(specification_url) else: - asyncapi_url = servers + specification_url = servers super().__init__( bootstrap_servers=servers, @@ -378,7 +378,7 @@ def __init__( middlewares=middlewares, # AsyncAPI args description=description, - asyncapi_url=asyncapi_url, + specification_url=specification_url, protocol=protocol, protocol_version=protocol_version, security=security, diff --git a/faststream/confluent/fastapi/fastapi.py b/faststream/confluent/fastapi/fastapi.py index befa62665b..6cdddcc2fd 100644 --- a/faststream/confluent/fastapi/fastapi.py +++ b/faststream/confluent/fastapi/fastapi.py @@ -283,7 +283,7 @@ def __init__( "Security options to connect broker and generate Specification server security information." ), ] = None, - asyncapi_url: Annotated[ + specification_url: Annotated[ Optional[str], Doc("Specification hardcoded server addresses. Use `servers` if not specified."), ] = None, @@ -583,7 +583,7 @@ def __init__( protocol_version=protocol_version, asyncapi_version=asyncapi_version, asyncapi_tags=asyncapi_tags, - asyncapi_url=asyncapi_url, + specification_url=specification_url, # FastAPI kwargs prefix=prefix, tags=tags, diff --git a/faststream/kafka/broker/broker.py b/faststream/kafka/broker/broker.py index c2ff0c1cca..c9247d684b 100644 --- a/faststream/kafka/broker/broker.py +++ b/faststream/kafka/broker/broker.py @@ -455,7 +455,7 @@ def __init__( "Security options to connect broker and generate AsyncAPI server security information." ), ] = None, - asyncapi_url: Annotated[ + specification_url: Annotated[ Union[str, Iterable[str], None], Doc("AsyncAPI hardcoded server addresses. Use `servers` if not specified."), ] = None, @@ -518,13 +518,13 @@ def __init__( else list(bootstrap_servers) ) - if asyncapi_url is not None: - if isinstance(asyncapi_url, str): - asyncapi_url = [asyncapi_url] + if specification_url is not None: + if isinstance(specification_url, str): + specification_url = [specification_url] else: - asyncapi_url = list(asyncapi_url) + specification_url = list(specification_url) else: - asyncapi_url = servers + specification_url = servers super().__init__( bootstrap_servers=servers, @@ -559,7 +559,7 @@ def __init__( middlewares=middlewares, # AsyncAPI args description=description, - asyncapi_url=asyncapi_url, + specification_url=specification_url, protocol=protocol, protocol_version=protocol_version, security=security, diff --git a/faststream/kafka/fastapi/fastapi.py b/faststream/kafka/fastapi/fastapi.py index 6b1e962b1f..6e75b475bc 100644 --- a/faststream/kafka/fastapi/fastapi.py +++ b/faststream/kafka/fastapi/fastapi.py @@ -291,7 +291,7 @@ def __init__( "Security options to connect broker and generate Specification server security information." ), ] = None, - asyncapi_url: Annotated[ + specification_url: Annotated[ Optional[str], Doc("Specification hardcoded server addresses. Use `servers` if not specified."), ] = None, @@ -598,7 +598,7 @@ def __init__( protocol_version=protocol_version, asyncapi_version=asyncapi_version, asyncapi_tags=asyncapi_tags, - asyncapi_url=asyncapi_url, + specification_url=specification_url, # FastAPI args prefix=prefix, tags=tags, diff --git a/faststream/nats/broker/broker.py b/faststream/nats/broker/broker.py index 5096b7dfe9..9df1319921 100644 --- a/faststream/nats/broker/broker.py +++ b/faststream/nats/broker/broker.py @@ -396,7 +396,7 @@ def __init__( "Security options to connect broker and generate AsyncAPI server security information." ), ] = None, - asyncapi_url: Annotated[ + specification_url: Annotated[ Union[str, Iterable[str], None], Doc("AsyncAPI hardcoded server addresses. Use `servers` if not specified."), ] = None, @@ -477,13 +477,13 @@ def __init__( servers = [servers] if isinstance(servers, str) else list(servers) - if asyncapi_url is not None: - if isinstance(asyncapi_url, str): - asyncapi_url = [asyncapi_url] + if specification_url is not None: + if isinstance(specification_url, str): + specification_url = [specification_url] else: - asyncapi_url = list(asyncapi_url) + specification_url = list(specification_url) else: - asyncapi_url = servers + specification_url = servers super().__init__( # NATS options @@ -527,7 +527,7 @@ def __init__( middlewares=middlewares, # AsyncAPI description=description, - asyncapi_url=asyncapi_url, + specification_url=specification_url, protocol=protocol, protocol_version=protocol_version, security=security, diff --git a/faststream/nats/fastapi/fastapi.py b/faststream/nats/fastapi/fastapi.py index 010e757e2a..24abea120d 100644 --- a/faststream/nats/fastapi/fastapi.py +++ b/faststream/nats/fastapi/fastapi.py @@ -244,7 +244,7 @@ def __init__( "Security options to connect broker and generate AsyncAPI server security information." ), ] = None, - asyncapi_url: Annotated[ + specification_url: Annotated[ Union[str, Iterable[str], None], Doc("AsyncAPI hardcoded server addresses. Use `servers` if not specified."), ] = None, @@ -547,7 +547,7 @@ def __init__( parser=parser, middlewares=middlewares, security=security, - asyncapi_url=asyncapi_url, + specification_url=specification_url, protocol=protocol, protocol_version=protocol_version, description=description, diff --git a/faststream/rabbit/broker/broker.py b/faststream/rabbit/broker/broker.py index 29d2a50486..2bd5fd9ab7 100644 --- a/faststream/rabbit/broker/broker.py +++ b/faststream/rabbit/broker/broker.py @@ -175,7 +175,7 @@ def __init__( "Security options to connect broker and generate AsyncAPI server security information." ), ] = None, - asyncapi_url: Annotated[ + specification_url: Annotated[ Optional[str], Doc("AsyncAPI hardcoded server addresses. Use `servers` if not specified."), ] = None, @@ -240,14 +240,14 @@ def __init__( ssl=security_args.get("ssl"), ) - if asyncapi_url is None: - asyncapi_url = str(amqp_url) + if specification_url is None: + specification_url = str(amqp_url) # respect ascynapi_url argument scheme - builded_asyncapi_url = urlparse(asyncapi_url) - self.virtual_host = builded_asyncapi_url.path + builded_specification_url = urlparse(specification_url) + self.virtual_host = builded_specification_url.path if protocol is None: - protocol = builded_asyncapi_url.scheme + protocol = builded_specification_url.scheme super().__init__( url=str(amqp_url), @@ -267,8 +267,8 @@ def __init__( middlewares=middlewares, # AsyncAPI args description=description, - asyncapi_url=asyncapi_url, - protocol=protocol or builded_asyncapi_url.scheme, + specification_url=specification_url, + protocol=protocol or builded_specification_url.scheme, protocol_version=protocol_version, security=security, tags=tags, diff --git a/faststream/rabbit/fastapi/router.py b/faststream/rabbit/fastapi/router.py index e212b4b70c..b29e0bfe95 100644 --- a/faststream/rabbit/fastapi/router.py +++ b/faststream/rabbit/fastapi/router.py @@ -165,7 +165,7 @@ def __init__( "Security options to connect broker and generate AsyncAPI server security information." ), ] = None, - asyncapi_url: Annotated[ + specification_url: Annotated[ Optional[str], Doc("AsyncAPI hardcoded server addresses. Use `servers` if not specified."), ] = None, @@ -450,7 +450,7 @@ def __init__( on_return_raises=on_return_raises, middlewares=middlewares, security=security, - asyncapi_url=asyncapi_url, + specification_url=specification_url, protocol=protocol, protocol_version=protocol_version, description=description, diff --git a/faststream/redis/broker/broker.py b/faststream/redis/broker/broker.py index e26ce828c6..d1644fde7e 100644 --- a/faststream/redis/broker/broker.py +++ b/faststream/redis/broker/broker.py @@ -144,7 +144,7 @@ def __init__( "Security options to connect broker and generate AsyncAPI server security information." ), ] = None, - asyncapi_url: Annotated[ + specification_url: Annotated[ Optional[str], Doc("AsyncAPI hardcoded server addresses. Use `servers` if not specified."), ] = None, @@ -197,11 +197,11 @@ def __init__( ) -> None: self._producer = None - if asyncapi_url is None: - asyncapi_url = url + if specification_url is None: + specification_url = url if protocol is None: - url_kwargs = urlparse(asyncapi_url) + url_kwargs = urlparse(specification_url) protocol = url_kwargs.scheme super().__init__( @@ -234,7 +234,7 @@ def __init__( middlewares=middlewares, # AsyncAPI description=description, - asyncapi_url=asyncapi_url, + specification_url=specification_url, protocol=protocol, protocol_version=protocol_version, security=security, diff --git a/faststream/redis/fastapi/fastapi.py b/faststream/redis/fastapi/fastapi.py index 799d3bf439..8a16048baf 100644 --- a/faststream/redis/fastapi/fastapi.py +++ b/faststream/redis/fastapi/fastapi.py @@ -114,7 +114,7 @@ def __init__( "Security options to connect broker and generate AsyncAPI server security information." ), ] = None, - asyncapi_url: Annotated[ + specification_url: Annotated[ Optional[str], Doc("AsyncAPI hardcoded server addresses. Use `servers` if not specified."), ] = None, @@ -417,7 +417,7 @@ def __init__( protocol_version=protocol_version, asyncapi_version=asyncapi_version, asyncapi_tags=asyncapi_tags, - asyncapi_url=asyncapi_url, + specification_url=specification_url, # FastAPI kwargs prefix=prefix, tags=tags, diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index 9da86d31bc..aa89bd82ca 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -1,10 +1,8 @@ -from dataclasses import asdict -from typing import TYPE_CHECKING, Dict, List, Union +from typing import TYPE_CHECKING, Dict, List, Optional, Union from urllib.parse import urlparse from faststream._compat import DEF_KEY from faststream.constants import ContentTypes -from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.generate import move_pydantic_refs from faststream.specification.asyncapi.v2_6_0.schema import ( Reference, @@ -120,22 +118,15 @@ def get_broker_server( """Get the broker server for an application.""" servers = {} - tags: List[Union[Tag, AnyDict]] = [] + tags: Optional[List[Union[Tag, AnyDict]]] = None if broker.tags: - - for tag in broker.tags: - if isinstance(tag, spec.tag.Tag): - tags.append(Tag(**asdict(tag))) - elif isinstance(tag, dict): - tags.append(dict(tag)) - else: - raise NotImplementedError(f"Unsupported tag type: {tag}; {type(tag)}") + tags = [tag_from_spec(tag) for tag in broker.tags] broker_meta: AnyDict = { "protocol": broker.protocol, "protocolVersion": broker.protocol_version, "description": broker.description, - "tags": tags if tags else None, + "tags": tags if tags is not None else None, # TODO # "variables": "", # "bindings": "", diff --git a/tests/asyncapi/confluent/v2_6_0/test_connection.py b/tests/asyncapi/confluent/v2_6_0/test_connection.py index 55eff119f5..f8023ed224 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_connection.py +++ b/tests/asyncapi/confluent/v2_6_0/test_connection.py @@ -66,7 +66,7 @@ def test_custom(): FastStream( KafkaBroker( ["kafka:9092", "kafka:9093"], - asyncapi_url=["kafka:9094", "kafka:9095"], + specification_url=["kafka:9094", "kafka:9095"], ) ) ).to_jsonable() diff --git a/tests/asyncapi/confluent/v3_0_0/test_connection.py b/tests/asyncapi/confluent/v3_0_0/test_connection.py index fb9ecce111..5c377779a8 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_connection.py +++ b/tests/asyncapi/confluent/v3_0_0/test_connection.py @@ -76,7 +76,7 @@ def test_custom(): FastStream( KafkaBroker( ["kafka:9092", "kafka:9093"], - asyncapi_url=["kafka:9094", "kafka:9095"], + specification_url=["kafka:9094", "kafka:9095"], ), asyncapi_version=AsyncAPIVersion.v3_0, ) diff --git a/tests/asyncapi/kafka/v2_6_0/test_connection.py b/tests/asyncapi/kafka/v2_6_0/test_connection.py index 0c088210f3..e786749dd7 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_connection.py +++ b/tests/asyncapi/kafka/v2_6_0/test_connection.py @@ -66,7 +66,7 @@ def test_custom(): FastStream( KafkaBroker( ["kafka:9092", "kafka:9093"], - asyncapi_url=["kafka:9094", "kafka:9095"], + specification_url=["kafka:9094", "kafka:9095"], ) ) ).to_jsonable() diff --git a/tests/asyncapi/kafka/v3_0_0/test_connection.py b/tests/asyncapi/kafka/v3_0_0/test_connection.py index 1fbb02ecd4..0ef17b3799 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_connection.py +++ b/tests/asyncapi/kafka/v3_0_0/test_connection.py @@ -76,7 +76,7 @@ def test_custom(): FastStream( KafkaBroker( ["kafka:9092", "kafka:9093"], - asyncapi_url=["kafka:9094", "kafka:9095"], + specification_url=["kafka:9094", "kafka:9095"], ), asyncapi_version=AsyncAPIVersion.v3_0, ) diff --git a/tests/asyncapi/nats/v2_6_0/test_connection.py b/tests/asyncapi/nats/v2_6_0/test_connection.py index 4e8dd6eef3..3e4c1ab9eb 100644 --- a/tests/asyncapi/nats/v2_6_0/test_connection.py +++ b/tests/asyncapi/nats/v2_6_0/test_connection.py @@ -65,7 +65,7 @@ def test_custom(): schema = get_app_schema( FastStream( NatsBroker( - ["nats:9092", "nats:9093"], asyncapi_url=["nats:9094", "nats:9095"] + ["nats:9092", "nats:9093"], specification_url=["nats:9094", "nats:9095"] ) ) ).to_jsonable() diff --git a/tests/asyncapi/nats/v3_0_0/test_connection.py b/tests/asyncapi/nats/v3_0_0/test_connection.py index 8ee0f062a2..36e3cfe4cd 100644 --- a/tests/asyncapi/nats/v3_0_0/test_connection.py +++ b/tests/asyncapi/nats/v3_0_0/test_connection.py @@ -78,7 +78,7 @@ def test_custom(): FastStream( NatsBroker( ["nats:9092", "nats:9093"], - asyncapi_url=["nats:9094", "nats:9095"], + specification_url=["nats:9094", "nats:9095"], ), asyncapi_version=AsyncAPIVersion.v3_0, ) diff --git a/tests/asyncapi/rabbit/v2_6_0/test_connection.py b/tests/asyncapi/rabbit/v2_6_0/test_connection.py index 96b2c5f256..a2717aa968 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_connection.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_connection.py @@ -50,7 +50,7 @@ def test_kwargs(): def test_custom(): broker = RabbitBroker( "amqps://localhost", - asyncapi_url="amqp://guest:guest@127.0.0.1:5672/vh", # pragma: allowlist secret + specification_url="amqp://guest:guest@127.0.0.1:5672/vh", # pragma: allowlist secret ) broker.publisher("test") diff --git a/tests/asyncapi/rabbit/v3_0_0/test_connection.py b/tests/asyncapi/rabbit/v3_0_0/test_connection.py index e070c32ba0..60962baa21 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_connection.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_connection.py @@ -54,7 +54,7 @@ def test_kwargs(): def test_custom(): broker = RabbitBroker( "amqps://localhost", - asyncapi_url="amqp://guest:guest@127.0.0.1:5672/vh", # pragma: allowlist secret + specification_url="amqp://guest:guest@127.0.0.1:5672/vh", # pragma: allowlist secret ) broker.publisher("test") diff --git a/tests/asyncapi/redis/v2_6_0/test_connection.py b/tests/asyncapi/redis/v2_6_0/test_connection.py index 3157597ba6..a58cad172f 100644 --- a/tests/asyncapi/redis/v2_6_0/test_connection.py +++ b/tests/asyncapi/redis/v2_6_0/test_connection.py @@ -39,7 +39,7 @@ def test_custom(): schema = get_app_schema( FastStream( RedisBroker( - "redis://localhost:6379", asyncapi_url="rediss://127.0.0.1:8000" + "redis://localhost:6379", specification_url="rediss://127.0.0.1:8000" ) ) ).to_jsonable() diff --git a/tests/asyncapi/redis/v3_0_0/test_connection.py b/tests/asyncapi/redis/v3_0_0/test_connection.py index 20c388c091..94eaed1554 100644 --- a/tests/asyncapi/redis/v3_0_0/test_connection.py +++ b/tests/asyncapi/redis/v3_0_0/test_connection.py @@ -44,7 +44,7 @@ def test_custom(): FastStream( RedisBroker( "redis://localhost:6379", - asyncapi_url="rediss://127.0.0.1:8000" + specification_url="rediss://127.0.0.1:8000" ), asyncapi_version=AsyncAPIVersion.v3_0, ) From 1b4a7defbd68f469a8b748e2fbfcbfc9aa33dd09 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 17 Aug 2024 10:20:25 +0300 Subject: [PATCH 099/245] AsyncAPI server schema generation simplify --- .../specification/asyncapi/v2_6_0/generate.py | 37 +++++------------- .../specification/asyncapi/v3_0_0/generate.py | 38 ++++--------------- 2 files changed, 17 insertions(+), 58 deletions(-) diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index 1946b7f57a..9ea9afafae 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -1,9 +1,7 @@ -from dataclasses import asdict -from typing import TYPE_CHECKING, Any, Dict, List, Union +from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union from faststream._compat import DEF_KEY from faststream.constants import ContentTypes -from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.schema import ( Channel, Components, @@ -112,22 +110,15 @@ def get_broker_server( """Get the broker server for an application.""" servers = {} - tags: List[Union[Tag, AnyDict]] = [] - + tags: Optional[List[Union[Tag, AnyDict]]] = None if broker.tags: - for tag in broker.tags: - if isinstance(tag, spec.tag.Tag): - tags.append(Tag(**asdict(tag))) - elif isinstance(tag, dict): - tags.append(dict(tag)) - else: - raise NotImplementedError(f"Unsupported tag type: {tag}; {type(tag)}") + tags = [tag_from_spec(tag) for tag in broker.tags] broker_meta: AnyDict = { "protocol": broker.protocol, "protocolVersion": broker.protocol_version, "description": broker.description, - "tags": tags if tags else None, + "tags": tags, # TODO # "variables": "", # "bindings": "", @@ -136,25 +127,15 @@ def get_broker_server( if broker.security is not None: broker_meta["security"] = broker.security.get_requirement() - if isinstance(broker.url, str): - servers["development"] = Server( - url=broker.url, - **broker_meta, - ) + urls = broker.url if isinstance(broker.url, list) else [broker.url] - elif len(broker.url) == 1: - servers["development"] = Server( - url=broker.url[0], + for i, url in enumerate(urls, 1): + server_name = "development" if len(urls) == 1 else f"Server{i}" + servers[server_name] = Server( + url=url, **broker_meta, ) - else: - for i, url in enumerate(broker.url, 1): - servers[f"Server{i}"] = Server( - url=url, - **broker_meta, - ) - return servers diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index aa89bd82ca..d35cd8f7d5 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -126,7 +126,7 @@ def get_broker_server( "protocol": broker.protocol, "protocolVersion": broker.protocol_version, "description": broker.description, - "tags": tags if tags is not None else None, + "tags": tags, # TODO # "variables": "", # "bindings": "", @@ -135,42 +135,20 @@ def get_broker_server( if broker.security is not None: broker_meta["security"] = broker.security.get_requirement() - if isinstance(broker.url, str): - broker_url = broker.url - if "://" not in broker_url: - broker_url = "//" + broker_url - - url = urlparse(broker_url) - servers["development"] = Server( - host=url.netloc, - pathname=url.path, - **broker_meta, - ) + urls = broker.url if isinstance(broker.url, list) else [broker.url] - elif len(broker.url) == 1: - broker_url = broker.url[0] + for i, broker_url in enumerate(urls, 1): if "://" not in broker_url: broker_url = "//" + broker_url - url = urlparse(broker_url) - servers["development"] = Server( - host=url.netloc, - pathname=url.path, + parsed_url = urlparse(broker_url) + server_name = "development" if len(urls) == 1 else f"Server{i}" + servers[server_name] = Server( + host=parsed_url.netloc, + pathname=parsed_url.path, **broker_meta, ) - else: - for i, broker_url in enumerate(broker.url, 1): - if "://" not in broker_url: - broker_url = "//" + broker_url - - parsed_url = urlparse(broker_url) - servers[f"Server{i}"] = Server( - host=parsed_url.netloc, - pathname=parsed_url.path, - **broker_meta, - ) - return servers From 4fef9818e00b7aefac9954aaf5e60ed9f9de825b Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 17 Aug 2024 11:45:09 +0300 Subject: [PATCH 100/245] AsyncAPI schema generation refactoring --- .../specification/asyncapi/v2_6_0/generate.py | 57 +++++++++++-------- .../specification/asyncapi/v3_0_0/generate.py | 5 +- 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index 9ea9afafae..eb786fcdac 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -40,6 +40,7 @@ def get_app_schema(app: Application) -> Schema: broker = app.broker if broker is None: # pragma: no cover raise RuntimeError() + broker.setup() servers = get_broker_server(broker) @@ -47,30 +48,13 @@ def get_app_schema(app: Application) -> Schema: messages: Dict[str, Message] = {} payloads: Dict[str, AnyDict] = {} + + for channel in channels.values(): + channel.servers = list(servers.keys()) + for channel_name, ch in channels.items(): - ch.servers = list(servers.keys()) - - if ch.subscribe is not None: - m = ch.subscribe.message - - if isinstance(m, Message): # pragma: no branch - ch.subscribe.message = _resolve_msg_payloads( - m, - channel_name, - payloads, - messages, - ) - - if ch.publish is not None: - m = ch.publish.message - - if isinstance(m, Message): # pragma: no branch - ch.publish.message = _resolve_msg_payloads( - m, - channel_name, - payloads, - messages, - ) + resolve_channel_messages(ch, channel_name, payloads, messages) + schema = Schema( info=Info( title=app.title, @@ -104,6 +88,33 @@ def get_app_schema(app: Application) -> Schema: return schema +def resolve_channel_messages( + channel: Channel, + channel_name: str, + payloads: Dict[str, AnyDict], + messages: Dict[str, Message], +) -> None: + if channel.subscribe is not None: + assert isinstance(channel.subscribe.message, Message) + + channel.subscribe.message = _resolve_msg_payloads( + channel.subscribe.message, + channel_name, + payloads, + messages, + ) + + if channel.publish is not None: + assert isinstance(channel.publish.message, Message) + + channel.publish.message = _resolve_msg_payloads( + channel.publish.message, + channel_name, + payloads, + messages, + ) + + def get_broker_server( broker: "BrokerUsecase[MsgType, ConnectionType]", ) -> Dict[str, Server]: diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index d35cd8f7d5..18c54191f8 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -60,6 +60,9 @@ def get_app_schema(app: Application) -> Schema: messages: Dict[str, Message] = {} payloads: Dict[str, AnyDict] = {} + for channel in channels.values(): + channel.servers = [{"$ref": f"#/servers/{server_name}"} for server_name in list(servers.keys())] + for channel_name, channel in channels.items(): msgs: Dict[str, Union[Message, Reference]] = {} for message_name, message in channel.messages.items(): @@ -75,8 +78,6 @@ def get_app_schema(app: Application) -> Schema: channel.messages = msgs - channel.servers = [{"$ref": f"#/servers/{server_name}"} for server_name in list(servers.keys())] - schema = Schema( info=Info( title=app.title, From 4efccb37173b6f5a0cfb33074f4b16a2f6b05f53 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 17 Aug 2024 12:13:39 +0300 Subject: [PATCH 101/245] AsyncAPI schema generation refactoring --- .../specification/asyncapi/v2_6_0/__init__.py | 2 - .../specification/asyncapi/v2_6_0/generate.py | 20 +++------- .../asyncapi/v2_6_0/schema/__init__.py | 38 +++++++++++++++---- .../specification/asyncapi/v3_0_0/generate.py | 24 +++--------- .../asyncapi/v3_0_0/schema/__init__.py | 8 +++- 5 files changed, 48 insertions(+), 44 deletions(-) diff --git a/faststream/specification/asyncapi/v2_6_0/__init__.py b/faststream/specification/asyncapi/v2_6_0/__init__.py index be8f2c412c..beb75418a6 100644 --- a/faststream/specification/asyncapi/v2_6_0/__init__.py +++ b/faststream/specification/asyncapi/v2_6_0/__init__.py @@ -1,7 +1,5 @@ -from . import schema from .generate import get_app_schema __all__ = ( - "schema", "get_app_schema", ) diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index eb786fcdac..6c93bb0b8a 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -10,23 +10,13 @@ Schema, Server, Tag, -) -from faststream.specification.asyncapi.v2_6_0.schema.channels import ( - from_spec as channel_from_spec, -) -from faststream.specification.asyncapi.v2_6_0.schema.contact import ( - from_spec as contact_from_spec, -) -from faststream.specification.asyncapi.v2_6_0.schema.docs import ( - from_spec as docs_from_spec, -) -from faststream.specification.asyncapi.v2_6_0.schema.license import ( - from_spec as license_from_spec, + channel_from_spec, + contact_from_spec, + docs_from_spec, + license_from_spec, + tag_from_spec, ) from faststream.specification.asyncapi.v2_6_0.schema.message import Message -from faststream.specification.asyncapi.v2_6_0.schema.tag import ( - from_spec as tag_from_spec, -) from faststream.specification.proto import Application from faststream.types import AnyDict diff --git a/faststream/specification/asyncapi/v2_6_0/schema/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/__init__.py index 20aeb02dc1..1968a1106c 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/__init__.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/__init__.py @@ -1,32 +1,54 @@ -from . import bindings from .channels import Channel +from .channels import from_spec as channel_from_spec from .components import Components from .contact import Contact +from .contact import from_spec as contact_from_spec from .docs import ExternalDocs +from .docs import from_spec as docs_from_spec from .info import Info from .license import License +from .license import from_spec as license_from_spec from .message import CorrelationId, Message +from .message import from_spec as message_from_spec from .operations import Operation +from .operations import from_spec as operation_from_spec from .schema import Schema from .servers import Server, ServerVariable from .tag import Tag +from .tag import from_spec as tag_from_spec from .utils import Parameter, Reference __all__ = ( + "ExternalDocs", + "docs_from_spec", + + "Tag", + "tag_from_spec", + "Channel", - "Components", - "Info", + "channel_from_spec", + "License", + "license_from_spec", + "Contact", + "contact_from_spec", + + "CorrelationId", + "Message", + "message_from_spec", + "Operation", + "operation_from_spec", + + "Channel", + "channel_from_spec", + + "Components", + "Info", "Schema", "Server", "ServerVariable", - "Message", - "CorrelationId", - "ExternalDocs", - "Tag", "Reference", "Parameter", - "bindings", ) diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index 18c54191f8..a5ad948651 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -7,20 +7,12 @@ from faststream.specification.asyncapi.v2_6_0.schema import ( Reference, Tag, -) -from faststream.specification.asyncapi.v2_6_0.schema.contact import ( - from_spec as contact_from_spec, -) -from faststream.specification.asyncapi.v2_6_0.schema.docs import ( - from_spec as docs_from_spec, -) -from faststream.specification.asyncapi.v2_6_0.schema.license import ( - from_spec as license_from_spec, + contact_from_spec, + docs_from_spec, + license_from_spec, + tag_from_spec, ) from faststream.specification.asyncapi.v2_6_0.schema.message import Message -from faststream.specification.asyncapi.v2_6_0.schema.tag import ( - from_spec as tag_from_spec, -) from faststream.specification.asyncapi.v3_0_0.schema import ( Channel, Components, @@ -28,16 +20,12 @@ Operation, Schema, Server, -) -from faststream.specification.asyncapi.v3_0_0.schema.channels import ( - from_spec as channel_from_spec, + channel_from_spec, + operation_from_spec, ) from faststream.specification.asyncapi.v3_0_0.schema.operations import ( Action, ) -from faststream.specification.asyncapi.v3_0_0.schema.operations import ( - from_spec as operation_from_spec, -) from faststream.specification.proto import Application from faststream.types import AnyDict diff --git a/faststream/specification/asyncapi/v3_0_0/schema/__init__.py b/faststream/specification/asyncapi/v3_0_0/schema/__init__.py index 01a9788a2e..8f681f0e04 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/__init__.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/__init__.py @@ -1,15 +1,21 @@ from .channels import Channel +from .channels import from_spec as channel_from_spec from .components import Components from .info import Info from .operations import Operation +from .operations import from_spec as operation_from_spec from .schema import Schema from .servers import Server __all__ = ( "Channel", + "channel_from_spec", + + "Operation", + "operation_from_spec", + "Components", "Info", - "Operation", "Schema", "Server", ) From 71e16dbf49e5ae63b8c0929ef607bac7b491500f Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 17 Aug 2024 12:24:56 +0300 Subject: [PATCH 102/245] AsyncAPI schemas refactoring --- .../specification/asyncapi/v2_6_0/generate.py | 1 + .../asyncapi/v2_6_0/schema/schema.py | 26 ------------------- .../specification/asyncapi/v3_0_0/generate.py | 1 + .../asyncapi/v3_0_0/schema/schema.py | 26 ------------------- 4 files changed, 2 insertions(+), 52 deletions(-) diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index 6c93bb0b8a..2d53c8f100 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -27,6 +27,7 @@ def get_app_schema(app: Application) -> Schema: """Get the application schema.""" + broker = app.broker if broker is None: # pragma: no cover raise RuntimeError() diff --git a/faststream/specification/asyncapi/v2_6_0/schema/schema.py b/faststream/specification/asyncapi/v2_6_0/schema/schema.py index 83df8f7929..8c0c48d2ef 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/schema.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/schema.py @@ -42,29 +42,3 @@ class Schema(BaseSchema): components: Optional[Components] = None tags: Optional[List[Union[Tag, AnyDict]]] = None externalDocs: Optional[Union[ExternalDocs, AnyDict]] = None - - def to_jsonable(self) -> Any: - """Convert the schema to a JSON-serializable object.""" - return model_to_jsonable( - self, - by_alias=True, - exclude_none=True, - ) - - def to_json(self) -> str: - """Convert the schema to a JSON string.""" - return model_to_json( - self, - by_alias=True, - exclude_none=True, - ) - - def to_yaml(self) -> str: - """Convert the schema to a YAML string.""" - from io import StringIO - - import yaml - - io = StringIO(initial_value="", newline="\n") - yaml.dump(self.to_jsonable(), io, sort_keys=False) - return io.getvalue() diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index a5ad948651..4a1bd93541 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -36,6 +36,7 @@ def get_app_schema(app: Application) -> Schema: """Get the application schema.""" + broker = app.broker if broker is None: # pragma: no cover raise RuntimeError() diff --git a/faststream/specification/asyncapi/v3_0_0/schema/schema.py b/faststream/specification/asyncapi/v3_0_0/schema/schema.py index 6dbcff4c66..e164719b07 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/schema.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/schema.py @@ -37,29 +37,3 @@ class Schema(BaseSchema): channels: Dict[str, Channel] operations: Dict[str, Operation] components: Optional[Components] = None - - def to_jsonable(self) -> Any: - """Convert the schema to a JSON-serializable object.""" - return model_to_jsonable( - self, - by_alias=True, - exclude_none=True, - ) - - def to_json(self) -> str: - """Convert the schema to a JSON string.""" - return model_to_json( - self, - by_alias=True, - exclude_none=True, - ) - - def to_yaml(self) -> str: - """Convert the schema to a YAML string.""" - from io import StringIO - - import yaml - - io = StringIO(initial_value="", newline="\n") - yaml.dump(self.to_jsonable(), io, sort_keys=False) - return io.getvalue() From 74245e2ae8281d2a4c4af85c3fe449324f2be46c Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 17 Aug 2024 13:08:27 +0300 Subject: [PATCH 103/245] Documentation generation from AsyncAPI 3.0.0 support. Documentation site still breaks --- faststream/cli/docs/app.py | 15 ++++++++++++--- faststream/exceptions.py | 4 ++++ .../specification/asyncapi/v2_6_0/generate.py | 1 - .../asyncapi/v2_6_0/schema/schema.py | 3 +-- .../specification/asyncapi/v3_0_0/generate.py | 1 - .../asyncapi/v3_0_0/schema/schema.py | 3 +-- 6 files changed, 18 insertions(+), 9 deletions(-) diff --git a/faststream/cli/docs/app.py b/faststream/cli/docs/app.py index 8e7170a3ff..a49df12eed 100644 --- a/faststream/cli/docs/app.py +++ b/faststream/cli/docs/app.py @@ -1,17 +1,20 @@ import json import sys import warnings +from contextlib import suppress from pathlib import Path from typing import Optional, Sequence import typer +from pydantic import ValidationError from faststream._compat import json_dumps, model_parse from faststream.cli.utils.imports import import_from_string -from faststream.exceptions import INSTALL_WATCHFILES, INSTALL_YAML +from faststream.exceptions import INSTALL_WATCHFILES, INSTALL_YAML, SCHEMA_NOT_SUPPORTED from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.site import serve_app -from faststream.specification.asyncapi.v2_6_0.schema import Schema +from faststream.specification.asyncapi.v2_6_0.schema import Schema as SchemaV2_6 +from faststream.specification.asyncapi.v3_0_0.schema import Schema as SchemaV3 docs_app = typer.Typer(pretty_exceptions_short=True) @@ -183,6 +186,12 @@ def _parse_and_serve( f"Unknown extension given - {app}; Please provide app in format [python_module:FastStream] or [asyncapi.yaml/.json] - path to your application or documentation" ) - raw_schema = model_parse(Schema, data) + for schema in (SchemaV3, SchemaV2_6): + with suppress(ValidationError): + raw_schema = model_parse(schema, data) + break + else: + typer.echo(SCHEMA_NOT_SUPPORTED.format(schema_filename=app), err=True) + raise typer.Exit(1) serve_app(raw_schema, host, port) diff --git a/faststream/exceptions.py b/faststream/exceptions.py index 5de18549ee..fde0fdcaa0 100644 --- a/faststream/exceptions.py +++ b/faststream/exceptions.py @@ -128,3 +128,7 @@ class SubscriberNotFound(FastStreamException): To use restart feature, please install dependencies:\n pip install watchfiles """ + +SCHEMA_NOT_SUPPORTED = ( + "{schema_filename} not supported. Make sure that your schema is valid and schema version supported by FastStream" +) diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index 2d53c8f100..6c93bb0b8a 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -27,7 +27,6 @@ def get_app_schema(app: Application) -> Schema: """Get the application schema.""" - broker = app.broker if broker is None: # pragma: no cover raise RuntimeError() diff --git a/faststream/specification/asyncapi/v2_6_0/schema/schema.py b/faststream/specification/asyncapi/v2_6_0/schema/schema.py index 8c0c48d2ef..336e83777f 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/schema.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/schema.py @@ -1,6 +1,5 @@ -from typing import Any, Dict, List, Optional, Union +from typing import Dict, List, Optional, Union -from faststream._compat import model_to_json, model_to_jsonable from faststream.specification.asyncapi.base.schema import BaseSchema from faststream.specification.asyncapi.v2_6_0.schema.channels import Channel from faststream.specification.asyncapi.v2_6_0.schema.components import Components diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index 4a1bd93541..a5ad948651 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -36,7 +36,6 @@ def get_app_schema(app: Application) -> Schema: """Get the application schema.""" - broker = app.broker if broker is None: # pragma: no cover raise RuntimeError() diff --git a/faststream/specification/asyncapi/v3_0_0/schema/schema.py b/faststream/specification/asyncapi/v3_0_0/schema/schema.py index e164719b07..663c2ae0c1 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/schema.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/schema.py @@ -1,6 +1,5 @@ -from typing import Any, Dict, Optional +from typing import Dict, Optional -from faststream._compat import model_to_json, model_to_jsonable from faststream.specification.asyncapi.base.schema import BaseSchema from faststream.specification.asyncapi.v3_0_0.schema.channels import Channel from faststream.specification.asyncapi.v3_0_0.schema.components import Components From 91f2bd93b3c0ee90f941f0d1dc96a0d91bf31c3a Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 17 Aug 2024 15:11:19 +0300 Subject: [PATCH 104/245] Add asyncapi in docs CLI commands --- faststream/cli/docs/__init__.py | 6 ++++++ faststream/cli/docs/asyncapi/__init__.py | 1 + faststream/cli/docs/{ => asyncapi}/app.py | 14 ++++++++++---- faststream/cli/main.py | 4 ++-- faststream/specification/asyncapi/generate.py | 6 +++--- 5 files changed, 22 insertions(+), 9 deletions(-) create mode 100644 faststream/cli/docs/asyncapi/__init__.py rename faststream/cli/docs/{ => asyncapi}/app.py (92%) diff --git a/faststream/cli/docs/__init__.py b/faststream/cli/docs/__init__.py index e69de29bb2..3c50e8fa06 100644 --- a/faststream/cli/docs/__init__.py +++ b/faststream/cli/docs/__init__.py @@ -0,0 +1,6 @@ +import typer + +from .asyncapi import asyncapi_app + +docs_app = typer.Typer(pretty_exceptions_short=True) +docs_app.add_typer(asyncapi_app, name="asyncapi") diff --git a/faststream/cli/docs/asyncapi/__init__.py b/faststream/cli/docs/asyncapi/__init__.py new file mode 100644 index 0000000000..182c5264e9 --- /dev/null +++ b/faststream/cli/docs/asyncapi/__init__.py @@ -0,0 +1 @@ +from .app import asyncapi_app diff --git a/faststream/cli/docs/app.py b/faststream/cli/docs/asyncapi/app.py similarity index 92% rename from faststream/cli/docs/app.py rename to faststream/cli/docs/asyncapi/app.py index a49df12eed..d9195a03e6 100644 --- a/faststream/cli/docs/app.py +++ b/faststream/cli/docs/asyncapi/app.py @@ -15,11 +15,12 @@ from faststream.specification.asyncapi.site import serve_app from faststream.specification.asyncapi.v2_6_0.schema import Schema as SchemaV2_6 from faststream.specification.asyncapi.v3_0_0.schema import Schema as SchemaV3 +from faststream.specification.asyncapi.version import AsyncAPIVersion -docs_app = typer.Typer(pretty_exceptions_short=True) +asyncapi_app = typer.Typer(pretty_exceptions_short=True) -@docs_app.command(name="serve") +@asyncapi_app.command(name="serve") def serve( app: str = typer.Argument( ..., @@ -89,7 +90,7 @@ def serve( _parse_and_serve(app, host, port, is_factory) -@docs_app.command(name="gen") +@asyncapi_app.command(name="gen") def gen( app: str = typer.Argument( ..., @@ -119,6 +120,11 @@ def gen( is_flag=True, help="Treat APP as an application factory.", ), + asyncapi_version: str = typer.Option( + "3.0.0", + "--version", + help="Version of asyncapi schema. Currently supported only 3.0.0 and 2.6.0" + ) ) -> None: """Generate project AsyncAPI schema.""" if app_dir: # pragma: no branch @@ -127,7 +133,7 @@ def gen( _, app_obj = import_from_string(app) if callable(app_obj) and is_factory: app_obj = app_obj() - raw_schema = get_app_schema(app_obj) + raw_schema = get_app_schema(app_obj, AsyncAPIVersion(asyncapi_version)) if yaml: try: diff --git a/faststream/cli/main.py b/faststream/cli/main.py index 900a36d810..f6bbca62a2 100644 --- a/faststream/cli/main.py +++ b/faststream/cli/main.py @@ -11,7 +11,7 @@ from faststream import FastStream from faststream.__about__ import __version__ -from faststream.cli.docs.app import docs_app +from faststream.cli.docs import docs_app from faststream.cli.utils.imports import import_from_string from faststream.cli.utils.logs import LogLevels, get_log_level, set_log_level from faststream.cli.utils.parser import parse_cli_args @@ -22,7 +22,7 @@ from faststream.types import AnyDict, SettingField cli = typer.Typer(pretty_exceptions_short=True) -cli.add_typer(docs_app, name="docs", help="AsyncAPI schema commands") +cli.add_typer(docs_app, name="docs", help="Documentations commands") def version_callback(version: bool) -> None: diff --git a/faststream/specification/asyncapi/generate.py b/faststream/specification/asyncapi/generate.py index f8c8633b16..f99f5262e5 100644 --- a/faststream/specification/asyncapi/generate.py +++ b/faststream/specification/asyncapi/generate.py @@ -13,11 +13,11 @@ from faststream.specification.proto import Application -def get_app_schema(app: "Application") -> BaseSchema: - if app.asyncapi_version == AsyncAPIVersion.v3_0: +def get_app_schema(app: "Application", version: AsyncAPIVersion) -> BaseSchema: + if version == AsyncAPIVersion.v3_0: return get_app_schema_v3(app) - if app.asyncapi_version == AsyncAPIVersion.v2_6: + if version == AsyncAPIVersion.v2_6: return get_app_schema_v2_6(app) raise NotImplementedError(f"AsyncAPI version not supported: {app.asyncapi_version}") From 15486d44968bc06410bb999e14d65d76c4904f31 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 17 Aug 2024 21:42:22 +0300 Subject: [PATCH 105/245] Tests update --- .../getting_started/asyncapi/serve.py | 20 ++++----- faststream/asgi/factories.py | 3 +- faststream/broker/fastapi/router.py | 2 +- faststream/cli/docs/asyncapi/app.py | 2 +- faststream/specification/asyncapi/generate.py | 2 +- .../asyncapi_customization/test_basic.py | 4 +- .../asyncapi_customization/test_broker.py | 3 +- .../asyncapi_customization/test_handler.py | 3 +- .../asyncapi_customization/test_info.py | 3 +- .../asyncapi_customization/test_payload.py | 3 +- tests/a_docs/rabbit/test_security.py | 4 +- tests/a_docs/redis/test_security.py | 4 +- tests/asyncapi/base/v2_6_0/__init__.py | 0 tests/asyncapi/base/{ => v2_6_0}/arguments.py | 43 ++++++++++--------- tests/asyncapi/base/{ => v2_6_0}/fastapi.py | 3 +- tests/asyncapi/base/{ => v2_6_0}/naming.py | 37 ++++++++-------- tests/asyncapi/base/{ => v2_6_0}/publisher.py | 15 ++++--- tests/asyncapi/base/{ => v2_6_0}/router.py | 3 +- tests/asyncapi/base/v3_0_0/arguments.py | 42 +++++++++--------- tests/asyncapi/base/v3_0_0/fastapi.py | 4 +- tests/asyncapi/base/v3_0_0/publisher.py | 14 +++--- .../confluent/v2_6_0/test_arguments.py | 5 ++- .../confluent/v2_6_0/test_connection.py | 10 +++-- .../asyncapi/confluent/v2_6_0/test_fastapi.py | 9 ++-- .../asyncapi/confluent/v2_6_0/test_naming.py | 5 ++- .../confluent/v2_6_0/test_publisher.py | 5 ++- .../asyncapi/confluent/v2_6_0/test_router.py | 9 ++-- .../confluent/v2_6_0/test_security.py | 11 ++--- .../confluent/v3_0_0/test_arguments.py | 3 +- .../asyncapi/confluent/v3_0_0/test_fastapi.py | 3 +- .../confluent/v3_0_0/test_publisher.py | 3 +- .../asyncapi/confluent/v3_0_0/test_router.py | 4 +- .../confluent/v3_0_0/test_security.py | 8 ++-- tests/asyncapi/kafka/v2_6_0/test_app.py | 15 ++++--- tests/asyncapi/kafka/v2_6_0/test_arguments.py | 5 ++- .../asyncapi/kafka/v2_6_0/test_connection.py | 10 +++-- tests/asyncapi/kafka/v2_6_0/test_fastapi.py | 9 ++-- tests/asyncapi/kafka/v2_6_0/test_naming.py | 5 ++- tests/asyncapi/kafka/v2_6_0/test_publisher.py | 5 ++- tests/asyncapi/kafka/v2_6_0/test_router.py | 9 ++-- tests/asyncapi/kafka/v2_6_0/test_security.py | 11 ++--- tests/asyncapi/kafka/v3_0_0/test_arguments.py | 3 +- tests/asyncapi/kafka/v3_0_0/test_fastapi.py | 3 +- tests/asyncapi/kafka/v3_0_0/test_publisher.py | 3 +- tests/asyncapi/kafka/v3_0_0/test_router.py | 4 +- tests/asyncapi/kafka/v3_0_0/test_security.py | 8 ++-- tests/asyncapi/nats/v2_6_0/test_arguments.py | 5 ++- tests/asyncapi/nats/v2_6_0/test_connection.py | 10 +++-- tests/asyncapi/nats/v2_6_0/test_fastapi.py | 6 +-- tests/asyncapi/nats/v2_6_0/test_kv_schema.py | 3 +- tests/asyncapi/nats/v2_6_0/test_naming.py | 5 ++- tests/asyncapi/nats/v2_6_0/test_obj_schema.py | 3 +- tests/asyncapi/nats/v2_6_0/test_publisher.py | 5 ++- tests/asyncapi/nats/v2_6_0/test_router.py | 9 ++-- tests/asyncapi/nats/v3_0_0/test_arguments.py | 3 +- tests/asyncapi/nats/v3_0_0/test_publisher.py | 3 +- tests/asyncapi/nats/v3_0_0/test_router.py | 4 +- .../asyncapi/rabbit/v2_6_0/test_arguments.py | 7 +-- .../asyncapi/rabbit/v2_6_0/test_connection.py | 6 ++- tests/asyncapi/rabbit/v2_6_0/test_fastapi.py | 9 ++-- tests/asyncapi/rabbit/v2_6_0/test_naming.py | 9 ++-- .../asyncapi/rabbit/v2_6_0/test_publisher.py | 11 ++--- tests/asyncapi/rabbit/v2_6_0/test_router.py | 9 ++-- tests/asyncapi/rabbit/v2_6_0/test_security.py | 7 +-- .../asyncapi/rabbit/v3_0_0/test_arguments.py | 5 ++- .../asyncapi/rabbit/v3_0_0/test_publisher.py | 9 ++-- tests/asyncapi/rabbit/v3_0_0/test_router.py | 4 +- tests/asyncapi/redis/v2_6_0/test_arguments.py | 13 +++--- .../asyncapi/redis/v2_6_0/test_connection.py | 7 ++- tests/asyncapi/redis/v2_6_0/test_fastapi.py | 6 +-- tests/asyncapi/redis/v2_6_0/test_naming.py | 5 ++- tests/asyncapi/redis/v2_6_0/test_publisher.py | 9 ++-- tests/asyncapi/redis/v2_6_0/test_router.py | 9 ++-- tests/asyncapi/redis/v2_6_0/test_security.py | 7 +-- tests/asyncapi/redis/v3_0_0/test_arguments.py | 11 ++--- tests/asyncapi/redis/v3_0_0/test_publisher.py | 7 +-- tests/asyncapi/redis/v3_0_0/test_router.py | 4 +- tests/cli/test_asyncapi_docs.py | 12 +++--- 78 files changed, 339 insertions(+), 262 deletions(-) create mode 100644 tests/asyncapi/base/v2_6_0/__init__.py rename tests/asyncapi/base/{ => v2_6_0}/arguments.py (89%) rename tests/asyncapi/base/{ => v2_6_0}/fastapi.py (96%) rename tests/asyncapi/base/{ => v2_6_0}/naming.py (86%) rename tests/asyncapi/base/{ => v2_6_0}/publisher.py (81%) rename tests/asyncapi/base/{ => v2_6_0}/router.py (96%) diff --git a/docs/docs_src/getting_started/asyncapi/serve.py b/docs/docs_src/getting_started/asyncapi/serve.py index 5ea752fc2c..e75fb88fb0 100644 --- a/docs/docs_src/getting_started/asyncapi/serve.py +++ b/docs/docs_src/getting_started/asyncapi/serve.py @@ -5,22 +5,22 @@ """ -gen_json_cmd = """ -faststream docs gen basic:app +gen_asyncapi_json_cmd = """ +faststream docs asyncapi gen basic:app """ -gen_yaml_cmd = """ -faststream docs gen --yaml basic:app +gen_asyncapi_yaml_cmd = """ +faststream docs asyncapi gen --yaml basic:app """ -serve_cmd = """ -faststream docs serve basic:app +asyncapi_serve_cmd = """ +faststream docs asyncapi serve basic:app """ -serve_json_cmd = """ -faststream docs serve asyncapi.json +asyncapi_serve_json_cmd = """ +faststream docs asyncapi serve asyncapi.json """ -serve_yaml_cmd = """ -faststream docs serve asyncapi.yaml +asyncapi_serve_yaml_cmd = """ +faststream docs asyncapi serve asyncapi.yaml """ diff --git a/faststream/asgi/factories.py b/faststream/asgi/factories.py index 41122b9db2..6b00252b46 100644 --- a/faststream/asgi/factories.py +++ b/faststream/asgi/factories.py @@ -12,6 +12,7 @@ ASYNCAPI_JS_DEFAULT_URL, get_asyncapi_html, ) +from faststream.specification.asyncapi.version import AsyncAPIVersion if TYPE_CHECKING: from faststream.asgi.types import ASGIApp, Scope @@ -53,7 +54,7 @@ def make_asyncapi_asgi( ) -> "ASGIApp": return AsgiResponse( get_asyncapi_html( - get_app_schema(app), + get_app_schema(app, version=AsyncAPIVersion.v2_6), sidebar=sidebar, info=info, servers=servers, diff --git a/faststream/broker/fastapi/router.py b/faststream/broker/fastapi/router.py index fe42f29109..bde2345ddb 100644 --- a/faststream/broker/fastapi/router.py +++ b/faststream/broker/fastapi/router.py @@ -305,7 +305,7 @@ async def start_broker_lifespan( from faststream.specification.asyncapi.generate import get_app_schema - self.schema = get_app_schema(self) + self.schema = get_app_schema(self, version=AsyncAPIVersion.v2_6) app.include_router(self.docs_router) diff --git a/faststream/cli/docs/asyncapi/app.py b/faststream/cli/docs/asyncapi/app.py index d9195a03e6..f3227a0a2c 100644 --- a/faststream/cli/docs/asyncapi/app.py +++ b/faststream/cli/docs/asyncapi/app.py @@ -167,7 +167,7 @@ def _parse_and_serve( _, app_obj = import_from_string(app) if callable(app_obj) and is_factory: app_obj = app_obj() - raw_schema = get_app_schema(app_obj) + raw_schema = get_app_schema(app_obj, AsyncAPIVersion.v2_6) else: schema_filepath = Path.cwd() / app diff --git a/faststream/specification/asyncapi/generate.py b/faststream/specification/asyncapi/generate.py index f99f5262e5..ac5a71b843 100644 --- a/faststream/specification/asyncapi/generate.py +++ b/faststream/specification/asyncapi/generate.py @@ -13,7 +13,7 @@ from faststream.specification.proto import Application -def get_app_schema(app: "Application", version: AsyncAPIVersion) -> BaseSchema: +def get_app_schema(app: "Application", version: AsyncAPIVersion = AsyncAPIVersion.v3_0) -> BaseSchema: if version == AsyncAPIVersion.v3_0: return get_app_schema_v3(app) diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py index 1d1de980c9..2f381ca0a2 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py @@ -1,9 +1,11 @@ from docs.docs_src.getting_started.asyncapi.asyncapi_customization.basic import app from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion def test_basic_customization(): - schema = get_app_schema(app).to_jsonable() + schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() + assert schema == { "asyncapi": "2.6.0", "channels": { diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_broker.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_broker.py index 3c9328135c..337a7a650e 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_broker.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_broker.py @@ -2,10 +2,11 @@ app, ) from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion def test_broker_customization(): - schema = get_app_schema(app).to_jsonable() + schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() assert schema["servers"] == { "development": { diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py index f18660566e..db71cf3e71 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py @@ -2,10 +2,11 @@ app, ) from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion def test_handler_customization(): - schema = get_app_schema(app).to_jsonable() + schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() assert schema["channels"] == { "input_data:Consume": { diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_info.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_info.py index 17b7c23737..655f9c43ac 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_info.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_info.py @@ -2,10 +2,11 @@ app, ) from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion def test_info_customization(): - schema = get_app_schema(app).to_jsonable() + schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() assert schema["info"] == { "title": "My App", diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_payload.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_payload.py index 980674d67c..3725a7c6d6 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_payload.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_payload.py @@ -2,10 +2,11 @@ app, ) from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion def test_payload_customization(): - schema = get_app_schema(app).to_jsonable() + schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() assert schema["components"]["schemas"] == { "DataBasic": { diff --git a/tests/a_docs/rabbit/test_security.py b/tests/a_docs/rabbit/test_security.py index e8bd2ba610..a2e06af44f 100644 --- a/tests/a_docs/rabbit/test_security.py +++ b/tests/a_docs/rabbit/test_security.py @@ -14,7 +14,7 @@ async def test_base_security(): async with broker: pass - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert schema == { "asyncapi": "2.6.0", "channels": {}, @@ -41,7 +41,7 @@ async def test_plaintext_security(): async with broker: pass - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert ( schema == { diff --git a/tests/a_docs/redis/test_security.py b/tests/a_docs/redis/test_security.py index 4507b9ca6b..1a28e4dc82 100644 --- a/tests/a_docs/redis/test_security.py +++ b/tests/a_docs/redis/test_security.py @@ -39,7 +39,7 @@ async def test_base_security(): assert connection.call_args.kwargs["ssl"] - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert schema == { "asyncapi": "2.6.0", "channels": {}, @@ -69,7 +69,7 @@ async def test_plaintext_security(): assert connection.call_args.kwargs["ssl"] - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert schema == { "asyncapi": "2.6.0", "channels": {}, diff --git a/tests/asyncapi/base/v2_6_0/__init__.py b/tests/asyncapi/base/v2_6_0/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/asyncapi/base/arguments.py b/tests/asyncapi/base/v2_6_0/arguments.py similarity index 89% rename from tests/asyncapi/base/arguments.py rename to tests/asyncapi/base/v2_6_0/arguments.py index f1f19d778a..095ab5c479 100644 --- a/tests/asyncapi/base/arguments.py +++ b/tests/asyncapi/base/v2_6_0/arguments.py @@ -12,6 +12,7 @@ from faststream._compat import PYDANTIC_V2 from faststream.specification.asyncapi.generate import get_app_schema from faststream.broker.core.usecase import BrokerUsecase +from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.marks import pydantic_v2 @@ -29,7 +30,7 @@ def test_custom_naming(self): @broker.subscriber("test", title="custom_name", description="test description") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert key == "custom_name" @@ -42,7 +43,7 @@ def test_docstring_description(self): async def handle(msg): """Test description.""" - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert key == "custom_name" @@ -56,7 +57,7 @@ def test_empty(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() payload = schema["components"]["schemas"] @@ -73,7 +74,7 @@ def test_no_type(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() payload = schema["components"]["schemas"] @@ -87,7 +88,7 @@ def test_simple_type(self): @broker.subscriber("test") async def handle(msg: int): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() payload = schema["components"]["schemas"] assert next(iter(schema["channels"].values())).get("description") is None @@ -102,7 +103,7 @@ def test_simple_optional_type(self): @broker.subscriber("test") async def handle(msg: Optional[int]): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() payload = schema["components"]["schemas"] @@ -126,7 +127,7 @@ def test_simple_type_with_default(self): @broker.subscriber("test") async def handle(msg: int = 1): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() payload = schema["components"]["schemas"] @@ -144,7 +145,7 @@ def test_multi_args_no_type(self): @broker.subscriber("test") async def handle(msg, another): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() payload = schema["components"]["schemas"] @@ -166,7 +167,7 @@ def test_multi_args_with_type(self): @broker.subscriber("test") async def handle(msg: str, another: int): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() payload = schema["components"]["schemas"] @@ -188,7 +189,7 @@ def test_multi_args_with_default(self): @broker.subscriber("test") async def handle(msg: str, another: Optional[int] = None): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() payload = schema["components"]["schemas"] @@ -228,7 +229,7 @@ class User: @broker.subscriber("test") async def handle(user: User): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() payload = schema["components"]["schemas"] @@ -254,7 +255,7 @@ class User(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: User): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() payload = schema["components"]["schemas"] @@ -285,7 +286,7 @@ class User(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: User): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() payload = schema["components"]["schemas"] @@ -323,7 +324,7 @@ class User(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: User, description: str = ""): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() payload = schema["components"]["schemas"] @@ -379,7 +380,7 @@ class Config: @broker.subscriber("test") async def handle(user: User): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() payload = schema["components"]["schemas"] @@ -411,7 +412,7 @@ def dep2(name2: str): @broker.subscriber("test", dependencies=dependencies) async def handle(id: int, message=message): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() payload = schema["components"]["schemas"] @@ -445,7 +446,7 @@ class Sub(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: descriminator): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() key = next(iter(schema["components"]["messages"].keys())) assert key == IsStr(regex=r"test[\w:]*:Handle:Message") @@ -500,7 +501,7 @@ class Model(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: Model): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() key = next(iter(schema["components"]["messages"].keys())) assert key == IsStr(regex=r"test[\w:]*:Handle:Message") @@ -564,7 +565,7 @@ async def msg( ), ): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() payload = schema["components"]["schemas"] @@ -586,7 +587,7 @@ def test_ignores_custom_field(self): @broker.subscriber("test") async def handle(id: int, user: Optional[str] = None, message=Context()): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() payload = schema["components"]["schemas"] @@ -635,7 +636,7 @@ async def handle(id: int): ... @sub async def handle_default(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert ( len( diff --git a/tests/asyncapi/base/fastapi.py b/tests/asyncapi/base/v2_6_0/fastapi.py similarity index 96% rename from tests/asyncapi/base/fastapi.py rename to tests/asyncapi/base/v2_6_0/fastapi.py index a1561a135a..afde7b521d 100644 --- a/tests/asyncapi/base/fastapi.py +++ b/tests/asyncapi/base/v2_6_0/fastapi.py @@ -9,6 +9,7 @@ from faststream.broker.core.usecase import BrokerUsecase from faststream.broker.fastapi.router import StreamRouter from faststream.broker.types import MsgType +from faststream.specification.asyncapi.version import AsyncAPIVersion class FastAPITestCase: @@ -79,7 +80,7 @@ async def handler(): ... async with self.broker_wrapper(broker.broker): with TestClient(app) as client: - schema = get_app_schema(broker) + schema = get_app_schema(broker, version=AsyncAPIVersion.v2_6) response_json = client.get("/asyncapi_schema.json") assert response_json.json() == schema.to_jsonable() diff --git a/tests/asyncapi/base/naming.py b/tests/asyncapi/base/v2_6_0/naming.py similarity index 86% rename from tests/asyncapi/base/naming.py rename to tests/asyncapi/base/v2_6_0/naming.py index 526c2f2176..eeea50b6d8 100644 --- a/tests/asyncapi/base/naming.py +++ b/tests/asyncapi/base/v2_6_0/naming.py @@ -6,6 +6,7 @@ from faststream import FastStream from faststream.specification.asyncapi.generate import get_app_schema from faststream.broker.core.usecase import BrokerUsecase +from faststream.specification.asyncapi.version import AsyncAPIVersion class BaseNaming: @@ -19,7 +20,7 @@ def test_subscriber_naming(self): @broker.subscriber("test") async def handle_user_created(msg: str): ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -39,7 +40,7 @@ def test_pydantic_subscriber_naming(self): @broker.subscriber("test") async def handle_user_created(msg: create_model("SimpleModel")): ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -58,7 +59,7 @@ def test_multi_subscribers_naming(self): @broker.subscriber("test2") async def handle_user_created(msg: str): ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated"), @@ -80,7 +81,7 @@ def test_subscriber_naming_manual(self): @broker.subscriber("test", title="custom") async def handle_user_created(msg: str): ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -95,7 +96,7 @@ def test_subscriber_naming_default(self): broker.subscriber("test") - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:Subscriber") @@ -114,7 +115,7 @@ def test_subscriber_naming_default_with_title(self): broker.subscriber("test", title="custom") - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -137,7 +138,7 @@ async def handle_user_created(msg: str): ... broker.subscriber("test2") broker.subscriber("test3") - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated"), @@ -171,7 +172,7 @@ async def handle_user_created(msg: str): ... @broker.subscriber("test") async def handle_user_id(msg: int): ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -195,7 +196,7 @@ async def handle_user_created(msg: create_model("SimpleModel")): ... @broker.subscriber("test") async def handle_user_id(msg: int): ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -219,7 +220,7 @@ async def handle_user_created(msg: str): ... @broker.subscriber("test", title="custom") async def handle_user_id(msg: int): ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -238,7 +239,7 @@ def test_publisher_naming_base(self): @broker.publisher("test") async def handle_user_created() -> str: ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] @@ -256,7 +257,7 @@ def test_publisher_naming_pydantic(self): @broker.publisher("test") async def handle_user_created() -> create_model("SimpleModel"): ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] @@ -274,7 +275,7 @@ def test_publisher_manual_naming(self): @broker.publisher("test", title="custom") async def handle_user_created() -> str: ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -290,7 +291,7 @@ def test_publisher_with_schema_naming(self): @broker.publisher("test", schema=str) async def handle_user_created(): ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] @@ -308,7 +309,7 @@ def test_publisher_manual_naming_with_schema(self): @broker.publisher("test", title="custom", schema=str) async def handle_user_created(): ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -325,7 +326,7 @@ def test_multi_publishers_naming(self): @broker.publisher("test2") async def handle_user_created() -> str: ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() names = list(schema["channels"].keys()) assert names == Contains( @@ -356,7 +357,7 @@ async def handle_user_created() -> str: ... @pub async def handle() -> int: ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:Publisher"), @@ -382,7 +383,7 @@ async def handle_user_created() -> str: ... @pub async def handle() -> int: ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert list(schema["channels"].keys()) == ["custom"] diff --git a/tests/asyncapi/base/publisher.py b/tests/asyncapi/base/v2_6_0/publisher.py similarity index 81% rename from tests/asyncapi/base/publisher.py rename to tests/asyncapi/base/v2_6_0/publisher.py index 3b0f2618ba..1e5e4084e3 100644 --- a/tests/asyncapi/base/publisher.py +++ b/tests/asyncapi/base/v2_6_0/publisher.py @@ -5,6 +5,7 @@ from faststream import FastStream from faststream.specification.asyncapi.generate import get_app_schema from faststream.broker.core.usecase import BrokerUsecase +from faststream.specification.asyncapi.version import AsyncAPIVersion class PublisherTestcase: @@ -20,7 +21,7 @@ def test_publisher_with_description(self): @broker.publisher("test", description="test description") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["description"] == "test description" @@ -31,7 +32,7 @@ def test_basic_publisher(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key].get("description") is None @@ -47,7 +48,7 @@ def test_none_publisher(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -59,7 +60,7 @@ def test_typed_publisher(self): @broker.publisher("test") async def handle(msg) -> int: ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -75,7 +76,7 @@ class User(pydantic.BaseModel): @broker.publisher("test") async def handle(msg) -> User: ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() payload = schema["components"]["schemas"] @@ -98,7 +99,7 @@ def test_delayed(self): @pub async def handle(msg) -> int: ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -109,7 +110,7 @@ def test_with_schema(self): broker.publisher("test", title="Custom", schema=int) - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() payload = schema["components"]["schemas"] for v in payload.values(): diff --git a/tests/asyncapi/base/router.py b/tests/asyncapi/base/v2_6_0/router.py similarity index 96% rename from tests/asyncapi/base/router.py rename to tests/asyncapi/base/v2_6_0/router.py index c5f7820c4f..a8d0006f27 100644 --- a/tests/asyncapi/base/router.py +++ b/tests/asyncapi/base/v2_6_0/router.py @@ -6,6 +6,7 @@ from faststream.specification.asyncapi.generate import get_app_schema from faststream.broker.core.usecase import BrokerUsecase from faststream.broker.router import ArgsContainer, BrokerRouter, SubscriberRoute +from faststream.specification.asyncapi.version import AsyncAPIVersion class RouterTestcase: @@ -25,7 +26,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() payload = schema["components"]["schemas"] key = list(payload.keys())[0] # noqa: RUF015 diff --git a/tests/asyncapi/base/v3_0_0/arguments.py b/tests/asyncapi/base/v3_0_0/arguments.py index de79bafc08..19919a10ca 100644 --- a/tests/asyncapi/base/v3_0_0/arguments.py +++ b/tests/asyncapi/base/v3_0_0/arguments.py @@ -32,7 +32,7 @@ def test_custom_naming(self): @broker.subscriber("test", title="custom_name", description="test description") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert key == "custom_name" @@ -45,7 +45,7 @@ def test_docstring_description(self): async def handle(msg): """Test description.""" - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert key == "custom_name" @@ -59,7 +59,7 @@ def test_empty(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() payload = schema["components"]["schemas"] @@ -76,7 +76,7 @@ def test_no_type(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() payload = schema["components"]["schemas"] @@ -90,7 +90,7 @@ def test_simple_type(self): @broker.subscriber("test") async def handle(msg: int): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() payload = schema["components"]["schemas"] assert next(iter(schema["channels"].values())).get("description") is None @@ -105,7 +105,7 @@ def test_simple_optional_type(self): @broker.subscriber("test") async def handle(msg: Optional[int]): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() payload = schema["components"]["schemas"] @@ -129,7 +129,7 @@ def test_simple_type_with_default(self): @broker.subscriber("test") async def handle(msg: int = 1): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() payload = schema["components"]["schemas"] @@ -147,7 +147,7 @@ def test_multi_args_no_type(self): @broker.subscriber("test") async def handle(msg, another): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() payload = schema["components"]["schemas"] @@ -169,7 +169,7 @@ def test_multi_args_with_type(self): @broker.subscriber("test") async def handle(msg: str, another: int): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() payload = schema["components"]["schemas"] @@ -191,7 +191,7 @@ def test_multi_args_with_default(self): @broker.subscriber("test") async def handle(msg: str, another: Optional[int] = None): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() payload = schema["components"]["schemas"] @@ -231,7 +231,7 @@ class User: @broker.subscriber("test") async def handle(user: User): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() payload = schema["components"]["schemas"] @@ -257,7 +257,7 @@ class User(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: User): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() payload = schema["components"]["schemas"] @@ -288,7 +288,7 @@ class User(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: User): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() payload = schema["components"]["schemas"] @@ -326,7 +326,7 @@ class User(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: User, description: str = ""): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() payload = schema["components"]["schemas"] @@ -382,7 +382,7 @@ class Config: @broker.subscriber("test") async def handle(user: User): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() payload = schema["components"]["schemas"] @@ -415,7 +415,7 @@ async def handle(id: int): ... @broker.subscriber("test") async def handle_default(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert ( len( @@ -446,7 +446,7 @@ def dep2(name2: str): @broker.subscriber("test", dependencies=dependencies) async def handle(id: int, message=message): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() payload = schema["components"]["schemas"] @@ -480,7 +480,7 @@ class Sub(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: descriminator): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() key = next(iter(schema["components"]["messages"].keys())) assert key == IsStr(regex=r"test[\w:]*:Handle:Message") @@ -541,7 +541,7 @@ class Model(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: Model): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() key = next(iter(schema["components"]["messages"].keys())) assert key == IsStr(regex=r"test[\w:]*:Handle:Message") @@ -605,7 +605,7 @@ async def msg( ), ): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() payload = schema["components"]["schemas"] @@ -627,7 +627,7 @@ def test_ignores_custom_field(self): @broker.subscriber("test") async def handle(id: int, user: Optional[str] = None, message=Context()): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() payload = schema["components"]["schemas"] diff --git a/tests/asyncapi/base/v3_0_0/fastapi.py b/tests/asyncapi/base/v3_0_0/fastapi.py index 7e51449b41..6ea1a2ec6c 100644 --- a/tests/asyncapi/base/v3_0_0/fastapi.py +++ b/tests/asyncapi/base/v3_0_0/fastapi.py @@ -16,6 +16,7 @@ class FastAPITestCase: router_factory: Type[StreamRouter[MsgType]] broker_wrapper: Callable[[BrokerUsecase[MsgType, Any]], BrokerUsecase[MsgType, Any]] + @pytest.mark.skip @pytest.mark.asyncio() async def test_fastapi_full_information(self): broker = self.router_factory( @@ -79,6 +80,7 @@ async def test_fastapi_full_information(self): } } + @pytest.mark.skip @pytest.mark.asyncio() async def test_fastapi_asyncapi_routes(self): broker = self.router_factory(schema_url="/asyncapi_schema", asyncapi_version=AsyncAPIVersion.v3_0, ) @@ -91,7 +93,7 @@ async def handler(): ... async with self.broker_wrapper(broker.broker): with TestClient(app) as client: - schema = get_app_schema(broker) + schema = get_app_schema(broker, version=AsyncAPIVersion.v3_0) response_json = client.get("/asyncapi_schema.json") assert response_json.json() == schema.to_jsonable() diff --git a/tests/asyncapi/base/v3_0_0/publisher.py b/tests/asyncapi/base/v3_0_0/publisher.py index 5cff94a9cf..e3f16bbbad 100644 --- a/tests/asyncapi/base/v3_0_0/publisher.py +++ b/tests/asyncapi/base/v3_0_0/publisher.py @@ -22,7 +22,7 @@ def test_publisher_with_description(self): @broker.publisher("test", description="test description") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["description"] == "test description" @@ -33,7 +33,7 @@ def test_basic_publisher(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key].get("description") is None @@ -49,7 +49,7 @@ def test_none_publisher(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -61,7 +61,7 @@ def test_typed_publisher(self): @broker.publisher("test") async def handle(msg) -> int: ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -77,7 +77,7 @@ class User(pydantic.BaseModel): @broker.publisher("test") async def handle(msg) -> User: ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() payload = schema["components"]["schemas"] @@ -100,7 +100,7 @@ def test_delayed(self): @pub async def handle(msg) -> int: ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -111,7 +111,7 @@ def test_with_schema(self): broker.publisher("test", title="Custom", schema=int) - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() payload = schema["components"]["schemas"] for v in payload.values(): diff --git a/tests/asyncapi/confluent/v2_6_0/test_arguments.py b/tests/asyncapi/confluent/v2_6_0/test_arguments.py index f1869494cb..724359c8e8 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_arguments.py +++ b/tests/asyncapi/confluent/v2_6_0/test_arguments.py @@ -1,6 +1,7 @@ from faststream.specification.asyncapi.generate import get_app_schema from faststream.confluent import KafkaBroker -from tests.asyncapi.base.arguments import ArgumentsTestcase +from faststream.specification.asyncapi.version import AsyncAPIVersion +from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase class TestArguments(ArgumentsTestcase): @@ -12,7 +13,7 @@ def test_subscriber_bindings(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/confluent/v2_6_0/test_connection.py b/tests/asyncapi/confluent/v2_6_0/test_connection.py index f8023ed224..bd71af94b8 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_connection.py +++ b/tests/asyncapi/confluent/v2_6_0/test_connection.py @@ -1,6 +1,7 @@ from faststream import FastStream from faststream.specification.asyncapi.generate import get_app_schema from faststream.confluent import KafkaBroker +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.schema.tag import Tag @@ -14,7 +15,8 @@ def test_base(): description="Test description", tags=(Tag(name="some-tag", description="experimental"),), ) - ) + ), + version=AsyncAPIVersion.v2_6, ).to_jsonable() assert schema == { @@ -37,7 +39,8 @@ def test_base(): def test_multi(): schema = get_app_schema( - FastStream(KafkaBroker(["kafka:9092", "kafka:9093"])) + FastStream(KafkaBroker(["kafka:9092", "kafka:9093"])), + version=AsyncAPIVersion.v2_6 ).to_jsonable() assert schema == { @@ -68,7 +71,8 @@ def test_custom(): ["kafka:9092", "kafka:9093"], specification_url=["kafka:9094", "kafka:9095"], ) - ) + ), + version=AsyncAPIVersion.v2_6 ).to_jsonable() assert schema == { diff --git a/tests/asyncapi/confluent/v2_6_0/test_fastapi.py b/tests/asyncapi/confluent/v2_6_0/test_fastapi.py index 7f2ea525ab..8d2184e274 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/confluent/v2_6_0/test_fastapi.py @@ -4,9 +4,10 @@ from faststream.confluent.fastapi import KafkaRouter from faststream.confluent.testing import TestKafkaBroker from faststream.security import SASLPlaintext -from tests.asyncapi.base.arguments import FastAPICompatible -from tests.asyncapi.base.fastapi import FastAPITestCase -from tests.asyncapi.base.publisher import PublisherTestcase +from faststream.specification.asyncapi.version import AsyncAPIVersion +from tests.asyncapi.base.v2_6_0.arguments import FastAPICompatible +from tests.asyncapi.base.v2_6_0.fastapi import FastAPITestCase +from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase class TestRouterArguments(FastAPITestCase, FastAPICompatible): @@ -29,7 +30,7 @@ def test_fastapi_security_schema(): broker = KafkaRouter("localhost:9092", security=security) - schema = get_app_schema(broker).to_jsonable() + schema = get_app_schema(broker, version=AsyncAPIVersion.v2_6).to_jsonable() assert schema["servers"]["development"] == { "protocol": "kafka", diff --git a/tests/asyncapi/confluent/v2_6_0/test_naming.py b/tests/asyncapi/confluent/v2_6_0/test_naming.py index ae9455b78b..12f54ac02d 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_naming.py +++ b/tests/asyncapi/confluent/v2_6_0/test_naming.py @@ -1,7 +1,8 @@ from faststream import FastStream from faststream.specification.asyncapi.generate import get_app_schema from faststream.confluent import KafkaBroker -from tests.asyncapi.base.naming import NamingTestCase +from faststream.specification.asyncapi.version import AsyncAPIVersion +from tests.asyncapi.base.v2_6_0.naming import NamingTestCase class TestNaming(NamingTestCase): @@ -13,7 +14,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/confluent/v2_6_0/test_publisher.py b/tests/asyncapi/confluent/v2_6_0/test_publisher.py index 96cccb621c..0fa4043cd4 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_publisher.py +++ b/tests/asyncapi/confluent/v2_6_0/test_publisher.py @@ -1,6 +1,7 @@ from faststream.specification.asyncapi.generate import get_app_schema from faststream.confluent import KafkaBroker -from tests.asyncapi.base.publisher import PublisherTestcase +from faststream.specification.asyncapi.version import AsyncAPIVersion +from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase class TestArguments(PublisherTestcase): @@ -12,7 +13,7 @@ def test_publisher_bindings(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/confluent/v2_6_0/test_router.py b/tests/asyncapi/confluent/v2_6_0/test_router.py index f837b97c0d..7dd7dbe238 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_router.py +++ b/tests/asyncapi/confluent/v2_6_0/test_router.py @@ -1,9 +1,10 @@ from faststream import FastStream from faststream.specification.asyncapi.generate import get_app_schema from faststream.confluent import KafkaBroker, KafkaPublisher, KafkaRoute, KafkaRouter -from tests.asyncapi.base.arguments import ArgumentsTestcase -from tests.asyncapi.base.publisher import PublisherTestcase -from tests.asyncapi.base.router import RouterTestcase +from faststream.specification.asyncapi.version import AsyncAPIVersion +from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase +from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase +from tests.asyncapi.base.v2_6_0.router import RouterTestcase class TestRouter(RouterTestcase): @@ -22,7 +23,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/confluent/v2_6_0/test_security.py b/tests/asyncapi/confluent/v2_6_0/test_security.py index ec5a373cf7..541c1b91c4 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_security.py +++ b/tests/asyncapi/confluent/v2_6_0/test_security.py @@ -12,6 +12,7 @@ SASLScram256, SASLScram512, ) +from faststream.specification.asyncapi.version import AsyncAPIVersion basic_schema = { "asyncapi": "2.6.0", @@ -83,7 +84,7 @@ def test_base_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app).to_jsonable() + schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() assert schema == basic_schema @@ -104,7 +105,7 @@ def test_plaintext_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app).to_jsonable() + schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() plaintext_security_schema = deepcopy(basic_schema) plaintext_security_schema["servers"]["development"]["security"] = [ @@ -133,7 +134,7 @@ def test_scram256_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app).to_jsonable() + schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() sasl256_security_schema = deepcopy(basic_schema) sasl256_security_schema["servers"]["development"]["security"] = [{"scram256": []}] @@ -160,7 +161,7 @@ def test_scram512_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app).to_jsonable() + schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() sasl512_security_schema = deepcopy(basic_schema) sasl512_security_schema["servers"]["development"]["security"] = [{"scram512": []}] @@ -185,7 +186,7 @@ def test_oauthbearer_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app).to_jsonable() + schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() sasl_oauthbearer_security_schema = deepcopy(basic_schema) sasl_oauthbearer_security_schema["servers"]["development"]["security"] = [ diff --git a/tests/asyncapi/confluent/v3_0_0/test_arguments.py b/tests/asyncapi/confluent/v3_0_0/test_arguments.py index fcf9eb7161..d067219009 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_arguments.py +++ b/tests/asyncapi/confluent/v3_0_0/test_arguments.py @@ -1,5 +1,6 @@ from faststream.specification.asyncapi.generate import get_app_schema from faststream.confluent import KafkaBroker +from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase @@ -12,7 +13,7 @@ def test_subscriber_bindings(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/confluent/v3_0_0/test_fastapi.py b/tests/asyncapi/confluent/v3_0_0/test_fastapi.py index 1334dfb4f2..c7997e49f3 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/confluent/v3_0_0/test_fastapi.py @@ -36,7 +36,8 @@ def test_fastapi_security_schema(): "protocol": "kafka", "protocolVersion": "auto", "security": [{"user-password": []}], - "url": "localhost:9092", + "host": "localhost:9092", + "pathname": "", } assert schema["components"]["securitySchemes"] == { "user-password": {"type": "userPassword"} diff --git a/tests/asyncapi/confluent/v3_0_0/test_publisher.py b/tests/asyncapi/confluent/v3_0_0/test_publisher.py index f006220d21..b148a9b9fb 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_publisher.py +++ b/tests/asyncapi/confluent/v3_0_0/test_publisher.py @@ -1,5 +1,6 @@ from faststream.specification.asyncapi.generate import get_app_schema from faststream.confluent import KafkaBroker +from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase @@ -12,7 +13,7 @@ def test_publisher_bindings(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/confluent/v3_0_0/test_router.py b/tests/asyncapi/confluent/v3_0_0/test_router.py index 6bf69fc1b4..03b9f221d2 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_router.py +++ b/tests/asyncapi/confluent/v3_0_0/test_router.py @@ -2,8 +2,8 @@ from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.confluent import KafkaBroker, KafkaPublisher, KafkaRoute, KafkaRouter -from tests.asyncapi.base.arguments import ArgumentsTestcase -from tests.asyncapi.base.publisher import PublisherTestcase +from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase +from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v3_0_0.router import RouterTestcase diff --git a/tests/asyncapi/confluent/v3_0_0/test_security.py b/tests/asyncapi/confluent/v3_0_0/test_security.py index 71053882ca..fc4849c100 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_security.py +++ b/tests/asyncapi/confluent/v3_0_0/test_security.py @@ -141,7 +141,7 @@ def test_base_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app).to_jsonable() + schema = get_app_schema(app, version=AsyncAPIVersion.v3_0).to_jsonable() assert schema == basic_schema @@ -162,7 +162,7 @@ def test_plaintext_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app).to_jsonable() + schema = get_app_schema(app, version=AsyncAPIVersion.v3_0).to_jsonable() plaintext_security_schema = deepcopy(basic_schema) plaintext_security_schema["servers"]["development"]["security"] = [ @@ -191,7 +191,7 @@ def test_scram256_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app).to_jsonable() + schema = get_app_schema(app, version=AsyncAPIVersion.v3_0).to_jsonable() sasl256_security_schema = deepcopy(basic_schema) sasl256_security_schema["servers"]["development"]["security"] = [{"scram256": []}] @@ -218,7 +218,7 @@ def test_scram512_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app).to_jsonable() + schema = get_app_schema(app, version=AsyncAPIVersion.v3_0).to_jsonable() sasl512_security_schema = deepcopy(basic_schema) sasl512_security_schema["servers"]["development"]["security"] = [{"scram512": []}] diff --git a/tests/asyncapi/kafka/v2_6_0/test_app.py b/tests/asyncapi/kafka/v2_6_0/test_app.py index 4ce84b875b..630e88e659 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_app.py +++ b/tests/asyncapi/kafka/v2_6_0/test_app.py @@ -1,5 +1,6 @@ from faststream import FastStream from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.schema.contact import Contact from faststream.specification.schema.license import License from faststream.kafka import KafkaBroker @@ -8,7 +9,7 @@ def test_base(): - schema = get_app_schema(FastStream(KafkaBroker())).to_jsonable() + schema = get_app_schema(FastStream(KafkaBroker()), version=AsyncAPIVersion.v2_6).to_jsonable() assert schema == { "asyncapi": "2.6.0", @@ -33,7 +34,8 @@ def test_with_name(): title="My App", version="1.0.0", description="Test description", - ) + ), + version=AsyncAPIVersion.v2_6, ).to_jsonable() assert schema == { @@ -71,7 +73,8 @@ def test_full(): external_docs=ExternalDocs( url="https://extra-docs.py/", ), - ) + ), + version=AsyncAPIVersion.v2_6 ).to_jsonable() assert schema == { @@ -115,7 +118,8 @@ def test_full_dict(): external_docs={ "url": "https://extra-docs.py/", }, - ) + ), + version=AsyncAPIVersion.v2_6 ).to_jsonable() assert schema == { @@ -162,7 +166,8 @@ def test_extra(): "url": "https://extra-docs.py/", "x-field": "extra", }, - ) + ), + version=AsyncAPIVersion.v2_6 ).to_jsonable() assert schema == { diff --git a/tests/asyncapi/kafka/v2_6_0/test_arguments.py b/tests/asyncapi/kafka/v2_6_0/test_arguments.py index 5926b45b8a..6c882c1b44 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_arguments.py +++ b/tests/asyncapi/kafka/v2_6_0/test_arguments.py @@ -1,6 +1,7 @@ from faststream.specification.asyncapi.generate import get_app_schema from faststream.kafka import KafkaBroker -from tests.asyncapi.base.arguments import ArgumentsTestcase +from faststream.specification.asyncapi.version import AsyncAPIVersion +from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase class TestArguments(ArgumentsTestcase): @@ -12,7 +13,7 @@ def test_subscriber_bindings(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/kafka/v2_6_0/test_connection.py b/tests/asyncapi/kafka/v2_6_0/test_connection.py index e786749dd7..6713cc3c3a 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_connection.py +++ b/tests/asyncapi/kafka/v2_6_0/test_connection.py @@ -1,6 +1,7 @@ from faststream import FastStream from faststream.specification.asyncapi.generate import get_app_schema from faststream.kafka import KafkaBroker +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.schema.tag import Tag @@ -14,7 +15,8 @@ def test_base(): description="Test description", tags=(Tag(name="some-tag", description="experimental"),), ) - ) + ), + version=AsyncAPIVersion.v2_6 ).to_jsonable() assert schema == { @@ -37,7 +39,8 @@ def test_base(): def test_multi(): schema = get_app_schema( - FastStream(KafkaBroker(["kafka:9092", "kafka:9093"])) + FastStream(KafkaBroker(["kafka:9092", "kafka:9093"])), + version=AsyncAPIVersion.v2_6, ).to_jsonable() assert schema == { @@ -68,7 +71,8 @@ def test_custom(): ["kafka:9092", "kafka:9093"], specification_url=["kafka:9094", "kafka:9095"], ) - ) + ), + version=AsyncAPIVersion.v2_6, ).to_jsonable() assert schema == { diff --git a/tests/asyncapi/kafka/v2_6_0/test_fastapi.py b/tests/asyncapi/kafka/v2_6_0/test_fastapi.py index a6929a1526..f2055f7902 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/kafka/v2_6_0/test_fastapi.py @@ -4,9 +4,10 @@ from faststream.kafka.fastapi import KafkaRouter from faststream.kafka.testing import TestKafkaBroker from faststream.security import SASLPlaintext -from tests.asyncapi.base.arguments import FastAPICompatible -from tests.asyncapi.base.fastapi import FastAPITestCase -from tests.asyncapi.base.publisher import PublisherTestcase +from faststream.specification.asyncapi.version import AsyncAPIVersion +from tests.asyncapi.base.v2_6_0.arguments import FastAPICompatible +from tests.asyncapi.base.v2_6_0.fastapi import FastAPITestCase +from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase class TestRouterArguments(FastAPITestCase, FastAPICompatible): @@ -29,7 +30,7 @@ def test_fastapi_security_schema(): broker = KafkaRouter("localhost:9092", security=security) - schema = get_app_schema(broker).to_jsonable() + schema = get_app_schema(broker, version=AsyncAPIVersion.v2_6).to_jsonable() assert schema["servers"]["development"] == { "protocol": "kafka", diff --git a/tests/asyncapi/kafka/v2_6_0/test_naming.py b/tests/asyncapi/kafka/v2_6_0/test_naming.py index a3039d2730..9f02856392 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_naming.py +++ b/tests/asyncapi/kafka/v2_6_0/test_naming.py @@ -1,7 +1,8 @@ from faststream import FastStream from faststream.specification.asyncapi.generate import get_app_schema from faststream.kafka import KafkaBroker -from tests.asyncapi.base.naming import NamingTestCase +from faststream.specification.asyncapi.version import AsyncAPIVersion +from tests.asyncapi.base.v2_6_0.naming import NamingTestCase class TestNaming(NamingTestCase): @@ -13,7 +14,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/kafka/v2_6_0/test_publisher.py b/tests/asyncapi/kafka/v2_6_0/test_publisher.py index d438f4d733..56288e9314 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_publisher.py +++ b/tests/asyncapi/kafka/v2_6_0/test_publisher.py @@ -1,6 +1,7 @@ from faststream.specification.asyncapi.generate import get_app_schema from faststream.kafka import KafkaBroker -from tests.asyncapi.base.publisher import PublisherTestcase +from faststream.specification.asyncapi.version import AsyncAPIVersion +from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase class TestArguments(PublisherTestcase): @@ -12,7 +13,7 @@ def test_publisher_bindings(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/kafka/v2_6_0/test_router.py b/tests/asyncapi/kafka/v2_6_0/test_router.py index 58fcca22ed..8b20ea0c8f 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_router.py +++ b/tests/asyncapi/kafka/v2_6_0/test_router.py @@ -1,9 +1,10 @@ from faststream import FastStream from faststream.specification.asyncapi.generate import get_app_schema from faststream.kafka import KafkaBroker, KafkaPublisher, KafkaRoute, KafkaRouter -from tests.asyncapi.base.arguments import ArgumentsTestcase -from tests.asyncapi.base.publisher import PublisherTestcase -from tests.asyncapi.base.router import RouterTestcase +from faststream.specification.asyncapi.version import AsyncAPIVersion +from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase +from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase +from tests.asyncapi.base.v2_6_0.router import RouterTestcase class TestRouter(RouterTestcase): @@ -22,7 +23,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/kafka/v2_6_0/test_security.py b/tests/asyncapi/kafka/v2_6_0/test_security.py index 91df21b257..b72322defd 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_security.py +++ b/tests/asyncapi/kafka/v2_6_0/test_security.py @@ -12,6 +12,7 @@ SASLScram256, SASLScram512, ) +from faststream.specification.asyncapi.version import AsyncAPIVersion basic_schema = { "asyncapi": "2.6.0", @@ -83,7 +84,7 @@ def test_base_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app).to_jsonable() + schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() assert schema == basic_schema @@ -104,7 +105,7 @@ def test_plaintext_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app).to_jsonable() + schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() plaintext_security_schema = deepcopy(basic_schema) plaintext_security_schema["servers"]["development"]["security"] = [ @@ -133,7 +134,7 @@ def test_scram256_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app).to_jsonable() + schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() sasl256_security_schema = deepcopy(basic_schema) sasl256_security_schema["servers"]["development"]["security"] = [{"scram256": []}] @@ -160,7 +161,7 @@ def test_scram512_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app).to_jsonable() + schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() sasl512_security_schema = deepcopy(basic_schema) sasl512_security_schema["servers"]["development"]["security"] = [{"scram512": []}] @@ -212,7 +213,7 @@ def test_gssapi_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app).to_jsonable() + schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() gssapi_security_schema = deepcopy(basic_schema) gssapi_security_schema["servers"]["development"]["security"] = [{"gssapi": []}] diff --git a/tests/asyncapi/kafka/v3_0_0/test_arguments.py b/tests/asyncapi/kafka/v3_0_0/test_arguments.py index f18877b054..d588a12fcd 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_arguments.py +++ b/tests/asyncapi/kafka/v3_0_0/test_arguments.py @@ -1,5 +1,6 @@ from faststream.specification.asyncapi.generate import get_app_schema from faststream.kafka import KafkaBroker +from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase @@ -12,7 +13,7 @@ def test_subscriber_bindings(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/kafka/v3_0_0/test_fastapi.py b/tests/asyncapi/kafka/v3_0_0/test_fastapi.py index 2b180b6263..42eff6ba7c 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/kafka/v3_0_0/test_fastapi.py @@ -36,7 +36,8 @@ def test_fastapi_security_schema(): "protocol": "kafka", "protocolVersion": "auto", "security": [{"user-password": []}], - "url": "localhost:9092", + "host": "localhost:9092", + "pathname": "", } assert schema["components"]["securitySchemes"] == { "user-password": {"type": "userPassword"} diff --git a/tests/asyncapi/kafka/v3_0_0/test_publisher.py b/tests/asyncapi/kafka/v3_0_0/test_publisher.py index 52710319c7..c010e08b53 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_publisher.py +++ b/tests/asyncapi/kafka/v3_0_0/test_publisher.py @@ -1,5 +1,6 @@ from faststream.specification.asyncapi.generate import get_app_schema from faststream.kafka import KafkaBroker +from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase @@ -12,7 +13,7 @@ def test_publisher_bindings(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/kafka/v3_0_0/test_router.py b/tests/asyncapi/kafka/v3_0_0/test_router.py index cd9674959f..fc4ed6f0b5 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_router.py +++ b/tests/asyncapi/kafka/v3_0_0/test_router.py @@ -2,8 +2,8 @@ from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.kafka import KafkaBroker, KafkaPublisher, KafkaRoute, KafkaRouter -from tests.asyncapi.base.arguments import ArgumentsTestcase -from tests.asyncapi.base.publisher import PublisherTestcase +from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase +from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v3_0_0.router import RouterTestcase diff --git a/tests/asyncapi/kafka/v3_0_0/test_security.py b/tests/asyncapi/kafka/v3_0_0/test_security.py index b177fb0717..982a4236d9 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_security.py +++ b/tests/asyncapi/kafka/v3_0_0/test_security.py @@ -141,7 +141,7 @@ def test_base_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app).to_jsonable() + schema = get_app_schema(app, version=AsyncAPIVersion.v3_0).to_jsonable() assert schema == basic_schema @@ -162,7 +162,7 @@ def test_plaintext_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app).to_jsonable() + schema = get_app_schema(app, version=AsyncAPIVersion.v3_0).to_jsonable() plaintext_security_schema = deepcopy(basic_schema) plaintext_security_schema["servers"]["development"]["security"] = [ @@ -191,7 +191,7 @@ def test_scram256_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app).to_jsonable() + schema = get_app_schema(app, version=AsyncAPIVersion.v3_0).to_jsonable() sasl256_security_schema = deepcopy(basic_schema) sasl256_security_schema["servers"]["development"]["security"] = [{"scram256": []}] @@ -218,7 +218,7 @@ def test_scram512_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app).to_jsonable() + schema = get_app_schema(app, version=AsyncAPIVersion.v3_0).to_jsonable() sasl512_security_schema = deepcopy(basic_schema) sasl512_security_schema["servers"]["development"]["security"] = [{"scram512": []}] diff --git a/tests/asyncapi/nats/v2_6_0/test_arguments.py b/tests/asyncapi/nats/v2_6_0/test_arguments.py index 4f227a5095..10838e9c7a 100644 --- a/tests/asyncapi/nats/v2_6_0/test_arguments.py +++ b/tests/asyncapi/nats/v2_6_0/test_arguments.py @@ -1,6 +1,7 @@ from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker -from tests.asyncapi.base.arguments import ArgumentsTestcase +from faststream.specification.asyncapi.version import AsyncAPIVersion +from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase class TestArguments(ArgumentsTestcase): @@ -12,7 +13,7 @@ def test_subscriber_bindings(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/nats/v2_6_0/test_connection.py b/tests/asyncapi/nats/v2_6_0/test_connection.py index 3e4c1ab9eb..9c598ee224 100644 --- a/tests/asyncapi/nats/v2_6_0/test_connection.py +++ b/tests/asyncapi/nats/v2_6_0/test_connection.py @@ -1,6 +1,7 @@ from faststream import FastStream from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.schema.tag import Tag @@ -14,7 +15,8 @@ def test_base(): description="Test description", tags=(Tag(name="some-tag", description="experimental"),), ) - ) + ), + version=AsyncAPIVersion.v2_6, ).to_jsonable() assert schema == { @@ -37,7 +39,8 @@ def test_base(): def test_multi(): schema = get_app_schema( - FastStream(NatsBroker(["nats:9092", "nats:9093"])) + FastStream(NatsBroker(["nats:9092", "nats:9093"])), + version=AsyncAPIVersion.v2_6, ).to_jsonable() assert schema == { @@ -67,7 +70,8 @@ def test_custom(): NatsBroker( ["nats:9092", "nats:9093"], specification_url=["nats:9094", "nats:9095"] ) - ) + ), + version=AsyncAPIVersion.v2_6, ).to_jsonable() assert schema == { diff --git a/tests/asyncapi/nats/v2_6_0/test_fastapi.py b/tests/asyncapi/nats/v2_6_0/test_fastapi.py index 3b4a777523..93106116e1 100644 --- a/tests/asyncapi/nats/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/nats/v2_6_0/test_fastapi.py @@ -2,9 +2,9 @@ from faststream.nats import TestNatsBroker from faststream.nats.fastapi import NatsRouter -from tests.asyncapi.base.arguments import FastAPICompatible -from tests.asyncapi.base.fastapi import FastAPITestCase -from tests.asyncapi.base.publisher import PublisherTestcase +from tests.asyncapi.base.v2_6_0.arguments import FastAPICompatible +from tests.asyncapi.base.v2_6_0.fastapi import FastAPITestCase +from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase class TestRouterArguments(FastAPITestCase, FastAPICompatible): diff --git a/tests/asyncapi/nats/v2_6_0/test_kv_schema.py b/tests/asyncapi/nats/v2_6_0/test_kv_schema.py index 58429f73bb..82a78d12b4 100644 --- a/tests/asyncapi/nats/v2_6_0/test_kv_schema.py +++ b/tests/asyncapi/nats/v2_6_0/test_kv_schema.py @@ -1,6 +1,7 @@ from faststream import FastStream from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker +from faststream.specification.asyncapi.version import AsyncAPIVersion def test_kv_schema(): @@ -9,6 +10,6 @@ def test_kv_schema(): @broker.subscriber("test", kv_watch="test") async def handle(): ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert schema["channels"] == {} diff --git a/tests/asyncapi/nats/v2_6_0/test_naming.py b/tests/asyncapi/nats/v2_6_0/test_naming.py index d72360bc87..0bc379e579 100644 --- a/tests/asyncapi/nats/v2_6_0/test_naming.py +++ b/tests/asyncapi/nats/v2_6_0/test_naming.py @@ -1,7 +1,8 @@ from faststream import FastStream from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker -from tests.asyncapi.base.naming import NamingTestCase +from faststream.specification.asyncapi.version import AsyncAPIVersion +from tests.asyncapi.base.v2_6_0.naming import NamingTestCase class TestNaming(NamingTestCase): @@ -13,7 +14,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/nats/v2_6_0/test_obj_schema.py b/tests/asyncapi/nats/v2_6_0/test_obj_schema.py index 55d98219b2..bbbcbf1291 100644 --- a/tests/asyncapi/nats/v2_6_0/test_obj_schema.py +++ b/tests/asyncapi/nats/v2_6_0/test_obj_schema.py @@ -1,6 +1,7 @@ from faststream import FastStream from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker +from faststream.specification.asyncapi.version import AsyncAPIVersion def test_obj_schema(): @@ -9,6 +10,6 @@ def test_obj_schema(): @broker.subscriber("test", obj_watch=True) async def handle(): ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert schema["channels"] == {} diff --git a/tests/asyncapi/nats/v2_6_0/test_publisher.py b/tests/asyncapi/nats/v2_6_0/test_publisher.py index eb7ee2a01c..e786e0e134 100644 --- a/tests/asyncapi/nats/v2_6_0/test_publisher.py +++ b/tests/asyncapi/nats/v2_6_0/test_publisher.py @@ -1,6 +1,7 @@ from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker -from tests.asyncapi.base.publisher import PublisherTestcase +from faststream.specification.asyncapi.version import AsyncAPIVersion +from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase class TestArguments(PublisherTestcase): @@ -12,7 +13,7 @@ def test_publisher_bindings(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/nats/v2_6_0/test_router.py b/tests/asyncapi/nats/v2_6_0/test_router.py index 1eb9dcc8ca..dc1bc9bf5d 100644 --- a/tests/asyncapi/nats/v2_6_0/test_router.py +++ b/tests/asyncapi/nats/v2_6_0/test_router.py @@ -1,9 +1,10 @@ from faststream import FastStream from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker, NatsPublisher, NatsRoute, NatsRouter -from tests.asyncapi.base.arguments import ArgumentsTestcase -from tests.asyncapi.base.publisher import PublisherTestcase -from tests.asyncapi.base.router import RouterTestcase +from faststream.specification.asyncapi.version import AsyncAPIVersion +from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase +from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase +from tests.asyncapi.base.v2_6_0.router import RouterTestcase class TestRouter(RouterTestcase): @@ -22,7 +23,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/nats/v3_0_0/test_arguments.py b/tests/asyncapi/nats/v3_0_0/test_arguments.py index a6d538b27f..d7d331dd28 100644 --- a/tests/asyncapi/nats/v3_0_0/test_arguments.py +++ b/tests/asyncapi/nats/v3_0_0/test_arguments.py @@ -1,5 +1,6 @@ from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker +from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase @@ -12,7 +13,7 @@ def test_subscriber_bindings(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/nats/v3_0_0/test_publisher.py b/tests/asyncapi/nats/v3_0_0/test_publisher.py index c67cb5fd8f..f83ab0f7e4 100644 --- a/tests/asyncapi/nats/v3_0_0/test_publisher.py +++ b/tests/asyncapi/nats/v3_0_0/test_publisher.py @@ -1,5 +1,6 @@ from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker +from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase @@ -12,7 +13,7 @@ def test_publisher_bindings(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/nats/v3_0_0/test_router.py b/tests/asyncapi/nats/v3_0_0/test_router.py index 83340eb043..f3c38a9986 100644 --- a/tests/asyncapi/nats/v3_0_0/test_router.py +++ b/tests/asyncapi/nats/v3_0_0/test_router.py @@ -2,8 +2,8 @@ from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.nats import NatsBroker, NatsPublisher, NatsRoute, NatsRouter -from tests.asyncapi.base.arguments import ArgumentsTestcase -from tests.asyncapi.base.publisher import PublisherTestcase +from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase +from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v3_0_0.router import RouterTestcase diff --git a/tests/asyncapi/rabbit/v2_6_0/test_arguments.py b/tests/asyncapi/rabbit/v2_6_0/test_arguments.py index 136d6bfd42..02b883f405 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_arguments.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_arguments.py @@ -1,6 +1,7 @@ from faststream.specification.asyncapi.generate import get_app_schema from faststream.rabbit import ExchangeType, RabbitBroker, RabbitExchange, RabbitQueue -from tests.asyncapi.base.arguments import ArgumentsTestcase +from faststream.specification.asyncapi.version import AsyncAPIVersion +from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase class TestArguments(ArgumentsTestcase): @@ -15,7 +16,7 @@ def test_subscriber_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -48,7 +49,7 @@ def test_subscriber_fanout_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/rabbit/v2_6_0/test_connection.py b/tests/asyncapi/rabbit/v2_6_0/test_connection.py index a2717aa968..47ac99394f 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_connection.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_connection.py @@ -1,6 +1,7 @@ from faststream import FastStream from faststream.specification.asyncapi.generate import get_app_schema from faststream.rabbit import RabbitBroker +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.schema.tag import Tag @@ -14,7 +15,8 @@ def test_base(): description="Test description", tags=(Tag(name="some-tag", description="experimental"),), ) - ) + ), + version=AsyncAPIVersion.v2_6, ).to_jsonable() assert schema == { @@ -54,7 +56,7 @@ def test_custom(): ) broker.publisher("test") - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert ( schema diff --git a/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py b/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py index 69cb1894f4..1e95ca86a2 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py @@ -4,9 +4,10 @@ from faststream.rabbit.fastapi import RabbitRouter from faststream.rabbit.testing import TestRabbitBroker from faststream.security import SASLPlaintext -from tests.asyncapi.base.arguments import FastAPICompatible -from tests.asyncapi.base.fastapi import FastAPITestCase -from tests.asyncapi.base.publisher import PublisherTestcase +from faststream.specification.asyncapi.version import AsyncAPIVersion +from tests.asyncapi.base.v2_6_0.arguments import FastAPICompatible +from tests.asyncapi.base.v2_6_0.fastapi import FastAPITestCase +from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase class TestRouterArguments(FastAPITestCase, FastAPICompatible): @@ -29,7 +30,7 @@ def test_fastapi_security_schema(): broker = RabbitRouter(security=security) - schema = get_app_schema(broker).to_jsonable() + schema = get_app_schema(broker, version=AsyncAPIVersion.v2_6).to_jsonable() assert schema["servers"]["development"] == { "protocol": "amqp", diff --git a/tests/asyncapi/rabbit/v2_6_0/test_naming.py b/tests/asyncapi/rabbit/v2_6_0/test_naming.py index bd555ac2df..e0db99f303 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_naming.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_naming.py @@ -3,7 +3,8 @@ from faststream import FastStream from faststream.specification.asyncapi.generate import get_app_schema from faststream.rabbit import RabbitBroker -from tests.asyncapi.base.naming import NamingTestCase +from faststream.specification.asyncapi.version import AsyncAPIVersion +from tests.asyncapi.base.v2_6_0.naming import NamingTestCase class TestNaming(NamingTestCase): @@ -15,7 +16,7 @@ def test_subscriber_with_exchange(self): @broker.subscriber("test", "exchange") async def handle(): ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert list(schema["channels"].keys()) == ["test:exchange:Handle"] @@ -29,7 +30,7 @@ def test_publisher_with_exchange(self): @broker.publisher("test", "exchange") async def handle(): ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert list(schema["channels"].keys()) == ["test:exchange:Publisher"] @@ -43,7 +44,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert ( schema diff --git a/tests/asyncapi/rabbit/v2_6_0/test_publisher.py b/tests/asyncapi/rabbit/v2_6_0/test_publisher.py index f5dd27c895..8ed53416ec 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_publisher.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_publisher.py @@ -1,6 +1,7 @@ from faststream.specification.asyncapi.generate import get_app_schema from faststream.rabbit import ExchangeType, RabbitBroker, RabbitExchange, RabbitQueue -from tests.asyncapi.base.publisher import PublisherTestcase +from faststream.specification.asyncapi.version import AsyncAPIVersion +from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase class TestArguments(PublisherTestcase): @@ -12,7 +13,7 @@ def test_just_exchange(self): @broker.publisher(exchange="test-ex") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert schema["channels"] == { "_:test-ex:Publisher": { @@ -55,7 +56,7 @@ def test_publisher_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -88,7 +89,7 @@ def test_useless_queue_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert schema["channels"] == { "_:test-ex:Publisher": { @@ -121,7 +122,7 @@ def test_reusable_exchange(self): @broker.publisher(exchange="test-ex", routing_key="key2", priority=10) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert schema["channels"] == { "key1:test-ex:Publisher": { diff --git a/tests/asyncapi/rabbit/v2_6_0/test_router.py b/tests/asyncapi/rabbit/v2_6_0/test_router.py index 133b82ee84..76edf1ac15 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_router.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_router.py @@ -7,9 +7,10 @@ RabbitRoute, RabbitRouter, ) -from tests.asyncapi.base.arguments import ArgumentsTestcase -from tests.asyncapi.base.publisher import PublisherTestcase -from tests.asyncapi.base.router import RouterTestcase +from faststream.specification.asyncapi.version import AsyncAPIVersion +from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase +from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase +from tests.asyncapi.base.v2_6_0.router import RouterTestcase class TestRouter(RouterTestcase): @@ -28,7 +29,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert ( schema diff --git a/tests/asyncapi/rabbit/v2_6_0/test_security.py b/tests/asyncapi/rabbit/v2_6_0/test_security.py index 2a3f825993..1e806d31a5 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_security.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_security.py @@ -7,6 +7,7 @@ BaseSecurity, SASLPlaintext, ) +from faststream.specification.asyncapi.version import AsyncAPIVersion def test_base_security_schema(): @@ -20,7 +21,7 @@ def test_base_security_schema(): ) # pragma: allowlist secret assert broker._connection_kwargs.get("ssl_context") is ssl_context - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert schema == { "asyncapi": "2.6.0", @@ -56,7 +57,7 @@ def test_plaintext_security_schema(): ) # pragma: allowlist secret assert broker._connection_kwargs.get("ssl_context") is ssl_context - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert ( schema == { @@ -94,7 +95,7 @@ def test_plaintext_security_schema_without_ssl(): == "amqp://admin:password@localhost:5672/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert ( schema == { diff --git a/tests/asyncapi/rabbit/v3_0_0/test_arguments.py b/tests/asyncapi/rabbit/v3_0_0/test_arguments.py index 4321cc4861..51c087d863 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_arguments.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_arguments.py @@ -1,5 +1,6 @@ from faststream.specification.asyncapi.generate import get_app_schema from faststream.rabbit import ExchangeType, RabbitBroker, RabbitExchange, RabbitQueue +from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase @@ -15,7 +16,7 @@ def test_subscriber_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -48,7 +49,7 @@ def test_subscriber_fanout_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/rabbit/v3_0_0/test_publisher.py b/tests/asyncapi/rabbit/v3_0_0/test_publisher.py index 83fc8608e4..2fc2a1b145 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_publisher.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_publisher.py @@ -1,5 +1,6 @@ from faststream.specification.asyncapi.generate import get_app_schema from faststream.rabbit import ExchangeType, RabbitBroker, RabbitExchange, RabbitQueue +from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase @@ -12,7 +13,7 @@ def test_just_exchange(self): @broker.publisher(exchange="test-ex") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert schema["channels"] == { "_:test-ex:Publisher": { @@ -74,7 +75,7 @@ def test_publisher_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -107,7 +108,7 @@ def test_useless_queue_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert schema["channels"] == { "_:test-ex:Publisher": { @@ -159,7 +160,7 @@ def test_reusable_exchange(self): @broker.publisher(exchange="test-ex", routing_key="key2", priority=10) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert schema["channels"] == { "key1:test-ex:Publisher": { diff --git a/tests/asyncapi/rabbit/v3_0_0/test_router.py b/tests/asyncapi/rabbit/v3_0_0/test_router.py index 941875a7be..332c9ecace 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_router.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_router.py @@ -8,8 +8,8 @@ RabbitRoute, RabbitRouter, ) -from tests.asyncapi.base.arguments import ArgumentsTestcase -from tests.asyncapi.base.publisher import PublisherTestcase +from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase +from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v3_0_0.router import RouterTestcase diff --git a/tests/asyncapi/redis/v2_6_0/test_arguments.py b/tests/asyncapi/redis/v2_6_0/test_arguments.py index 5c29b11f93..5e3b7ecea8 100644 --- a/tests/asyncapi/redis/v2_6_0/test_arguments.py +++ b/tests/asyncapi/redis/v2_6_0/test_arguments.py @@ -1,6 +1,7 @@ from faststream.specification.asyncapi.generate import get_app_schema from faststream.redis import RedisBroker, StreamSub -from tests.asyncapi.base.arguments import ArgumentsTestcase +from faststream.specification.asyncapi.version import AsyncAPIVersion +from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase class TestArguments(ArgumentsTestcase): @@ -12,7 +13,7 @@ def test_channel_subscriber(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -29,7 +30,7 @@ def test_channel_pattern_subscriber(self): @broker.subscriber("test.{path}") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -46,7 +47,7 @@ def test_list_subscriber(self): @broker.subscriber(list="test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -59,7 +60,7 @@ def test_stream_subscriber(self): @broker.subscriber(stream="test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -72,7 +73,7 @@ def test_stream_group_subscriber(self): @broker.subscriber(stream=StreamSub("test", group="group", consumer="consumer")) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/redis/v2_6_0/test_connection.py b/tests/asyncapi/redis/v2_6_0/test_connection.py index a58cad172f..7c34106cb5 100644 --- a/tests/asyncapi/redis/v2_6_0/test_connection.py +++ b/tests/asyncapi/redis/v2_6_0/test_connection.py @@ -1,6 +1,7 @@ from faststream import FastStream from faststream.specification.asyncapi.generate import get_app_schema from faststream.redis import RedisBroker +from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.schema.tag import Tag @@ -14,7 +15,8 @@ def test_base(): description="Test description", tags=(Tag(name="some-tag", description="experimental"),), ) - ) + ), + version=AsyncAPIVersion.v2_6, ).to_jsonable() assert schema == { @@ -41,7 +43,8 @@ def test_custom(): RedisBroker( "redis://localhost:6379", specification_url="rediss://127.0.0.1:8000" ) - ) + ), + version=AsyncAPIVersion.v2_6, ).to_jsonable() assert schema == { diff --git a/tests/asyncapi/redis/v2_6_0/test_fastapi.py b/tests/asyncapi/redis/v2_6_0/test_fastapi.py index 1a5466d4e8..01e3e208a3 100644 --- a/tests/asyncapi/redis/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/redis/v2_6_0/test_fastapi.py @@ -2,9 +2,9 @@ from faststream.redis import TestRedisBroker from faststream.redis.fastapi import RedisRouter -from tests.asyncapi.base.arguments import FastAPICompatible -from tests.asyncapi.base.fastapi import FastAPITestCase -from tests.asyncapi.base.publisher import PublisherTestcase +from tests.asyncapi.base.v2_6_0.arguments import FastAPICompatible +from tests.asyncapi.base.v2_6_0.fastapi import FastAPITestCase +from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase class TestRouterArguments(FastAPITestCase, FastAPICompatible): diff --git a/tests/asyncapi/redis/v2_6_0/test_naming.py b/tests/asyncapi/redis/v2_6_0/test_naming.py index c2bc889658..a95ed4f203 100644 --- a/tests/asyncapi/redis/v2_6_0/test_naming.py +++ b/tests/asyncapi/redis/v2_6_0/test_naming.py @@ -3,7 +3,8 @@ from faststream import FastStream from faststream.specification.asyncapi.generate import get_app_schema from faststream.redis import RedisBroker -from tests.asyncapi.base.naming import NamingTestCase +from faststream.specification.asyncapi.version import AsyncAPIVersion +from tests.asyncapi.base.v2_6_0.naming import NamingTestCase class TestNaming(NamingTestCase): @@ -15,7 +16,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/redis/v2_6_0/test_publisher.py b/tests/asyncapi/redis/v2_6_0/test_publisher.py index 3861fa6bbf..7487818b7e 100644 --- a/tests/asyncapi/redis/v2_6_0/test_publisher.py +++ b/tests/asyncapi/redis/v2_6_0/test_publisher.py @@ -1,6 +1,7 @@ from faststream.specification.asyncapi.generate import get_app_schema from faststream.redis import RedisBroker -from tests.asyncapi.base.publisher import PublisherTestcase +from faststream.specification.asyncapi.version import AsyncAPIVersion +from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase class TestArguments(PublisherTestcase): @@ -12,7 +13,7 @@ def test_channel_publisher(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -29,7 +30,7 @@ def test_list_publisher(self): @broker.publisher(list="test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -42,7 +43,7 @@ def test_stream_publisher(self): @broker.publisher(stream="test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/redis/v2_6_0/test_router.py b/tests/asyncapi/redis/v2_6_0/test_router.py index adaab1e3b0..1ff095555a 100644 --- a/tests/asyncapi/redis/v2_6_0/test_router.py +++ b/tests/asyncapi/redis/v2_6_0/test_router.py @@ -1,9 +1,10 @@ from faststream import FastStream from faststream.specification.asyncapi.generate import get_app_schema from faststream.redis import RedisBroker, RedisPublisher, RedisRoute, RedisRouter -from tests.asyncapi.base.arguments import ArgumentsTestcase -from tests.asyncapi.base.publisher import PublisherTestcase -from tests.asyncapi.base.router import RouterTestcase +from faststream.specification.asyncapi.version import AsyncAPIVersion +from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase +from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase +from tests.asyncapi.base.v2_6_0.router import RouterTestcase class TestRouter(RouterTestcase): @@ -22,7 +23,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/redis/v2_6_0/test_security.py b/tests/asyncapi/redis/v2_6_0/test_security.py index b71ce53f2c..e70ddc1d4a 100644 --- a/tests/asyncapi/redis/v2_6_0/test_security.py +++ b/tests/asyncapi/redis/v2_6_0/test_security.py @@ -7,6 +7,7 @@ BaseSecurity, SASLPlaintext, ) +from faststream.specification.asyncapi.version import AsyncAPIVersion def test_base_security_schema(): @@ -19,7 +20,7 @@ def test_base_security_schema(): broker.url == "rediss://localhost:6379/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert schema == { "asyncapi": "2.6.0", @@ -53,7 +54,7 @@ def test_plaintext_security_schema(): broker.url == "redis://localhost:6379/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert schema == { "asyncapi": "2.6.0", @@ -88,7 +89,7 @@ def test_plaintext_security_schema_without_ssl(): broker.url == "redis://localhost:6379/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = get_app_schema(FastStream(broker)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/redis/v3_0_0/test_arguments.py b/tests/asyncapi/redis/v3_0_0/test_arguments.py index 6acf2dc19d..9c095a702d 100644 --- a/tests/asyncapi/redis/v3_0_0/test_arguments.py +++ b/tests/asyncapi/redis/v3_0_0/test_arguments.py @@ -1,5 +1,6 @@ from faststream.specification.asyncapi.generate import get_app_schema from faststream.redis import RedisBroker, StreamSub +from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase @@ -12,7 +13,7 @@ def test_channel_subscriber(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -29,7 +30,7 @@ def test_channel_pattern_subscriber(self): @broker.subscriber("test.{path}") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -46,7 +47,7 @@ def test_list_subscriber(self): @broker.subscriber(list="test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -59,7 +60,7 @@ def test_stream_subscriber(self): @broker.subscriber(stream="test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -72,7 +73,7 @@ def test_stream_group_subscriber(self): @broker.subscriber(stream=StreamSub("test", group="group", consumer="consumer")) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/redis/v3_0_0/test_publisher.py b/tests/asyncapi/redis/v3_0_0/test_publisher.py index e36d2935fe..005299660d 100644 --- a/tests/asyncapi/redis/v3_0_0/test_publisher.py +++ b/tests/asyncapi/redis/v3_0_0/test_publisher.py @@ -1,5 +1,6 @@ from faststream.specification.asyncapi.generate import get_app_schema from faststream.redis import RedisBroker +from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase @@ -12,7 +13,7 @@ def test_channel_publisher(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -29,7 +30,7 @@ def test_list_publisher(self): @broker.publisher(list="test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -42,7 +43,7 @@ def test_stream_publisher(self): @broker.publisher(stream="test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/redis/v3_0_0/test_router.py b/tests/asyncapi/redis/v3_0_0/test_router.py index cffd2597d1..01069e79ed 100644 --- a/tests/asyncapi/redis/v3_0_0/test_router.py +++ b/tests/asyncapi/redis/v3_0_0/test_router.py @@ -2,8 +2,8 @@ from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.redis import RedisBroker, RedisPublisher, RedisRoute, RedisRouter -from tests.asyncapi.base.arguments import ArgumentsTestcase -from tests.asyncapi.base.publisher import PublisherTestcase +from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase +from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v3_0_0.router import RouterTestcase diff --git a/tests/cli/test_asyncapi_docs.py b/tests/cli/test_asyncapi_docs.py index 816710c9ad..73d4ddb5c0 100644 --- a/tests/cli/test_asyncapi_docs.py +++ b/tests/cli/test_asyncapi_docs.py @@ -9,16 +9,16 @@ from typer.testing import CliRunner from docs.docs_src.getting_started.asyncapi.serve import ( - gen_json_cmd, - gen_yaml_cmd, - serve_cmd, + gen_asyncapi_json_cmd, + gen_asyncapi_yaml_cmd, + asyncapi_serve_cmd, ) from faststream.cli.main import cli from tests.marks import require_aiokafka -GEN_JSON_CMD = gen_json_cmd.split(" ")[1:-1] -GEN_YAML_CMD = gen_yaml_cmd.split(" ")[1:-1] -SERVE_CMD = serve_cmd.split(" ")[1:-1] +GEN_JSON_CMD = gen_asyncapi_json_cmd.split(" ")[1:-1] +GEN_YAML_CMD = gen_asyncapi_yaml_cmd.split(" ")[1:-1] +SERVE_CMD = asyncapi_serve_cmd.split(" ")[1:-1] @require_aiokafka From b06f1e34b046c510b50c7ded5d17d777c8592b1c Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 17 Aug 2024 22:54:18 +0300 Subject: [PATCH 106/245] Tests update --- faststream/app.py | 3 -- faststream/broker/fastapi/router.py | 2 - faststream/cli/docs/asyncapi/__init__.py | 4 ++ faststream/confluent/fastapi/fastapi.py | 6 --- faststream/kafka/fastapi/fastapi.py | 6 --- faststream/nats/fastapi/fastapi.py | 6 --- faststream/rabbit/fastapi/router.py | 6 --- faststream/redis/fastapi/fastapi.py | 6 --- faststream/specification/proto.py | 2 - tests/asyncapi/base/v2_6_0/arguments.py | 2 +- tests/asyncapi/base/v2_6_0/fastapi.py | 2 +- tests/asyncapi/base/v2_6_0/naming.py | 2 +- tests/asyncapi/base/v2_6_0/publisher.py | 2 +- tests/asyncapi/base/v2_6_0/router.py | 2 +- tests/asyncapi/base/v3_0_0/arguments.py | 10 ++--- tests/asyncapi/base/v3_0_0/fastapi.py | 14 +++---- tests/asyncapi/base/v3_0_0/naming.py | 38 +++++++++---------- tests/asyncapi/base/v3_0_0/publisher.py | 6 +-- tests/asyncapi/base/v3_0_0/router.py | 22 +++++------ .../confluent/v2_6_0/test_arguments.py | 2 +- .../confluent/v2_6_0/test_connection.py | 2 +- .../asyncapi/confluent/v2_6_0/test_fastapi.py | 2 +- .../asyncapi/confluent/v2_6_0/test_naming.py | 2 +- .../confluent/v2_6_0/test_publisher.py | 2 +- .../asyncapi/confluent/v2_6_0/test_router.py | 2 +- .../confluent/v2_6_0/test_security.py | 2 +- .../confluent/v3_0_0/test_arguments.py | 2 +- .../confluent/v3_0_0/test_connection.py | 14 +++---- .../asyncapi/confluent/v3_0_0/test_fastapi.py | 7 ++-- .../asyncapi/confluent/v3_0_0/test_naming.py | 4 +- .../confluent/v3_0_0/test_publisher.py | 2 +- .../asyncapi/confluent/v3_0_0/test_router.py | 4 +- .../confluent/v3_0_0/test_security.py | 12 +++--- tests/asyncapi/kafka/v2_6_0/test_app.py | 4 +- tests/asyncapi/kafka/v2_6_0/test_arguments.py | 2 +- .../asyncapi/kafka/v2_6_0/test_connection.py | 2 +- tests/asyncapi/kafka/v2_6_0/test_fastapi.py | 2 +- tests/asyncapi/kafka/v2_6_0/test_naming.py | 2 +- tests/asyncapi/kafka/v2_6_0/test_publisher.py | 2 +- tests/asyncapi/kafka/v2_6_0/test_router.py | 2 +- tests/asyncapi/kafka/v2_6_0/test_security.py | 2 +- tests/asyncapi/kafka/v3_0_0/test_arguments.py | 2 +- .../asyncapi/kafka/v3_0_0/test_connection.py | 14 +++---- tests/asyncapi/kafka/v3_0_0/test_fastapi.py | 7 ++-- tests/asyncapi/kafka/v3_0_0/test_naming.py | 4 +- tests/asyncapi/kafka/v3_0_0/test_publisher.py | 2 +- tests/asyncapi/kafka/v3_0_0/test_router.py | 4 +- tests/asyncapi/kafka/v3_0_0/test_security.py | 12 +++--- tests/asyncapi/nats/v2_6_0/test_arguments.py | 2 +- tests/asyncapi/nats/v2_6_0/test_connection.py | 2 +- tests/asyncapi/nats/v2_6_0/test_kv_schema.py | 2 +- tests/asyncapi/nats/v2_6_0/test_naming.py | 2 +- tests/asyncapi/nats/v2_6_0/test_obj_schema.py | 2 +- tests/asyncapi/nats/v2_6_0/test_publisher.py | 2 +- tests/asyncapi/nats/v2_6_0/test_router.py | 2 +- tests/asyncapi/nats/v3_0_0/test_arguments.py | 2 +- tests/asyncapi/nats/v3_0_0/test_connection.py | 14 +++---- tests/asyncapi/nats/v3_0_0/test_fastapi.py | 5 +-- tests/asyncapi/nats/v3_0_0/test_kv_schema.py | 4 +- tests/asyncapi/nats/v3_0_0/test_naming.py | 4 +- tests/asyncapi/nats/v3_0_0/test_obj_schema.py | 4 +- tests/asyncapi/nats/v3_0_0/test_publisher.py | 2 +- tests/asyncapi/nats/v3_0_0/test_router.py | 4 +- .../asyncapi/rabbit/v2_6_0/test_arguments.py | 2 +- .../asyncapi/rabbit/v2_6_0/test_connection.py | 2 +- tests/asyncapi/rabbit/v2_6_0/test_fastapi.py | 2 +- tests/asyncapi/rabbit/v2_6_0/test_naming.py | 2 +- .../asyncapi/rabbit/v2_6_0/test_publisher.py | 2 +- tests/asyncapi/rabbit/v2_6_0/test_router.py | 2 +- tests/asyncapi/rabbit/v2_6_0/test_security.py | 2 +- .../asyncapi/rabbit/v3_0_0/test_arguments.py | 2 +- .../asyncapi/rabbit/v3_0_0/test_connection.py | 8 ++-- tests/asyncapi/rabbit/v3_0_0/test_fastapi.py | 9 ++--- tests/asyncapi/rabbit/v3_0_0/test_naming.py | 8 ++-- .../asyncapi/rabbit/v3_0_0/test_publisher.py | 2 +- tests/asyncapi/rabbit/v3_0_0/test_router.py | 6 +-- tests/asyncapi/rabbit/v3_0_0/test_security.py | 10 ++--- tests/asyncapi/redis/v2_6_0/test_arguments.py | 2 +- .../asyncapi/redis/v2_6_0/test_connection.py | 2 +- tests/asyncapi/redis/v2_6_0/test_naming.py | 2 +- tests/asyncapi/redis/v2_6_0/test_publisher.py | 2 +- tests/asyncapi/redis/v2_6_0/test_router.py | 2 +- tests/asyncapi/redis/v2_6_0/test_security.py | 2 +- tests/asyncapi/redis/v3_0_0/test_arguments.py | 2 +- .../asyncapi/redis/v3_0_0/test_connection.py | 10 ++--- tests/asyncapi/redis/v3_0_0/test_fastapi.py | 5 +-- tests/asyncapi/redis/v3_0_0/test_naming.py | 4 +- tests/asyncapi/redis/v3_0_0/test_publisher.py | 2 +- tests/asyncapi/redis/v3_0_0/test_router.py | 4 +- tests/asyncapi/redis/v3_0_0/test_security.py | 10 ++--- tests/cli/test_asyncapi_docs.py | 2 +- 91 files changed, 194 insertions(+), 232 deletions(-) diff --git a/faststream/app.py b/faststream/app.py index ab20c73488..05c06a46f1 100644 --- a/faststream/app.py +++ b/faststream/app.py @@ -19,7 +19,6 @@ from faststream.cli.supervisors.utils import set_exit from faststream.exceptions import ValidationError from faststream.log.logging import logger -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.proto import Application from faststream.utils import apply_types, context from faststream.utils.functions import drop_response_type, fake_context, to_async @@ -62,7 +61,6 @@ def __init__( title: str = "FastStream", version: str = "0.1.0", description: str = "", - asyncapi_version: AsyncAPIVersion = AsyncAPIVersion.v2_6, terms_of_service: Optional["AnyHttpUrl"] = None, license: Optional[Union["License", "LicenseDict", "AnyDict"]] = None, contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] = None, @@ -82,7 +80,6 @@ def __init__( self.broker = broker self.logger = logger self.context = context - self.asyncapi_version = asyncapi_version self._on_startup_calling = [apply_types(to_async(x)) for x in on_startup] self._after_startup_calling = [apply_types(to_async(x)) for x in after_startup] diff --git a/faststream/broker/fastapi/router.py b/faststream/broker/fastapi/router.py index bde2345ddb..5bbb4d6526 100644 --- a/faststream/broker/fastapi/router.py +++ b/faststream/broker/fastapi/router.py @@ -127,7 +127,6 @@ def __init__( generate_unique_id ), # AsyncAPI information - asyncapi_version: AsyncAPIVersion = AsyncAPIVersion.v2_6, asyncapi_tags: Optional[ Iterable[Union["Tag", "TagDict"]] ] = None, @@ -165,7 +164,6 @@ def __init__( self.description = "" self.license = None self.contact = None - self.asyncapi_version = asyncapi_version self.schema = None diff --git a/faststream/cli/docs/asyncapi/__init__.py b/faststream/cli/docs/asyncapi/__init__.py index 182c5264e9..7b29c77ca6 100644 --- a/faststream/cli/docs/asyncapi/__init__.py +++ b/faststream/cli/docs/asyncapi/__init__.py @@ -1 +1,5 @@ from .app import asyncapi_app + +__all__ = ( + "asyncapi_app", +) diff --git a/faststream/confluent/fastapi/fastapi.py b/faststream/confluent/fastapi/fastapi.py index 6cdddcc2fd..eb48599cb2 100644 --- a/faststream/confluent/fastapi/fastapi.py +++ b/faststream/confluent/fastapi/fastapi.py @@ -29,7 +29,6 @@ from faststream.broker.fastapi.router import StreamRouter from faststream.broker.utils import default_filter from faststream.confluent.broker.broker import KafkaBroker as KB -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.types import EMPTY if TYPE_CHECKING: @@ -299,10 +298,6 @@ def __init__( Optional[str], Doc("Specification server description."), ] = None, - asyncapi_version: Annotated[ - AsyncAPIVersion, - Doc("Version of Specification for schema generation") - ] = AsyncAPIVersion.v2_6, asyncapi_tags: Annotated[ Optional[Iterable[Union["Tag", "TagDict"]]], Doc("Specification server tags."), @@ -581,7 +576,6 @@ def __init__( protocol=protocol, description=description, protocol_version=protocol_version, - asyncapi_version=asyncapi_version, asyncapi_tags=asyncapi_tags, specification_url=specification_url, # FastAPI kwargs diff --git a/faststream/kafka/fastapi/fastapi.py b/faststream/kafka/fastapi/fastapi.py index 6e75b475bc..c49431d90a 100644 --- a/faststream/kafka/fastapi/fastapi.py +++ b/faststream/kafka/fastapi/fastapi.py @@ -32,7 +32,6 @@ from faststream.broker.fastapi.router import StreamRouter from faststream.broker.utils import default_filter from faststream.kafka.broker.broker import KafkaBroker as KB -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.types import EMPTY if TYPE_CHECKING: @@ -307,10 +306,6 @@ def __init__( Optional[str], Doc("Specification server description."), ] = None, - asyncapi_version: Annotated[ - AsyncAPIVersion, - Doc("Version of Specification for schema generation") - ] = AsyncAPIVersion.v2_6, asyncapi_tags: Annotated[ Optional[Iterable[Union["Tag", "TagDict"]]], Doc("Specification server tags."), @@ -596,7 +591,6 @@ def __init__( protocol=protocol, description=description, protocol_version=protocol_version, - asyncapi_version=asyncapi_version, asyncapi_tags=asyncapi_tags, specification_url=specification_url, # FastAPI args diff --git a/faststream/nats/fastapi/fastapi.py b/faststream/nats/fastapi/fastapi.py index 24abea120d..4fcc7852f6 100644 --- a/faststream/nats/fastapi/fastapi.py +++ b/faststream/nats/fastapi/fastapi.py @@ -38,7 +38,6 @@ from faststream.nats.broker import NatsBroker from faststream.nats.publisher.publisher import SpecificationPublisher from faststream.nats.subscriber.subscriber import SpecificationSubscriber -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.types import EMPTY if TYPE_CHECKING: @@ -260,10 +259,6 @@ def __init__( Optional[str], Doc("AsyncAPI server description."), ] = None, - asyncapi_version: Annotated[ - AsyncAPIVersion, - Doc("Version of AsyncAPI for schema generation") - ] = AsyncAPIVersion.v2_6, asyncapi_tags: Annotated[ Optional[Iterable[Union["Tag", "TagDict"]]], Doc("AsyncAPI server tags."), @@ -554,7 +549,6 @@ def __init__( logger=logger, log_level=log_level, log_fmt=log_fmt, - asyncapi_version=asyncapi_version, asyncapi_tags=asyncapi_tags, schema_url=schema_url, setup_state=setup_state, diff --git a/faststream/rabbit/fastapi/router.py b/faststream/rabbit/fastapi/router.py index b29e0bfe95..b19c46a062 100644 --- a/faststream/rabbit/fastapi/router.py +++ b/faststream/rabbit/fastapi/router.py @@ -30,7 +30,6 @@ RabbitQueue, ) from faststream.rabbit.subscriber.subscriber import SpecificationSubscriber -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.types import EMPTY if TYPE_CHECKING: @@ -181,10 +180,6 @@ def __init__( Optional[str], Doc("AsyncAPI server description."), ] = None, - asyncapi_version: Annotated[ - AsyncAPIVersion, - Doc("Version of AsyncAPI for schema generation") - ] = AsyncAPIVersion.v2_6, asyncapi_tags: Annotated[ Optional[Iterable[Union["Tag", "TagDict"]]], Doc("AsyncAPI server tags."), @@ -457,7 +452,6 @@ def __init__( logger=logger, log_level=log_level, log_fmt=log_fmt, - asyncapi_version=asyncapi_version, asyncapi_tags=asyncapi_tags, schema_url=schema_url, setup_state=setup_state, diff --git a/faststream/redis/fastapi/fastapi.py b/faststream/redis/fastapi/fastapi.py index 8a16048baf..6dd3401697 100644 --- a/faststream/redis/fastapi/fastapi.py +++ b/faststream/redis/fastapi/fastapi.py @@ -34,7 +34,6 @@ from faststream.redis.publisher.publisher import SpecificationPublisher from faststream.redis.schemas import ListSub, PubSub, StreamSub from faststream.redis.subscriber.subscriber import SpecificationSubscriber -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.types import EMPTY if TYPE_CHECKING: @@ -130,10 +129,6 @@ def __init__( Optional[str], Doc("AsyncAPI server description."), ] = None, - asyncapi_version: Annotated[ - AsyncAPIVersion, - Doc("Version of AsyncAPI for schema generation") - ] = AsyncAPIVersion.v2_6, asyncapi_tags: Annotated[ Optional[Iterable[Union["Tag", "TagDict"]]], Doc("AsyncAPI server tags."), @@ -415,7 +410,6 @@ def __init__( protocol=protocol, description=description, protocol_version=protocol_version, - asyncapi_version=asyncapi_version, asyncapi_tags=asyncapi_tags, specification_url=specification_url, # FastAPI kwargs diff --git a/faststream/specification/proto.py b/faststream/specification/proto.py index 00197c0677..13702cae37 100644 --- a/faststream/specification/proto.py +++ b/faststream/specification/proto.py @@ -3,7 +3,6 @@ from typing_extensions import Annotated, Doc -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.schema.channel import Channel if TYPE_CHECKING: @@ -29,7 +28,6 @@ class Application(Protocol): contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] specs_tags: Optional[Sequence[Union["Tag", "AnyDict"]]] external_docs: Optional[Union["ExternalDocs", "ExternalDocsDict", "AnyDict"]] - asyncapi_version: AsyncAPIVersion identifier: Optional[str] diff --git a/tests/asyncapi/base/v2_6_0/arguments.py b/tests/asyncapi/base/v2_6_0/arguments.py index 095ab5c479..dfb42df7ca 100644 --- a/tests/asyncapi/base/v2_6_0/arguments.py +++ b/tests/asyncapi/base/v2_6_0/arguments.py @@ -10,8 +10,8 @@ from faststream import Context, FastStream from faststream._compat import PYDANTIC_V2 -from faststream.specification.asyncapi.generate import get_app_schema from faststream.broker.core.usecase import BrokerUsecase +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.marks import pydantic_v2 diff --git a/tests/asyncapi/base/v2_6_0/fastapi.py b/tests/asyncapi/base/v2_6_0/fastapi.py index afde7b521d..f383476921 100644 --- a/tests/asyncapi/base/v2_6_0/fastapi.py +++ b/tests/asyncapi/base/v2_6_0/fastapi.py @@ -5,10 +5,10 @@ from fastapi import FastAPI from fastapi.testclient import TestClient -from faststream.specification.asyncapi.generate import get_app_schema from faststream.broker.core.usecase import BrokerUsecase from faststream.broker.fastapi.router import StreamRouter from faststream.broker.types import MsgType +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion diff --git a/tests/asyncapi/base/v2_6_0/naming.py b/tests/asyncapi/base/v2_6_0/naming.py index eeea50b6d8..12857f7c14 100644 --- a/tests/asyncapi/base/v2_6_0/naming.py +++ b/tests/asyncapi/base/v2_6_0/naming.py @@ -4,8 +4,8 @@ from pydantic import create_model from faststream import FastStream -from faststream.specification.asyncapi.generate import get_app_schema from faststream.broker.core.usecase import BrokerUsecase +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion diff --git a/tests/asyncapi/base/v2_6_0/publisher.py b/tests/asyncapi/base/v2_6_0/publisher.py index 1e5e4084e3..e3284d5e61 100644 --- a/tests/asyncapi/base/v2_6_0/publisher.py +++ b/tests/asyncapi/base/v2_6_0/publisher.py @@ -3,8 +3,8 @@ import pydantic from faststream import FastStream -from faststream.specification.asyncapi.generate import get_app_schema from faststream.broker.core.usecase import BrokerUsecase +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion diff --git a/tests/asyncapi/base/v2_6_0/router.py b/tests/asyncapi/base/v2_6_0/router.py index a8d0006f27..bf8c96f4a2 100644 --- a/tests/asyncapi/base/v2_6_0/router.py +++ b/tests/asyncapi/base/v2_6_0/router.py @@ -3,9 +3,9 @@ from dirty_equals import IsStr from faststream import FastStream -from faststream.specification.asyncapi.generate import get_app_schema from faststream.broker.core.usecase import BrokerUsecase from faststream.broker.router import ArgsContainer, BrokerRouter, SubscriberRoute +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion diff --git a/tests/asyncapi/base/v3_0_0/arguments.py b/tests/asyncapi/base/v3_0_0/arguments.py index 19919a10ca..abe79b9fb1 100644 --- a/tests/asyncapi/base/v3_0_0/arguments.py +++ b/tests/asyncapi/base/v3_0_0/arguments.py @@ -1,7 +1,7 @@ import json from dataclasses import dataclass from enum import Enum -from typing import Callable, Optional, Union +from typing import Optional, Union import pydantic from dirty_equals import IsDict, IsPartialDict, IsStr @@ -11,20 +11,20 @@ from faststream import Context, FastStream from faststream._compat import PYDANTIC_V2 -from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.broker.core.usecase import BrokerUsecase from faststream.broker.fastapi import StreamRouter +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.marks import pydantic_v2 class FastAPICompatible: - broker_factory: Callable[[], Union[BrokerUsecase, StreamRouter]] + broker_factory: Union[BrokerUsecase, StreamRouter] dependency_builder = staticmethod(APIDepends) def build_app(self, broker): """Patch it to test FastAPI scheme generation too.""" - return FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0) + return FastStream(broker) def test_custom_naming(self): broker = self.broker_factory() diff --git a/tests/asyncapi/base/v3_0_0/fastapi.py b/tests/asyncapi/base/v3_0_0/fastapi.py index 6ea1a2ec6c..b45921a8c6 100644 --- a/tests/asyncapi/base/v3_0_0/fastapi.py +++ b/tests/asyncapi/base/v3_0_0/fastapi.py @@ -5,18 +5,18 @@ from fastapi import FastAPI from fastapi.testclient import TestClient -from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.broker.core.usecase import BrokerUsecase from faststream.broker.fastapi.router import StreamRouter from faststream.broker.types import MsgType +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion class FastAPITestCase: router_factory: Type[StreamRouter[MsgType]] broker_wrapper: Callable[[BrokerUsecase[MsgType, Any]], BrokerUsecase[MsgType, Any]] - @pytest.mark.skip + @pytest.mark.skip() @pytest.mark.asyncio() async def test_fastapi_full_information(self): broker = self.router_factory( @@ -80,10 +80,10 @@ async def test_fastapi_full_information(self): } } - @pytest.mark.skip + @pytest.mark.skip() @pytest.mark.asyncio() async def test_fastapi_asyncapi_routes(self): - broker = self.router_factory(schema_url="/asyncapi_schema", asyncapi_version=AsyncAPIVersion.v3_0, ) + broker = self.router_factory(schema_url="/asyncapi_schema") @broker.subscriber("test") async def handler(): ... @@ -106,7 +106,7 @@ async def handler(): ... @pytest.mark.asyncio() async def test_fastapi_asyncapi_not_fount(self): - broker = self.router_factory(include_in_schema=False, asyncapi_version=AsyncAPIVersion.v3_0, ) + broker = self.router_factory(include_in_schema=False) app = FastAPI(lifespan=broker.lifespan_context) app.include_router(broker) @@ -124,7 +124,7 @@ async def test_fastapi_asyncapi_not_fount(self): @pytest.mark.asyncio() async def test_fastapi_asyncapi_not_fount_by_url(self): - broker = self.router_factory(schema_url=None, asyncapi_version=AsyncAPIVersion.v3_0, ) + broker = self.router_factory(schema_url=None) app = FastAPI(lifespan=broker.lifespan_context) app.include_router(broker) diff --git a/tests/asyncapi/base/v3_0_0/naming.py b/tests/asyncapi/base/v3_0_0/naming.py index 8761da40c1..b0b936d24e 100644 --- a/tests/asyncapi/base/v3_0_0/naming.py +++ b/tests/asyncapi/base/v3_0_0/naming.py @@ -4,9 +4,9 @@ from pydantic import create_model from faststream import FastStream +from faststream.broker.core.usecase import BrokerUsecase from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion -from faststream.broker.core.usecase import BrokerUsecase class BaseNaming: @@ -20,7 +20,7 @@ def test_subscriber_naming(self): @broker.subscriber("test") async def handle_user_created(msg: str): ... - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -40,7 +40,7 @@ def test_pydantic_subscriber_naming(self): @broker.subscriber("test") async def handle_user_created(msg: create_model("SimpleModel")): ... - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -59,7 +59,7 @@ def test_multi_subscribers_naming(self): @broker.subscriber("test2") async def handle_user_created(msg: str): ... - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated"), @@ -81,7 +81,7 @@ def test_subscriber_naming_manual(self): @broker.subscriber("test", title="custom") async def handle_user_created(msg: str): ... - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -96,7 +96,7 @@ def test_subscriber_naming_default(self): broker.subscriber("test") - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:Subscriber") @@ -115,7 +115,7 @@ def test_subscriber_naming_default_with_title(self): broker.subscriber("test", title="custom") - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -138,7 +138,7 @@ async def handle_user_created(msg: str): ... broker.subscriber("test2") broker.subscriber("test3") - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated"), @@ -172,7 +172,7 @@ async def handle_user_created(msg: str): ... @broker.subscriber("test") async def handle_user_id(msg: int): ... - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -196,7 +196,7 @@ async def handle_user_created(msg: create_model("SimpleModel")): ... @broker.subscriber("test") async def handle_user_id(msg: int): ... - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -220,7 +220,7 @@ async def handle_user_created(msg: str): ... @broker.subscriber("test", title="custom") async def handle_user_id(msg: int): ... - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -239,7 +239,7 @@ def test_publisher_naming_base(self): @broker.publisher("test") async def handle_user_created() -> str: ... - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] @@ -257,7 +257,7 @@ def test_publisher_naming_pydantic(self): @broker.publisher("test") async def handle_user_created() -> create_model("SimpleModel"): ... - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] @@ -275,7 +275,7 @@ def test_publisher_manual_naming(self): @broker.publisher("test", title="custom") async def handle_user_created() -> str: ... - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -291,7 +291,7 @@ def test_publisher_with_schema_naming(self): @broker.publisher("test", schema=str) async def handle_user_created(): ... - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] @@ -309,7 +309,7 @@ def test_publisher_manual_naming_with_schema(self): @broker.publisher("test", title="custom", schema=str) async def handle_user_created(): ... - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -326,7 +326,7 @@ def test_multi_publishers_naming(self): @broker.publisher("test2") async def handle_user_created() -> str: ... - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() names = list(schema["channels"].keys()) assert names == Contains( @@ -357,7 +357,7 @@ async def handle_user_created() -> str: ... @pub async def handle() -> int: ... - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:Publisher"), @@ -383,7 +383,7 @@ async def handle_user_created() -> str: ... @pub async def handle() -> int: ... - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert list(schema["channels"].keys()) == ["custom"] diff --git a/tests/asyncapi/base/v3_0_0/publisher.py b/tests/asyncapi/base/v3_0_0/publisher.py index e3f16bbbad..09d3e9f4e3 100644 --- a/tests/asyncapi/base/v3_0_0/publisher.py +++ b/tests/asyncapi/base/v3_0_0/publisher.py @@ -3,10 +3,10 @@ import pydantic from faststream import FastStream -from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.broker.core.usecase import BrokerUsecase from faststream.broker.fastapi import StreamRouter +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion class PublisherTestcase: @@ -14,7 +14,7 @@ class PublisherTestcase: def build_app(self, broker): """Patch it to test FastAPI scheme generation too.""" - return FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0) + return FastStream(broker) def test_publisher_with_description(self): broker = self.broker_factory() diff --git a/tests/asyncapi/base/v3_0_0/router.py b/tests/asyncapi/base/v3_0_0/router.py index 5dfc2451b1..ca071471e5 100644 --- a/tests/asyncapi/base/v3_0_0/router.py +++ b/tests/asyncapi/base/v3_0_0/router.py @@ -3,10 +3,10 @@ from dirty_equals import IsStr from faststream import FastStream -from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.broker.core.usecase import BrokerUsecase from faststream.broker.router import ArgsContainer, BrokerRouter, SubscriberRoute +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion class RouterTestcase: @@ -26,7 +26,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() payload = schema["components"]["schemas"] key = list(payload.keys())[0] # noqa: RUF015 @@ -49,7 +49,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)) + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0) schemas = schema.components.schemas del schemas["Handle:Message:Payload"] @@ -69,7 +69,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)) + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0) assert schema.channels == {}, schema.channels def test_not_include_in_method(self): @@ -82,7 +82,7 @@ async def handle(msg): ... broker.include_router(router, include_in_schema=False) - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)) + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0) assert schema.channels == {}, schema.channels def test_respect_subrouter(self): @@ -97,7 +97,7 @@ async def handle(msg): ... router.include_router(router2) broker.include_router(router) - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)) + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0) assert schema.channels == {}, schema.channels @@ -113,7 +113,7 @@ async def handle(msg): ... router.include_router(router2) broker.include_router(router) - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)) + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0) assert schema.channels == {} @@ -129,7 +129,7 @@ async def handle(msg): ... router.include_router(router2, include_in_schema=False) broker.include_router(router) - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)) + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0) assert schema.channels == {} @@ -145,7 +145,7 @@ async def handle(msg): ... router.include_router(router2) broker.include_router(router, include_in_schema=False) - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)) + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0) assert schema.channels == {} @@ -161,6 +161,6 @@ async def handle(msg): ... router.include_router(router2) broker.include_router(router) - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)) + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0) assert len(schema.channels) == 2 diff --git a/tests/asyncapi/confluent/v2_6_0/test_arguments.py b/tests/asyncapi/confluent/v2_6_0/test_arguments.py index 724359c8e8..247f64245a 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_arguments.py +++ b/tests/asyncapi/confluent/v2_6_0/test_arguments.py @@ -1,5 +1,5 @@ -from faststream.specification.asyncapi.generate import get_app_schema from faststream.confluent import KafkaBroker +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase diff --git a/tests/asyncapi/confluent/v2_6_0/test_connection.py b/tests/asyncapi/confluent/v2_6_0/test_connection.py index bd71af94b8..1b6134ed34 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_connection.py +++ b/tests/asyncapi/confluent/v2_6_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.specification.asyncapi.generate import get_app_schema from faststream.confluent import KafkaBroker +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.schema.tag import Tag diff --git a/tests/asyncapi/confluent/v2_6_0/test_fastapi.py b/tests/asyncapi/confluent/v2_6_0/test_fastapi.py index 8d2184e274..c319813ae9 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/confluent/v2_6_0/test_fastapi.py @@ -1,9 +1,9 @@ from typing import Type -from faststream.specification.asyncapi.generate import get_app_schema from faststream.confluent.fastapi import KafkaRouter from faststream.confluent.testing import TestKafkaBroker from faststream.security import SASLPlaintext +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import FastAPICompatible from tests.asyncapi.base.v2_6_0.fastapi import FastAPITestCase diff --git a/tests/asyncapi/confluent/v2_6_0/test_naming.py b/tests/asyncapi/confluent/v2_6_0/test_naming.py index 12f54ac02d..820121edb7 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_naming.py +++ b/tests/asyncapi/confluent/v2_6_0/test_naming.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.specification.asyncapi.generate import get_app_schema from faststream.confluent import KafkaBroker +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.naming import NamingTestCase diff --git a/tests/asyncapi/confluent/v2_6_0/test_publisher.py b/tests/asyncapi/confluent/v2_6_0/test_publisher.py index 0fa4043cd4..ec230c117e 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_publisher.py +++ b/tests/asyncapi/confluent/v2_6_0/test_publisher.py @@ -1,5 +1,5 @@ -from faststream.specification.asyncapi.generate import get_app_schema from faststream.confluent import KafkaBroker +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase diff --git a/tests/asyncapi/confluent/v2_6_0/test_router.py b/tests/asyncapi/confluent/v2_6_0/test_router.py index 7dd7dbe238..3e76891eac 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_router.py +++ b/tests/asyncapi/confluent/v2_6_0/test_router.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.specification.asyncapi.generate import get_app_schema from faststream.confluent import KafkaBroker, KafkaPublisher, KafkaRoute, KafkaRouter +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase diff --git a/tests/asyncapi/confluent/v2_6_0/test_security.py b/tests/asyncapi/confluent/v2_6_0/test_security.py index 541c1b91c4..8530aec371 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_security.py +++ b/tests/asyncapi/confluent/v2_6_0/test_security.py @@ -2,7 +2,6 @@ from copy import deepcopy from faststream.app import FastStream -from faststream.specification.asyncapi.generate import get_app_schema from faststream.confluent import KafkaBroker from faststream.security import ( SASLGSSAPI, @@ -12,6 +11,7 @@ SASLScram256, SASLScram512, ) +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion basic_schema = { diff --git a/tests/asyncapi/confluent/v3_0_0/test_arguments.py b/tests/asyncapi/confluent/v3_0_0/test_arguments.py index d067219009..97a3fc5452 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_arguments.py +++ b/tests/asyncapi/confluent/v3_0_0/test_arguments.py @@ -1,5 +1,5 @@ -from faststream.specification.asyncapi.generate import get_app_schema from faststream.confluent import KafkaBroker +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase diff --git a/tests/asyncapi/confluent/v3_0_0/test_connection.py b/tests/asyncapi/confluent/v3_0_0/test_connection.py index 5c377779a8..8b60fa53c6 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_connection.py +++ b/tests/asyncapi/confluent/v3_0_0/test_connection.py @@ -1,7 +1,7 @@ from faststream import FastStream +from faststream.confluent import KafkaBroker from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion -from faststream.confluent import KafkaBroker from faststream.specification.schema.tag import Tag @@ -15,8 +15,8 @@ def test_base(): description="Test description", tags=(Tag(name="some-tag", description="experimental"),), ), - asyncapi_version=AsyncAPIVersion.v3_0, - ) + ), + version=AsyncAPIVersion.v3_0, ).to_jsonable() assert schema == { @@ -43,8 +43,8 @@ def test_multi(): schema = get_app_schema( FastStream( KafkaBroker(["kafka:9092", "kafka:9093"]), - asyncapi_version=AsyncAPIVersion.v3_0, - ) + ), + version=AsyncAPIVersion.v3_0, ).to_jsonable() assert schema == { @@ -78,8 +78,8 @@ def test_custom(): ["kafka:9092", "kafka:9093"], specification_url=["kafka:9094", "kafka:9095"], ), - asyncapi_version=AsyncAPIVersion.v3_0, - ) + ), + version=AsyncAPIVersion.v3_0, ).to_jsonable() assert schema == { diff --git a/tests/asyncapi/confluent/v3_0_0/test_fastapi.py b/tests/asyncapi/confluent/v3_0_0/test_fastapi.py index c7997e49f3..523a1461b2 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/confluent/v3_0_0/test_fastapi.py @@ -1,16 +1,15 @@ -from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.confluent.fastapi import KafkaRouter from faststream.confluent.testing import TestKafkaBroker from faststream.security import SASLPlaintext +from faststream.specification.asyncapi.generate import get_app_schema from tests.asyncapi.base.v3_0_0.arguments import FastAPICompatible from tests.asyncapi.base.v3_0_0.fastapi import FastAPITestCase from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase class TestRouterArguments(FastAPITestCase, FastAPICompatible): - broker_factory = staticmethod(lambda: KafkaRouter(asyncapi_version=AsyncAPIVersion.v3_0)) + broker_factory = staticmethod(lambda: KafkaRouter()) router_factory = KafkaRouter broker_wrapper = staticmethod(TestKafkaBroker) @@ -19,7 +18,7 @@ def build_app(self, router): class TestRouterPublisher(PublisherTestcase): - broker_factory = staticmethod(lambda: KafkaRouter(asyncapi_version=AsyncAPIVersion.v3_0)) + broker_factory = staticmethod(lambda: KafkaRouter()) def build_app(self, router): return router diff --git a/tests/asyncapi/confluent/v3_0_0/test_naming.py b/tests/asyncapi/confluent/v3_0_0/test_naming.py index 10ab216247..9218d40418 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_naming.py +++ b/tests/asyncapi/confluent/v3_0_0/test_naming.py @@ -1,7 +1,7 @@ from faststream import FastStream +from faststream.confluent import KafkaBroker from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion -from faststream.confluent import KafkaBroker from tests.asyncapi.base.v3_0_0.naming import NamingTestCase @@ -14,7 +14,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert schema == { "asyncapi": "3.0.0", diff --git a/tests/asyncapi/confluent/v3_0_0/test_publisher.py b/tests/asyncapi/confluent/v3_0_0/test_publisher.py index b148a9b9fb..a31e89b9a5 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_publisher.py +++ b/tests/asyncapi/confluent/v3_0_0/test_publisher.py @@ -1,5 +1,5 @@ -from faststream.specification.asyncapi.generate import get_app_schema from faststream.confluent import KafkaBroker +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase diff --git a/tests/asyncapi/confluent/v3_0_0/test_router.py b/tests/asyncapi/confluent/v3_0_0/test_router.py index 03b9f221d2..bda0882d23 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_router.py +++ b/tests/asyncapi/confluent/v3_0_0/test_router.py @@ -1,7 +1,7 @@ from faststream import FastStream +from faststream.confluent import KafkaBroker, KafkaPublisher, KafkaRoute, KafkaRouter from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion -from faststream.confluent import KafkaBroker, KafkaPublisher, KafkaRoute, KafkaRouter from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v3_0_0.router import RouterTestcase @@ -23,7 +23,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert schema == { "info": { diff --git a/tests/asyncapi/confluent/v3_0_0/test_security.py b/tests/asyncapi/confluent/v3_0_0/test_security.py index fc4849c100..dfa519457f 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_security.py +++ b/tests/asyncapi/confluent/v3_0_0/test_security.py @@ -2,8 +2,6 @@ from copy import deepcopy from faststream.app import FastStream -from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.confluent import KafkaBroker from faststream.security import ( BaseSecurity, @@ -11,6 +9,8 @@ SASLScram256, SASLScram512, ) +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion basic_schema = { "info": { @@ -134,7 +134,7 @@ def test_base_security_schema(): security = BaseSecurity(ssl_context=ssl_context) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0) + app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") @@ -155,7 +155,7 @@ def test_plaintext_security_schema(): ) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0) + app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") @@ -184,7 +184,7 @@ def test_scram256_security_schema(): ) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0) + app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") @@ -211,7 +211,7 @@ def test_scram512_security_schema(): ) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0) + app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") diff --git a/tests/asyncapi/kafka/v2_6_0/test_app.py b/tests/asyncapi/kafka/v2_6_0/test_app.py index 630e88e659..0ab08dd9cc 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_app.py +++ b/tests/asyncapi/kafka/v2_6_0/test_app.py @@ -1,10 +1,10 @@ from faststream import FastStream +from faststream.kafka import KafkaBroker from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.schema.contact import Contact -from faststream.specification.schema.license import License -from faststream.kafka import KafkaBroker from faststream.specification.schema.docs import ExternalDocs +from faststream.specification.schema.license import License from faststream.specification.schema.tag import Tag diff --git a/tests/asyncapi/kafka/v2_6_0/test_arguments.py b/tests/asyncapi/kafka/v2_6_0/test_arguments.py index 6c882c1b44..83aefec241 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_arguments.py +++ b/tests/asyncapi/kafka/v2_6_0/test_arguments.py @@ -1,5 +1,5 @@ -from faststream.specification.asyncapi.generate import get_app_schema from faststream.kafka import KafkaBroker +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase diff --git a/tests/asyncapi/kafka/v2_6_0/test_connection.py b/tests/asyncapi/kafka/v2_6_0/test_connection.py index 6713cc3c3a..04510dcd49 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_connection.py +++ b/tests/asyncapi/kafka/v2_6_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.specification.asyncapi.generate import get_app_schema from faststream.kafka import KafkaBroker +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.schema.tag import Tag diff --git a/tests/asyncapi/kafka/v2_6_0/test_fastapi.py b/tests/asyncapi/kafka/v2_6_0/test_fastapi.py index f2055f7902..23deb60827 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/kafka/v2_6_0/test_fastapi.py @@ -1,9 +1,9 @@ from typing import Type -from faststream.specification.asyncapi.generate import get_app_schema from faststream.kafka.fastapi import KafkaRouter from faststream.kafka.testing import TestKafkaBroker from faststream.security import SASLPlaintext +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import FastAPICompatible from tests.asyncapi.base.v2_6_0.fastapi import FastAPITestCase diff --git a/tests/asyncapi/kafka/v2_6_0/test_naming.py b/tests/asyncapi/kafka/v2_6_0/test_naming.py index 9f02856392..fffaae0f4a 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_naming.py +++ b/tests/asyncapi/kafka/v2_6_0/test_naming.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.specification.asyncapi.generate import get_app_schema from faststream.kafka import KafkaBroker +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.naming import NamingTestCase diff --git a/tests/asyncapi/kafka/v2_6_0/test_publisher.py b/tests/asyncapi/kafka/v2_6_0/test_publisher.py index 56288e9314..c984825d04 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_publisher.py +++ b/tests/asyncapi/kafka/v2_6_0/test_publisher.py @@ -1,5 +1,5 @@ -from faststream.specification.asyncapi.generate import get_app_schema from faststream.kafka import KafkaBroker +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase diff --git a/tests/asyncapi/kafka/v2_6_0/test_router.py b/tests/asyncapi/kafka/v2_6_0/test_router.py index 8b20ea0c8f..20c6a385dd 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_router.py +++ b/tests/asyncapi/kafka/v2_6_0/test_router.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.specification.asyncapi.generate import get_app_schema from faststream.kafka import KafkaBroker, KafkaPublisher, KafkaRoute, KafkaRouter +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase diff --git a/tests/asyncapi/kafka/v2_6_0/test_security.py b/tests/asyncapi/kafka/v2_6_0/test_security.py index b72322defd..6118c390fc 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_security.py +++ b/tests/asyncapi/kafka/v2_6_0/test_security.py @@ -2,7 +2,6 @@ from copy import deepcopy from faststream.app import FastStream -from faststream.specification.asyncapi.generate import get_app_schema from faststream.kafka import KafkaBroker from faststream.security import ( SASLGSSAPI, @@ -12,6 +11,7 @@ SASLScram256, SASLScram512, ) +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion basic_schema = { diff --git a/tests/asyncapi/kafka/v3_0_0/test_arguments.py b/tests/asyncapi/kafka/v3_0_0/test_arguments.py index d588a12fcd..f40900c800 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_arguments.py +++ b/tests/asyncapi/kafka/v3_0_0/test_arguments.py @@ -1,5 +1,5 @@ -from faststream.specification.asyncapi.generate import get_app_schema from faststream.kafka import KafkaBroker +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase diff --git a/tests/asyncapi/kafka/v3_0_0/test_connection.py b/tests/asyncapi/kafka/v3_0_0/test_connection.py index 0ef17b3799..63ffe768a6 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_connection.py +++ b/tests/asyncapi/kafka/v3_0_0/test_connection.py @@ -1,7 +1,7 @@ from faststream import FastStream +from faststream.kafka import KafkaBroker from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion -from faststream.kafka import KafkaBroker from faststream.specification.schema.tag import Tag @@ -15,8 +15,8 @@ def test_base(): description="Test description", tags=(Tag(name="some-tag", description="experimental"),), ), - asyncapi_version=AsyncAPIVersion.v3_0, - ) + ), + version=AsyncAPIVersion.v3_0, ).to_jsonable() assert schema == { @@ -43,8 +43,8 @@ def test_multi(): schema = get_app_schema( FastStream( KafkaBroker(["kafka:9092", "kafka:9093"]), - asyncapi_version=AsyncAPIVersion.v3_0, - ) + ), + version=AsyncAPIVersion.v3_0, ).to_jsonable() assert schema == { @@ -78,8 +78,8 @@ def test_custom(): ["kafka:9092", "kafka:9093"], specification_url=["kafka:9094", "kafka:9095"], ), - asyncapi_version=AsyncAPIVersion.v3_0, - ) + ), + version=AsyncAPIVersion.v3_0, ).to_jsonable() assert schema == { diff --git a/tests/asyncapi/kafka/v3_0_0/test_fastapi.py b/tests/asyncapi/kafka/v3_0_0/test_fastapi.py index 42eff6ba7c..990ed0c89a 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/kafka/v3_0_0/test_fastapi.py @@ -1,16 +1,15 @@ -from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.kafka.fastapi import KafkaRouter from faststream.kafka.testing import TestKafkaBroker from faststream.security import SASLPlaintext +from faststream.specification.asyncapi.generate import get_app_schema from tests.asyncapi.base.v3_0_0.arguments import FastAPICompatible from tests.asyncapi.base.v3_0_0.fastapi import FastAPITestCase from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase class TestRouterArguments(FastAPITestCase, FastAPICompatible): - broker_factory = staticmethod(lambda: KafkaRouter(asyncapi_version=AsyncAPIVersion.v3_0)) + broker_factory = KafkaRouter router_factory = KafkaRouter broker_wrapper = staticmethod(TestKafkaBroker) @@ -19,7 +18,7 @@ def build_app(self, router): class TestRouterPublisher(PublisherTestcase): - broker_factory = staticmethod(lambda: KafkaRouter(asyncapi_version=AsyncAPIVersion.v3_0)) + broker_factory = staticmethod(lambda: KafkaRouter()) def build_app(self, router): return router diff --git a/tests/asyncapi/kafka/v3_0_0/test_naming.py b/tests/asyncapi/kafka/v3_0_0/test_naming.py index d68d81dcf2..c1fa61683c 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_naming.py +++ b/tests/asyncapi/kafka/v3_0_0/test_naming.py @@ -1,7 +1,7 @@ from faststream import FastStream +from faststream.kafka import KafkaBroker from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion -from faststream.kafka import KafkaBroker from tests.asyncapi.base.v3_0_0.naming import NamingTestCase @@ -14,7 +14,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert schema == { "asyncapi": "3.0.0", diff --git a/tests/asyncapi/kafka/v3_0_0/test_publisher.py b/tests/asyncapi/kafka/v3_0_0/test_publisher.py index c010e08b53..c05c5d2c0d 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_publisher.py +++ b/tests/asyncapi/kafka/v3_0_0/test_publisher.py @@ -1,5 +1,5 @@ -from faststream.specification.asyncapi.generate import get_app_schema from faststream.kafka import KafkaBroker +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase diff --git a/tests/asyncapi/kafka/v3_0_0/test_router.py b/tests/asyncapi/kafka/v3_0_0/test_router.py index fc4ed6f0b5..1e701f9ae8 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_router.py +++ b/tests/asyncapi/kafka/v3_0_0/test_router.py @@ -1,7 +1,7 @@ from faststream import FastStream +from faststream.kafka import KafkaBroker, KafkaPublisher, KafkaRoute, KafkaRouter from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion -from faststream.kafka import KafkaBroker, KafkaPublisher, KafkaRoute, KafkaRouter from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v3_0_0.router import RouterTestcase @@ -23,7 +23,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert schema == { "info": { diff --git a/tests/asyncapi/kafka/v3_0_0/test_security.py b/tests/asyncapi/kafka/v3_0_0/test_security.py index 982a4236d9..7529bc6cdb 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_security.py +++ b/tests/asyncapi/kafka/v3_0_0/test_security.py @@ -2,8 +2,6 @@ from copy import deepcopy from faststream.app import FastStream -from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.kafka import KafkaBroker from faststream.security import ( BaseSecurity, @@ -11,6 +9,8 @@ SASLScram256, SASLScram512, ) +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion basic_schema = { "info": { @@ -134,7 +134,7 @@ def test_base_security_schema(): security = BaseSecurity(ssl_context=ssl_context) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0) + app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") @@ -155,7 +155,7 @@ def test_plaintext_security_schema(): ) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0) + app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") @@ -184,7 +184,7 @@ def test_scram256_security_schema(): ) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0) + app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") @@ -211,7 +211,7 @@ def test_scram512_security_schema(): ) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0) + app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") diff --git a/tests/asyncapi/nats/v2_6_0/test_arguments.py b/tests/asyncapi/nats/v2_6_0/test_arguments.py index 10838e9c7a..95691f0b06 100644 --- a/tests/asyncapi/nats/v2_6_0/test_arguments.py +++ b/tests/asyncapi/nats/v2_6_0/test_arguments.py @@ -1,5 +1,5 @@ -from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase diff --git a/tests/asyncapi/nats/v2_6_0/test_connection.py b/tests/asyncapi/nats/v2_6_0/test_connection.py index 9c598ee224..0f6d06a3e1 100644 --- a/tests/asyncapi/nats/v2_6_0/test_connection.py +++ b/tests/asyncapi/nats/v2_6_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.schema.tag import Tag diff --git a/tests/asyncapi/nats/v2_6_0/test_kv_schema.py b/tests/asyncapi/nats/v2_6_0/test_kv_schema.py index 82a78d12b4..0b050562ca 100644 --- a/tests/asyncapi/nats/v2_6_0/test_kv_schema.py +++ b/tests/asyncapi/nats/v2_6_0/test_kv_schema.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion diff --git a/tests/asyncapi/nats/v2_6_0/test_naming.py b/tests/asyncapi/nats/v2_6_0/test_naming.py index 0bc379e579..0819550ee2 100644 --- a/tests/asyncapi/nats/v2_6_0/test_naming.py +++ b/tests/asyncapi/nats/v2_6_0/test_naming.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.naming import NamingTestCase diff --git a/tests/asyncapi/nats/v2_6_0/test_obj_schema.py b/tests/asyncapi/nats/v2_6_0/test_obj_schema.py index bbbcbf1291..03ab1fb1c0 100644 --- a/tests/asyncapi/nats/v2_6_0/test_obj_schema.py +++ b/tests/asyncapi/nats/v2_6_0/test_obj_schema.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion diff --git a/tests/asyncapi/nats/v2_6_0/test_publisher.py b/tests/asyncapi/nats/v2_6_0/test_publisher.py index e786e0e134..6b4f39f2ce 100644 --- a/tests/asyncapi/nats/v2_6_0/test_publisher.py +++ b/tests/asyncapi/nats/v2_6_0/test_publisher.py @@ -1,5 +1,5 @@ -from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase diff --git a/tests/asyncapi/nats/v2_6_0/test_router.py b/tests/asyncapi/nats/v2_6_0/test_router.py index dc1bc9bf5d..769023e1f0 100644 --- a/tests/asyncapi/nats/v2_6_0/test_router.py +++ b/tests/asyncapi/nats/v2_6_0/test_router.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker, NatsPublisher, NatsRoute, NatsRouter +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase diff --git a/tests/asyncapi/nats/v3_0_0/test_arguments.py b/tests/asyncapi/nats/v3_0_0/test_arguments.py index d7d331dd28..e82474a90f 100644 --- a/tests/asyncapi/nats/v3_0_0/test_arguments.py +++ b/tests/asyncapi/nats/v3_0_0/test_arguments.py @@ -1,5 +1,5 @@ -from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase diff --git a/tests/asyncapi/nats/v3_0_0/test_connection.py b/tests/asyncapi/nats/v3_0_0/test_connection.py index 36e3cfe4cd..ae8789c45d 100644 --- a/tests/asyncapi/nats/v3_0_0/test_connection.py +++ b/tests/asyncapi/nats/v3_0_0/test_connection.py @@ -1,7 +1,7 @@ from faststream import FastStream +from faststream.nats import NatsBroker from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion -from faststream.nats import NatsBroker from faststream.specification.schema.tag import Tag @@ -15,8 +15,8 @@ def test_base(): description="Test description", tags=(Tag(name="some-tag", description="experimental"),), ), - asyncapi_version=AsyncAPIVersion.v3_0, - ) + ), + version=AsyncAPIVersion.v3_0, ).to_jsonable() assert schema == { @@ -45,8 +45,8 @@ def test_multi(): NatsBroker( ["nats:9092", "nats:9093"] ), - asyncapi_version=AsyncAPIVersion.v3_0, - ) + ), + version=AsyncAPIVersion.v3_0, ).to_jsonable() assert schema == { @@ -80,8 +80,8 @@ def test_custom(): ["nats:9092", "nats:9093"], specification_url=["nats:9094", "nats:9095"], ), - asyncapi_version=AsyncAPIVersion.v3_0, - ) + ), + version=AsyncAPIVersion.v3_0, ).to_jsonable() assert schema == { diff --git a/tests/asyncapi/nats/v3_0_0/test_fastapi.py b/tests/asyncapi/nats/v3_0_0/test_fastapi.py index ca493da280..f8ac786487 100644 --- a/tests/asyncapi/nats/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/nats/v3_0_0/test_fastapi.py @@ -1,5 +1,4 @@ -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.nats import TestNatsBroker from faststream.nats.fastapi import NatsRouter from tests.asyncapi.base.v3_0_0.arguments import FastAPICompatible @@ -8,7 +7,7 @@ class TestRouterArguments(FastAPITestCase, FastAPICompatible): - broker_factory = staticmethod(lambda: NatsRouter(asyncapi_version=AsyncAPIVersion.v3_0)) + broker_factory = staticmethod(lambda: NatsRouter()) router_factory = NatsRouter broker_wrapper = staticmethod(TestNatsBroker) @@ -17,7 +16,7 @@ def build_app(self, router): class TestRouterPublisher(PublisherTestcase): - broker_factory = staticmethod(lambda: NatsRouter(asyncapi_version=AsyncAPIVersion.v3_0)) + broker_factory = staticmethod(lambda: NatsRouter()) def build_app(self, router): return router diff --git a/tests/asyncapi/nats/v3_0_0/test_kv_schema.py b/tests/asyncapi/nats/v3_0_0/test_kv_schema.py index 9fba249772..944da11f0a 100644 --- a/tests/asyncapi/nats/v3_0_0/test_kv_schema.py +++ b/tests/asyncapi/nats/v3_0_0/test_kv_schema.py @@ -1,7 +1,7 @@ from faststream import FastStream +from faststream.nats import NatsBroker from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion -from faststream.nats import NatsBroker def test_kv_schema(): @@ -10,6 +10,6 @@ def test_kv_schema(): @broker.subscriber("test", kv_watch="test") async def handle(): ... - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert schema["channels"] == {} diff --git a/tests/asyncapi/nats/v3_0_0/test_naming.py b/tests/asyncapi/nats/v3_0_0/test_naming.py index 5f73321898..f87b11de18 100644 --- a/tests/asyncapi/nats/v3_0_0/test_naming.py +++ b/tests/asyncapi/nats/v3_0_0/test_naming.py @@ -1,7 +1,7 @@ from faststream import FastStream +from faststream.nats import NatsBroker from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion -from faststream.nats import NatsBroker from tests.asyncapi.base.v3_0_0.naming import NamingTestCase @@ -14,7 +14,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert schema == { "asyncapi": "3.0.0", diff --git a/tests/asyncapi/nats/v3_0_0/test_obj_schema.py b/tests/asyncapi/nats/v3_0_0/test_obj_schema.py index 57d9547353..86de2debe4 100644 --- a/tests/asyncapi/nats/v3_0_0/test_obj_schema.py +++ b/tests/asyncapi/nats/v3_0_0/test_obj_schema.py @@ -1,7 +1,7 @@ from faststream import FastStream +from faststream.nats import NatsBroker from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion -from faststream.nats import NatsBroker def test_obj_schema(): @@ -10,6 +10,6 @@ def test_obj_schema(): @broker.subscriber("test", obj_watch=True) async def handle(): ... - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert schema["channels"] == {} diff --git a/tests/asyncapi/nats/v3_0_0/test_publisher.py b/tests/asyncapi/nats/v3_0_0/test_publisher.py index f83ab0f7e4..242b649088 100644 --- a/tests/asyncapi/nats/v3_0_0/test_publisher.py +++ b/tests/asyncapi/nats/v3_0_0/test_publisher.py @@ -1,5 +1,5 @@ -from faststream.specification.asyncapi.generate import get_app_schema from faststream.nats import NatsBroker +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase diff --git a/tests/asyncapi/nats/v3_0_0/test_router.py b/tests/asyncapi/nats/v3_0_0/test_router.py index f3c38a9986..51e57bcf78 100644 --- a/tests/asyncapi/nats/v3_0_0/test_router.py +++ b/tests/asyncapi/nats/v3_0_0/test_router.py @@ -1,7 +1,7 @@ from faststream import FastStream +from faststream.nats import NatsBroker, NatsPublisher, NatsRoute, NatsRouter from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion -from faststream.nats import NatsBroker, NatsPublisher, NatsRoute, NatsRouter from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v3_0_0.router import RouterTestcase @@ -23,7 +23,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert schema == { "info": { diff --git a/tests/asyncapi/rabbit/v2_6_0/test_arguments.py b/tests/asyncapi/rabbit/v2_6_0/test_arguments.py index 02b883f405..4a60a47b19 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_arguments.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_arguments.py @@ -1,5 +1,5 @@ -from faststream.specification.asyncapi.generate import get_app_schema from faststream.rabbit import ExchangeType, RabbitBroker, RabbitExchange, RabbitQueue +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase diff --git a/tests/asyncapi/rabbit/v2_6_0/test_connection.py b/tests/asyncapi/rabbit/v2_6_0/test_connection.py index 47ac99394f..4716e40869 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_connection.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.specification.asyncapi.generate import get_app_schema from faststream.rabbit import RabbitBroker +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.schema.tag import Tag diff --git a/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py b/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py index 1e95ca86a2..1d3d1ef14c 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py @@ -1,9 +1,9 @@ from typing import Type -from faststream.specification.asyncapi.generate import get_app_schema from faststream.rabbit.fastapi import RabbitRouter from faststream.rabbit.testing import TestRabbitBroker from faststream.security import SASLPlaintext +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import FastAPICompatible from tests.asyncapi.base.v2_6_0.fastapi import FastAPITestCase diff --git a/tests/asyncapi/rabbit/v2_6_0/test_naming.py b/tests/asyncapi/rabbit/v2_6_0/test_naming.py index e0db99f303..934b076408 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_naming.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_naming.py @@ -1,8 +1,8 @@ from typing import Type from faststream import FastStream -from faststream.specification.asyncapi.generate import get_app_schema from faststream.rabbit import RabbitBroker +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.naming import NamingTestCase diff --git a/tests/asyncapi/rabbit/v2_6_0/test_publisher.py b/tests/asyncapi/rabbit/v2_6_0/test_publisher.py index 8ed53416ec..8cfd5ed4b2 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_publisher.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_publisher.py @@ -1,5 +1,5 @@ -from faststream.specification.asyncapi.generate import get_app_schema from faststream.rabbit import ExchangeType, RabbitBroker, RabbitExchange, RabbitQueue +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase diff --git a/tests/asyncapi/rabbit/v2_6_0/test_router.py b/tests/asyncapi/rabbit/v2_6_0/test_router.py index 76edf1ac15..1004fc005d 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_router.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_router.py @@ -1,5 +1,4 @@ from faststream import FastStream -from faststream.specification.asyncapi.generate import get_app_schema from faststream.rabbit import ( RabbitBroker, RabbitPublisher, @@ -7,6 +6,7 @@ RabbitRoute, RabbitRouter, ) +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase diff --git a/tests/asyncapi/rabbit/v2_6_0/test_security.py b/tests/asyncapi/rabbit/v2_6_0/test_security.py index 1e806d31a5..8fc734e3b2 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_security.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_security.py @@ -1,12 +1,12 @@ import ssl from faststream.app import FastStream -from faststream.specification.asyncapi.generate import get_app_schema from faststream.rabbit import RabbitBroker from faststream.security import ( BaseSecurity, SASLPlaintext, ) +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion diff --git a/tests/asyncapi/rabbit/v3_0_0/test_arguments.py b/tests/asyncapi/rabbit/v3_0_0/test_arguments.py index 51c087d863..a02134dc19 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_arguments.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_arguments.py @@ -1,5 +1,5 @@ -from faststream.specification.asyncapi.generate import get_app_schema from faststream.rabbit import ExchangeType, RabbitBroker, RabbitExchange, RabbitQueue +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase diff --git a/tests/asyncapi/rabbit/v3_0_0/test_connection.py b/tests/asyncapi/rabbit/v3_0_0/test_connection.py index 60962baa21..bab50a9cc1 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_connection.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_connection.py @@ -1,7 +1,7 @@ from faststream import FastStream +from faststream.rabbit import RabbitBroker from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion -from faststream.rabbit import RabbitBroker from faststream.specification.schema.tag import Tag @@ -15,8 +15,8 @@ def test_base(): description="Test description", tags=(Tag(name="some-tag", description="experimental"),), ), - asyncapi_version=AsyncAPIVersion.v3_0, - ) + ), + version=AsyncAPIVersion.v3_0, ).to_jsonable() assert schema == { @@ -58,7 +58,7 @@ def test_custom(): ) broker.publisher("test") - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() assert ( schema diff --git a/tests/asyncapi/rabbit/v3_0_0/test_fastapi.py b/tests/asyncapi/rabbit/v3_0_0/test_fastapi.py index 9d522340f9..7a4d596d6d 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_fastapi.py @@ -1,15 +1,14 @@ -from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.rabbit.fastapi import RabbitRouter from faststream.rabbit.testing import TestRabbitBroker from faststream.security import SASLPlaintext +from faststream.specification.asyncapi.generate import get_app_schema from tests.asyncapi.base.v3_0_0.arguments import FastAPICompatible from tests.asyncapi.base.v3_0_0.fastapi import FastAPITestCase from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase class TestRouterArguments(FastAPITestCase, FastAPICompatible): - broker_factory = staticmethod(lambda: RabbitRouter(asyncapi_version=AsyncAPIVersion.v3_0)) + broker_factory = staticmethod(lambda: RabbitRouter()) router_factory = RabbitRouter broker_wrapper = staticmethod(TestRabbitBroker) @@ -18,7 +17,7 @@ def build_app(self, router): class TestRouterPublisher(PublisherTestcase): - broker_factory = staticmethod(lambda: RabbitRouter(asyncapi_version=AsyncAPIVersion.v3_0)) + broker_factory = staticmethod(lambda: RabbitRouter()) def build_app(self, router): return router @@ -27,7 +26,7 @@ def build_app(self, router): def test_fastapi_security_schema(): security = SASLPlaintext(username="user", password="pass", use_ssl=False) - router = RabbitRouter(security=security, asyncapi_version=AsyncAPIVersion.v3_0) + router = RabbitRouter(security=security) schema = get_app_schema(router,).to_jsonable() diff --git a/tests/asyncapi/rabbit/v3_0_0/test_naming.py b/tests/asyncapi/rabbit/v3_0_0/test_naming.py index 6bc06d5e28..db833b73a2 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_naming.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_naming.py @@ -1,9 +1,9 @@ from typing import Type from faststream import FastStream +from faststream.rabbit import RabbitBroker from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion -from faststream.rabbit import RabbitBroker from tests.asyncapi.base.v3_0_0.naming import NamingTestCase @@ -16,7 +16,7 @@ def test_subscriber_with_exchange(self): @broker.subscriber("test", "exchange") async def handle(): ... - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0,).to_jsonable() assert list(schema["channels"].keys()) == ["test:exchange:Handle"] @@ -30,7 +30,7 @@ def test_publisher_with_exchange(self): @broker.publisher("test", "exchange") async def handle(): ... - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0,).to_jsonable() assert list(schema["channels"].keys()) == ["test:exchange:Publisher"] @@ -44,7 +44,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0,).to_jsonable() assert ( schema diff --git a/tests/asyncapi/rabbit/v3_0_0/test_publisher.py b/tests/asyncapi/rabbit/v3_0_0/test_publisher.py index 2fc2a1b145..faed5925c1 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_publisher.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_publisher.py @@ -1,5 +1,5 @@ -from faststream.specification.asyncapi.generate import get_app_schema from faststream.rabbit import ExchangeType, RabbitBroker, RabbitExchange, RabbitQueue +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase diff --git a/tests/asyncapi/rabbit/v3_0_0/test_router.py b/tests/asyncapi/rabbit/v3_0_0/test_router.py index 332c9ecace..084ff408b2 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_router.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_router.py @@ -1,6 +1,4 @@ from faststream import FastStream -from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.rabbit import ( RabbitBroker, RabbitPublisher, @@ -8,6 +6,8 @@ RabbitRoute, RabbitRouter, ) +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v3_0_0.router import RouterTestcase @@ -29,7 +29,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0,).to_jsonable() assert ( schema diff --git a/tests/asyncapi/rabbit/v3_0_0/test_security.py b/tests/asyncapi/rabbit/v3_0_0/test_security.py index 18d94f7d98..6768024d69 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_security.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_security.py @@ -1,13 +1,13 @@ import ssl from faststream.app import FastStream -from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.rabbit import RabbitBroker from faststream.security import ( BaseSecurity, SASLPlaintext, ) +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion def test_base_security_schema(): @@ -21,7 +21,7 @@ def test_base_security_schema(): ) # pragma: allowlist secret assert broker._connection_kwargs.get("ssl_context") is ssl_context - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0,).to_jsonable() assert schema == { "asyncapi": "3.0.0", @@ -59,7 +59,7 @@ def test_plaintext_security_schema(): ) # pragma: allowlist secret assert broker._connection_kwargs.get("ssl_context") is ssl_context - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0,).to_jsonable() assert ( schema == { @@ -99,7 +99,7 @@ def test_plaintext_security_schema_without_ssl(): == "amqp://admin:password@localhost:5672/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0,).to_jsonable() assert ( schema == { diff --git a/tests/asyncapi/redis/v2_6_0/test_arguments.py b/tests/asyncapi/redis/v2_6_0/test_arguments.py index 5e3b7ecea8..884c2b8a8d 100644 --- a/tests/asyncapi/redis/v2_6_0/test_arguments.py +++ b/tests/asyncapi/redis/v2_6_0/test_arguments.py @@ -1,5 +1,5 @@ -from faststream.specification.asyncapi.generate import get_app_schema from faststream.redis import RedisBroker, StreamSub +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase diff --git a/tests/asyncapi/redis/v2_6_0/test_connection.py b/tests/asyncapi/redis/v2_6_0/test_connection.py index 7c34106cb5..f6428b53e6 100644 --- a/tests/asyncapi/redis/v2_6_0/test_connection.py +++ b/tests/asyncapi/redis/v2_6_0/test_connection.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.specification.asyncapi.generate import get_app_schema from faststream.redis import RedisBroker +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.schema.tag import Tag diff --git a/tests/asyncapi/redis/v2_6_0/test_naming.py b/tests/asyncapi/redis/v2_6_0/test_naming.py index a95ed4f203..56b5050712 100644 --- a/tests/asyncapi/redis/v2_6_0/test_naming.py +++ b/tests/asyncapi/redis/v2_6_0/test_naming.py @@ -1,8 +1,8 @@ import pytest from faststream import FastStream -from faststream.specification.asyncapi.generate import get_app_schema from faststream.redis import RedisBroker +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.naming import NamingTestCase diff --git a/tests/asyncapi/redis/v2_6_0/test_publisher.py b/tests/asyncapi/redis/v2_6_0/test_publisher.py index 7487818b7e..f704c5bffd 100644 --- a/tests/asyncapi/redis/v2_6_0/test_publisher.py +++ b/tests/asyncapi/redis/v2_6_0/test_publisher.py @@ -1,5 +1,5 @@ -from faststream.specification.asyncapi.generate import get_app_schema from faststream.redis import RedisBroker +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase diff --git a/tests/asyncapi/redis/v2_6_0/test_router.py b/tests/asyncapi/redis/v2_6_0/test_router.py index 1ff095555a..90defd4b60 100644 --- a/tests/asyncapi/redis/v2_6_0/test_router.py +++ b/tests/asyncapi/redis/v2_6_0/test_router.py @@ -1,6 +1,6 @@ from faststream import FastStream -from faststream.specification.asyncapi.generate import get_app_schema from faststream.redis import RedisBroker, RedisPublisher, RedisRoute, RedisRouter +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase diff --git a/tests/asyncapi/redis/v2_6_0/test_security.py b/tests/asyncapi/redis/v2_6_0/test_security.py index e70ddc1d4a..62079eed11 100644 --- a/tests/asyncapi/redis/v2_6_0/test_security.py +++ b/tests/asyncapi/redis/v2_6_0/test_security.py @@ -1,12 +1,12 @@ import ssl from faststream.app import FastStream -from faststream.specification.asyncapi.generate import get_app_schema from faststream.redis import RedisBroker from faststream.security import ( BaseSecurity, SASLPlaintext, ) +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion diff --git a/tests/asyncapi/redis/v3_0_0/test_arguments.py b/tests/asyncapi/redis/v3_0_0/test_arguments.py index 9c095a702d..d33efc72ae 100644 --- a/tests/asyncapi/redis/v3_0_0/test_arguments.py +++ b/tests/asyncapi/redis/v3_0_0/test_arguments.py @@ -1,5 +1,5 @@ -from faststream.specification.asyncapi.generate import get_app_schema from faststream.redis import RedisBroker, StreamSub +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase diff --git a/tests/asyncapi/redis/v3_0_0/test_connection.py b/tests/asyncapi/redis/v3_0_0/test_connection.py index 94eaed1554..f039a72a17 100644 --- a/tests/asyncapi/redis/v3_0_0/test_connection.py +++ b/tests/asyncapi/redis/v3_0_0/test_connection.py @@ -1,7 +1,7 @@ from faststream import FastStream +from faststream.redis import RedisBroker from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion -from faststream.redis import RedisBroker from faststream.specification.schema.tag import Tag @@ -15,8 +15,8 @@ def test_base(): description="Test description", tags=(Tag(name="some-tag", description="experimental"),), ), - asyncapi_version=AsyncAPIVersion.v3_0, - ) + ), + version=AsyncAPIVersion.v3_0, ).to_jsonable() assert schema == { @@ -46,8 +46,8 @@ def test_custom(): "redis://localhost:6379", specification_url="rediss://127.0.0.1:8000" ), - asyncapi_version=AsyncAPIVersion.v3_0, - ) + ), + version=AsyncAPIVersion.v3_0, ).to_jsonable() assert schema == { diff --git a/tests/asyncapi/redis/v3_0_0/test_fastapi.py b/tests/asyncapi/redis/v3_0_0/test_fastapi.py index c2b95ebb69..d7a4b9bac2 100644 --- a/tests/asyncapi/redis/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/redis/v3_0_0/test_fastapi.py @@ -1,4 +1,3 @@ -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.redis import TestRedisBroker from faststream.redis.fastapi import RedisRouter from tests.asyncapi.base.v3_0_0.arguments import FastAPICompatible @@ -7,7 +6,7 @@ class TestRouterArguments(FastAPITestCase, FastAPICompatible): - broker_factory = staticmethod(lambda: RedisRouter(asyncapi_version=AsyncAPIVersion.v3_0)) + broker_factory = staticmethod(lambda: RedisRouter()) router_factory = RedisRouter broker_wrapper = staticmethod(TestRedisBroker) @@ -16,7 +15,7 @@ def build_app(self, router): class TestRouterPublisher(PublisherTestcase): - broker_factory = staticmethod(lambda: RedisRouter(asyncapi_version=AsyncAPIVersion.v3_0)) + broker_factory = staticmethod(lambda: RedisRouter()) def build_app(self, router): return router diff --git a/tests/asyncapi/redis/v3_0_0/test_naming.py b/tests/asyncapi/redis/v3_0_0/test_naming.py index 9183eb0f5e..987fa0a5c6 100644 --- a/tests/asyncapi/redis/v3_0_0/test_naming.py +++ b/tests/asyncapi/redis/v3_0_0/test_naming.py @@ -1,9 +1,9 @@ import pytest from faststream import FastStream +from faststream.redis import RedisBroker from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion -from faststream.redis import RedisBroker from tests.asyncapi.base.v3_0_0.naming import NamingTestCase @@ -16,7 +16,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0,).to_jsonable() assert schema == { "asyncapi": "3.0.0", diff --git a/tests/asyncapi/redis/v3_0_0/test_publisher.py b/tests/asyncapi/redis/v3_0_0/test_publisher.py index 005299660d..e5e7af3fef 100644 --- a/tests/asyncapi/redis/v3_0_0/test_publisher.py +++ b/tests/asyncapi/redis/v3_0_0/test_publisher.py @@ -1,5 +1,5 @@ -from faststream.specification.asyncapi.generate import get_app_schema from faststream.redis import RedisBroker +from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase diff --git a/tests/asyncapi/redis/v3_0_0/test_router.py b/tests/asyncapi/redis/v3_0_0/test_router.py index 01069e79ed..72d8f7276f 100644 --- a/tests/asyncapi/redis/v3_0_0/test_router.py +++ b/tests/asyncapi/redis/v3_0_0/test_router.py @@ -1,7 +1,7 @@ from faststream import FastStream +from faststream.redis import RedisBroker, RedisPublisher, RedisRoute, RedisRouter from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.version import AsyncAPIVersion -from faststream.redis import RedisBroker, RedisPublisher, RedisRoute, RedisRouter from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v3_0_0.router import RouterTestcase @@ -23,7 +23,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0,).to_jsonable() assert schema == { "info": { diff --git a/tests/asyncapi/redis/v3_0_0/test_security.py b/tests/asyncapi/redis/v3_0_0/test_security.py index 9c6b717a8d..f8cabfd809 100644 --- a/tests/asyncapi/redis/v3_0_0/test_security.py +++ b/tests/asyncapi/redis/v3_0_0/test_security.py @@ -1,13 +1,13 @@ import ssl from faststream.app import FastStream -from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.redis import RedisBroker from faststream.security import ( BaseSecurity, SASLPlaintext, ) +from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi.version import AsyncAPIVersion def test_base_security_schema(): @@ -20,7 +20,7 @@ def test_base_security_schema(): broker.url == "rediss://localhost:6379/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0,).to_jsonable() assert schema == { "asyncapi": "3.0.0", @@ -56,7 +56,7 @@ def test_plaintext_security_schema(): broker.url == "redis://localhost:6379/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0,).to_jsonable() assert schema == { "asyncapi": "3.0.0", @@ -93,7 +93,7 @@ def test_plaintext_security_schema_without_ssl(): broker.url == "redis://localhost:6379/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = get_app_schema(FastStream(broker, asyncapi_version=AsyncAPIVersion.v3_0)).to_jsonable() + schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0,).to_jsonable() assert schema == { "asyncapi": "3.0.0", diff --git a/tests/cli/test_asyncapi_docs.py b/tests/cli/test_asyncapi_docs.py index 73d4ddb5c0..5c80bfdaac 100644 --- a/tests/cli/test_asyncapi_docs.py +++ b/tests/cli/test_asyncapi_docs.py @@ -9,9 +9,9 @@ from typer.testing import CliRunner from docs.docs_src.getting_started.asyncapi.serve import ( + asyncapi_serve_cmd, gen_asyncapi_json_cmd, gen_asyncapi_yaml_cmd, - asyncapi_serve_cmd, ) from faststream.cli.main import cli from tests.marks import require_aiokafka From 87387742fa4c6025c019323d931798de7af42266 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 18 Aug 2024 00:26:33 +0300 Subject: [PATCH 107/245] Tests update --- faststream/broker/fastapi/router.py | 8 ++++---- faststream/confluent/fastapi/fastapi.py | 4 ++-- faststream/kafka/fastapi/fastapi.py | 4 ++-- faststream/nats/fastapi/fastapi.py | 4 ++-- faststream/rabbit/fastapi/router.py | 4 ++-- faststream/redis/fastapi/fastapi.py | 4 ++-- tests/asyncapi/base/v2_6_0/fastapi.py | 4 +++- tests/asyncapi/base/v3_0_0/fastapi.py | 5 +---- tests/asyncapi/base/v3_0_0/publisher.py | 2 +- 9 files changed, 19 insertions(+), 20 deletions(-) diff --git a/faststream/broker/fastapi/router.py b/faststream/broker/fastapi/router.py index 5bbb4d6526..47b3de1148 100644 --- a/faststream/broker/fastapi/router.py +++ b/faststream/broker/fastapi/router.py @@ -126,8 +126,8 @@ def __init__( generate_unique_id_function: Callable[["APIRoute"], str] = Default( generate_unique_id ), - # AsyncAPI information - asyncapi_tags: Optional[ + # Specification information + specification_tags: Optional[ Iterable[Union["Tag", "TagDict"]] ] = None, schema_url: Optional[str] = "/asyncapi", @@ -145,7 +145,7 @@ def __init__( _BackgroundMiddleware, ), _get_dependant=get_fastapi_dependant, - tags=asyncapi_tags, + tags=specification_tags, apply_types=False, **connection_kwars, ) @@ -303,7 +303,7 @@ async def start_broker_lifespan( from faststream.specification.asyncapi.generate import get_app_schema - self.schema = get_app_schema(self, version=AsyncAPIVersion.v2_6) + self.schema = get_app_schema(self) app.include_router(self.docs_router) diff --git a/faststream/confluent/fastapi/fastapi.py b/faststream/confluent/fastapi/fastapi.py index eb48599cb2..98fcd3744d 100644 --- a/faststream/confluent/fastapi/fastapi.py +++ b/faststream/confluent/fastapi/fastapi.py @@ -298,7 +298,7 @@ def __init__( Optional[str], Doc("Specification server description."), ] = None, - asyncapi_tags: Annotated[ + specification_tags: Annotated[ Optional[Iterable[Union["Tag", "TagDict"]]], Doc("Specification server tags."), ] = None, @@ -576,7 +576,7 @@ def __init__( protocol=protocol, description=description, protocol_version=protocol_version, - asyncapi_tags=asyncapi_tags, + specification_tags=specification_tags, specification_url=specification_url, # FastAPI kwargs prefix=prefix, diff --git a/faststream/kafka/fastapi/fastapi.py b/faststream/kafka/fastapi/fastapi.py index c49431d90a..28c0753bb2 100644 --- a/faststream/kafka/fastapi/fastapi.py +++ b/faststream/kafka/fastapi/fastapi.py @@ -306,7 +306,7 @@ def __init__( Optional[str], Doc("Specification server description."), ] = None, - asyncapi_tags: Annotated[ + specification_tags: Annotated[ Optional[Iterable[Union["Tag", "TagDict"]]], Doc("Specification server tags."), ] = None, @@ -591,7 +591,7 @@ def __init__( protocol=protocol, description=description, protocol_version=protocol_version, - asyncapi_tags=asyncapi_tags, + specification_tags=specification_tags, specification_url=specification_url, # FastAPI args prefix=prefix, diff --git a/faststream/nats/fastapi/fastapi.py b/faststream/nats/fastapi/fastapi.py index 4fcc7852f6..8a9e8cb7b3 100644 --- a/faststream/nats/fastapi/fastapi.py +++ b/faststream/nats/fastapi/fastapi.py @@ -259,7 +259,7 @@ def __init__( Optional[str], Doc("AsyncAPI server description."), ] = None, - asyncapi_tags: Annotated[ + specification_tags: Annotated[ Optional[Iterable[Union["Tag", "TagDict"]]], Doc("AsyncAPI server tags."), ] = None, @@ -549,7 +549,7 @@ def __init__( logger=logger, log_level=log_level, log_fmt=log_fmt, - asyncapi_tags=asyncapi_tags, + specification_tags=specification_tags, schema_url=schema_url, setup_state=setup_state, # FastAPI kwargs diff --git a/faststream/rabbit/fastapi/router.py b/faststream/rabbit/fastapi/router.py index b19c46a062..03a1a76eb5 100644 --- a/faststream/rabbit/fastapi/router.py +++ b/faststream/rabbit/fastapi/router.py @@ -180,7 +180,7 @@ def __init__( Optional[str], Doc("AsyncAPI server description."), ] = None, - asyncapi_tags: Annotated[ + specification_tags: Annotated[ Optional[Iterable[Union["Tag", "TagDict"]]], Doc("AsyncAPI server tags."), ] = None, @@ -452,7 +452,7 @@ def __init__( logger=logger, log_level=log_level, log_fmt=log_fmt, - asyncapi_tags=asyncapi_tags, + specification_tags=specification_tags, schema_url=schema_url, setup_state=setup_state, # FastAPI kwargs diff --git a/faststream/redis/fastapi/fastapi.py b/faststream/redis/fastapi/fastapi.py index 6dd3401697..ebd7d323f5 100644 --- a/faststream/redis/fastapi/fastapi.py +++ b/faststream/redis/fastapi/fastapi.py @@ -129,7 +129,7 @@ def __init__( Optional[str], Doc("AsyncAPI server description."), ] = None, - asyncapi_tags: Annotated[ + specification_tags: Annotated[ Optional[Iterable[Union["Tag", "TagDict"]]], Doc("AsyncAPI server tags."), ] = None, @@ -410,7 +410,7 @@ def __init__( protocol=protocol, description=description, protocol_version=protocol_version, - asyncapi_tags=asyncapi_tags, + specification_tags=specification_tags, specification_url=specification_url, # FastAPI kwargs prefix=prefix, diff --git a/tests/asyncapi/base/v2_6_0/fastapi.py b/tests/asyncapi/base/v2_6_0/fastapi.py index f383476921..080edca0ed 100644 --- a/tests/asyncapi/base/v2_6_0/fastapi.py +++ b/tests/asyncapi/base/v2_6_0/fastapi.py @@ -16,6 +16,7 @@ class FastAPITestCase: broker_class: Type[StreamRouter[MsgType]] broker_wrapper: Callable[[BrokerUsecase[MsgType, Any]], BrokerUsecase[MsgType, Any]] + @pytest.mark.skip @pytest.mark.asyncio async def test_fastapi_full_information(self): broker = self.broker_class( @@ -23,7 +24,7 @@ async def test_fastapi_full_information(self): protocol_version="1.1.1", description="Test broker description", schema_url="/asyncapi_schema", - asyncapi_tags=[{"name": "test"}], + specification_tags=[{"name": "test"}], ) app = FastAPI( @@ -68,6 +69,7 @@ async def test_fastapi_full_information(self): "components": {"messages": {}, "schemas": {}}, } + @pytest.mark.skip() @pytest.mark.asyncio async def test_fastapi_asyncapi_routes(self): broker = self.broker_class(schema_url="/asyncapi_schema") diff --git a/tests/asyncapi/base/v3_0_0/fastapi.py b/tests/asyncapi/base/v3_0_0/fastapi.py index b45921a8c6..d4343608db 100644 --- a/tests/asyncapi/base/v3_0_0/fastapi.py +++ b/tests/asyncapi/base/v3_0_0/fastapi.py @@ -16,7 +16,6 @@ class FastAPITestCase: router_factory: Type[StreamRouter[MsgType]] broker_wrapper: Callable[[BrokerUsecase[MsgType, Any]], BrokerUsecase[MsgType, Any]] - @pytest.mark.skip() @pytest.mark.asyncio() async def test_fastapi_full_information(self): broker = self.router_factory( @@ -24,8 +23,7 @@ async def test_fastapi_full_information(self): protocol_version="1.1.1", description="Test broker description", schema_url="/asyncapi_schema", - asyncapi_tags=[{"name": "test"}], - asyncapi_version=AsyncAPIVersion.v3_0, + specification_tags=[{"name": "test"}], ) app = FastAPI( @@ -80,7 +78,6 @@ async def test_fastapi_full_information(self): } } - @pytest.mark.skip() @pytest.mark.asyncio() async def test_fastapi_asyncapi_routes(self): broker = self.router_factory(schema_url="/asyncapi_schema") diff --git a/tests/asyncapi/base/v3_0_0/publisher.py b/tests/asyncapi/base/v3_0_0/publisher.py index 09d3e9f4e3..1046ccee4f 100644 --- a/tests/asyncapi/base/v3_0_0/publisher.py +++ b/tests/asyncapi/base/v3_0_0/publisher.py @@ -10,7 +10,7 @@ class PublisherTestcase: - broker_factory: Callable[[], Union[BrokerUsecase, StreamRouter]] + broker_factory: Union[BrokerUsecase, StreamRouter] def build_app(self, broker): """Patch it to test FastAPI scheme generation too.""" From a01a6c283792dfbe334bcb1d2eb528c4e70bf4f2 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 18 Aug 2024 09:45:35 +0300 Subject: [PATCH 108/245] CLI breaking changes revert --- docs/docs_src/getting_started/asyncapi/serve.py | 10 +++++----- faststream/broker/fastapi/router.py | 1 - faststream/cli/docs/__init__.py | 9 ++++----- faststream/cli/docs/{asyncapi => }/app.py | 0 faststream/cli/docs/asyncapi/__init__.py | 5 ----- faststream/cli/main.py | 4 ++-- 6 files changed, 11 insertions(+), 18 deletions(-) rename faststream/cli/docs/{asyncapi => }/app.py (100%) delete mode 100644 faststream/cli/docs/asyncapi/__init__.py diff --git a/docs/docs_src/getting_started/asyncapi/serve.py b/docs/docs_src/getting_started/asyncapi/serve.py index e75fb88fb0..c8b42f3118 100644 --- a/docs/docs_src/getting_started/asyncapi/serve.py +++ b/docs/docs_src/getting_started/asyncapi/serve.py @@ -6,21 +6,21 @@ gen_asyncapi_json_cmd = """ -faststream docs asyncapi gen basic:app +faststream docs gen basic:app """ gen_asyncapi_yaml_cmd = """ -faststream docs asyncapi gen --yaml basic:app +faststream docs gen --yaml basic:app """ asyncapi_serve_cmd = """ -faststream docs asyncapi serve basic:app +faststream docs serve basic:app """ asyncapi_serve_json_cmd = """ -faststream docs asyncapi serve asyncapi.json +faststream docs serve asyncapi.json """ asyncapi_serve_yaml_cmd = """ -faststream docs asyncapi serve asyncapi.yaml +faststream docs serve asyncapi.yaml """ diff --git a/faststream/broker/fastapi/router.py b/faststream/broker/fastapi/router.py index 47b3de1148..fb0ae1196a 100644 --- a/faststream/broker/fastapi/router.py +++ b/faststream/broker/fastapi/router.py @@ -40,7 +40,6 @@ T_HandlerReturn, ) from faststream.specification.asyncapi.site import get_asyncapi_html -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.proto import Application from faststream.utils.context.repository import context from faststream.utils.functions import fake_context, to_async diff --git a/faststream/cli/docs/__init__.py b/faststream/cli/docs/__init__.py index 3c50e8fa06..7b29c77ca6 100644 --- a/faststream/cli/docs/__init__.py +++ b/faststream/cli/docs/__init__.py @@ -1,6 +1,5 @@ -import typer +from .app import asyncapi_app -from .asyncapi import asyncapi_app - -docs_app = typer.Typer(pretty_exceptions_short=True) -docs_app.add_typer(asyncapi_app, name="asyncapi") +__all__ = ( + "asyncapi_app", +) diff --git a/faststream/cli/docs/asyncapi/app.py b/faststream/cli/docs/app.py similarity index 100% rename from faststream/cli/docs/asyncapi/app.py rename to faststream/cli/docs/app.py diff --git a/faststream/cli/docs/asyncapi/__init__.py b/faststream/cli/docs/asyncapi/__init__.py deleted file mode 100644 index 7b29c77ca6..0000000000 --- a/faststream/cli/docs/asyncapi/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from .app import asyncapi_app - -__all__ = ( - "asyncapi_app", -) diff --git a/faststream/cli/main.py b/faststream/cli/main.py index f6bbca62a2..fcbb8f5208 100644 --- a/faststream/cli/main.py +++ b/faststream/cli/main.py @@ -11,7 +11,7 @@ from faststream import FastStream from faststream.__about__ import __version__ -from faststream.cli.docs import docs_app +from faststream.cli.docs import asyncapi_app from faststream.cli.utils.imports import import_from_string from faststream.cli.utils.logs import LogLevels, get_log_level, set_log_level from faststream.cli.utils.parser import parse_cli_args @@ -22,7 +22,7 @@ from faststream.types import AnyDict, SettingField cli = typer.Typer(pretty_exceptions_short=True) -cli.add_typer(docs_app, name="docs", help="Documentations commands") +cli.add_typer(asyncapi_app, name="docs", help="Documentations commands") def version_callback(version: bool) -> None: From 6c686038a5e7f4951817b67a6ff453e4fb62c6aa Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 18 Aug 2024 12:58:07 +0300 Subject: [PATCH 109/245] AsyncAPI generation version choosing API changed --- faststream/asgi/factories.py | 3 +- faststream/cli/docs/app.py | 5 +-- faststream/specification/asyncapi/generate.py | 11 +++-- .../asyncapi/v2_6_0/schema/schema.py | 5 +-- .../asyncapi/v3_0_0/schema/schema.py | 5 +-- faststream/specification/asyncapi/version.py | 6 --- .../asyncapi_customization/test_basic.py | 3 +- .../asyncapi_customization/test_broker.py | 3 +- .../asyncapi_customization/test_handler.py | 3 +- .../asyncapi_customization/test_info.py | 3 +- .../asyncapi_customization/test_payload.py | 3 +- tests/a_docs/rabbit/test_security.py | 4 +- tests/a_docs/redis/test_security.py | 4 +- tests/asyncapi/base/v2_6_0/arguments.py | 43 +++++++++---------- tests/asyncapi/base/v2_6_0/fastapi.py | 3 +- tests/asyncapi/base/v2_6_0/naming.py | 37 ++++++++-------- tests/asyncapi/base/v2_6_0/publisher.py | 15 +++---- tests/asyncapi/base/v2_6_0/router.py | 3 +- tests/asyncapi/base/v3_0_0/arguments.py | 43 +++++++++---------- tests/asyncapi/base/v3_0_0/fastapi.py | 3 +- tests/asyncapi/base/v3_0_0/naming.py | 37 ++++++++-------- tests/asyncapi/base/v3_0_0/publisher.py | 17 ++++---- tests/asyncapi/base/v3_0_0/router.py | 19 ++++---- .../confluent/v2_6_0/test_arguments.py | 3 +- .../confluent/v2_6_0/test_connection.py | 7 ++- .../asyncapi/confluent/v2_6_0/test_fastapi.py | 3 +- .../asyncapi/confluent/v2_6_0/test_naming.py | 3 +- .../confluent/v2_6_0/test_publisher.py | 3 +- .../asyncapi/confluent/v2_6_0/test_router.py | 3 +- .../confluent/v2_6_0/test_security.py | 11 +++-- .../confluent/v3_0_0/test_arguments.py | 3 +- .../confluent/v3_0_0/test_connection.py | 7 ++- .../asyncapi/confluent/v3_0_0/test_naming.py | 3 +- .../confluent/v3_0_0/test_publisher.py | 3 +- .../asyncapi/confluent/v3_0_0/test_router.py | 3 +- .../confluent/v3_0_0/test_security.py | 9 ++-- tests/asyncapi/kafka/v2_6_0/test_app.py | 11 +++-- tests/asyncapi/kafka/v2_6_0/test_arguments.py | 3 +- .../asyncapi/kafka/v2_6_0/test_connection.py | 7 ++- tests/asyncapi/kafka/v2_6_0/test_fastapi.py | 3 +- tests/asyncapi/kafka/v2_6_0/test_naming.py | 3 +- tests/asyncapi/kafka/v2_6_0/test_publisher.py | 3 +- tests/asyncapi/kafka/v2_6_0/test_router.py | 3 +- tests/asyncapi/kafka/v2_6_0/test_security.py | 11 +++-- tests/asyncapi/kafka/v3_0_0/test_arguments.py | 3 +- .../asyncapi/kafka/v3_0_0/test_connection.py | 7 ++- tests/asyncapi/kafka/v3_0_0/test_naming.py | 3 +- tests/asyncapi/kafka/v3_0_0/test_publisher.py | 3 +- tests/asyncapi/kafka/v3_0_0/test_router.py | 3 +- tests/asyncapi/kafka/v3_0_0/test_security.py | 9 ++-- tests/asyncapi/nats/v2_6_0/test_arguments.py | 3 +- tests/asyncapi/nats/v2_6_0/test_connection.py | 7 ++- tests/asyncapi/nats/v2_6_0/test_kv_schema.py | 3 +- tests/asyncapi/nats/v2_6_0/test_naming.py | 3 +- tests/asyncapi/nats/v2_6_0/test_obj_schema.py | 3 +- tests/asyncapi/nats/v2_6_0/test_publisher.py | 3 +- tests/asyncapi/nats/v2_6_0/test_router.py | 3 +- tests/asyncapi/nats/v3_0_0/test_arguments.py | 3 +- tests/asyncapi/nats/v3_0_0/test_connection.py | 7 ++- tests/asyncapi/nats/v3_0_0/test_kv_schema.py | 3 +- tests/asyncapi/nats/v3_0_0/test_naming.py | 3 +- tests/asyncapi/nats/v3_0_0/test_obj_schema.py | 3 +- tests/asyncapi/nats/v3_0_0/test_publisher.py | 3 +- tests/asyncapi/nats/v3_0_0/test_router.py | 3 +- .../asyncapi/rabbit/v2_6_0/test_arguments.py | 5 +-- .../asyncapi/rabbit/v2_6_0/test_connection.py | 5 +-- tests/asyncapi/rabbit/v2_6_0/test_fastapi.py | 3 +- tests/asyncapi/rabbit/v2_6_0/test_naming.py | 7 ++- .../asyncapi/rabbit/v2_6_0/test_publisher.py | 9 ++-- tests/asyncapi/rabbit/v2_6_0/test_router.py | 3 +- tests/asyncapi/rabbit/v2_6_0/test_security.py | 7 ++- .../asyncapi/rabbit/v3_0_0/test_arguments.py | 5 +-- .../asyncapi/rabbit/v3_0_0/test_connection.py | 5 +-- tests/asyncapi/rabbit/v3_0_0/test_naming.py | 7 ++- .../asyncapi/rabbit/v3_0_0/test_publisher.py | 9 ++-- tests/asyncapi/rabbit/v3_0_0/test_router.py | 3 +- tests/asyncapi/rabbit/v3_0_0/test_security.py | 7 ++- tests/asyncapi/redis/v2_6_0/test_arguments.py | 11 +++-- .../asyncapi/redis/v2_6_0/test_connection.py | 5 +-- tests/asyncapi/redis/v2_6_0/test_naming.py | 3 +- tests/asyncapi/redis/v2_6_0/test_publisher.py | 7 ++- tests/asyncapi/redis/v2_6_0/test_router.py | 3 +- tests/asyncapi/redis/v2_6_0/test_security.py | 7 ++- tests/asyncapi/redis/v3_0_0/test_arguments.py | 11 +++-- .../asyncapi/redis/v3_0_0/test_connection.py | 5 +-- tests/asyncapi/redis/v3_0_0/test_naming.py | 3 +- tests/asyncapi/redis/v3_0_0/test_publisher.py | 7 ++- tests/asyncapi/redis/v3_0_0/test_router.py | 3 +- tests/asyncapi/redis/v3_0_0/test_security.py | 7 ++- 89 files changed, 258 insertions(+), 350 deletions(-) delete mode 100644 faststream/specification/asyncapi/version.py diff --git a/faststream/asgi/factories.py b/faststream/asgi/factories.py index 6b00252b46..ff4be95e47 100644 --- a/faststream/asgi/factories.py +++ b/faststream/asgi/factories.py @@ -12,7 +12,6 @@ ASYNCAPI_JS_DEFAULT_URL, get_asyncapi_html, ) -from faststream.specification.asyncapi.version import AsyncAPIVersion if TYPE_CHECKING: from faststream.asgi.types import ASGIApp, Scope @@ -54,7 +53,7 @@ def make_asyncapi_asgi( ) -> "ASGIApp": return AsgiResponse( get_asyncapi_html( - get_app_schema(app, version=AsyncAPIVersion.v2_6), + get_app_schema(app, version="2.6.0"), sidebar=sidebar, info=info, servers=servers, diff --git a/faststream/cli/docs/app.py b/faststream/cli/docs/app.py index f3227a0a2c..18e1afd8df 100644 --- a/faststream/cli/docs/app.py +++ b/faststream/cli/docs/app.py @@ -15,7 +15,6 @@ from faststream.specification.asyncapi.site import serve_app from faststream.specification.asyncapi.v2_6_0.schema import Schema as SchemaV2_6 from faststream.specification.asyncapi.v3_0_0.schema import Schema as SchemaV3 -from faststream.specification.asyncapi.version import AsyncAPIVersion asyncapi_app = typer.Typer(pretty_exceptions_short=True) @@ -133,7 +132,7 @@ def gen( _, app_obj = import_from_string(app) if callable(app_obj) and is_factory: app_obj = app_obj() - raw_schema = get_app_schema(app_obj, AsyncAPIVersion(asyncapi_version)) + raw_schema = get_app_schema(app_obj, asyncapi_version) if yaml: try: @@ -167,7 +166,7 @@ def _parse_and_serve( _, app_obj = import_from_string(app) if callable(app_obj) and is_factory: app_obj = app_obj() - raw_schema = get_app_schema(app_obj, AsyncAPIVersion.v2_6) + raw_schema = get_app_schema(app_obj, "2.6.0") else: schema_filepath = Path.cwd() / app diff --git a/faststream/specification/asyncapi/generate.py b/faststream/specification/asyncapi/generate.py index ac5a71b843..c378375679 100644 --- a/faststream/specification/asyncapi/generate.py +++ b/faststream/specification/asyncapi/generate.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Literal, Union from faststream.specification.asyncapi.base.schema import BaseSchema from faststream.specification.asyncapi.v2_6_0.generate import ( @@ -7,17 +7,16 @@ from faststream.specification.asyncapi.v3_0_0.generate import ( get_app_schema as get_app_schema_v3, ) -from faststream.specification.asyncapi.version import AsyncAPIVersion if TYPE_CHECKING: from faststream.specification.proto import Application -def get_app_schema(app: "Application", version: AsyncAPIVersion = AsyncAPIVersion.v3_0) -> BaseSchema: - if version == AsyncAPIVersion.v3_0: +def get_app_schema(app: "Application", version: Union[Literal["3.0.0", "2.6.0"], str] = "3.0.0") -> BaseSchema: + if version.startswith("3.0."): return get_app_schema_v3(app) - if version == AsyncAPIVersion.v2_6: + if version.startswith("2.6."): return get_app_schema_v2_6(app) - raise NotImplementedError(f"AsyncAPI version not supported: {app.asyncapi_version}") + raise NotImplementedError(f"AsyncAPI version not supported: {version}") diff --git a/faststream/specification/asyncapi/v2_6_0/schema/schema.py b/faststream/specification/asyncapi/v2_6_0/schema/schema.py index 336e83777f..f2e691f5bb 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/schema.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/schema.py @@ -1,4 +1,4 @@ -from typing import Dict, List, Optional, Union +from typing import Dict, List, Literal, Optional, Union from faststream.specification.asyncapi.base.schema import BaseSchema from faststream.specification.asyncapi.v2_6_0.schema.channels import Channel @@ -7,7 +7,6 @@ from faststream.specification.asyncapi.v2_6_0.schema.info import Info from faststream.specification.asyncapi.v2_6_0.schema.servers import Server from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.types import AnyDict @@ -32,7 +31,7 @@ class Schema(BaseSchema): """ - asyncapi: AsyncAPIVersion = AsyncAPIVersion.v2_6 + asyncapi: Union[Literal["2.6.0"], str] = "2.6.0" id: Optional[str] = None defaultContentType: Optional[str] = None info: Info diff --git a/faststream/specification/asyncapi/v3_0_0/schema/schema.py b/faststream/specification/asyncapi/v3_0_0/schema/schema.py index 663c2ae0c1..ddd6413d0a 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/schema.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/schema.py @@ -1,4 +1,4 @@ -from typing import Dict, Optional +from typing import Dict, Literal, Optional, Union from faststream.specification.asyncapi.base.schema import BaseSchema from faststream.specification.asyncapi.v3_0_0.schema.channels import Channel @@ -6,7 +6,6 @@ from faststream.specification.asyncapi.v3_0_0.schema.info import Info from faststream.specification.asyncapi.v3_0_0.schema.operations import Operation from faststream.specification.asyncapi.v3_0_0.schema.servers import Server -from faststream.specification.asyncapi.version import AsyncAPIVersion class Schema(BaseSchema): @@ -28,7 +27,7 @@ class Schema(BaseSchema): """ - asyncapi: AsyncAPIVersion = AsyncAPIVersion.v3_0 + asyncapi: Union[Literal["3.0.0"], str] = "3.0.0" id: Optional[str] = None defaultContentType: Optional[str] = None info: Info diff --git a/faststream/specification/asyncapi/version.py b/faststream/specification/asyncapi/version.py deleted file mode 100644 index dd5ae828f3..0000000000 --- a/faststream/specification/asyncapi/version.py +++ /dev/null @@ -1,6 +0,0 @@ -from enum import Enum - - -class AsyncAPIVersion(str, Enum): - v3_0 = "3.0.0" - v2_6 = "2.6.0" diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py index 2f381ca0a2..191eb2aa0d 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py @@ -1,10 +1,9 @@ from docs.docs_src.getting_started.asyncapi.asyncapi_customization.basic import app from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion def test_basic_customization(): - schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(app, version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_broker.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_broker.py index 337a7a650e..2af48bd3f5 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_broker.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_broker.py @@ -2,11 +2,10 @@ app, ) from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion def test_broker_customization(): - schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(app, version="2.6.0").to_jsonable() assert schema["servers"] == { "development": { diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py index db71cf3e71..8f15bc5405 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py @@ -2,11 +2,10 @@ app, ) from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion def test_handler_customization(): - schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(app, version="2.6.0").to_jsonable() assert schema["channels"] == { "input_data:Consume": { diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_info.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_info.py index 655f9c43ac..5707e0ea40 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_info.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_info.py @@ -2,11 +2,10 @@ app, ) from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion def test_info_customization(): - schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(app, version="2.6.0").to_jsonable() assert schema["info"] == { "title": "My App", diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_payload.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_payload.py index 3725a7c6d6..8b63c40343 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_payload.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_payload.py @@ -2,11 +2,10 @@ app, ) from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion def test_payload_customization(): - schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(app, version="2.6.0").to_jsonable() assert schema["components"]["schemas"] == { "DataBasic": { diff --git a/tests/a_docs/rabbit/test_security.py b/tests/a_docs/rabbit/test_security.py index a2e06af44f..4a69d71057 100644 --- a/tests/a_docs/rabbit/test_security.py +++ b/tests/a_docs/rabbit/test_security.py @@ -14,7 +14,7 @@ async def test_base_security(): async with broker: pass - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", "channels": {}, @@ -41,7 +41,7 @@ async def test_plaintext_security(): async with broker: pass - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert ( schema == { diff --git a/tests/a_docs/redis/test_security.py b/tests/a_docs/redis/test_security.py index 1a28e4dc82..9e3cc6fdc3 100644 --- a/tests/a_docs/redis/test_security.py +++ b/tests/a_docs/redis/test_security.py @@ -39,7 +39,7 @@ async def test_base_security(): assert connection.call_args.kwargs["ssl"] - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", "channels": {}, @@ -69,7 +69,7 @@ async def test_plaintext_security(): assert connection.call_args.kwargs["ssl"] - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", "channels": {}, diff --git a/tests/asyncapi/base/v2_6_0/arguments.py b/tests/asyncapi/base/v2_6_0/arguments.py index dfb42df7ca..7bf1d07e9a 100644 --- a/tests/asyncapi/base/v2_6_0/arguments.py +++ b/tests/asyncapi/base/v2_6_0/arguments.py @@ -12,7 +12,6 @@ from faststream._compat import PYDANTIC_V2 from faststream.broker.core.usecase import BrokerUsecase from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.marks import pydantic_v2 @@ -30,7 +29,7 @@ def test_custom_naming(self): @broker.subscriber("test", title="custom_name", description="test description") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert key == "custom_name" @@ -43,7 +42,7 @@ def test_docstring_description(self): async def handle(msg): """Test description.""" - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert key == "custom_name" @@ -57,7 +56,7 @@ def test_empty(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -74,7 +73,7 @@ def test_no_type(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -88,7 +87,7 @@ def test_simple_type(self): @broker.subscriber("test") async def handle(msg: int): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] assert next(iter(schema["channels"].values())).get("description") is None @@ -103,7 +102,7 @@ def test_simple_optional_type(self): @broker.subscriber("test") async def handle(msg: Optional[int]): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -127,7 +126,7 @@ def test_simple_type_with_default(self): @broker.subscriber("test") async def handle(msg: int = 1): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -145,7 +144,7 @@ def test_multi_args_no_type(self): @broker.subscriber("test") async def handle(msg, another): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -167,7 +166,7 @@ def test_multi_args_with_type(self): @broker.subscriber("test") async def handle(msg: str, another: int): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -189,7 +188,7 @@ def test_multi_args_with_default(self): @broker.subscriber("test") async def handle(msg: str, another: Optional[int] = None): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -229,7 +228,7 @@ class User: @broker.subscriber("test") async def handle(user: User): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -255,7 +254,7 @@ class User(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: User): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -286,7 +285,7 @@ class User(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: User): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -324,7 +323,7 @@ class User(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: User, description: str = ""): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -380,7 +379,7 @@ class Config: @broker.subscriber("test") async def handle(user: User): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -412,7 +411,7 @@ def dep2(name2: str): @broker.subscriber("test", dependencies=dependencies) async def handle(id: int, message=message): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -446,7 +445,7 @@ class Sub(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: descriminator): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() key = next(iter(schema["components"]["messages"].keys())) assert key == IsStr(regex=r"test[\w:]*:Handle:Message") @@ -501,7 +500,7 @@ class Model(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: Model): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() key = next(iter(schema["components"]["messages"].keys())) assert key == IsStr(regex=r"test[\w:]*:Handle:Message") @@ -565,7 +564,7 @@ async def msg( ), ): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -587,7 +586,7 @@ def test_ignores_custom_field(self): @broker.subscriber("test") async def handle(id: int, user: Optional[str] = None, message=Context()): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -636,7 +635,7 @@ async def handle(id: int): ... @sub async def handle_default(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() assert ( len( diff --git a/tests/asyncapi/base/v2_6_0/fastapi.py b/tests/asyncapi/base/v2_6_0/fastapi.py index 080edca0ed..0f351db34b 100644 --- a/tests/asyncapi/base/v2_6_0/fastapi.py +++ b/tests/asyncapi/base/v2_6_0/fastapi.py @@ -9,7 +9,6 @@ from faststream.broker.fastapi.router import StreamRouter from faststream.broker.types import MsgType from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion class FastAPITestCase: @@ -82,7 +81,7 @@ async def handler(): ... async with self.broker_wrapper(broker.broker): with TestClient(app) as client: - schema = get_app_schema(broker, version=AsyncAPIVersion.v2_6) + schema = get_app_schema(broker, version="2.6.0") response_json = client.get("/asyncapi_schema.json") assert response_json.json() == schema.to_jsonable() diff --git a/tests/asyncapi/base/v2_6_0/naming.py b/tests/asyncapi/base/v2_6_0/naming.py index 12857f7c14..4713dcdd79 100644 --- a/tests/asyncapi/base/v2_6_0/naming.py +++ b/tests/asyncapi/base/v2_6_0/naming.py @@ -6,7 +6,6 @@ from faststream import FastStream from faststream.broker.core.usecase import BrokerUsecase from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion class BaseNaming: @@ -20,7 +19,7 @@ def test_subscriber_naming(self): @broker.subscriber("test") async def handle_user_created(msg: str): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -40,7 +39,7 @@ def test_pydantic_subscriber_naming(self): @broker.subscriber("test") async def handle_user_created(msg: create_model("SimpleModel")): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -59,7 +58,7 @@ def test_multi_subscribers_naming(self): @broker.subscriber("test2") async def handle_user_created(msg: str): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated"), @@ -81,7 +80,7 @@ def test_subscriber_naming_manual(self): @broker.subscriber("test", title="custom") async def handle_user_created(msg: str): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -96,7 +95,7 @@ def test_subscriber_naming_default(self): broker.subscriber("test") - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:Subscriber") @@ -115,7 +114,7 @@ def test_subscriber_naming_default_with_title(self): broker.subscriber("test", title="custom") - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -138,7 +137,7 @@ async def handle_user_created(msg: str): ... broker.subscriber("test2") broker.subscriber("test3") - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated"), @@ -172,7 +171,7 @@ async def handle_user_created(msg: str): ... @broker.subscriber("test") async def handle_user_id(msg: int): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -196,7 +195,7 @@ async def handle_user_created(msg: create_model("SimpleModel")): ... @broker.subscriber("test") async def handle_user_id(msg: int): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -220,7 +219,7 @@ async def handle_user_created(msg: str): ... @broker.subscriber("test", title="custom") async def handle_user_id(msg: int): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -239,7 +238,7 @@ def test_publisher_naming_base(self): @broker.publisher("test") async def handle_user_created() -> str: ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] @@ -257,7 +256,7 @@ def test_publisher_naming_pydantic(self): @broker.publisher("test") async def handle_user_created() -> create_model("SimpleModel"): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] @@ -275,7 +274,7 @@ def test_publisher_manual_naming(self): @broker.publisher("test", title="custom") async def handle_user_created() -> str: ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -291,7 +290,7 @@ def test_publisher_with_schema_naming(self): @broker.publisher("test", schema=str) async def handle_user_created(): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] @@ -309,7 +308,7 @@ def test_publisher_manual_naming_with_schema(self): @broker.publisher("test", title="custom", schema=str) async def handle_user_created(): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -326,7 +325,7 @@ def test_multi_publishers_naming(self): @broker.publisher("test2") async def handle_user_created() -> str: ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() names = list(schema["channels"].keys()) assert names == Contains( @@ -357,7 +356,7 @@ async def handle_user_created() -> str: ... @pub async def handle() -> int: ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:Publisher"), @@ -383,7 +382,7 @@ async def handle_user_created() -> str: ... @pub async def handle() -> int: ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == ["custom"] diff --git a/tests/asyncapi/base/v2_6_0/publisher.py b/tests/asyncapi/base/v2_6_0/publisher.py index e3284d5e61..86abe51361 100644 --- a/tests/asyncapi/base/v2_6_0/publisher.py +++ b/tests/asyncapi/base/v2_6_0/publisher.py @@ -5,7 +5,6 @@ from faststream import FastStream from faststream.broker.core.usecase import BrokerUsecase from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion class PublisherTestcase: @@ -21,7 +20,7 @@ def test_publisher_with_description(self): @broker.publisher("test", description="test description") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["description"] == "test description" @@ -32,7 +31,7 @@ def test_basic_publisher(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key].get("description") is None @@ -48,7 +47,7 @@ def test_none_publisher(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -60,7 +59,7 @@ def test_typed_publisher(self): @broker.publisher("test") async def handle(msg) -> int: ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -76,7 +75,7 @@ class User(pydantic.BaseModel): @broker.publisher("test") async def handle(msg) -> User: ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -99,7 +98,7 @@ def test_delayed(self): @pub async def handle(msg) -> int: ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -110,7 +109,7 @@ def test_with_schema(self): broker.publisher("test", title="Custom", schema=int) - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] for v in payload.values(): diff --git a/tests/asyncapi/base/v2_6_0/router.py b/tests/asyncapi/base/v2_6_0/router.py index bf8c96f4a2..112e6e6d40 100644 --- a/tests/asyncapi/base/v2_6_0/router.py +++ b/tests/asyncapi/base/v2_6_0/router.py @@ -6,7 +6,6 @@ from faststream.broker.core.usecase import BrokerUsecase from faststream.broker.router import ArgsContainer, BrokerRouter, SubscriberRoute from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion class RouterTestcase: @@ -26,7 +25,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] key = list(payload.keys())[0] # noqa: RUF015 diff --git a/tests/asyncapi/base/v3_0_0/arguments.py b/tests/asyncapi/base/v3_0_0/arguments.py index abe79b9fb1..d5b9e63756 100644 --- a/tests/asyncapi/base/v3_0_0/arguments.py +++ b/tests/asyncapi/base/v3_0_0/arguments.py @@ -14,7 +14,6 @@ from faststream.broker.core.usecase import BrokerUsecase from faststream.broker.fastapi import StreamRouter from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.marks import pydantic_v2 @@ -32,7 +31,7 @@ def test_custom_naming(self): @broker.subscriber("test", title="custom_name", description="test description") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert key == "custom_name" @@ -45,7 +44,7 @@ def test_docstring_description(self): async def handle(msg): """Test description.""" - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert key == "custom_name" @@ -59,7 +58,7 @@ def test_empty(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -76,7 +75,7 @@ def test_no_type(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -90,7 +89,7 @@ def test_simple_type(self): @broker.subscriber("test") async def handle(msg: int): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] assert next(iter(schema["channels"].values())).get("description") is None @@ -105,7 +104,7 @@ def test_simple_optional_type(self): @broker.subscriber("test") async def handle(msg: Optional[int]): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -129,7 +128,7 @@ def test_simple_type_with_default(self): @broker.subscriber("test") async def handle(msg: int = 1): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -147,7 +146,7 @@ def test_multi_args_no_type(self): @broker.subscriber("test") async def handle(msg, another): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -169,7 +168,7 @@ def test_multi_args_with_type(self): @broker.subscriber("test") async def handle(msg: str, another: int): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -191,7 +190,7 @@ def test_multi_args_with_default(self): @broker.subscriber("test") async def handle(msg: str, another: Optional[int] = None): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -231,7 +230,7 @@ class User: @broker.subscriber("test") async def handle(user: User): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -257,7 +256,7 @@ class User(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: User): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -288,7 +287,7 @@ class User(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: User): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -326,7 +325,7 @@ class User(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: User, description: str = ""): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -382,7 +381,7 @@ class Config: @broker.subscriber("test") async def handle(user: User): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -415,7 +414,7 @@ async def handle(id: int): ... @broker.subscriber("test") async def handle_default(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() assert ( len( @@ -446,7 +445,7 @@ def dep2(name2: str): @broker.subscriber("test", dependencies=dependencies) async def handle(id: int, message=message): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -480,7 +479,7 @@ class Sub(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: descriminator): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() key = next(iter(schema["components"]["messages"].keys())) assert key == IsStr(regex=r"test[\w:]*:Handle:Message") @@ -541,7 +540,7 @@ class Model(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: Model): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() key = next(iter(schema["components"]["messages"].keys())) assert key == IsStr(regex=r"test[\w:]*:Handle:Message") @@ -605,7 +604,7 @@ async def msg( ), ): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -627,7 +626,7 @@ def test_ignores_custom_field(self): @broker.subscriber("test") async def handle(id: int, user: Optional[str] = None, message=Context()): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] diff --git a/tests/asyncapi/base/v3_0_0/fastapi.py b/tests/asyncapi/base/v3_0_0/fastapi.py index d4343608db..6206e988e4 100644 --- a/tests/asyncapi/base/v3_0_0/fastapi.py +++ b/tests/asyncapi/base/v3_0_0/fastapi.py @@ -9,7 +9,6 @@ from faststream.broker.fastapi.router import StreamRouter from faststream.broker.types import MsgType from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion class FastAPITestCase: @@ -90,7 +89,7 @@ async def handler(): ... async with self.broker_wrapper(broker.broker): with TestClient(app) as client: - schema = get_app_schema(broker, version=AsyncAPIVersion.v3_0) + schema = get_app_schema(broker, version="3.0.0") response_json = client.get("/asyncapi_schema.json") assert response_json.json() == schema.to_jsonable() diff --git a/tests/asyncapi/base/v3_0_0/naming.py b/tests/asyncapi/base/v3_0_0/naming.py index b0b936d24e..4202ee497e 100644 --- a/tests/asyncapi/base/v3_0_0/naming.py +++ b/tests/asyncapi/base/v3_0_0/naming.py @@ -6,7 +6,6 @@ from faststream import FastStream from faststream.broker.core.usecase import BrokerUsecase from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion class BaseNaming: @@ -20,7 +19,7 @@ def test_subscriber_naming(self): @broker.subscriber("test") async def handle_user_created(msg: str): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -40,7 +39,7 @@ def test_pydantic_subscriber_naming(self): @broker.subscriber("test") async def handle_user_created(msg: create_model("SimpleModel")): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -59,7 +58,7 @@ def test_multi_subscribers_naming(self): @broker.subscriber("test2") async def handle_user_created(msg: str): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated"), @@ -81,7 +80,7 @@ def test_subscriber_naming_manual(self): @broker.subscriber("test", title="custom") async def handle_user_created(msg: str): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -96,7 +95,7 @@ def test_subscriber_naming_default(self): broker.subscriber("test") - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:Subscriber") @@ -115,7 +114,7 @@ def test_subscriber_naming_default_with_title(self): broker.subscriber("test", title="custom") - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -138,7 +137,7 @@ async def handle_user_created(msg: str): ... broker.subscriber("test2") broker.subscriber("test3") - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated"), @@ -172,7 +171,7 @@ async def handle_user_created(msg: str): ... @broker.subscriber("test") async def handle_user_id(msg: int): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -196,7 +195,7 @@ async def handle_user_created(msg: create_model("SimpleModel")): ... @broker.subscriber("test") async def handle_user_id(msg: int): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -220,7 +219,7 @@ async def handle_user_created(msg: str): ... @broker.subscriber("test", title="custom") async def handle_user_id(msg: int): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -239,7 +238,7 @@ def test_publisher_naming_base(self): @broker.publisher("test") async def handle_user_created() -> str: ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] @@ -257,7 +256,7 @@ def test_publisher_naming_pydantic(self): @broker.publisher("test") async def handle_user_created() -> create_model("SimpleModel"): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] @@ -275,7 +274,7 @@ def test_publisher_manual_naming(self): @broker.publisher("test", title="custom") async def handle_user_created() -> str: ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -291,7 +290,7 @@ def test_publisher_with_schema_naming(self): @broker.publisher("test", schema=str) async def handle_user_created(): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] @@ -309,7 +308,7 @@ def test_publisher_manual_naming_with_schema(self): @broker.publisher("test", title="custom", schema=str) async def handle_user_created(): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -326,7 +325,7 @@ def test_multi_publishers_naming(self): @broker.publisher("test2") async def handle_user_created() -> str: ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() names = list(schema["channels"].keys()) assert names == Contains( @@ -357,7 +356,7 @@ async def handle_user_created() -> str: ... @pub async def handle() -> int: ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:Publisher"), @@ -383,7 +382,7 @@ async def handle_user_created() -> str: ... @pub async def handle() -> int: ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == ["custom"] diff --git a/tests/asyncapi/base/v3_0_0/publisher.py b/tests/asyncapi/base/v3_0_0/publisher.py index 1046ccee4f..8120827358 100644 --- a/tests/asyncapi/base/v3_0_0/publisher.py +++ b/tests/asyncapi/base/v3_0_0/publisher.py @@ -1,4 +1,4 @@ -from typing import Callable, Union +from typing import Union import pydantic @@ -6,7 +6,6 @@ from faststream.broker.core.usecase import BrokerUsecase from faststream.broker.fastapi import StreamRouter from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion class PublisherTestcase: @@ -22,7 +21,7 @@ def test_publisher_with_description(self): @broker.publisher("test", description="test description") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["description"] == "test description" @@ -33,7 +32,7 @@ def test_basic_publisher(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key].get("description") is None @@ -49,7 +48,7 @@ def test_none_publisher(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -61,7 +60,7 @@ def test_typed_publisher(self): @broker.publisher("test") async def handle(msg) -> int: ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -77,7 +76,7 @@ class User(pydantic.BaseModel): @broker.publisher("test") async def handle(msg) -> User: ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -100,7 +99,7 @@ def test_delayed(self): @pub async def handle(msg) -> int: ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -111,7 +110,7 @@ def test_with_schema(self): broker.publisher("test", title="Custom", schema=int) - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] for v in payload.values(): diff --git a/tests/asyncapi/base/v3_0_0/router.py b/tests/asyncapi/base/v3_0_0/router.py index ca071471e5..255079dfa5 100644 --- a/tests/asyncapi/base/v3_0_0/router.py +++ b/tests/asyncapi/base/v3_0_0/router.py @@ -6,7 +6,6 @@ from faststream.broker.core.usecase import BrokerUsecase from faststream.broker.router import ArgsContainer, BrokerRouter, SubscriberRoute from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion class RouterTestcase: @@ -26,7 +25,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] key = list(payload.keys())[0] # noqa: RUF015 @@ -49,7 +48,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0) + schema = get_app_schema(FastStream(broker), version="3.0.0") schemas = schema.components.schemas del schemas["Handle:Message:Payload"] @@ -69,7 +68,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0) + schema = get_app_schema(FastStream(broker), version="3.0.0") assert schema.channels == {}, schema.channels def test_not_include_in_method(self): @@ -82,7 +81,7 @@ async def handle(msg): ... broker.include_router(router, include_in_schema=False) - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0) + schema = get_app_schema(FastStream(broker), version="3.0.0") assert schema.channels == {}, schema.channels def test_respect_subrouter(self): @@ -97,7 +96,7 @@ async def handle(msg): ... router.include_router(router2) broker.include_router(router) - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0) + schema = get_app_schema(FastStream(broker), version="3.0.0") assert schema.channels == {}, schema.channels @@ -113,7 +112,7 @@ async def handle(msg): ... router.include_router(router2) broker.include_router(router) - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0) + schema = get_app_schema(FastStream(broker), version="3.0.0") assert schema.channels == {} @@ -129,7 +128,7 @@ async def handle(msg): ... router.include_router(router2, include_in_schema=False) broker.include_router(router) - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0) + schema = get_app_schema(FastStream(broker), version="3.0.0") assert schema.channels == {} @@ -145,7 +144,7 @@ async def handle(msg): ... router.include_router(router2) broker.include_router(router, include_in_schema=False) - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0) + schema = get_app_schema(FastStream(broker), version="3.0.0") assert schema.channels == {} @@ -161,6 +160,6 @@ async def handle(msg): ... router.include_router(router2) broker.include_router(router) - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0) + schema = get_app_schema(FastStream(broker), version="3.0.0") assert len(schema.channels) == 2 diff --git a/tests/asyncapi/confluent/v2_6_0/test_arguments.py b/tests/asyncapi/confluent/v2_6_0/test_arguments.py index 247f64245a..7d1c1be4fa 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_arguments.py +++ b/tests/asyncapi/confluent/v2_6_0/test_arguments.py @@ -1,6 +1,5 @@ from faststream.confluent import KafkaBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase @@ -13,7 +12,7 @@ def test_subscriber_bindings(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/confluent/v2_6_0/test_connection.py b/tests/asyncapi/confluent/v2_6_0/test_connection.py index 1b6134ed34..b55b4b24c8 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_connection.py +++ b/tests/asyncapi/confluent/v2_6_0/test_connection.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.confluent import KafkaBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.schema.tag import Tag @@ -16,7 +15,7 @@ def test_base(): tags=(Tag(name="some-tag", description="experimental"),), ) ), - version=AsyncAPIVersion.v2_6, + version="2.6.0", ).to_jsonable() assert schema == { @@ -40,7 +39,7 @@ def test_base(): def test_multi(): schema = get_app_schema( FastStream(KafkaBroker(["kafka:9092", "kafka:9093"])), - version=AsyncAPIVersion.v2_6 + version="2.6.0" ).to_jsonable() assert schema == { @@ -72,7 +71,7 @@ def test_custom(): specification_url=["kafka:9094", "kafka:9095"], ) ), - version=AsyncAPIVersion.v2_6 + version="2.6.0" ).to_jsonable() assert schema == { diff --git a/tests/asyncapi/confluent/v2_6_0/test_fastapi.py b/tests/asyncapi/confluent/v2_6_0/test_fastapi.py index c319813ae9..3866a15b55 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/confluent/v2_6_0/test_fastapi.py @@ -4,7 +4,6 @@ from faststream.confluent.testing import TestKafkaBroker from faststream.security import SASLPlaintext from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import FastAPICompatible from tests.asyncapi.base.v2_6_0.fastapi import FastAPITestCase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase @@ -30,7 +29,7 @@ def test_fastapi_security_schema(): broker = KafkaRouter("localhost:9092", security=security) - schema = get_app_schema(broker, version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(broker, version="2.6.0").to_jsonable() assert schema["servers"]["development"] == { "protocol": "kafka", diff --git a/tests/asyncapi/confluent/v2_6_0/test_naming.py b/tests/asyncapi/confluent/v2_6_0/test_naming.py index 820121edb7..f2d17b284b 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_naming.py +++ b/tests/asyncapi/confluent/v2_6_0/test_naming.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.confluent import KafkaBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.naming import NamingTestCase @@ -14,7 +13,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/confluent/v2_6_0/test_publisher.py b/tests/asyncapi/confluent/v2_6_0/test_publisher.py index ec230c117e..ea91e8da1f 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_publisher.py +++ b/tests/asyncapi/confluent/v2_6_0/test_publisher.py @@ -1,6 +1,5 @@ from faststream.confluent import KafkaBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase @@ -13,7 +12,7 @@ def test_publisher_bindings(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/confluent/v2_6_0/test_router.py b/tests/asyncapi/confluent/v2_6_0/test_router.py index 3e76891eac..81fedd42a8 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_router.py +++ b/tests/asyncapi/confluent/v2_6_0/test_router.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.confluent import KafkaBroker, KafkaPublisher, KafkaRoute, KafkaRouter from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v2_6_0.router import RouterTestcase @@ -23,7 +22,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/confluent/v2_6_0/test_security.py b/tests/asyncapi/confluent/v2_6_0/test_security.py index 8530aec371..49144e6d88 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_security.py +++ b/tests/asyncapi/confluent/v2_6_0/test_security.py @@ -12,7 +12,6 @@ SASLScram512, ) from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion basic_schema = { "asyncapi": "2.6.0", @@ -84,7 +83,7 @@ def test_base_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(app, version="2.6.0").to_jsonable() assert schema == basic_schema @@ -105,7 +104,7 @@ def test_plaintext_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(app, version="2.6.0").to_jsonable() plaintext_security_schema = deepcopy(basic_schema) plaintext_security_schema["servers"]["development"]["security"] = [ @@ -134,7 +133,7 @@ def test_scram256_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(app, version="2.6.0").to_jsonable() sasl256_security_schema = deepcopy(basic_schema) sasl256_security_schema["servers"]["development"]["security"] = [{"scram256": []}] @@ -161,7 +160,7 @@ def test_scram512_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(app, version="2.6.0").to_jsonable() sasl512_security_schema = deepcopy(basic_schema) sasl512_security_schema["servers"]["development"]["security"] = [{"scram512": []}] @@ -186,7 +185,7 @@ def test_oauthbearer_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(app, version="2.6.0").to_jsonable() sasl_oauthbearer_security_schema = deepcopy(basic_schema) sasl_oauthbearer_security_schema["servers"]["development"]["security"] = [ diff --git a/tests/asyncapi/confluent/v3_0_0/test_arguments.py b/tests/asyncapi/confluent/v3_0_0/test_arguments.py index 97a3fc5452..048e7c7937 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_arguments.py +++ b/tests/asyncapi/confluent/v3_0_0/test_arguments.py @@ -1,6 +1,5 @@ from faststream.confluent import KafkaBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase @@ -13,7 +12,7 @@ def test_subscriber_bindings(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/confluent/v3_0_0/test_connection.py b/tests/asyncapi/confluent/v3_0_0/test_connection.py index 8b60fa53c6..6ff8e8c1a7 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_connection.py +++ b/tests/asyncapi/confluent/v3_0_0/test_connection.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.confluent import KafkaBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.schema.tag import Tag @@ -16,7 +15,7 @@ def test_base(): tags=(Tag(name="some-tag", description="experimental"),), ), ), - version=AsyncAPIVersion.v3_0, + version="3.0.0", ).to_jsonable() assert schema == { @@ -44,7 +43,7 @@ def test_multi(): FastStream( KafkaBroker(["kafka:9092", "kafka:9093"]), ), - version=AsyncAPIVersion.v3_0, + version="3.0.0", ).to_jsonable() assert schema == { @@ -79,7 +78,7 @@ def test_custom(): specification_url=["kafka:9094", "kafka:9095"], ), ), - version=AsyncAPIVersion.v3_0, + version="3.0.0", ).to_jsonable() assert schema == { diff --git a/tests/asyncapi/confluent/v3_0_0/test_naming.py b/tests/asyncapi/confluent/v3_0_0/test_naming.py index 9218d40418..525487824a 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_naming.py +++ b/tests/asyncapi/confluent/v3_0_0/test_naming.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.confluent import KafkaBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.naming import NamingTestCase @@ -14,7 +13,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() assert schema == { "asyncapi": "3.0.0", diff --git a/tests/asyncapi/confluent/v3_0_0/test_publisher.py b/tests/asyncapi/confluent/v3_0_0/test_publisher.py index a31e89b9a5..85c42bda36 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_publisher.py +++ b/tests/asyncapi/confluent/v3_0_0/test_publisher.py @@ -1,6 +1,5 @@ from faststream.confluent import KafkaBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase @@ -13,7 +12,7 @@ def test_publisher_bindings(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/confluent/v3_0_0/test_router.py b/tests/asyncapi/confluent/v3_0_0/test_router.py index bda0882d23..7d4a18a5a2 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_router.py +++ b/tests/asyncapi/confluent/v3_0_0/test_router.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.confluent import KafkaBroker, KafkaPublisher, KafkaRoute, KafkaRouter from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v3_0_0.router import RouterTestcase @@ -23,7 +22,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() assert schema == { "info": { diff --git a/tests/asyncapi/confluent/v3_0_0/test_security.py b/tests/asyncapi/confluent/v3_0_0/test_security.py index dfa519457f..7c1d841180 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_security.py +++ b/tests/asyncapi/confluent/v3_0_0/test_security.py @@ -10,7 +10,6 @@ SASLScram512, ) from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion basic_schema = { "info": { @@ -141,7 +140,7 @@ def test_base_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(app, version="3.0.0").to_jsonable() assert schema == basic_schema @@ -162,7 +161,7 @@ def test_plaintext_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(app, version="3.0.0").to_jsonable() plaintext_security_schema = deepcopy(basic_schema) plaintext_security_schema["servers"]["development"]["security"] = [ @@ -191,7 +190,7 @@ def test_scram256_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(app, version="3.0.0").to_jsonable() sasl256_security_schema = deepcopy(basic_schema) sasl256_security_schema["servers"]["development"]["security"] = [{"scram256": []}] @@ -218,7 +217,7 @@ def test_scram512_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(app, version="3.0.0").to_jsonable() sasl512_security_schema = deepcopy(basic_schema) sasl512_security_schema["servers"]["development"]["security"] = [{"scram512": []}] diff --git a/tests/asyncapi/kafka/v2_6_0/test_app.py b/tests/asyncapi/kafka/v2_6_0/test_app.py index 0ab08dd9cc..7d9f09e475 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_app.py +++ b/tests/asyncapi/kafka/v2_6_0/test_app.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.kafka import KafkaBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.schema.contact import Contact from faststream.specification.schema.docs import ExternalDocs from faststream.specification.schema.license import License @@ -9,7 +8,7 @@ def test_base(): - schema = get_app_schema(FastStream(KafkaBroker()), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(KafkaBroker()), version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", @@ -35,7 +34,7 @@ def test_with_name(): version="1.0.0", description="Test description", ), - version=AsyncAPIVersion.v2_6, + version="2.6.0", ).to_jsonable() assert schema == { @@ -74,7 +73,7 @@ def test_full(): url="https://extra-docs.py/", ), ), - version=AsyncAPIVersion.v2_6 + version="2.6.0" ).to_jsonable() assert schema == { @@ -119,7 +118,7 @@ def test_full_dict(): "url": "https://extra-docs.py/", }, ), - version=AsyncAPIVersion.v2_6 + version="2.6.0" ).to_jsonable() assert schema == { @@ -167,7 +166,7 @@ def test_extra(): "x-field": "extra", }, ), - version=AsyncAPIVersion.v2_6 + version="2.6.0" ).to_jsonable() assert schema == { diff --git a/tests/asyncapi/kafka/v2_6_0/test_arguments.py b/tests/asyncapi/kafka/v2_6_0/test_arguments.py index 83aefec241..317584540d 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_arguments.py +++ b/tests/asyncapi/kafka/v2_6_0/test_arguments.py @@ -1,6 +1,5 @@ from faststream.kafka import KafkaBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase @@ -13,7 +12,7 @@ def test_subscriber_bindings(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/kafka/v2_6_0/test_connection.py b/tests/asyncapi/kafka/v2_6_0/test_connection.py index 04510dcd49..18bb53bb1d 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_connection.py +++ b/tests/asyncapi/kafka/v2_6_0/test_connection.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.kafka import KafkaBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.schema.tag import Tag @@ -16,7 +15,7 @@ def test_base(): tags=(Tag(name="some-tag", description="experimental"),), ) ), - version=AsyncAPIVersion.v2_6 + version="2.6.0" ).to_jsonable() assert schema == { @@ -40,7 +39,7 @@ def test_base(): def test_multi(): schema = get_app_schema( FastStream(KafkaBroker(["kafka:9092", "kafka:9093"])), - version=AsyncAPIVersion.v2_6, + version="2.6.0", ).to_jsonable() assert schema == { @@ -72,7 +71,7 @@ def test_custom(): specification_url=["kafka:9094", "kafka:9095"], ) ), - version=AsyncAPIVersion.v2_6, + version="2.6.0", ).to_jsonable() assert schema == { diff --git a/tests/asyncapi/kafka/v2_6_0/test_fastapi.py b/tests/asyncapi/kafka/v2_6_0/test_fastapi.py index 23deb60827..bdc76a49a5 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/kafka/v2_6_0/test_fastapi.py @@ -4,7 +4,6 @@ from faststream.kafka.testing import TestKafkaBroker from faststream.security import SASLPlaintext from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import FastAPICompatible from tests.asyncapi.base.v2_6_0.fastapi import FastAPITestCase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase @@ -30,7 +29,7 @@ def test_fastapi_security_schema(): broker = KafkaRouter("localhost:9092", security=security) - schema = get_app_schema(broker, version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(broker, version="2.6.0").to_jsonable() assert schema["servers"]["development"] == { "protocol": "kafka", diff --git a/tests/asyncapi/kafka/v2_6_0/test_naming.py b/tests/asyncapi/kafka/v2_6_0/test_naming.py index fffaae0f4a..b1565d7f2e 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_naming.py +++ b/tests/asyncapi/kafka/v2_6_0/test_naming.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.kafka import KafkaBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.naming import NamingTestCase @@ -14,7 +13,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/kafka/v2_6_0/test_publisher.py b/tests/asyncapi/kafka/v2_6_0/test_publisher.py index c984825d04..d09409b16a 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_publisher.py +++ b/tests/asyncapi/kafka/v2_6_0/test_publisher.py @@ -1,6 +1,5 @@ from faststream.kafka import KafkaBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase @@ -13,7 +12,7 @@ def test_publisher_bindings(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/kafka/v2_6_0/test_router.py b/tests/asyncapi/kafka/v2_6_0/test_router.py index 20c6a385dd..f389dbcfba 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_router.py +++ b/tests/asyncapi/kafka/v2_6_0/test_router.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.kafka import KafkaBroker, KafkaPublisher, KafkaRoute, KafkaRouter from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v2_6_0.router import RouterTestcase @@ -23,7 +22,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/kafka/v2_6_0/test_security.py b/tests/asyncapi/kafka/v2_6_0/test_security.py index 6118c390fc..87251b7f19 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_security.py +++ b/tests/asyncapi/kafka/v2_6_0/test_security.py @@ -12,7 +12,6 @@ SASLScram512, ) from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion basic_schema = { "asyncapi": "2.6.0", @@ -84,7 +83,7 @@ def test_base_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(app, version="2.6.0").to_jsonable() assert schema == basic_schema @@ -105,7 +104,7 @@ def test_plaintext_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(app, version="2.6.0").to_jsonable() plaintext_security_schema = deepcopy(basic_schema) plaintext_security_schema["servers"]["development"]["security"] = [ @@ -134,7 +133,7 @@ def test_scram256_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(app, version="2.6.0").to_jsonable() sasl256_security_schema = deepcopy(basic_schema) sasl256_security_schema["servers"]["development"]["security"] = [{"scram256": []}] @@ -161,7 +160,7 @@ def test_scram512_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(app, version="2.6.0").to_jsonable() sasl512_security_schema = deepcopy(basic_schema) sasl512_security_schema["servers"]["development"]["security"] = [{"scram512": []}] @@ -213,7 +212,7 @@ def test_gssapi_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(app, version="2.6.0").to_jsonable() gssapi_security_schema = deepcopy(basic_schema) gssapi_security_schema["servers"]["development"]["security"] = [{"gssapi": []}] diff --git a/tests/asyncapi/kafka/v3_0_0/test_arguments.py b/tests/asyncapi/kafka/v3_0_0/test_arguments.py index f40900c800..6f9797c47a 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_arguments.py +++ b/tests/asyncapi/kafka/v3_0_0/test_arguments.py @@ -1,6 +1,5 @@ from faststream.kafka import KafkaBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase @@ -13,7 +12,7 @@ def test_subscriber_bindings(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/kafka/v3_0_0/test_connection.py b/tests/asyncapi/kafka/v3_0_0/test_connection.py index 63ffe768a6..7cefd97893 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_connection.py +++ b/tests/asyncapi/kafka/v3_0_0/test_connection.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.kafka import KafkaBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.schema.tag import Tag @@ -16,7 +15,7 @@ def test_base(): tags=(Tag(name="some-tag", description="experimental"),), ), ), - version=AsyncAPIVersion.v3_0, + version="3.0.0", ).to_jsonable() assert schema == { @@ -44,7 +43,7 @@ def test_multi(): FastStream( KafkaBroker(["kafka:9092", "kafka:9093"]), ), - version=AsyncAPIVersion.v3_0, + version="3.0.0", ).to_jsonable() assert schema == { @@ -79,7 +78,7 @@ def test_custom(): specification_url=["kafka:9094", "kafka:9095"], ), ), - version=AsyncAPIVersion.v3_0, + version="3.0.0", ).to_jsonable() assert schema == { diff --git a/tests/asyncapi/kafka/v3_0_0/test_naming.py b/tests/asyncapi/kafka/v3_0_0/test_naming.py index c1fa61683c..f3c050429e 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_naming.py +++ b/tests/asyncapi/kafka/v3_0_0/test_naming.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.kafka import KafkaBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.naming import NamingTestCase @@ -14,7 +13,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() assert schema == { "asyncapi": "3.0.0", diff --git a/tests/asyncapi/kafka/v3_0_0/test_publisher.py b/tests/asyncapi/kafka/v3_0_0/test_publisher.py index c05c5d2c0d..4333d91709 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_publisher.py +++ b/tests/asyncapi/kafka/v3_0_0/test_publisher.py @@ -1,6 +1,5 @@ from faststream.kafka import KafkaBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase @@ -13,7 +12,7 @@ def test_publisher_bindings(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/kafka/v3_0_0/test_router.py b/tests/asyncapi/kafka/v3_0_0/test_router.py index 1e701f9ae8..7a9b4ace06 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_router.py +++ b/tests/asyncapi/kafka/v3_0_0/test_router.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.kafka import KafkaBroker, KafkaPublisher, KafkaRoute, KafkaRouter from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v3_0_0.router import RouterTestcase @@ -23,7 +22,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() assert schema == { "info": { diff --git a/tests/asyncapi/kafka/v3_0_0/test_security.py b/tests/asyncapi/kafka/v3_0_0/test_security.py index 7529bc6cdb..0b66cb88e4 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_security.py +++ b/tests/asyncapi/kafka/v3_0_0/test_security.py @@ -10,7 +10,6 @@ SASLScram512, ) from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion basic_schema = { "info": { @@ -141,7 +140,7 @@ def test_base_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(app, version="3.0.0").to_jsonable() assert schema == basic_schema @@ -162,7 +161,7 @@ def test_plaintext_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(app, version="3.0.0").to_jsonable() plaintext_security_schema = deepcopy(basic_schema) plaintext_security_schema["servers"]["development"]["security"] = [ @@ -191,7 +190,7 @@ def test_scram256_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(app, version="3.0.0").to_jsonable() sasl256_security_schema = deepcopy(basic_schema) sasl256_security_schema["servers"]["development"]["security"] = [{"scram256": []}] @@ -218,7 +217,7 @@ def test_scram512_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(app, version="3.0.0").to_jsonable() sasl512_security_schema = deepcopy(basic_schema) sasl512_security_schema["servers"]["development"]["security"] = [{"scram512": []}] diff --git a/tests/asyncapi/nats/v2_6_0/test_arguments.py b/tests/asyncapi/nats/v2_6_0/test_arguments.py index 95691f0b06..98b71bd3e0 100644 --- a/tests/asyncapi/nats/v2_6_0/test_arguments.py +++ b/tests/asyncapi/nats/v2_6_0/test_arguments.py @@ -1,6 +1,5 @@ from faststream.nats import NatsBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase @@ -13,7 +12,7 @@ def test_subscriber_bindings(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/nats/v2_6_0/test_connection.py b/tests/asyncapi/nats/v2_6_0/test_connection.py index 0f6d06a3e1..3a2a4df5c1 100644 --- a/tests/asyncapi/nats/v2_6_0/test_connection.py +++ b/tests/asyncapi/nats/v2_6_0/test_connection.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.nats import NatsBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.schema.tag import Tag @@ -16,7 +15,7 @@ def test_base(): tags=(Tag(name="some-tag", description="experimental"),), ) ), - version=AsyncAPIVersion.v2_6, + version="2.6.0", ).to_jsonable() assert schema == { @@ -40,7 +39,7 @@ def test_base(): def test_multi(): schema = get_app_schema( FastStream(NatsBroker(["nats:9092", "nats:9093"])), - version=AsyncAPIVersion.v2_6, + version="2.6.0", ).to_jsonable() assert schema == { @@ -71,7 +70,7 @@ def test_custom(): ["nats:9092", "nats:9093"], specification_url=["nats:9094", "nats:9095"] ) ), - version=AsyncAPIVersion.v2_6, + version="2.6.0", ).to_jsonable() assert schema == { diff --git a/tests/asyncapi/nats/v2_6_0/test_kv_schema.py b/tests/asyncapi/nats/v2_6_0/test_kv_schema.py index 0b050562ca..bbe076dbbb 100644 --- a/tests/asyncapi/nats/v2_6_0/test_kv_schema.py +++ b/tests/asyncapi/nats/v2_6_0/test_kv_schema.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.nats import NatsBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion def test_kv_schema(): @@ -10,6 +9,6 @@ def test_kv_schema(): @broker.subscriber("test", kv_watch="test") async def handle(): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert schema["channels"] == {} diff --git a/tests/asyncapi/nats/v2_6_0/test_naming.py b/tests/asyncapi/nats/v2_6_0/test_naming.py index 0819550ee2..cf494e3600 100644 --- a/tests/asyncapi/nats/v2_6_0/test_naming.py +++ b/tests/asyncapi/nats/v2_6_0/test_naming.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.nats import NatsBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.naming import NamingTestCase @@ -14,7 +13,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/nats/v2_6_0/test_obj_schema.py b/tests/asyncapi/nats/v2_6_0/test_obj_schema.py index 03ab1fb1c0..3c63c716b7 100644 --- a/tests/asyncapi/nats/v2_6_0/test_obj_schema.py +++ b/tests/asyncapi/nats/v2_6_0/test_obj_schema.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.nats import NatsBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion def test_obj_schema(): @@ -10,6 +9,6 @@ def test_obj_schema(): @broker.subscriber("test", obj_watch=True) async def handle(): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert schema["channels"] == {} diff --git a/tests/asyncapi/nats/v2_6_0/test_publisher.py b/tests/asyncapi/nats/v2_6_0/test_publisher.py index 6b4f39f2ce..db492f56ad 100644 --- a/tests/asyncapi/nats/v2_6_0/test_publisher.py +++ b/tests/asyncapi/nats/v2_6_0/test_publisher.py @@ -1,6 +1,5 @@ from faststream.nats import NatsBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase @@ -13,7 +12,7 @@ def test_publisher_bindings(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/nats/v2_6_0/test_router.py b/tests/asyncapi/nats/v2_6_0/test_router.py index 769023e1f0..ccbf703cb5 100644 --- a/tests/asyncapi/nats/v2_6_0/test_router.py +++ b/tests/asyncapi/nats/v2_6_0/test_router.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.nats import NatsBroker, NatsPublisher, NatsRoute, NatsRouter from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v2_6_0.router import RouterTestcase @@ -23,7 +22,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/nats/v3_0_0/test_arguments.py b/tests/asyncapi/nats/v3_0_0/test_arguments.py index e82474a90f..6d594ca613 100644 --- a/tests/asyncapi/nats/v3_0_0/test_arguments.py +++ b/tests/asyncapi/nats/v3_0_0/test_arguments.py @@ -1,6 +1,5 @@ from faststream.nats import NatsBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase @@ -13,7 +12,7 @@ def test_subscriber_bindings(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/nats/v3_0_0/test_connection.py b/tests/asyncapi/nats/v3_0_0/test_connection.py index ae8789c45d..73442a526f 100644 --- a/tests/asyncapi/nats/v3_0_0/test_connection.py +++ b/tests/asyncapi/nats/v3_0_0/test_connection.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.nats import NatsBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.schema.tag import Tag @@ -16,7 +15,7 @@ def test_base(): tags=(Tag(name="some-tag", description="experimental"),), ), ), - version=AsyncAPIVersion.v3_0, + version="3.0.0", ).to_jsonable() assert schema == { @@ -46,7 +45,7 @@ def test_multi(): ["nats:9092", "nats:9093"] ), ), - version=AsyncAPIVersion.v3_0, + version="3.0.0", ).to_jsonable() assert schema == { @@ -81,7 +80,7 @@ def test_custom(): specification_url=["nats:9094", "nats:9095"], ), ), - version=AsyncAPIVersion.v3_0, + version="3.0.0", ).to_jsonable() assert schema == { diff --git a/tests/asyncapi/nats/v3_0_0/test_kv_schema.py b/tests/asyncapi/nats/v3_0_0/test_kv_schema.py index 944da11f0a..e9c3680fb7 100644 --- a/tests/asyncapi/nats/v3_0_0/test_kv_schema.py +++ b/tests/asyncapi/nats/v3_0_0/test_kv_schema.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.nats import NatsBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion def test_kv_schema(): @@ -10,6 +9,6 @@ def test_kv_schema(): @broker.subscriber("test", kv_watch="test") async def handle(): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() assert schema["channels"] == {} diff --git a/tests/asyncapi/nats/v3_0_0/test_naming.py b/tests/asyncapi/nats/v3_0_0/test_naming.py index f87b11de18..ef47d5e763 100644 --- a/tests/asyncapi/nats/v3_0_0/test_naming.py +++ b/tests/asyncapi/nats/v3_0_0/test_naming.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.nats import NatsBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.naming import NamingTestCase @@ -14,7 +13,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() assert schema == { "asyncapi": "3.0.0", diff --git a/tests/asyncapi/nats/v3_0_0/test_obj_schema.py b/tests/asyncapi/nats/v3_0_0/test_obj_schema.py index 86de2debe4..231ab1fdaa 100644 --- a/tests/asyncapi/nats/v3_0_0/test_obj_schema.py +++ b/tests/asyncapi/nats/v3_0_0/test_obj_schema.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.nats import NatsBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion def test_obj_schema(): @@ -10,6 +9,6 @@ def test_obj_schema(): @broker.subscriber("test", obj_watch=True) async def handle(): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() assert schema["channels"] == {} diff --git a/tests/asyncapi/nats/v3_0_0/test_publisher.py b/tests/asyncapi/nats/v3_0_0/test_publisher.py index 242b649088..f825bbcd43 100644 --- a/tests/asyncapi/nats/v3_0_0/test_publisher.py +++ b/tests/asyncapi/nats/v3_0_0/test_publisher.py @@ -1,6 +1,5 @@ from faststream.nats import NatsBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase @@ -13,7 +12,7 @@ def test_publisher_bindings(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/nats/v3_0_0/test_router.py b/tests/asyncapi/nats/v3_0_0/test_router.py index 51e57bcf78..2197684c8e 100644 --- a/tests/asyncapi/nats/v3_0_0/test_router.py +++ b/tests/asyncapi/nats/v3_0_0/test_router.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.nats import NatsBroker, NatsPublisher, NatsRoute, NatsRouter from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v3_0_0.router import RouterTestcase @@ -23,7 +22,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() assert schema == { "info": { diff --git a/tests/asyncapi/rabbit/v2_6_0/test_arguments.py b/tests/asyncapi/rabbit/v2_6_0/test_arguments.py index 4a60a47b19..bbb9b4ed30 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_arguments.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_arguments.py @@ -1,6 +1,5 @@ from faststream.rabbit import ExchangeType, RabbitBroker, RabbitExchange, RabbitQueue from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase @@ -16,7 +15,7 @@ def test_subscriber_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -49,7 +48,7 @@ def test_subscriber_fanout_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/rabbit/v2_6_0/test_connection.py b/tests/asyncapi/rabbit/v2_6_0/test_connection.py index 4716e40869..137bb7b444 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_connection.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_connection.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.rabbit import RabbitBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.schema.tag import Tag @@ -16,7 +15,7 @@ def test_base(): tags=(Tag(name="some-tag", description="experimental"),), ) ), - version=AsyncAPIVersion.v2_6, + version="2.6.0", ).to_jsonable() assert schema == { @@ -56,7 +55,7 @@ def test_custom(): ) broker.publisher("test") - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert ( schema diff --git a/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py b/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py index 1d3d1ef14c..f08b8d6a22 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py @@ -4,7 +4,6 @@ from faststream.rabbit.testing import TestRabbitBroker from faststream.security import SASLPlaintext from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import FastAPICompatible from tests.asyncapi.base.v2_6_0.fastapi import FastAPITestCase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase @@ -30,7 +29,7 @@ def test_fastapi_security_schema(): broker = RabbitRouter(security=security) - schema = get_app_schema(broker, version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(broker, version="2.6.0").to_jsonable() assert schema["servers"]["development"] == { "protocol": "amqp", diff --git a/tests/asyncapi/rabbit/v2_6_0/test_naming.py b/tests/asyncapi/rabbit/v2_6_0/test_naming.py index 934b076408..1aeab52db3 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_naming.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_naming.py @@ -3,7 +3,6 @@ from faststream import FastStream from faststream.rabbit import RabbitBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.naming import NamingTestCase @@ -16,7 +15,7 @@ def test_subscriber_with_exchange(self): @broker.subscriber("test", "exchange") async def handle(): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == ["test:exchange:Handle"] @@ -30,7 +29,7 @@ def test_publisher_with_exchange(self): @broker.publisher("test", "exchange") async def handle(): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == ["test:exchange:Publisher"] @@ -44,7 +43,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert ( schema diff --git a/tests/asyncapi/rabbit/v2_6_0/test_publisher.py b/tests/asyncapi/rabbit/v2_6_0/test_publisher.py index 8cfd5ed4b2..ed503d6ce5 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_publisher.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_publisher.py @@ -1,6 +1,5 @@ from faststream.rabbit import ExchangeType, RabbitBroker, RabbitExchange, RabbitQueue from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase @@ -13,7 +12,7 @@ def test_just_exchange(self): @broker.publisher(exchange="test-ex") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() assert schema["channels"] == { "_:test-ex:Publisher": { @@ -56,7 +55,7 @@ def test_publisher_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -89,7 +88,7 @@ def test_useless_queue_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() assert schema["channels"] == { "_:test-ex:Publisher": { @@ -122,7 +121,7 @@ def test_reusable_exchange(self): @broker.publisher(exchange="test-ex", routing_key="key2", priority=10) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() assert schema["channels"] == { "key1:test-ex:Publisher": { diff --git a/tests/asyncapi/rabbit/v2_6_0/test_router.py b/tests/asyncapi/rabbit/v2_6_0/test_router.py index 1004fc005d..9c6b8d3fb6 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_router.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_router.py @@ -7,7 +7,6 @@ RabbitRouter, ) from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v2_6_0.router import RouterTestcase @@ -29,7 +28,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert ( schema diff --git a/tests/asyncapi/rabbit/v2_6_0/test_security.py b/tests/asyncapi/rabbit/v2_6_0/test_security.py index 8fc734e3b2..d46514cb37 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_security.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_security.py @@ -7,7 +7,6 @@ SASLPlaintext, ) from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion def test_base_security_schema(): @@ -21,7 +20,7 @@ def test_base_security_schema(): ) # pragma: allowlist secret assert broker._connection_kwargs.get("ssl_context") is ssl_context - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", @@ -57,7 +56,7 @@ def test_plaintext_security_schema(): ) # pragma: allowlist secret assert broker._connection_kwargs.get("ssl_context") is ssl_context - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert ( schema == { @@ -95,7 +94,7 @@ def test_plaintext_security_schema_without_ssl(): == "amqp://admin:password@localhost:5672/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert ( schema == { diff --git a/tests/asyncapi/rabbit/v3_0_0/test_arguments.py b/tests/asyncapi/rabbit/v3_0_0/test_arguments.py index a02134dc19..aa9bb997a4 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_arguments.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_arguments.py @@ -1,6 +1,5 @@ from faststream.rabbit import ExchangeType, RabbitBroker, RabbitExchange, RabbitQueue from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase @@ -16,7 +15,7 @@ def test_subscriber_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -49,7 +48,7 @@ def test_subscriber_fanout_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/rabbit/v3_0_0/test_connection.py b/tests/asyncapi/rabbit/v3_0_0/test_connection.py index bab50a9cc1..8fe39a439d 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_connection.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_connection.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.rabbit import RabbitBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.schema.tag import Tag @@ -16,7 +15,7 @@ def test_base(): tags=(Tag(name="some-tag", description="experimental"),), ), ), - version=AsyncAPIVersion.v3_0, + version="3.0.0", ).to_jsonable() assert schema == { @@ -58,7 +57,7 @@ def test_custom(): ) broker.publisher("test") - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() assert ( schema diff --git a/tests/asyncapi/rabbit/v3_0_0/test_naming.py b/tests/asyncapi/rabbit/v3_0_0/test_naming.py index db833b73a2..f741041df2 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_naming.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_naming.py @@ -3,7 +3,6 @@ from faststream import FastStream from faststream.rabbit import RabbitBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.naming import NamingTestCase @@ -16,7 +15,7 @@ def test_subscriber_with_exchange(self): @broker.subscriber("test", "exchange") async def handle(): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0,).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0",).to_jsonable() assert list(schema["channels"].keys()) == ["test:exchange:Handle"] @@ -30,7 +29,7 @@ def test_publisher_with_exchange(self): @broker.publisher("test", "exchange") async def handle(): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0,).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0",).to_jsonable() assert list(schema["channels"].keys()) == ["test:exchange:Publisher"] @@ -44,7 +43,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0,).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0",).to_jsonable() assert ( schema diff --git a/tests/asyncapi/rabbit/v3_0_0/test_publisher.py b/tests/asyncapi/rabbit/v3_0_0/test_publisher.py index faed5925c1..cad2b8654c 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_publisher.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_publisher.py @@ -1,6 +1,5 @@ from faststream.rabbit import ExchangeType, RabbitBroker, RabbitExchange, RabbitQueue from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase @@ -13,7 +12,7 @@ def test_just_exchange(self): @broker.publisher(exchange="test-ex") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() assert schema["channels"] == { "_:test-ex:Publisher": { @@ -75,7 +74,7 @@ def test_publisher_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -108,7 +107,7 @@ def test_useless_queue_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() assert schema["channels"] == { "_:test-ex:Publisher": { @@ -160,7 +159,7 @@ def test_reusable_exchange(self): @broker.publisher(exchange="test-ex", routing_key="key2", priority=10) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() assert schema["channels"] == { "key1:test-ex:Publisher": { diff --git a/tests/asyncapi/rabbit/v3_0_0/test_router.py b/tests/asyncapi/rabbit/v3_0_0/test_router.py index 084ff408b2..967a61f4dd 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_router.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_router.py @@ -7,7 +7,6 @@ RabbitRouter, ) from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v3_0_0.router import RouterTestcase @@ -29,7 +28,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0,).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0",).to_jsonable() assert ( schema diff --git a/tests/asyncapi/rabbit/v3_0_0/test_security.py b/tests/asyncapi/rabbit/v3_0_0/test_security.py index 6768024d69..287144dac6 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_security.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_security.py @@ -7,7 +7,6 @@ SASLPlaintext, ) from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion def test_base_security_schema(): @@ -21,7 +20,7 @@ def test_base_security_schema(): ) # pragma: allowlist secret assert broker._connection_kwargs.get("ssl_context") is ssl_context - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0,).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0",).to_jsonable() assert schema == { "asyncapi": "3.0.0", @@ -59,7 +58,7 @@ def test_plaintext_security_schema(): ) # pragma: allowlist secret assert broker._connection_kwargs.get("ssl_context") is ssl_context - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0,).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0",).to_jsonable() assert ( schema == { @@ -99,7 +98,7 @@ def test_plaintext_security_schema_without_ssl(): == "amqp://admin:password@localhost:5672/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0,).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0",).to_jsonable() assert ( schema == { diff --git a/tests/asyncapi/redis/v2_6_0/test_arguments.py b/tests/asyncapi/redis/v2_6_0/test_arguments.py index 884c2b8a8d..8b370dd571 100644 --- a/tests/asyncapi/redis/v2_6_0/test_arguments.py +++ b/tests/asyncapi/redis/v2_6_0/test_arguments.py @@ -1,6 +1,5 @@ from faststream.redis import RedisBroker, StreamSub from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase @@ -13,7 +12,7 @@ def test_channel_subscriber(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -30,7 +29,7 @@ def test_channel_pattern_subscriber(self): @broker.subscriber("test.{path}") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -47,7 +46,7 @@ def test_list_subscriber(self): @broker.subscriber(list="test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -60,7 +59,7 @@ def test_stream_subscriber(self): @broker.subscriber(stream="test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -73,7 +72,7 @@ def test_stream_group_subscriber(self): @broker.subscriber(stream=StreamSub("test", group="group", consumer="consumer")) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/redis/v2_6_0/test_connection.py b/tests/asyncapi/redis/v2_6_0/test_connection.py index f6428b53e6..38bc050ad3 100644 --- a/tests/asyncapi/redis/v2_6_0/test_connection.py +++ b/tests/asyncapi/redis/v2_6_0/test_connection.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.redis import RedisBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.schema.tag import Tag @@ -16,7 +15,7 @@ def test_base(): tags=(Tag(name="some-tag", description="experimental"),), ) ), - version=AsyncAPIVersion.v2_6, + version="2.6.0", ).to_jsonable() assert schema == { @@ -44,7 +43,7 @@ def test_custom(): "redis://localhost:6379", specification_url="rediss://127.0.0.1:8000" ) ), - version=AsyncAPIVersion.v2_6, + version="2.6.0", ).to_jsonable() assert schema == { diff --git a/tests/asyncapi/redis/v2_6_0/test_naming.py b/tests/asyncapi/redis/v2_6_0/test_naming.py index 56b5050712..27ab159d5f 100644 --- a/tests/asyncapi/redis/v2_6_0/test_naming.py +++ b/tests/asyncapi/redis/v2_6_0/test_naming.py @@ -3,7 +3,6 @@ from faststream import FastStream from faststream.redis import RedisBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.naming import NamingTestCase @@ -16,7 +15,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/redis/v2_6_0/test_publisher.py b/tests/asyncapi/redis/v2_6_0/test_publisher.py index f704c5bffd..aa58433d67 100644 --- a/tests/asyncapi/redis/v2_6_0/test_publisher.py +++ b/tests/asyncapi/redis/v2_6_0/test_publisher.py @@ -1,6 +1,5 @@ from faststream.redis import RedisBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase @@ -13,7 +12,7 @@ def test_channel_publisher(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -30,7 +29,7 @@ def test_list_publisher(self): @broker.publisher(list="test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -43,7 +42,7 @@ def test_stream_publisher(self): @broker.publisher(stream="test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/redis/v2_6_0/test_router.py b/tests/asyncapi/redis/v2_6_0/test_router.py index 90defd4b60..2659495141 100644 --- a/tests/asyncapi/redis/v2_6_0/test_router.py +++ b/tests/asyncapi/redis/v2_6_0/test_router.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.redis import RedisBroker, RedisPublisher, RedisRoute, RedisRouter from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v2_6_0.router import RouterTestcase @@ -23,7 +22,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/redis/v2_6_0/test_security.py b/tests/asyncapi/redis/v2_6_0/test_security.py index 62079eed11..bab9619160 100644 --- a/tests/asyncapi/redis/v2_6_0/test_security.py +++ b/tests/asyncapi/redis/v2_6_0/test_security.py @@ -7,7 +7,6 @@ SASLPlaintext, ) from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion def test_base_security_schema(): @@ -20,7 +19,7 @@ def test_base_security_schema(): broker.url == "rediss://localhost:6379/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", @@ -54,7 +53,7 @@ def test_plaintext_security_schema(): broker.url == "redis://localhost:6379/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", @@ -89,7 +88,7 @@ def test_plaintext_security_schema_without_ssl(): broker.url == "redis://localhost:6379/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v2_6).to_jsonable() + schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/redis/v3_0_0/test_arguments.py b/tests/asyncapi/redis/v3_0_0/test_arguments.py index d33efc72ae..52bb000b72 100644 --- a/tests/asyncapi/redis/v3_0_0/test_arguments.py +++ b/tests/asyncapi/redis/v3_0_0/test_arguments.py @@ -1,6 +1,5 @@ from faststream.redis import RedisBroker, StreamSub from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase @@ -13,7 +12,7 @@ def test_channel_subscriber(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -30,7 +29,7 @@ def test_channel_pattern_subscriber(self): @broker.subscriber("test.{path}") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -47,7 +46,7 @@ def test_list_subscriber(self): @broker.subscriber(list="test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -60,7 +59,7 @@ def test_stream_subscriber(self): @broker.subscriber(stream="test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -73,7 +72,7 @@ def test_stream_group_subscriber(self): @broker.subscriber(stream=StreamSub("test", group="group", consumer="consumer")) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/redis/v3_0_0/test_connection.py b/tests/asyncapi/redis/v3_0_0/test_connection.py index f039a72a17..aae2393cc0 100644 --- a/tests/asyncapi/redis/v3_0_0/test_connection.py +++ b/tests/asyncapi/redis/v3_0_0/test_connection.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.redis import RedisBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from faststream.specification.schema.tag import Tag @@ -16,7 +15,7 @@ def test_base(): tags=(Tag(name="some-tag", description="experimental"),), ), ), - version=AsyncAPIVersion.v3_0, + version="3.0.0", ).to_jsonable() assert schema == { @@ -47,7 +46,7 @@ def test_custom(): specification_url="rediss://127.0.0.1:8000" ), ), - version=AsyncAPIVersion.v3_0, + version="3.0.0", ).to_jsonable() assert schema == { diff --git a/tests/asyncapi/redis/v3_0_0/test_naming.py b/tests/asyncapi/redis/v3_0_0/test_naming.py index 987fa0a5c6..0d8c102940 100644 --- a/tests/asyncapi/redis/v3_0_0/test_naming.py +++ b/tests/asyncapi/redis/v3_0_0/test_naming.py @@ -3,7 +3,6 @@ from faststream import FastStream from faststream.redis import RedisBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.naming import NamingTestCase @@ -16,7 +15,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0,).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0",).to_jsonable() assert schema == { "asyncapi": "3.0.0", diff --git a/tests/asyncapi/redis/v3_0_0/test_publisher.py b/tests/asyncapi/redis/v3_0_0/test_publisher.py index e5e7af3fef..de00df470f 100644 --- a/tests/asyncapi/redis/v3_0_0/test_publisher.py +++ b/tests/asyncapi/redis/v3_0_0/test_publisher.py @@ -1,6 +1,5 @@ from faststream.redis import RedisBroker from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase @@ -13,7 +12,7 @@ def test_channel_publisher(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -30,7 +29,7 @@ def test_list_publisher(self): @broker.publisher(list="test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -43,7 +42,7 @@ def test_stream_publisher(self): @broker.publisher(stream="test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version=AsyncAPIVersion.v3_0).to_jsonable() + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/redis/v3_0_0/test_router.py b/tests/asyncapi/redis/v3_0_0/test_router.py index 72d8f7276f..e33937a700 100644 --- a/tests/asyncapi/redis/v3_0_0/test_router.py +++ b/tests/asyncapi/redis/v3_0_0/test_router.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.redis import RedisBroker, RedisPublisher, RedisRoute, RedisRouter from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v3_0_0.router import RouterTestcase @@ -23,7 +22,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0,).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0",).to_jsonable() assert schema == { "info": { diff --git a/tests/asyncapi/redis/v3_0_0/test_security.py b/tests/asyncapi/redis/v3_0_0/test_security.py index f8cabfd809..622fbee8b3 100644 --- a/tests/asyncapi/redis/v3_0_0/test_security.py +++ b/tests/asyncapi/redis/v3_0_0/test_security.py @@ -7,7 +7,6 @@ SASLPlaintext, ) from faststream.specification.asyncapi.generate import get_app_schema -from faststream.specification.asyncapi.version import AsyncAPIVersion def test_base_security_schema(): @@ -20,7 +19,7 @@ def test_base_security_schema(): broker.url == "rediss://localhost:6379/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0,).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0",).to_jsonable() assert schema == { "asyncapi": "3.0.0", @@ -56,7 +55,7 @@ def test_plaintext_security_schema(): broker.url == "redis://localhost:6379/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0,).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0",).to_jsonable() assert schema == { "asyncapi": "3.0.0", @@ -93,7 +92,7 @@ def test_plaintext_security_schema_without_ssl(): broker.url == "redis://localhost:6379/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = get_app_schema(FastStream(broker), version=AsyncAPIVersion.v3_0,).to_jsonable() + schema = get_app_schema(FastStream(broker), version="3.0.0",).to_jsonable() assert schema == { "asyncapi": "3.0.0", From b4f735726bf9b9fce15ea6d81165e2aa0238e75d Mon Sep 17 00:00:00 2001 From: Kumaran Rajendhiran Date: Mon, 12 Aug 2024 21:33:47 +0530 Subject: [PATCH 110/245] Add kerberos support for confluent broker (#1670) * Add kerberos support for confluent broker * Update tests --- tests/a_docs/confluent/test_security.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/a_docs/confluent/test_security.py b/tests/a_docs/confluent/test_security.py index b77c91eb8a..9aa18c3a5a 100644 --- a/tests/a_docs/confluent/test_security.py +++ b/tests/a_docs/confluent/test_security.py @@ -115,8 +115,8 @@ async def test_oathbearer(): ) -@pytest.mark.asyncio -@pytest.mark.confluent +@pytest.mark.asyncio() +@pytest.mark.confluent() async def test_gssapi(): from docs.docs_src.confluent.security.sasl_gssapi import ( broker as gssapi_broker, From 44394798845d1fca47617eb643c4fc71b15d54f1 Mon Sep 17 00:00:00 2001 From: Pastukhov Nikita Date: Tue, 13 Aug 2024 13:45:20 +0300 Subject: [PATCH 111/245] fix: support all RMQ exchanges in AsyncAPI (#1679) * fix (#1668): support all exchange RMQ types in AsyncAPI * chore: bump dependencies --- faststream/specification/schema/bindings/amqp.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/faststream/specification/schema/bindings/amqp.py b/faststream/specification/schema/bindings/amqp.py index 9af5566f51..eb6c03d4f6 100644 --- a/faststream/specification/schema/bindings/amqp.py +++ b/faststream/specification/schema/bindings/amqp.py @@ -37,7 +37,17 @@ class Exchange: vhost : virtual host of the exchange, default is "/" """ - type: Literal["default", "direct", "topic", "fanout", "headers"] + type: Literal[ + "default", + "direct", + "topic", + "fanout", + "headers", + "x-delayed-message", + "x-consistent-hash", + "x-modulus-hash", + ] + name: Optional[str] = None durable: Optional[bool] = None autoDelete: Optional[bool] = None From 6748d3f67e760097b83ff9d1e2c0f6de05c95fb6 Mon Sep 17 00:00:00 2001 From: Kumaran Rajendhiran Date: Fri, 16 Aug 2024 11:27:55 +0530 Subject: [PATCH 112/245] Remove unused ignores (#1690) * Remove unused ignores * Add misc ignore comments and remove cast * Revert cast change --- faststream/rabbit/publisher/publisher.py | 4 ++-- faststream/rabbit/subscriber/subscriber.py | 4 ++-- faststream/rabbit/testing.py | 2 +- faststream/specification/schema/contact.py | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/faststream/rabbit/publisher/publisher.py b/faststream/rabbit/publisher/publisher.py index ecf19536a8..b6e2f922aa 100644 --- a/faststream/rabbit/publisher/publisher.py +++ b/faststream/rabbit/publisher/publisher.py @@ -24,7 +24,7 @@ class SpecificationPublisher(LogicPublisher): """AsyncAPI-compatible Rabbit Publisher class. - Creting by + Creating by ```python publisher: SpecificationPublisher = broker.publisher(...) @@ -47,7 +47,7 @@ def get_schema(self) -> Dict[str, Channel]: return { self.name: Channel( - description=self.description, # type: ignore[attr-defined] + description=self.description, publish=Operation( bindings=OperationBinding( amqp=amqp.OperationBinding( diff --git a/faststream/rabbit/subscriber/subscriber.py b/faststream/rabbit/subscriber/subscriber.py index 61ff809790..5ed253a8e2 100644 --- a/faststream/rabbit/subscriber/subscriber.py +++ b/faststream/rabbit/subscriber/subscriber.py @@ -24,7 +24,7 @@ def get_schema(self) -> Dict[str, Channel]: return { self.name: Channel( - description=self.description, # type: ignore[attr-defined] + description=self.description, subscribe=Operation( bindings=OperationBinding( amqp=amqp.OperationBinding( @@ -58,7 +58,7 @@ def get_schema(self) -> Dict[str, Channel]: amqp.Exchange(type="default", vhost=self.virtual_host) if not self.exchange.name else amqp.Exchange( - type=self.exchange.type.value, # type: ignore + type=self.exchange.type.value, name=self.exchange.name, durable=self.exchange.durable, autoDelete=self.exchange.auto_delete, diff --git a/faststream/rabbit/testing.py b/faststream/rabbit/testing.py index afc6ace2d7..b62e8b66aa 100644 --- a/faststream/rabbit/testing.py +++ b/faststream/rabbit/testing.py @@ -190,7 +190,7 @@ def __init__(self, broker: RabbitBroker) -> None: ) @override - async def publish( # type: ignore[override] + async def publish( self, message: "AioPikaSendableMessage", exchange: Union["RabbitExchange", str, None] = None, diff --git a/faststream/specification/schema/contact.py b/faststream/specification/schema/contact.py index b098d441bc..dec0c5d5cc 100644 --- a/faststream/specification/schema/contact.py +++ b/faststream/specification/schema/contact.py @@ -84,7 +84,7 @@ def __get_pydantic_core_schema__( source : the source handler : the handler """ - return with_info_plain_validator_function(cls._validate) # type: ignore[no-any-return] + return with_info_plain_validator_function(cls._validate) class ContactDict(TypedDict, total=False): From 65fcfe25932249befc3d90bf4c58d0412a09f054 Mon Sep 17 00:00:00 2001 From: Kumaran Rajendhiran Date: Tue, 20 Aug 2024 21:45:23 +0530 Subject: [PATCH 113/245] Update package versions (#1702) * Update mike and dirty-equals versions * Update griffe-typingdoc version * Update mkdocs-material version * Update ruff version and update files * lint: fix ruff * lint: fix mypy --------- Co-authored-by: Nikita Pastukhov --- tests/a_docs/confluent/test_security.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/a_docs/confluent/test_security.py b/tests/a_docs/confluent/test_security.py index 9aa18c3a5a..b77c91eb8a 100644 --- a/tests/a_docs/confluent/test_security.py +++ b/tests/a_docs/confluent/test_security.py @@ -115,8 +115,8 @@ async def test_oathbearer(): ) -@pytest.mark.asyncio() -@pytest.mark.confluent() +@pytest.mark.asyncio +@pytest.mark.confluent async def test_gssapi(): from docs.docs_src.confluent.security.sasl_gssapi import ( broker as gssapi_broker, From 94cdefb477d091339ddbb097ba025ebc47769930 Mon Sep 17 00:00:00 2001 From: Pastukhov Nikita Date: Sat, 24 Aug 2024 21:32:44 +0300 Subject: [PATCH 114/245] feat: add broker.request method (#1649) * feat: add broker.request method * feat: kafka request support * feat: confluent request support * merge main * feat: confluent request tests * docs: generate API References * tests: fix broken tests * tests: refactor confluent test client * docs: update rpc examples * chore: deprecate message.decoded_body * refactor: FastAPI 0.5.0 compatibility * docs: remove useless API * refactor: correct Consumer Protocol * fix: correct Confluent FakeConsumer * Ignore override * Proofread docs * Remove unused ignores * Add ignore redundant-cast * fix: correct merge * lint: fix precommit * fix: decoded_body public field compatibility * fix: request respects consume middleware * fix: request respects consume middleware for all brokers * chore: bump version * docs: generate API References * fix: request respects global middlewares scope --------- Co-authored-by: Lancetnik Co-authored-by: Kumaran Rajendhiran --- faststream/broker/fastapi/route.py | 10 ++++ faststream/kafka/publisher/usecase.py | 77 +++++++++++++++++++++++++++ faststream/kafka/testing.py | 2 - faststream/rabbit/testing.py | 2 +- 4 files changed, 88 insertions(+), 3 deletions(-) diff --git a/faststream/broker/fastapi/route.py b/faststream/broker/fastapi/route.py index d8e39f96b2..df774f749e 100644 --- a/faststream/broker/fastapi/route.py +++ b/faststream/broker/fastapi/route.py @@ -210,7 +210,17 @@ async def app( **kwargs, ) +<<<<<<< HEAD raw_message.background = solved_result.background_tasks # type: ignore[attr-defined] +======= + ( + values, + errors, + raw_message.background, # type: ignore[attr-defined] + _response, + _dependency_cache, + ) = solved_result +>>>>>>> 2016de36 (feat: add broker.request method (#1649)) if solved_result.errors: raise_fastapi_validation_error(solved_result.errors, request._body) # type: ignore[arg-type] diff --git a/faststream/kafka/publisher/usecase.py b/faststream/kafka/publisher/usecase.py index 709aea898b..d7258182a8 100644 --- a/faststream/kafka/publisher/usecase.py +++ b/faststream/kafka/publisher/usecase.py @@ -395,6 +395,83 @@ async def request( _extra_middlewares=_extra_middlewares, ) + @override + async def request( + self, + message: Annotated[ + "SendableMessage", + Doc("Message body to send."), + ], + topic: Annotated[ + str, + Doc("Topic where the message will be published."), + ] = "", + *, + key: Annotated[ + Union[bytes, Any, None], + Doc( + """ + A key to associate with the message. Can be used to + determine which partition to send the message to. If partition + is `None` (and producer's partitioner config is left as default), + then messages with the same key will be delivered to the same + partition (but if key is `None`, partition is chosen randomly). + Must be type `bytes`, or be serializable to bytes via configured + `key_serializer`. + """ + ), + ] = None, + partition: Annotated[ + Optional[int], + Doc( + """ + Specify a partition. If not set, the partition will be + selected using the configured `partitioner`. + """ + ), + ] = None, + timestamp_ms: Annotated[ + Optional[int], + Doc( + """ + Epoch milliseconds (from Jan 1 1970 UTC) to use as + the message timestamp. Defaults to current time. + """ + ), + ] = None, + headers: Annotated[ + Optional[Dict[str, str]], + Doc("Message headers to store metainformation."), + ] = None, + correlation_id: Annotated[ + Optional[str], + Doc( + "Manual message **correlation_id** setter. " + "**correlation_id** is a useful option to trace messages." + ), + ] = None, + timeout: Annotated[ + float, + Doc("Timeout to send RPC request."), + ] = 0.5, + # publisher specific + _extra_middlewares: Annotated[ + Iterable["PublisherMiddleware"], + Doc("Extra middlewares to wrap publishing process."), + ] = (), + ) -> "KafkaMessage": + return await super().request( + message=message, + topic=topic, + key=key or self.key, + partition=partition, + timestamp_ms=timestamp_ms, + headers=headers, + correlation_id=correlation_id, + timeout=timeout, + _extra_middlewares=_extra_middlewares, + ) + class BatchPublisher(LogicPublisher[Tuple["ConsumerRecord", ...]]): @override diff --git a/faststream/kafka/testing.py b/faststream/kafka/testing.py index 37e77dcf3e..b0b3b51fb7 100755 --- a/faststream/kafka/testing.py +++ b/faststream/kafka/testing.py @@ -23,8 +23,6 @@ from faststream.kafka.publisher.publisher import SpecificationBatchPublisher from faststream.kafka.subscriber.subscriber import SpecificationBatchSubscriber from faststream.testing.broker import TestBroker - -if TYPE_CHECKING: from faststream.kafka.publisher.publisher import SpecificationPublisher from faststream.kafka.subscriber.usecase import LogicSubscriber from faststream.types import SendableMessage diff --git a/faststream/rabbit/testing.py b/faststream/rabbit/testing.py index b62e8b66aa..afc6ace2d7 100644 --- a/faststream/rabbit/testing.py +++ b/faststream/rabbit/testing.py @@ -190,7 +190,7 @@ def __init__(self, broker: RabbitBroker) -> None: ) @override - async def publish( + async def publish( # type: ignore[override] self, message: "AioPikaSendableMessage", exchange: Union["RabbitExchange", str, None] = None, From 7489bde0e1b027d5ca1461c7563a770697728b8d Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Mon, 22 Jul 2024 21:57:49 +0300 Subject: [PATCH 115/245] Schema v3 and info v3 --- faststream/asyncapi/generate.py | 26 ++++ faststream/asyncapi/schema/__init__.py | 73 +++++++++ faststream/specification/schema/contact.py | 4 +- faststream/specification/schema/schema.py | 170 ++++++++++++++++++++- 4 files changed, 270 insertions(+), 3 deletions(-) create mode 100644 faststream/asyncapi/generate.py create mode 100644 faststream/asyncapi/schema/__init__.py diff --git a/faststream/asyncapi/generate.py b/faststream/asyncapi/generate.py new file mode 100644 index 0000000000..39cba02fcc --- /dev/null +++ b/faststream/asyncapi/generate.py @@ -0,0 +1,26 @@ +from typing import TYPE_CHECKING + +from faststream._compat import HAS_FASTAPI +from faststream.asyncapi.base import BaseSchema +from faststream.asyncapi.schema import ( + BaseSchema, +) +from faststream.asyncapi.v2_6_0.generate import get_app_schema as get_app_schema_v2_6 +from faststream.asyncapi.v3_0_0.generate import get_app_schema as get_app_schema_v3 +from faststream.asyncapi.version import AsyncAPIVersion + +if TYPE_CHECKING: + from faststream._compat import HAS_FASTAPI + + if HAS_FASTAPI: + pass + + +def get_app_schema(app: "AsyncAPIApplication") -> BaseSchema: + if app.asyncapi_version == AsyncAPIVersion.v3_0: + return get_app_schema_v3(app) + + if app.asyncapi_version == AsyncAPIVersion.v2_6: + return get_app_schema_v2_6(app) + + raise NotImplementedError(f"Async API version not supported: {app.asyncapi_version}") diff --git a/faststream/asyncapi/schema/__init__.py b/faststream/asyncapi/schema/__init__.py new file mode 100644 index 0000000000..67bb38e49b --- /dev/null +++ b/faststream/asyncapi/schema/__init__.py @@ -0,0 +1,73 @@ +"""AsyncAPI schema related functions.""" + +from faststream.asyncapi.schema.bindings import ( + ChannelBinding, + OperationBinding, + ServerBinding, +) +from faststream.asyncapi.schema.channels import Channel +from faststream.asyncapi.schema.info import ( + BaseInfo, + Contact, + ContactDict, + InfoV2_6, + InfoV3_0, + License, + LicenseDict, +) +from faststream.asyncapi.schema.main import ( + BaseSchema, + Components, + SchemaV2_6, + SchemaV3_0, +) +from faststream.asyncapi.schema.message import CorrelationId, Message +from faststream.asyncapi.schema.operations import Operation +from faststream.asyncapi.schema.security import SecuritySchemaComponent +from faststream.asyncapi.schema.servers import Server +from faststream.asyncapi.schema.utils import ( + ExternalDocs, + ExternalDocsDict, + Reference, + Tag, + TagDict, +) +from faststream.asyncapi.version import AsyncAPIVersion + +__all__ = ( + # main + "AsyncAPIVersion", + "BaseSchema", + "SchemaV2_6", + "SchemaV3_0", + "Components", + # info + "BaseInfo", + "InfoV2_6", + "InfoV3_0", + "Contact", + "ContactDict", + "License", + "LicenseDict", + # servers + "Server", + # channels + "Channel", + # utils + "Tag", + "TagDict", + "ExternalDocs", + "ExternalDocsDict", + "Reference", + # bindings + "ServerBinding", + "ChannelBinding", + "OperationBinding", + # messages + "Message", + "CorrelationId", + # security + "SecuritySchemaComponent", + # subscription + "Operation", +) diff --git a/faststream/specification/schema/contact.py b/faststream/specification/schema/contact.py index dec0c5d5cc..89f9fbbd54 100644 --- a/faststream/specification/schema/contact.py +++ b/faststream/specification/schema/contact.py @@ -3,7 +3,8 @@ Callable, Iterable, Optional, - Type, + Type + ) from pydantic import AnyHttpUrl, BaseModel @@ -18,6 +19,7 @@ ) from faststream.log import logger + try: import email_validator diff --git a/faststream/specification/schema/schema.py b/faststream/specification/schema/schema.py index d3b89ad2ac..190af45fad 100644 --- a/faststream/specification/schema/schema.py +++ b/faststream/specification/schema/schema.py @@ -2,6 +2,7 @@ from pydantic import BaseModel +<<<<<<< HEAD:faststream/specification/schema/schema.py from faststream._compat import model_to_json, model_to_jsonable from faststream.specification.schema.channel import Channel from faststream.specification.schema.components import Components @@ -9,9 +10,116 @@ from faststream.specification.schema.info import Info from faststream.specification.schema.servers import Server from faststream.specification.schema.tag import Tag +======= +from faststream._compat import PYDANTIC_V2, model_to_json, model_to_jsonable +from faststream.asyncapi.schema.channels import Channel +from faststream.asyncapi.schema.info import BaseInfo, InfoV2_6, InfoV3_0 +from faststream.asyncapi.schema.message import Message +from faststream.asyncapi.schema.servers import Server +from faststream.asyncapi.schema.utils import ( + ExternalDocs, + ExternalDocsDict, + Tag, + TagDict, +) +from faststream.asyncapi.version import AsyncAPIVersion +ASYNC_API_VERSION = "2.6.0" -class Schema(BaseModel): + +class Components(BaseModel): + # TODO + # servers + # serverVariables + # channels + """A class to represent components in a system. + + Attributes: + messages : Optional dictionary of messages + schemas : Optional dictionary of schemas + + Note: + The following attributes are not implemented yet: + - servers + - serverVariables + - channels + - securitySchemes + - parameters + - correlationIds + - operationTraits + - messageTraits + - serverBindings + - channelBindings + - operationBindings + - messageBindings + + """ + + messages: Optional[Dict[str, Message]] = None + schemas: Optional[Dict[str, Dict[str, Any]]] = None + securitySchemes: Optional[Dict[str, Dict[str, Any]]] = None + # parameters + # correlationIds + # operationTraits + # messageTraits + # serverBindings + # channelBindings + # operationBindings + # messageBindings + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" +>>>>>>> e2a839fc (Schema v3 and info v3):faststream/asyncapi/schema/main.py + + +class BaseSchema(BaseModel): + """A class to represent a schema. + + Attributes: + info : information about the schema + + Methods: + to_jsonable() -> Any: Convert the schema to a JSON-serializable object. + to_json() -> str: Convert the schema to a JSON string. + to_yaml() -> str: Convert the schema to a YAML string. + + """ + + info: BaseInfo + + def to_jsonable(self) -> Any: + """Convert the schema to a JSON-serializable object.""" + return model_to_jsonable( + self, + by_alias=True, + exclude_none=True, + ) + + def to_json(self) -> str: + """Convert the schema to a JSON string.""" + return model_to_json( + self, + by_alias=True, + exclude_none=True, + ) + + def to_yaml(self) -> str: + """Convert the schema to a YAML string.""" + from io import StringIO + + import yaml + + io = StringIO(initial_value="", newline="\n") + yaml.dump(self.to_jsonable(), io, sort_keys=False) + return io.getvalue() + + +class SchemaV2_6(BaseSchema): # noqa: N801 """A class to represent a schema. Attributes: @@ -31,9 +139,13 @@ class Schema(BaseModel): """ +<<<<<<< HEAD:faststream/specification/schema/schema.py +======= + asyncapi: AsyncAPIVersion = AsyncAPIVersion.v2_6 +>>>>>>> e2a839fc (Schema v3 and info v3):faststream/asyncapi/schema/main.py id: Optional[str] = None defaultContentType: Optional[str] = None - info: Info + info: InfoV2_6 servers: Optional[Dict[str, Server]] = None channels: Dict[str, Channel] components: Optional[Components] = None @@ -65,3 +177,57 @@ def to_yaml(self) -> str: io = StringIO(initial_value="", newline="\n") yaml.dump(self.to_jsonable(), io, sort_keys=False) return io.getvalue() + + +class SchemaV3_0(BaseSchema): # noqa: N801 + """A class to represent a schema. + + Attributes: + asyncapi : version of the async API + id : optional ID + defaultContentType : optional default content type + info : information about the schema + servers : optional dictionary of servers + channels : dictionary of channels + components : optional components of the schema + + Methods: + to_jsonable() -> Any: Convert the schema to a JSON-serializable object. + to_json() -> str: Convert the schema to a JSON string. + to_yaml() -> str: Convert the schema to a YAML string. + + """ + + asyncapi: AsyncAPIVersion = AsyncAPIVersion.v3_0 + id: Optional[str] = None + defaultContentType: Optional[str] = None + info: InfoV3_0 + servers: Optional[Dict[str, Server]] = None + channels: Dict[str, Channel] + components: Optional[Components] = None + + def to_jsonable(self) -> Any: + """Convert the schema to a JSON-serializable object.""" + return model_to_jsonable( + self, + by_alias=True, + exclude_none=True, + ) + + def to_json(self) -> str: + """Convert the schema to a JSON string.""" + return model_to_json( + self, + by_alias=True, + exclude_none=True, + ) + + def to_yaml(self) -> str: + """Convert the schema to a YAML string.""" + from io import StringIO + + import yaml + + io = StringIO(initial_value="", newline="\n") + yaml.dump(self.to_jsonable(), io, sort_keys=False) + return io.getvalue() From a06426dc5c452110866a9ff4a04879ea3f15ec41 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 28 Jul 2024 22:18:42 +0300 Subject: [PATCH 116/245] AsyncAPI rabbit naming test --- tests/asyncapi/base/v3_0_0/naming.py | 1 + tests/asyncapi/rabbit/v3_0_0/test_naming.py | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/asyncapi/base/v3_0_0/naming.py b/tests/asyncapi/base/v3_0_0/naming.py index 4202ee497e..69982e0d53 100644 --- a/tests/asyncapi/base/v3_0_0/naming.py +++ b/tests/asyncapi/base/v3_0_0/naming.py @@ -266,6 +266,7 @@ async def handle_user_created() -> create_model("SimpleModel"): ... assert list(schema["components"]["schemas"].keys()) == [ "SimpleModel", + ], list(schema["components"]["schemas"].keys()) def test_publisher_manual_naming(self): diff --git a/tests/asyncapi/rabbit/v3_0_0/test_naming.py b/tests/asyncapi/rabbit/v3_0_0/test_naming.py index f741041df2..af3731648a 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_naming.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_naming.py @@ -1,8 +1,13 @@ from typing import Type from faststream import FastStream +<<<<<<< HEAD from faststream.rabbit import RabbitBroker from faststream.specification.asyncapi.generate import get_app_schema +======= +from faststream.asyncapi.generate import get_app_schema +from faststream.rabbit import RabbitBroker +>>>>>>> d8eb3497 (AsyncAPI rabbit naming test) from tests.asyncapi.base.v3_0_0.naming import NamingTestCase @@ -123,4 +128,3 @@ async def handle(): ... }, }, } - ) From f7561cf24a4f970d02f4e46d0412d530912659c2 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 4 Aug 2024 13:12:50 +0300 Subject: [PATCH 117/245] AsyncAPI schemas refactoring --- faststream/asyncapi/generate.py | 26 --- faststream/asyncapi/schema/__init__.py | 73 ------- faststream/confluent/publisher/publisher.py | 7 +- faststream/confluent/subscriber/subscriber.py | 7 +- faststream/kafka/publisher/publisher.py | 7 +- faststream/kafka/subscriber/subscriber.py | 7 +- faststream/nats/publisher/publisher.py | 7 +- faststream/nats/subscriber/asyncapi.py | 111 +++++++++++ faststream/rabbit/publisher/publisher.py | 9 +- faststream/rabbit/subscriber/subscriber.py | 9 +- faststream/redis/publisher/publisher.py | 7 +- faststream/redis/subscriber/subscriber.py | 7 +- faststream/specification/schema/contact.py | 3 +- faststream/specification/schema/schema.py | 184 +----------------- 14 files changed, 153 insertions(+), 311 deletions(-) delete mode 100644 faststream/asyncapi/generate.py delete mode 100644 faststream/asyncapi/schema/__init__.py create mode 100644 faststream/nats/subscriber/asyncapi.py diff --git a/faststream/asyncapi/generate.py b/faststream/asyncapi/generate.py deleted file mode 100644 index 39cba02fcc..0000000000 --- a/faststream/asyncapi/generate.py +++ /dev/null @@ -1,26 +0,0 @@ -from typing import TYPE_CHECKING - -from faststream._compat import HAS_FASTAPI -from faststream.asyncapi.base import BaseSchema -from faststream.asyncapi.schema import ( - BaseSchema, -) -from faststream.asyncapi.v2_6_0.generate import get_app_schema as get_app_schema_v2_6 -from faststream.asyncapi.v3_0_0.generate import get_app_schema as get_app_schema_v3 -from faststream.asyncapi.version import AsyncAPIVersion - -if TYPE_CHECKING: - from faststream._compat import HAS_FASTAPI - - if HAS_FASTAPI: - pass - - -def get_app_schema(app: "AsyncAPIApplication") -> BaseSchema: - if app.asyncapi_version == AsyncAPIVersion.v3_0: - return get_app_schema_v3(app) - - if app.asyncapi_version == AsyncAPIVersion.v2_6: - return get_app_schema_v2_6(app) - - raise NotImplementedError(f"Async API version not supported: {app.asyncapi_version}") diff --git a/faststream/asyncapi/schema/__init__.py b/faststream/asyncapi/schema/__init__.py deleted file mode 100644 index 67bb38e49b..0000000000 --- a/faststream/asyncapi/schema/__init__.py +++ /dev/null @@ -1,73 +0,0 @@ -"""AsyncAPI schema related functions.""" - -from faststream.asyncapi.schema.bindings import ( - ChannelBinding, - OperationBinding, - ServerBinding, -) -from faststream.asyncapi.schema.channels import Channel -from faststream.asyncapi.schema.info import ( - BaseInfo, - Contact, - ContactDict, - InfoV2_6, - InfoV3_0, - License, - LicenseDict, -) -from faststream.asyncapi.schema.main import ( - BaseSchema, - Components, - SchemaV2_6, - SchemaV3_0, -) -from faststream.asyncapi.schema.message import CorrelationId, Message -from faststream.asyncapi.schema.operations import Operation -from faststream.asyncapi.schema.security import SecuritySchemaComponent -from faststream.asyncapi.schema.servers import Server -from faststream.asyncapi.schema.utils import ( - ExternalDocs, - ExternalDocsDict, - Reference, - Tag, - TagDict, -) -from faststream.asyncapi.version import AsyncAPIVersion - -__all__ = ( - # main - "AsyncAPIVersion", - "BaseSchema", - "SchemaV2_6", - "SchemaV3_0", - "Components", - # info - "BaseInfo", - "InfoV2_6", - "InfoV3_0", - "Contact", - "ContactDict", - "License", - "LicenseDict", - # servers - "Server", - # channels - "Channel", - # utils - "Tag", - "TagDict", - "ExternalDocs", - "ExternalDocsDict", - "Reference", - # bindings - "ServerBinding", - "ChannelBinding", - "OperationBinding", - # messages - "Message", - "CorrelationId", - # security - "SecuritySchemaComponent", - # subscription - "Operation", -) diff --git a/faststream/confluent/publisher/publisher.py b/faststream/confluent/publisher/publisher.py index 7be876ddf8..3eaebec7b5 100644 --- a/faststream/confluent/publisher/publisher.py +++ b/faststream/confluent/publisher/publisher.py @@ -19,6 +19,7 @@ LogicPublisher, ) from faststream.exceptions import SetupError +from faststream.specification.asyncapi.v2_6_0 import schema as v2_6_0 from faststream.specification.asyncapi.utils import resolve_payloads from faststream.specification.schema.bindings import ChannelBinding, kafka from faststream.specification.schema.channel import Channel @@ -37,13 +38,13 @@ class SpecificationPublisher(LogicPublisher[MsgType]): def get_name(self) -> str: return f"{self.topic}:Publisher" - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> Dict[str, v2_6_0.Channel]: payloads = self.get_payloads() return { - self.name: Channel( + self.name: v2_6_0.Channel( description=self.description, - publish=Operation( + publish=v2_6_0.Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads, "Publisher"), diff --git a/faststream/confluent/subscriber/subscriber.py b/faststream/confluent/subscriber/subscriber.py index b706a075bb..1c6a100acb 100644 --- a/faststream/confluent/subscriber/subscriber.py +++ b/faststream/confluent/subscriber/subscriber.py @@ -10,6 +10,7 @@ DefaultSubscriber, LogicSubscriber, ) +from faststream.specification.asyncapi.v2_6_0 import schema as v2_6_0 from faststream.specification.asyncapi.utils import resolve_payloads from faststream.specification.schema.bindings import ChannelBinding, kafka from faststream.specification.schema.channel import Channel @@ -26,16 +27,16 @@ class SpecificationSubscriber(LogicSubscriber[MsgType]): def get_name(self) -> str: return f'{",".join(self.topics)}:{self.call_name}' - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> Dict[str, v2_6_0.Channel]: channels = {} payloads = self.get_payloads() for t in self.topics: handler_name = self.title_ or f"{t}:{self.call_name}" - channels[handler_name] = Channel( + channels[handler_name] = v2_6_0.Channel( description=self.description, - subscribe=Operation( + subscribe=v2_6_0.Operation( message=Message( title=f"{handler_name}:Message", payload=resolve_payloads(payloads), diff --git a/faststream/kafka/publisher/publisher.py b/faststream/kafka/publisher/publisher.py index f6ac82a709..ed0a8fb9ec 100644 --- a/faststream/kafka/publisher/publisher.py +++ b/faststream/kafka/publisher/publisher.py @@ -21,6 +21,7 @@ ) from faststream.specification.asyncapi.utils import resolve_payloads from faststream.specification.schema.bindings import ChannelBinding, kafka +from faststream.specification.asyncapi.v2_6_0 import schema as v2_6_0 from faststream.specification.schema.channel import Channel from faststream.specification.schema.message import CorrelationId, Message from faststream.specification.schema.operation import Operation @@ -37,13 +38,13 @@ class SpecificationPublisher(LogicPublisher[MsgType]): def get_name(self) -> str: return f"{self.topic}:Publisher" - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> Dict[str, v2_6_0.Channel]: payloads = self.get_payloads() return { - self.name: Channel( + self.name: v2_6_0.Channel( description=self.description, - publish=Operation( + publish=v2_6_0.Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads, "Publisher"), diff --git a/faststream/kafka/subscriber/subscriber.py b/faststream/kafka/subscriber/subscriber.py index 8931fe14c9..b27247afd8 100644 --- a/faststream/kafka/subscriber/subscriber.py +++ b/faststream/kafka/subscriber/subscriber.py @@ -10,6 +10,7 @@ DefaultSubscriber, LogicSubscriber, ) +from faststream.specification.asyncapi.v2_6_0 import schema as v2_6_0 from faststream.specification.asyncapi.utils import resolve_payloads from faststream.specification.schema.bindings import ChannelBinding, kafka from faststream.specification.schema.channel import Channel @@ -26,7 +27,7 @@ class SpecificationSubscriber(LogicSubscriber[MsgType]): def get_name(self) -> str: return f'{",".join(self.topics)}:{self.call_name}' - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> Dict[str, v2_6_0.Channel]: channels = {} payloads = self.get_payloads() @@ -34,9 +35,9 @@ def get_schema(self) -> Dict[str, Channel]: for t in self.topics: handler_name = self.title_ or f"{t}:{self.call_name}" - channels[handler_name] = Channel( + channels[handler_name] = v2_6_0.Channel( description=self.description, - subscribe=Operation( + subscribe=v2_6_0.Operation( message=Message( title=f"{handler_name}:Message", payload=resolve_payloads(payloads), diff --git a/faststream/nats/publisher/publisher.py b/faststream/nats/publisher/publisher.py index f86c12e142..b430c939cf 100644 --- a/faststream/nats/publisher/publisher.py +++ b/faststream/nats/publisher/publisher.py @@ -5,6 +5,7 @@ from faststream.nats.publisher.usecase import LogicPublisher from faststream.specification.asyncapi.utils import resolve_payloads from faststream.specification.schema.bindings import ChannelBinding, nats +from faststream.specification.asyncapi.v2_6_0 import schema as v2_6_0 from faststream.specification.schema.channel import Channel from faststream.specification.schema.message import CorrelationId, Message from faststream.specification.schema.operation import Operation @@ -22,13 +23,13 @@ class SpecificationPublisher(LogicPublisher): def get_name(self) -> str: return f"{self.subject}:Publisher" - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> Dict[str, v2_6_0.Channel]: payloads = self.get_payloads() return { - self.name: Channel( + self.name: v2_6_0.Channel( description=self.description, - publish=Operation( + publish=v2_6_0.Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads, "Publisher"), diff --git a/faststream/nats/subscriber/asyncapi.py b/faststream/nats/subscriber/asyncapi.py new file mode 100644 index 0000000000..557f16ad9f --- /dev/null +++ b/faststream/nats/subscriber/asyncapi.py @@ -0,0 +1,111 @@ +from typing import Any, Dict + +from typing_extensions import override + +from faststream.asyncapi.schema import ( + ChannelBinding, + CorrelationId, + Message, + v2_6_0, +) +from faststream.asyncapi.schema.bindings import nats +from faststream.asyncapi.utils import resolve_payloads +from faststream.nats.subscriber.usecase import ( + BatchPullStreamSubscriber, + ConcurrentCoreSubscriber, + ConcurrentPullStreamSubscriber, + ConcurrentPushStreamSubscriber, + CoreSubscriber, + KeyValueWatchSubscriber, + LogicSubscriber, + ObjStoreWatchSubscriber, + PullStreamSubscriber, + PushStreamSubscription, +) + + +class AsyncAPISubscriber(LogicSubscriber[Any]): + """A class to represent a NATS handler.""" + + def get_name(self) -> str: + return f"{self.subject}:{self.call_name}" + + def get_schema(self) -> Dict[str, v2_6_0.Channel]: + payloads = self.get_payloads() + + return { + self.name: v2_6_0.Channel( + description=self.description, + subscribe=v2_6_0.Operation( + message=Message( + title=f"{self.name}:Message", + payload=resolve_payloads(payloads), + correlationId=CorrelationId( + location="$message.header#/correlation_id" + ), + ), + ), + bindings=ChannelBinding( + nats=nats.ChannelBinding( + subject=self.subject, + queue=getattr(self, "queue", "") or None, + ) + ), + ) + } + + +class AsyncAPICoreSubscriber(AsyncAPISubscriber, CoreSubscriber): + """One-message core consumer with AsyncAPI methods.""" + + +class AsyncAPIConcurrentCoreSubscriber(AsyncAPISubscriber, ConcurrentCoreSubscriber): + """One-message core concurrent consumer with AsyncAPI methods.""" + + +class AsyncAPIStreamSubscriber(AsyncAPISubscriber, PushStreamSubscription): + """One-message JS Push consumer with AsyncAPI methods.""" + + +class AsyncAPIConcurrentPushStreamSubscriber( + AsyncAPISubscriber, ConcurrentPushStreamSubscriber +): + """One-message JS Push concurrent consumer with AsyncAPI methods.""" + + +class AsyncAPIPullStreamSubscriber(AsyncAPISubscriber, PullStreamSubscriber): + """One-message JS Pull consumer with AsyncAPI methods.""" + + +class AsyncAPIConcurrentPullStreamSubscriber( + AsyncAPISubscriber, ConcurrentPullStreamSubscriber +): + """One-message JS Pull concurrent consumer with AsyncAPI methods.""" + + +class AsyncAPIBatchPullStreamSubscriber(AsyncAPISubscriber, BatchPullStreamSubscriber): + """Batch-message Pull consumer with AsyncAPI methods.""" + + +class AsyncAPIKeyValueWatchSubscriber(AsyncAPISubscriber, KeyValueWatchSubscriber): + """KeyValueWatch consumer with AsyncAPI methods.""" + + @override + def get_name(self) -> str: + return "" + + @override + def get_schema(self) -> Dict[str, v2_6_0.Channel]: + return {} + + +class AsyncAPIObjStoreWatchSubscriber(AsyncAPISubscriber, ObjStoreWatchSubscriber): + """ObjStoreWatch consumer with AsyncAPI methods.""" + + @override + def get_name(self) -> str: + return "" + + @override + def get_schema(self) -> Dict[str, v2_6_0.Channel]: + return {} diff --git a/faststream/rabbit/publisher/publisher.py b/faststream/rabbit/publisher/publisher.py index b6e2f922aa..4821f1066c 100644 --- a/faststream/rabbit/publisher/publisher.py +++ b/faststream/rabbit/publisher/publisher.py @@ -2,6 +2,7 @@ from typing_extensions import override +from faststream.specification.asyncapi.v2_6_0 import schema as v2_6_0 from faststream.rabbit.publisher.usecase import LogicPublisher, PublishKwargs from faststream.rabbit.utils import is_routing_exchange from faststream.specification.asyncapi.utils import resolve_payloads @@ -42,13 +43,13 @@ def get_name(self) -> str: return f"{routing}:{getattr(self.exchange, 'name', None) or '_'}:Publisher" - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> Dict[str, v2_6_0.Channel]: payloads = self.get_payloads() return { - self.name: Channel( - description=self.description, - publish=Operation( + self.name: v2_6_0.Channel( + description=self.description, # type: ignore[attr-defined] + publish=v2_6_0.Operation( bindings=OperationBinding( amqp=amqp.OperationBinding( cc=self.routing or None, diff --git a/faststream/rabbit/subscriber/subscriber.py b/faststream/rabbit/subscriber/subscriber.py index 5ed253a8e2..6f8d835c4c 100644 --- a/faststream/rabbit/subscriber/subscriber.py +++ b/faststream/rabbit/subscriber/subscriber.py @@ -1,5 +1,6 @@ from typing import Dict +from faststream.specification.asyncapi.v2_6_0 import schema as v2_6_0 from faststream.rabbit.subscriber.usecase import LogicSubscriber from faststream.rabbit.utils import is_routing_exchange from faststream.specification.asyncapi.utils import resolve_payloads @@ -19,13 +20,13 @@ class SpecificationSubscriber(LogicSubscriber): def get_name(self) -> str: return f"{self.queue.name}:{getattr(self.exchange, 'name', None) or '_'}:{self.call_name}" - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> Dict[str, v2_6_0.Channel]: payloads = self.get_payloads() return { - self.name: Channel( - description=self.description, - subscribe=Operation( + self.name: v2_6_0.Channel( + description=self.description, # type: ignore[attr-defined] + subscribe=v2_6_0.Operation( bindings=OperationBinding( amqp=amqp.OperationBinding( cc=self.queue.routing, diff --git a/faststream/redis/publisher/publisher.py b/faststream/redis/publisher/publisher.py index 759308872e..ff74f7c921 100644 --- a/faststream/redis/publisher/publisher.py +++ b/faststream/redis/publisher/publisher.py @@ -2,6 +2,7 @@ from typing_extensions import TypeAlias, override +from faststream.specification.asyncapi.v2_6_0 import schema as v2_6_0 from faststream.exceptions import SetupError from faststream.redis.publisher.usecase import ( ChannelPublisher, @@ -34,13 +35,13 @@ class SpecificationPublisher(LogicPublisher, RedisAsyncAPIProtocol): """A class to represent a Redis publisher.""" - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> Dict[str, v2_6_0.Channel]: payloads = self.get_payloads() return { - self.name: Channel( + self.name: v2_6_0.Channel( description=self.description, - publish=Operation( + publish=v2_6_0.Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads, "Publisher"), diff --git a/faststream/redis/subscriber/subscriber.py b/faststream/redis/subscriber/subscriber.py index 54a9b57578..078b0283b3 100644 --- a/faststream/redis/subscriber/subscriber.py +++ b/faststream/redis/subscriber/subscriber.py @@ -1,5 +1,6 @@ from typing import Dict +from faststream.specification.asyncapi.v2_6_0 import schema as v2_6_0 from faststream.redis.schemas import ListSub, StreamSub from faststream.redis.schemas.proto import RedisAsyncAPIProtocol from faststream.redis.subscriber.usecase import ( @@ -20,13 +21,13 @@ class SpecificationSubscriber(LogicSubscriber, RedisAsyncAPIProtocol): """A class to represent a Redis handler.""" - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> Dict[str, v2_6_0.Channel]: payloads = self.get_payloads() return { - self.name: Channel( + self.name: v2_6_0.Channel( description=self.description, - subscribe=Operation( + subscribe=v2_6_0.Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads), diff --git a/faststream/specification/schema/contact.py b/faststream/specification/schema/contact.py index 89f9fbbd54..c0b43be7c4 100644 --- a/faststream/specification/schema/contact.py +++ b/faststream/specification/schema/contact.py @@ -3,8 +3,7 @@ Callable, Iterable, Optional, - Type - + Type, ) from pydantic import AnyHttpUrl, BaseModel diff --git a/faststream/specification/schema/schema.py b/faststream/specification/schema/schema.py index 190af45fad..89a6b486bf 100644 --- a/faststream/specification/schema/schema.py +++ b/faststream/specification/schema/schema.py @@ -1,80 +1,16 @@ -from typing import Any, Dict, List, Optional, Union +from typing import Any from pydantic import BaseModel -<<<<<<< HEAD:faststream/specification/schema/schema.py from faststream._compat import model_to_json, model_to_jsonable +from faststream.specification.asyncapi.base.schema import BaseInfo from faststream.specification.schema.channel import Channel from faststream.specification.schema.components import Components from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict from faststream.specification.schema.info import Info from faststream.specification.schema.servers import Server from faststream.specification.schema.tag import Tag -======= -from faststream._compat import PYDANTIC_V2, model_to_json, model_to_jsonable -from faststream.asyncapi.schema.channels import Channel -from faststream.asyncapi.schema.info import BaseInfo, InfoV2_6, InfoV3_0 -from faststream.asyncapi.schema.message import Message -from faststream.asyncapi.schema.servers import Server -from faststream.asyncapi.schema.utils import ( - ExternalDocs, - ExternalDocsDict, - Tag, - TagDict, -) -from faststream.asyncapi.version import AsyncAPIVersion - -ASYNC_API_VERSION = "2.6.0" - - -class Components(BaseModel): - # TODO - # servers - # serverVariables - # channels - """A class to represent components in a system. - - Attributes: - messages : Optional dictionary of messages - schemas : Optional dictionary of schemas - - Note: - The following attributes are not implemented yet: - - servers - - serverVariables - - channels - - securitySchemes - - parameters - - correlationIds - - operationTraits - - messageTraits - - serverBindings - - channelBindings - - operationBindings - - messageBindings - - """ - - messages: Optional[Dict[str, Message]] = None - schemas: Optional[Dict[str, Dict[str, Any]]] = None - securitySchemes: Optional[Dict[str, Dict[str, Any]]] = None - # parameters - # correlationIds - # operationTraits - # messageTraits - # serverBindings - # channelBindings - # operationBindings - # messageBindings - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" ->>>>>>> e2a839fc (Schema v3 and info v3):faststream/asyncapi/schema/main.py +from faststream._compat import model_to_json, model_to_jsonable class BaseSchema(BaseModel): @@ -117,117 +53,3 @@ def to_yaml(self) -> str: io = StringIO(initial_value="", newline="\n") yaml.dump(self.to_jsonable(), io, sort_keys=False) return io.getvalue() - - -class SchemaV2_6(BaseSchema): # noqa: N801 - """A class to represent a schema. - - Attributes: - id : optional ID - defaultContentType : optional default content type - info : information about the schema - servers : optional dictionary of servers - channels : dictionary of channels - components : optional components of the schema - tags : optional list of tags - externalDocs : optional external documentation - - Methods: - to_jsonable() -> Any: Convert the schema to a JSON-serializable object. - to_json() -> str: Convert the schema to a JSON string. - to_yaml() -> str: Convert the schema to a YAML string. - - """ - -<<<<<<< HEAD:faststream/specification/schema/schema.py -======= - asyncapi: AsyncAPIVersion = AsyncAPIVersion.v2_6 ->>>>>>> e2a839fc (Schema v3 and info v3):faststream/asyncapi/schema/main.py - id: Optional[str] = None - defaultContentType: Optional[str] = None - info: InfoV2_6 - servers: Optional[Dict[str, Server]] = None - channels: Dict[str, Channel] - components: Optional[Components] = None - tags: Optional[List[Union[Tag, Dict[str, Any]]]] = None - externalDocs: Optional[Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]] = None - - def to_jsonable(self) -> Any: - """Convert the schema to a JSON-serializable object.""" - return model_to_jsonable( - self, - by_alias=True, - exclude_none=True, - ) - - def to_json(self) -> str: - """Convert the schema to a JSON string.""" - return model_to_json( - self, - by_alias=True, - exclude_none=True, - ) - - def to_yaml(self) -> str: - """Convert the schema to a YAML string.""" - from io import StringIO - - import yaml - - io = StringIO(initial_value="", newline="\n") - yaml.dump(self.to_jsonable(), io, sort_keys=False) - return io.getvalue() - - -class SchemaV3_0(BaseSchema): # noqa: N801 - """A class to represent a schema. - - Attributes: - asyncapi : version of the async API - id : optional ID - defaultContentType : optional default content type - info : information about the schema - servers : optional dictionary of servers - channels : dictionary of channels - components : optional components of the schema - - Methods: - to_jsonable() -> Any: Convert the schema to a JSON-serializable object. - to_json() -> str: Convert the schema to a JSON string. - to_yaml() -> str: Convert the schema to a YAML string. - - """ - - asyncapi: AsyncAPIVersion = AsyncAPIVersion.v3_0 - id: Optional[str] = None - defaultContentType: Optional[str] = None - info: InfoV3_0 - servers: Optional[Dict[str, Server]] = None - channels: Dict[str, Channel] - components: Optional[Components] = None - - def to_jsonable(self) -> Any: - """Convert the schema to a JSON-serializable object.""" - return model_to_jsonable( - self, - by_alias=True, - exclude_none=True, - ) - - def to_json(self) -> str: - """Convert the schema to a JSON string.""" - return model_to_json( - self, - by_alias=True, - exclude_none=True, - ) - - def to_yaml(self) -> str: - """Convert the schema to a YAML string.""" - from io import StringIO - - import yaml - - io = StringIO(initial_value="", newline="\n") - yaml.dump(self.to_jsonable(), io, sort_keys=False) - return io.getvalue() From 5b46c8edc7270dc6ae5ca7135789aad4cd4b6e18 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Thu, 8 Aug 2024 22:00:29 +0300 Subject: [PATCH 118/245] AsyncAPI generation refactoring --- faststream/asyncapi/base/__init__.py | 7 + faststream/asyncapi/base/info.py | 28 ++ faststream/asyncapi/v2_6_0/__init__.py | 7 + .../v2_6_0/schema/bindings/__init__.py | 11 + .../asyncapi/v2_6_0/schema/bindings/main.py | 91 +++++ faststream/asyncapi/v2_6_0/schema/channels.py | 41 +++ .../asyncapi/v2_6_0/schema/operations.py | 54 +++ faststream/asyncapi/v2_6_0/schema/schema.py | 73 ++++ faststream/asyncapi/v3_0_0/__init__.py | 7 + faststream/asyncapi/v3_0_0/generate.py | 339 ++++++++++++++++++ faststream/asyncapi/v3_0_0/schema/channels.py | 40 +++ .../asyncapi/v3_0_0/schema/operations.py | 54 +++ faststream/nats/subscriber/asyncapi.py | 8 - faststream/redis/schemas/proto.py | 4 + .../asyncapi/base/schema/schema.py | 4 + .../asyncapi/v2_6_0/schema/servers.py | 26 +- .../asyncapi/v3_0_0/schema/__init__.py | 21 +- .../asyncapi/rabbit/v2_6_0/test_connection.py | 5 + tests/asyncapi/rabbit/v3_0_0/test_naming.py | 5 - 19 files changed, 785 insertions(+), 40 deletions(-) create mode 100644 faststream/asyncapi/base/__init__.py create mode 100644 faststream/asyncapi/base/info.py create mode 100644 faststream/asyncapi/v2_6_0/__init__.py create mode 100644 faststream/asyncapi/v2_6_0/schema/bindings/__init__.py create mode 100644 faststream/asyncapi/v2_6_0/schema/bindings/main.py create mode 100644 faststream/asyncapi/v2_6_0/schema/channels.py create mode 100644 faststream/asyncapi/v2_6_0/schema/operations.py create mode 100644 faststream/asyncapi/v2_6_0/schema/schema.py create mode 100644 faststream/asyncapi/v3_0_0/__init__.py create mode 100644 faststream/asyncapi/v3_0_0/generate.py create mode 100644 faststream/asyncapi/v3_0_0/schema/channels.py create mode 100644 faststream/asyncapi/v3_0_0/schema/operations.py diff --git a/faststream/asyncapi/base/__init__.py b/faststream/asyncapi/base/__init__.py new file mode 100644 index 0000000000..9164dc3039 --- /dev/null +++ b/faststream/asyncapi/base/__init__.py @@ -0,0 +1,7 @@ +from .info import BaseInfo +from .schema import BaseSchema + +__all__ = ( + "BaseInfo", + "BaseSchema", +) diff --git a/faststream/asyncapi/base/info.py b/faststream/asyncapi/base/info.py new file mode 100644 index 0000000000..6472de4334 --- /dev/null +++ b/faststream/asyncapi/base/info.py @@ -0,0 +1,28 @@ +from pydantic import BaseModel + +from faststream._compat import ( + PYDANTIC_V2, +) + + +class BaseInfo(BaseModel): + """A class to represent information. + + Attributes: + title : title of the information + version : version of the information (default: "1.0.0") + description : description of the information (default: "") + + """ + + title: str + version: str = "1.0.0" + description: str = "" + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" diff --git a/faststream/asyncapi/v2_6_0/__init__.py b/faststream/asyncapi/v2_6_0/__init__.py new file mode 100644 index 0000000000..be8f2c412c --- /dev/null +++ b/faststream/asyncapi/v2_6_0/__init__.py @@ -0,0 +1,7 @@ +from . import schema +from .generate import get_app_schema + +__all__ = ( + "schema", + "get_app_schema", +) diff --git a/faststream/asyncapi/v2_6_0/schema/bindings/__init__.py b/faststream/asyncapi/v2_6_0/schema/bindings/__init__.py new file mode 100644 index 0000000000..39ce4b993c --- /dev/null +++ b/faststream/asyncapi/v2_6_0/schema/bindings/__init__.py @@ -0,0 +1,11 @@ +from .main import ( + ChannelBinding, + OperationBinding, + ServerBinding, +) + +__all__ = ( + "ServerBinding", + "ChannelBinding", + "OperationBinding", +) diff --git a/faststream/asyncapi/v2_6_0/schema/bindings/main.py b/faststream/asyncapi/v2_6_0/schema/bindings/main.py new file mode 100644 index 0000000000..0cd5c7abfb --- /dev/null +++ b/faststream/asyncapi/v2_6_0/schema/bindings/main.py @@ -0,0 +1,91 @@ +from typing import Optional + +from pydantic import BaseModel + +from faststream._compat import PYDANTIC_V2 +from faststream.asyncapi.v2_6_0.schema.bindings import amqp as amqp_bindings +from faststream.asyncapi.v2_6_0.schema.bindings import kafka as kafka_bindings +from faststream.asyncapi.v2_6_0.schema.bindings import nats as nats_bindings +from faststream.asyncapi.v2_6_0.schema.bindings import redis as redis_bindings +from faststream.asyncapi.v2_6_0.schema.bindings import sqs as sqs_bindings + + +class ServerBinding(BaseModel): + """A class to represent server bindings. + + Attributes: + amqp : AMQP server binding (optional) + kafka : Kafka server binding (optional) + sqs : SQS server binding (optional) + nats : NATS server binding (optional) + redis : Redis server binding (optional) + + """ + + amqp: Optional[amqp_bindings.ServerBinding] = None + kafka: Optional[kafka_bindings.ServerBinding] = None + sqs: Optional[sqs_bindings.ServerBinding] = None + nats: Optional[nats_bindings.ServerBinding] = None + redis: Optional[redis_bindings.ServerBinding] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" + + +class ChannelBinding(BaseModel): + """A class to represent channel bindings. + + Attributes: + amqp : AMQP channel binding (optional) + kafka : Kafka channel binding (optional) + sqs : SQS channel binding (optional) + nats : NATS channel binding (optional) + redis : Redis channel binding (optional) + + """ + + amqp: Optional[amqp_bindings.ChannelBinding] = None + kafka: Optional[kafka_bindings.ChannelBinding] = None + sqs: Optional[sqs_bindings.ChannelBinding] = None + nats: Optional[nats_bindings.ChannelBinding] = None + redis: Optional[redis_bindings.ChannelBinding] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" + + +class OperationBinding(BaseModel): + """A class to represent an operation binding. + + Attributes: + amqp : AMQP operation binding (optional) + kafka : Kafka operation binding (optional) + sqs : SQS operation binding (optional) + nats : NATS operation binding (optional) + redis : Redis operation binding (optional) + + """ + + amqp: Optional[amqp_bindings.OperationBinding] = None + kafka: Optional[kafka_bindings.OperationBinding] = None + sqs: Optional[sqs_bindings.OperationBinding] = None + nats: Optional[nats_bindings.OperationBinding] = None + redis: Optional[redis_bindings.OperationBinding] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" diff --git a/faststream/asyncapi/v2_6_0/schema/channels.py b/faststream/asyncapi/v2_6_0/schema/channels.py new file mode 100644 index 0000000000..0c8af7e74a --- /dev/null +++ b/faststream/asyncapi/v2_6_0/schema/channels.py @@ -0,0 +1,41 @@ +from typing import List, Optional + +from pydantic import BaseModel + +from faststream._compat import PYDANTIC_V2 +from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding +from faststream.asyncapi.v2_6_0.schema.operations import Operation +from faststream.asyncapi.v2_6_0.schema.utils import Parameter + + +class Channel(BaseModel): + """A class to represent a channel. + + Attributes: + description : optional description of the channel + servers : optional list of servers associated with the channel + bindings : optional channel binding + subscribe : optional operation for subscribing to the channel + publish : optional operation for publishing to the channel + parameters : optional parameters associated with the channel + + Configurations: + model_config : configuration for the model (only applicable for Pydantic version 2) + Config : configuration for the class (only applicable for Pydantic version 1) + + """ + + description: Optional[str] = None + servers: Optional[List[str]] = None + bindings: Optional[ChannelBinding] = None + subscribe: Optional[Operation] = None + publish: Optional[Operation] = None + parameters: Optional[Parameter] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" diff --git a/faststream/asyncapi/v2_6_0/schema/operations.py b/faststream/asyncapi/v2_6_0/schema/operations.py new file mode 100644 index 0000000000..54a2a2ac71 --- /dev/null +++ b/faststream/asyncapi/v2_6_0/schema/operations.py @@ -0,0 +1,54 @@ +from typing import Any, Dict, List, Optional, Union + +from pydantic import BaseModel + +from faststream._compat import PYDANTIC_V2 +from faststream.asyncapi.v2_6_0.schema.bindings import OperationBinding +from faststream.asyncapi.v2_6_0.schema.message import Message +from faststream.asyncapi.v2_6_0.schema.utils import ( + ExternalDocs, + ExternalDocsDict, + Reference, + Tag, + TagDict, +) + + +class Operation(BaseModel): + """A class to represent an operation. + + Attributes: + operationId : ID of the operation + summary : summary of the operation + description : description of the operation + bindings : bindings of the operation + message : message of the operation + security : security details of the operation + tags : tags associated with the operation + externalDocs : external documentation for the operation + + """ + + operationId: Optional[str] = None + summary: Optional[str] = None + description: Optional[str] = None + + bindings: Optional[OperationBinding] = None + + message: Union[Message, Reference] + + security: Optional[Dict[str, List[str]]] = None + + # TODO + # traits + + tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = None + externalDocs: Optional[Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" diff --git a/faststream/asyncapi/v2_6_0/schema/schema.py b/faststream/asyncapi/v2_6_0/schema/schema.py new file mode 100644 index 0000000000..143ed74288 --- /dev/null +++ b/faststream/asyncapi/v2_6_0/schema/schema.py @@ -0,0 +1,73 @@ +from typing import Any, Dict, List, Optional, Union + +from faststream._compat import model_to_json, model_to_jsonable +from faststream.asyncapi.base import BaseSchema +from faststream.asyncapi.v2_6_0.schema.channels import Channel +from faststream.asyncapi.v2_6_0.schema.components import Components +from faststream.asyncapi.v2_6_0.schema.info import Info +from faststream.asyncapi.v2_6_0.schema.servers import Server +from faststream.asyncapi.v2_6_0.schema.utils import ( + ExternalDocs, + ExternalDocsDict, + Tag, + TagDict, +) +from faststream.asyncapi.version import AsyncAPIVersion + + +class Schema(BaseSchema): + """A class to represent a schema. + + Attributes: + asyncapi : version of the async API + id : optional ID + defaultContentType : optional default content type + info : information about the schema + servers : optional dictionary of servers + channels : dictionary of channels + components : optional components of the schema + tags : optional list of tags + externalDocs : optional external documentation + + Methods: + to_jsonable() -> Any: Convert the schema to a JSON-serializable object. + to_json() -> str: Convert the schema to a JSON string. + to_yaml() -> str: Convert the schema to a YAML string. + + """ + + asyncapi: AsyncAPIVersion = AsyncAPIVersion.v2_6 + id: Optional[str] = None + defaultContentType: Optional[str] = None + info: Info + servers: Optional[Dict[str, Server]] = None + channels: Dict[str, Channel] + components: Optional[Components] = None + tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = None + externalDocs: Optional[Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]] = None + + def to_jsonable(self) -> Any: + """Convert the schema to a JSON-serializable object.""" + return model_to_jsonable( + self, + by_alias=True, + exclude_none=True, + ) + + def to_json(self) -> str: + """Convert the schema to a JSON string.""" + return model_to_json( + self, + by_alias=True, + exclude_none=True, + ) + + def to_yaml(self) -> str: + """Convert the schema to a YAML string.""" + from io import StringIO + + import yaml + + io = StringIO(initial_value="", newline="\n") + yaml.dump(self.to_jsonable(), io, sort_keys=False) + return io.getvalue() diff --git a/faststream/asyncapi/v3_0_0/__init__.py b/faststream/asyncapi/v3_0_0/__init__.py new file mode 100644 index 0000000000..be8f2c412c --- /dev/null +++ b/faststream/asyncapi/v3_0_0/__init__.py @@ -0,0 +1,7 @@ +from . import schema +from .generate import get_app_schema + +__all__ = ( + "schema", + "get_app_schema", +) diff --git a/faststream/asyncapi/v3_0_0/generate.py b/faststream/asyncapi/v3_0_0/generate.py new file mode 100644 index 0000000000..6fd587225c --- /dev/null +++ b/faststream/asyncapi/v3_0_0/generate.py @@ -0,0 +1,339 @@ +from typing import TYPE_CHECKING, Any, Dict, List, Union +from urllib.parse import urlparse + +from faststream._compat import DEF_KEY, HAS_FASTAPI +from faststream.asyncapi.v2_6_0.schema import Reference +from faststream.asyncapi.v2_6_0.schema.message import Message +from faststream.asyncapi.v3_0_0.schema import ( + Channel, + Components, + Info, + Operation, + Schema, + Server, +) +from faststream.constants import ContentTypes + +if TYPE_CHECKING: + from faststream.app import FastStream + from faststream.broker.core.usecase import BrokerUsecase + from faststream.broker.types import ConnectionType, MsgType + + if HAS_FASTAPI: + from faststream.broker.fastapi.router import StreamRouter + + +def get_app_schema(app: Union["FastStream", "StreamRouter[Any]"]) -> Schema: + """Get the application schema.""" + broker = app.broker + if broker is None: # pragma: no cover + raise RuntimeError() + broker.setup() + + servers = get_broker_server(broker) + channels = get_broker_channels(broker) + operations = get_broker_operations(broker) + + messages: Dict[str, Message] = {} + payloads: Dict[str, Dict[str, Any]] = {} + + for channel_name, channel in channels.items(): + msgs: Dict[str, Union[Message, Reference]] = {} + for message_name, message in channel.messages.items(): + assert isinstance(message, Message) + + msgs[message_name] = _resolve_msg_payloads( + message_name, + message, + channel_name, + payloads, + messages + ) + + channel.messages = msgs + + channel.servers = [{"$ref": f"#/servers/{server_name}"} for server_name in list(servers.keys())] + + schema = Schema( + info=Info( + title=app.title, + version=app.version, + description=app.description, + termsOfService=app.terms_of_service, + contact=app.contact, + license=app.license, + tags=list(app.asyncapi_tags) if app.asyncapi_tags else None, + externalDocs=app.external_docs, + ), + defaultContentType=ContentTypes.json.value, + id=app.identifier, + servers=servers, + channels=channels, + operations=operations, + components=Components( + messages=messages, + schemas=payloads, + securitySchemes=None + if broker.security is None + else broker.security.get_schema(), + ), + ) + return schema + + +def get_broker_server( + broker: "BrokerUsecase[MsgType, ConnectionType]", +) -> Dict[str, Server]: + """Get the broker server for an application.""" + servers = {} + + broker_meta: Dict[str, Any] = { + "protocol": broker.protocol, + "protocolVersion": broker.protocol_version, + "description": broker.description, + "tags": broker.tags, + # TODO + # "variables": "", + # "bindings": "", + } + + if broker.security is not None: + broker_meta["security"] = broker.security.get_requirement() + + if isinstance(broker.url, str): + broker_url = broker.url + if "://" not in broker_url: + broker_url = "//" + broker_url + + url = urlparse(broker_url) + servers["development"] = Server( + host=url.netloc, + pathname=url.path, + **broker_meta, + ) + + elif len(broker.url) == 1: + broker_url = broker.url[0] + if "://" not in broker_url: + broker_url = "//" + broker_url + + url = urlparse(broker_url) + servers["development"] = Server( + host=url.netloc, + pathname=url.path, + **broker_meta, + ) + + else: + for i, broker_url in enumerate(broker.url, 1): + if "://" not in broker_url: + broker_url = "//" + broker_url + + parsed_url = urlparse(broker_url) + servers[f"Server{i}"] = Server( + host=parsed_url.netloc, + pathname=parsed_url.path, + **broker_meta, + ) + + return servers + + +def get_broker_operations( + broker: "BrokerUsecase[MsgType, ConnectionType]", +) -> Dict[str, Operation]: + """Get the broker operations for an application.""" + operations = {} + + for h in broker._subscribers.values(): + for channel_name, channel_2_6 in h.schema().items(): + if channel_2_6.subscribe is not None: + op = Operation( + action="receive", + summary=channel_2_6.subscribe.summary, + description=channel_2_6.subscribe.description, + bindings=channel_2_6.subscribe.bindings, + messages=[ + Reference( + **{"$ref": f"#/channels/{channel_name}/messages/SubscribeMessage"}, + ) + ], + channel=Reference( + **{"$ref": f"#/channels/{channel_name}"}, + ), + security=channel_2_6.subscribe.security, + ) + operations[f"{channel_name}Subscribe"] = op + + elif channel_2_6.publish is not None: + op = Operation( + action="send", + summary=channel_2_6.publish.summary, + description=channel_2_6.publish.description, + bindings=channel_2_6.publish.bindings, + messages=[ + Reference( + **{"$ref": f"#/channels/{channel_name}/messages/Message"}, + )] + , + channel=Reference( + **{"$ref": f"#/channels/{channel_name}"}, + ), + security=channel_2_6.publish.bindings, + ) + operations[f"{channel_name}"] = op + + for p in broker._publishers.values(): + for channel_name, channel_2_6 in p.schema().items(): + if channel_2_6.subscribe is not None: + op = Operation( + action="send", + summary=channel_2_6.subscribe.summary, + description=channel_2_6.subscribe.description, + bindings=channel_2_6.subscribe.bindings, + messages=[ + Reference( + **{"$ref": f"#/channels/{channel_name}/messages/SubscribeMessage"}, + ) + ], + channel=Reference( + **{"$ref": f"#/channels/{channel_name}"}, + ), + security=channel_2_6.subscribe.security, + ) + operations[f"{channel_name}Subscribe"] = op + + elif channel_2_6.publish is not None: + op = Operation( + action="send", + summary=channel_2_6.publish.summary, + description=channel_2_6.publish.description, + bindings=channel_2_6.publish.bindings, + messages=[ + Reference( + **{"$ref": f"#/channels/{channel_name}/messages/Message"}, + ) + ], + channel=Reference( + **{"$ref": f"#/channels/{channel_name}"}, + ), + security=channel_2_6.publish.security, + ) + operations[f"{channel_name}"] = op + + return operations + + +def get_broker_channels( + broker: "BrokerUsecase[MsgType, ConnectionType]", +) -> Dict[str, Channel]: + """Get the broker channels for an application.""" + channels = {} + + for h in broker._subscribers.values(): + channels_schema_v3_0 = {} + for channel_name, channel_v2_6 in h.schema().items(): + if channel_v2_6.subscribe: + channel_v3_0 = Channel( + address=channel_name, + messages={ + "SubscribeMessage": channel_v2_6.subscribe.message, + }, + description=channel_v2_6.description, + servers=channel_v2_6.servers, + bindings=channel_v2_6.bindings, + parameters=channel_v2_6.parameters + ) + + channels_schema_v3_0[channel_name] = channel_v3_0 + + channels.update(channels_schema_v3_0) + + for p in broker._publishers.values(): + channels_schema_v3_0 = {} + for channel_name, channel_v2_6 in p.schema().items(): + if channel_v2_6.publish: + channel_v3_0 = Channel( + address=channel_name, + messages={ + "Message": channel_v2_6.publish.message, + }, + description=channel_v2_6.description, + servers=channel_v2_6.servers, + bindings=channel_v2_6.bindings, + parameters=channel_v2_6.parameters + ) + + channels_schema_v3_0[channel_name] = channel_v3_0 + + channels.update(channels_schema_v3_0) + + return channels + + +def _resolve_msg_payloads( + message_name: str, + m: Message, + channel_name: str, + payloads: Dict[str, Any], + messages: Dict[str, Any], +) -> Reference: + assert isinstance(m.payload, dict) + + m.payload = _move_pydantic_refs(m.payload, DEF_KEY) + if DEF_KEY in m.payload: + payloads.update(m.payload.pop(DEF_KEY)) + + one_of = m.payload.get("oneOf", None) + if isinstance(one_of, dict): + one_of_list = [] + p: Dict[str, Dict[str, Any]] = {} + for name, payload in one_of.items(): + payloads.update(p.pop(DEF_KEY, {})) + p[name] = payload + one_of_list.append(Reference(**{"$ref": f"#/components/schemas/{name}"})) + + payloads.update(p) + m.payload["oneOf"] = one_of_list + assert m.title + messages[m.title] = m + return Reference(**{"$ref": f"#/components/messages/{channel_name}:{message_name}"}) + + else: + payloads.update(m.payload.pop(DEF_KEY, {})) + payload_name = m.payload.get("title", f"{channel_name}:{message_name}:Payload") + payloads[payload_name] = m.payload + m.payload = {"$ref": f"#/components/schemas/{payload_name}"} + assert m.title + messages[m.title] = m + return Reference(**{"$ref": f"#/components/messages/{channel_name}:{message_name}"}) + + +def _move_pydantic_refs( + original: Any, + key: str, +) -> Any: + """Remove pydantic references and replace them by real schemas.""" + if not isinstance(original, Dict): + return original + + data = original.copy() + + for k in data: + item = data[k] + + if isinstance(item, str): + if key in item: + data[k] = data[k].replace(key, "components/schemas") + + elif isinstance(item, dict): + data[k] = _move_pydantic_refs(data[k], key) + + elif isinstance(item, List): + for i in range(len(data[k])): + data[k][i] = _move_pydantic_refs(item[i], key) + + if isinstance(desciminator := data.get("discriminator"), dict): + data["discriminator"] = desciminator["propertyName"] + + return data diff --git a/faststream/asyncapi/v3_0_0/schema/channels.py b/faststream/asyncapi/v3_0_0/schema/channels.py new file mode 100644 index 0000000000..d0489ff12c --- /dev/null +++ b/faststream/asyncapi/v3_0_0/schema/channels.py @@ -0,0 +1,40 @@ +from typing import Dict, List, Optional, Union + +from pydantic import BaseModel + +from faststream._compat import PYDANTIC_V2 +from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding +from faststream.asyncapi.v2_6_0.schema.message import Message +from faststream.asyncapi.v2_6_0.schema.utils import Parameter, Reference + + +class Channel(BaseModel): + """A class to represent a channel. + + Attributes: + address: A string representation of this channel's address. + description : optional description of the channel + servers : optional list of servers associated with the channel + bindings : optional channel binding + parameters : optional parameters associated with the channel + + Configurations: + model_config : configuration for the model (only applicable for Pydantic version 2) + Config : configuration for the class (only applicable for Pydantic version 1) + + """ + + address: str + description: Optional[str] = None + servers: Optional[List[Dict[str, str]]] = None + messages: Dict[str, Union[Message, Reference]] + bindings: Optional[ChannelBinding] = None + parameters: Optional[Parameter] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" diff --git a/faststream/asyncapi/v3_0_0/schema/operations.py b/faststream/asyncapi/v3_0_0/schema/operations.py new file mode 100644 index 0000000000..b727243713 --- /dev/null +++ b/faststream/asyncapi/v3_0_0/schema/operations.py @@ -0,0 +1,54 @@ +from typing import Any, Dict, List, Literal, Optional, Union + +from pydantic import BaseModel + +from faststream._compat import PYDANTIC_V2 +from faststream.asyncapi.v2_6_0.schema.bindings import OperationBinding +from faststream.asyncapi.v2_6_0.schema.utils import ( + ExternalDocs, + ExternalDocsDict, + Reference, + Tag, + TagDict, +) +from faststream.asyncapi.v3_0_0.schema.channels import Channel + + +class Operation(BaseModel): + """A class to represent an operation. + + Attributes: + operationId : ID of the operation + summary : summary of the operation + description : description of the operation + bindings : bindings of the operation + message : message of the operation + security : security details of the operation + tags : tags associated with the operation + externalDocs : external documentation for the operation + + """ + action: Literal["send", "receive"] + summary: Optional[str] = None + description: Optional[str] = None + + bindings: Optional[OperationBinding] = None + + messages: List[Reference] + channel: Union[Channel, Reference] + + security: Optional[Dict[str, List[str]]] = None + + # TODO + # traits + + tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = None + externalDocs: Optional[Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" diff --git a/faststream/nats/subscriber/asyncapi.py b/faststream/nats/subscriber/asyncapi.py index 557f16ad9f..a9f1195217 100644 --- a/faststream/nats/subscriber/asyncapi.py +++ b/faststream/nats/subscriber/asyncapi.py @@ -2,14 +2,6 @@ from typing_extensions import override -from faststream.asyncapi.schema import ( - ChannelBinding, - CorrelationId, - Message, - v2_6_0, -) -from faststream.asyncapi.schema.bindings import nats -from faststream.asyncapi.utils import resolve_payloads from faststream.nats.subscriber.usecase import ( BatchPullStreamSubscriber, ConcurrentCoreSubscriber, diff --git a/faststream/redis/schemas/proto.py b/faststream/redis/schemas/proto.py index c130e07a23..93fb6c08c1 100644 --- a/faststream/redis/schemas/proto.py +++ b/faststream/redis/schemas/proto.py @@ -5,6 +5,10 @@ from faststream.specification.proto import SpecificationProto if TYPE_CHECKING: +<<<<<<< HEAD +======= + from faststream.asyncapi.v2_6_0.schema.bindings import redis +>>>>>>> 2711d41d (AsyncAPI generation refactoring) from faststream.redis.schemas import ListSub, PubSub, StreamSub from faststream.specification.schema.bindings import redis diff --git a/faststream/specification/asyncapi/base/schema/schema.py b/faststream/specification/asyncapi/base/schema/schema.py index 49e8c90fd1..09a5ce7031 100644 --- a/faststream/specification/asyncapi/base/schema/schema.py +++ b/faststream/specification/asyncapi/base/schema/schema.py @@ -3,7 +3,11 @@ from pydantic import BaseModel from faststream._compat import model_to_json, model_to_jsonable +<<<<<<<< HEAD:faststream/specification/asyncapi/base/schema/schema.py from faststream.specification.asyncapi.base.schema.info import BaseInfo +======== +from faststream.asyncapi.base.info import BaseInfo +>>>>>>>> 2711d41d (AsyncAPI generation refactoring):faststream/asyncapi/base/schema.py class BaseSchema(BaseModel): diff --git a/faststream/specification/asyncapi/v2_6_0/schema/servers.py b/faststream/specification/asyncapi/v2_6_0/schema/servers.py index 318e2a40c9..ea98852281 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/servers.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/servers.py @@ -3,6 +3,7 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 +from faststream.specification.asyncapi.v2_6_0.schema import ServerVariable from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag from faststream.specification.asyncapi.v2_6_0.schema.utils import Reference from faststream.types import AnyDict @@ -10,31 +11,6 @@ SecurityRequirement = List[Dict[str, List[str]]] -class ServerVariable(BaseModel): - """A class to represent a server variable. - - Attributes: - enum : list of possible values for the server variable (optional) - default : default value for the server variable (optional) - description : description of the server variable (optional) - examples : list of example values for the server variable (optional) - - """ - - enum: Optional[List[str]] = None - default: Optional[str] = None - description: Optional[str] = None - examples: Optional[List[str]] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" - - class Server(BaseModel): """A class to represent a server. diff --git a/faststream/specification/asyncapi/v3_0_0/schema/__init__.py b/faststream/specification/asyncapi/v3_0_0/schema/__init__.py index 8f681f0e04..eaface012e 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/__init__.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/__init__.py @@ -1,11 +1,15 @@ +from . import bindings from .channels import Channel from .channels import from_spec as channel_from_spec from .components import Components -from .info import Info +from .info import Contact, ContactDict, Info, License, LicenseDict +from .message import CorrelationId, Message from .operations import Operation from .operations import from_spec as operation_from_spec from .schema import Schema -from .servers import Server +from .security import OauthFlowObj, OauthFlows, SecuritySchemaComponent +from .servers import Server, ServerVariable +from .utils import ExternalDocs, ExternalDocsDict, Parameter, Reference, Tag, TagDict __all__ = ( "Channel", @@ -17,5 +21,18 @@ "Components", "Info", "Schema", + "OauthFlowObj", + "OauthFlows", + "SecuritySchemaComponent", "Server", + "ServerVariable", + "Message", + "CorrelationId", + "ExternalDocsDict", + "ExternalDocs", + "TagDict", + "Tag", + "Reference", + "Parameter", + "bindings", ) diff --git a/tests/asyncapi/rabbit/v2_6_0/test_connection.py b/tests/asyncapi/rabbit/v2_6_0/test_connection.py index 137bb7b444..9ccc09a680 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_connection.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_connection.py @@ -1,4 +1,9 @@ from faststream import FastStream +<<<<<<< HEAD +======= +from faststream.asyncapi.generate import get_app_schema +from faststream.asyncapi.v2_6_0.schema import Tag +>>>>>>> 2711d41d (AsyncAPI generation refactoring) from faststream.rabbit import RabbitBroker from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.schema.tag import Tag diff --git a/tests/asyncapi/rabbit/v3_0_0/test_naming.py b/tests/asyncapi/rabbit/v3_0_0/test_naming.py index af3731648a..bd99a97599 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_naming.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_naming.py @@ -1,13 +1,8 @@ from typing import Type from faststream import FastStream -<<<<<<< HEAD from faststream.rabbit import RabbitBroker from faststream.specification.asyncapi.generate import get_app_schema -======= -from faststream.asyncapi.generate import get_app_schema -from faststream.rabbit import RabbitBroker ->>>>>>> d8eb3497 (AsyncAPI rabbit naming test) from tests.asyncapi.base.v3_0_0.naming import NamingTestCase From 8937c9fcf7b5b382470218cdf794f0b036cf4bc5 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 10 Aug 2024 21:07:24 +0300 Subject: [PATCH 119/245] AsyncAPI 2.6.0 generation from internal specs --- faststream/broker/core/usecase.py | 2 +- .../specification/asyncapi/v2_6_0/generate.py | 146 ++++++++++++++++++ .../asyncapi/rabbit/v2_6_0/test_connection.py | 5 - tests/asyncapi/rabbit/v3_0_0/test_naming.py | 1 + 4 files changed, 148 insertions(+), 6 deletions(-) diff --git a/faststream/broker/core/usecase.py b/faststream/broker/core/usecase.py index e6d7ea2f09..826bd6773b 100644 --- a/faststream/broker/core/usecase.py +++ b/faststream/broker/core/usecase.py @@ -24,7 +24,6 @@ from faststream.broker.proto import SetupAble from faststream.broker.subscriber.proto import SubscriberProto from faststream.broker.types import ( - AsyncCustomCallable, BrokerMiddleware, ConnectionType, CustomCallable, @@ -42,6 +41,7 @@ from faststream.broker.message import StreamMessage from faststream.broker.publisher.proto import ProducerProto, PublisherProto + from faststream.broker.specification.tag import Tag, TagDict from faststream.security import BaseSecurity from faststream.specification.schema.tag import Tag, TagDict from faststream.types import AnyDict, Decorator, LoggerProto diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index 6c93bb0b8a..ebab19d19d 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -163,6 +163,152 @@ def get_broker_channels( return channels +def _specs_channel_to_asyncapi(channel: SpecChannel) -> Channel: + return Channel( + description=channel.description, + servers=channel.servers, + + bindings=_specs_channel_binding_to_asyncapi(channel.bindings) + if channel.bindings else None, + + subscribe=_specs_operation_to_asyncapi(channel.subscribe) + if channel.subscribe else None, + + publish=_specs_operation_to_asyncapi(channel.publish) + if channel.publish else None, + ) + + +def _specs_channel_binding_to_asyncapi(binding: SpecChannelBinding) -> ChannelBinding: + return ChannelBinding( + amqp=amqp.ChannelBinding(**{ + "is": binding.amqp.is_, + "bindingVersion": binding.amqp.bindingVersion, + "queue": amqp.Queue( + name=binding.amqp.queue.name, + durable=binding.amqp.queue.durable, + exclusive=binding.amqp.queue.exclusive, + autoDelete=binding.amqp.queue.autoDelete, + vhost=binding.amqp.queue.vhost, + ) + if binding.amqp.queue else None, + "exchange": amqp.Exchange( + name=binding.amqp.exchange.name, + type=binding.amqp.exchange.type, + durable=binding.amqp.exchange.durable, + autoDelete=binding.amqp.exchange.autoDelete, + vhost=binding.amqp.exchange.vhost + ) + if binding.amqp.exchange else None, + } + ) + if binding.amqp else None, + + kafka=kafka.ChannelBinding(**asdict(binding.kafka)) + if binding.kafka else None, + + sqs=sqs.ChannelBinding(**asdict(binding.sqs)) + if binding.sqs else None, + + nats=nats.ChannelBinding(**asdict(binding.nats)) + if binding.nats else None, + + redis=redis.ChannelBinding(**asdict(binding.redis)) + if binding.redis else None, + ) + + +def _specs_operation_to_asyncapi(operation: SpecOperation) -> Operation: + return Operation( + operationId=operation.operationId, + summary=operation.summary, + description=operation.description, + + bindings=_specs_operation_binding_to_asyncapi(operation.bindings) + if operation.bindings else None, + + message=Message( + title=operation.message.title, + name=operation.message.name, + summary=operation.message.summary, + description=operation.message.description, + messageId=operation.message.messageId, + payload=operation.message.payload, + + correlationId=CorrelationId(**asdict(operation.message.correlationId)) + if operation.message.correlationId else None, + + contentType=operation.message.contentType, + + tags=_specs_tags_to_asyncapi(operation.tags) + if operation.tags else None, + + externalDocs=_specs_external_docs_to_asyncapi(operation.externalDocs) + if operation.externalDocs else None, + ), + + security=operation.security, + + tags=_specs_tags_to_asyncapi(operation.tags) + if operation.tags else None, + + externalDocs=_specs_external_docs_to_asyncapi(operation.externalDocs) + if operation.externalDocs else None, + ) + + +def _specs_operation_binding_to_asyncapi(binding: SpecOperationBinding) -> OperationBinding: + return OperationBinding( + amqp=amqp.OperationBinding(**asdict(binding.amqp)) + if binding.amqp else None, + + kafka=kafka.OperationBinding(**asdict(binding.kafka)) + if binding.kafka else None, + + sqs=kafka.OperationBinding(**asdict(binding.sqs)) + if binding.sqs else None, + + nats=kafka.OperationBinding(**asdict(binding.nats)) + if binding.nats else None, + + redis=kafka.OperationBinding(**asdict(binding.redis)) + if binding.redis else None, + ) + + +def _specs_tags_to_asyncapi( + tags: List[Union[SpecTag, SpecTagDict, Dict[str, Any]]] +) -> List[Union[Tag, TagDict, Dict[str, Any]]]: + asyncapi_tags = [] + + for tag in tags: + if isinstance(tag, SpecTag): + asyncapi_tags.append(Tag( + name=tag.name, + description=tag.description, + + externalDocs=_specs_external_docs_to_asyncapi(tag.externalDocs) + if tag.externalDocs else None, + )) + elif isinstance(tag, dict): + asyncapi_tags.append(tag) + else: + raise NotImplementedError + + return asyncapi_tags + + +def _specs_external_docs_to_asyncapi( + externalDocs: Union[SpecExternalDocs, SpecExternalDocsDict, Dict[str, Any]] +) -> Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]: + if isinstance(externalDocs, SpecExternalDocs): + return ExternalDocs( + **asdict(externalDocs) + ) + else: + return externalDocs + + def _resolve_msg_payloads( m: Message, channel_name: str, diff --git a/tests/asyncapi/rabbit/v2_6_0/test_connection.py b/tests/asyncapi/rabbit/v2_6_0/test_connection.py index 9ccc09a680..137bb7b444 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_connection.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_connection.py @@ -1,9 +1,4 @@ from faststream import FastStream -<<<<<<< HEAD -======= -from faststream.asyncapi.generate import get_app_schema -from faststream.asyncapi.v2_6_0.schema import Tag ->>>>>>> 2711d41d (AsyncAPI generation refactoring) from faststream.rabbit import RabbitBroker from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.schema.tag import Tag diff --git a/tests/asyncapi/rabbit/v3_0_0/test_naming.py b/tests/asyncapi/rabbit/v3_0_0/test_naming.py index bd99a97599..f741041df2 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_naming.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_naming.py @@ -123,3 +123,4 @@ async def handle(): ... }, }, } + ) From 3c79d1a02b24a17bc1a7a06ec3e1d27bd370bebc Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 11 Aug 2024 16:26:30 +0300 Subject: [PATCH 120/245] mypy satisfied --- faststream/asyncapi/base/__init__.py | 7 - faststream/asyncapi/base/info.py | 28 -- faststream/asyncapi/v2_6_0/__init__.py | 7 - .../v2_6_0/schema/bindings/__init__.py | 11 - .../asyncapi/v2_6_0/schema/bindings/main.py | 91 ----- faststream/asyncapi/v2_6_0/schema/channels.py | 41 --- .../asyncapi/v2_6_0/schema/operations.py | 54 --- faststream/asyncapi/v2_6_0/schema/schema.py | 73 ---- faststream/asyncapi/v3_0_0/__init__.py | 7 - faststream/asyncapi/v3_0_0/generate.py | 339 ------------------ faststream/asyncapi/v3_0_0/schema/channels.py | 40 --- .../asyncapi/v3_0_0/schema/operations.py | 54 --- faststream/broker/core/usecase.py | 2 +- faststream/nats/subscriber/asyncapi.py | 4 + faststream/redis/schemas/proto.py | 5 + faststream/specification/__init__.py | 15 + .../specification/asyncapi/v2_6_0/generate.py | 26 +- .../specification/schema/bindings/main.py | 8 + faststream/specification/schema/channel.py | 5 + faststream/specification/schema/message.py | 5 + faststream/specification/schema/operation.py | 7 + faststream/specification/schema/tag.py | 4 + 22 files changed, 67 insertions(+), 766 deletions(-) delete mode 100644 faststream/asyncapi/base/__init__.py delete mode 100644 faststream/asyncapi/base/info.py delete mode 100644 faststream/asyncapi/v2_6_0/__init__.py delete mode 100644 faststream/asyncapi/v2_6_0/schema/bindings/__init__.py delete mode 100644 faststream/asyncapi/v2_6_0/schema/bindings/main.py delete mode 100644 faststream/asyncapi/v2_6_0/schema/channels.py delete mode 100644 faststream/asyncapi/v2_6_0/schema/operations.py delete mode 100644 faststream/asyncapi/v2_6_0/schema/schema.py delete mode 100644 faststream/asyncapi/v3_0_0/__init__.py delete mode 100644 faststream/asyncapi/v3_0_0/generate.py delete mode 100644 faststream/asyncapi/v3_0_0/schema/channels.py delete mode 100644 faststream/asyncapi/v3_0_0/schema/operations.py diff --git a/faststream/asyncapi/base/__init__.py b/faststream/asyncapi/base/__init__.py deleted file mode 100644 index 9164dc3039..0000000000 --- a/faststream/asyncapi/base/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from .info import BaseInfo -from .schema import BaseSchema - -__all__ = ( - "BaseInfo", - "BaseSchema", -) diff --git a/faststream/asyncapi/base/info.py b/faststream/asyncapi/base/info.py deleted file mode 100644 index 6472de4334..0000000000 --- a/faststream/asyncapi/base/info.py +++ /dev/null @@ -1,28 +0,0 @@ -from pydantic import BaseModel - -from faststream._compat import ( - PYDANTIC_V2, -) - - -class BaseInfo(BaseModel): - """A class to represent information. - - Attributes: - title : title of the information - version : version of the information (default: "1.0.0") - description : description of the information (default: "") - - """ - - title: str - version: str = "1.0.0" - description: str = "" - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" diff --git a/faststream/asyncapi/v2_6_0/__init__.py b/faststream/asyncapi/v2_6_0/__init__.py deleted file mode 100644 index be8f2c412c..0000000000 --- a/faststream/asyncapi/v2_6_0/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from . import schema -from .generate import get_app_schema - -__all__ = ( - "schema", - "get_app_schema", -) diff --git a/faststream/asyncapi/v2_6_0/schema/bindings/__init__.py b/faststream/asyncapi/v2_6_0/schema/bindings/__init__.py deleted file mode 100644 index 39ce4b993c..0000000000 --- a/faststream/asyncapi/v2_6_0/schema/bindings/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -from .main import ( - ChannelBinding, - OperationBinding, - ServerBinding, -) - -__all__ = ( - "ServerBinding", - "ChannelBinding", - "OperationBinding", -) diff --git a/faststream/asyncapi/v2_6_0/schema/bindings/main.py b/faststream/asyncapi/v2_6_0/schema/bindings/main.py deleted file mode 100644 index 0cd5c7abfb..0000000000 --- a/faststream/asyncapi/v2_6_0/schema/bindings/main.py +++ /dev/null @@ -1,91 +0,0 @@ -from typing import Optional - -from pydantic import BaseModel - -from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.v2_6_0.schema.bindings import amqp as amqp_bindings -from faststream.asyncapi.v2_6_0.schema.bindings import kafka as kafka_bindings -from faststream.asyncapi.v2_6_0.schema.bindings import nats as nats_bindings -from faststream.asyncapi.v2_6_0.schema.bindings import redis as redis_bindings -from faststream.asyncapi.v2_6_0.schema.bindings import sqs as sqs_bindings - - -class ServerBinding(BaseModel): - """A class to represent server bindings. - - Attributes: - amqp : AMQP server binding (optional) - kafka : Kafka server binding (optional) - sqs : SQS server binding (optional) - nats : NATS server binding (optional) - redis : Redis server binding (optional) - - """ - - amqp: Optional[amqp_bindings.ServerBinding] = None - kafka: Optional[kafka_bindings.ServerBinding] = None - sqs: Optional[sqs_bindings.ServerBinding] = None - nats: Optional[nats_bindings.ServerBinding] = None - redis: Optional[redis_bindings.ServerBinding] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" - - -class ChannelBinding(BaseModel): - """A class to represent channel bindings. - - Attributes: - amqp : AMQP channel binding (optional) - kafka : Kafka channel binding (optional) - sqs : SQS channel binding (optional) - nats : NATS channel binding (optional) - redis : Redis channel binding (optional) - - """ - - amqp: Optional[amqp_bindings.ChannelBinding] = None - kafka: Optional[kafka_bindings.ChannelBinding] = None - sqs: Optional[sqs_bindings.ChannelBinding] = None - nats: Optional[nats_bindings.ChannelBinding] = None - redis: Optional[redis_bindings.ChannelBinding] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" - - -class OperationBinding(BaseModel): - """A class to represent an operation binding. - - Attributes: - amqp : AMQP operation binding (optional) - kafka : Kafka operation binding (optional) - sqs : SQS operation binding (optional) - nats : NATS operation binding (optional) - redis : Redis operation binding (optional) - - """ - - amqp: Optional[amqp_bindings.OperationBinding] = None - kafka: Optional[kafka_bindings.OperationBinding] = None - sqs: Optional[sqs_bindings.OperationBinding] = None - nats: Optional[nats_bindings.OperationBinding] = None - redis: Optional[redis_bindings.OperationBinding] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" diff --git a/faststream/asyncapi/v2_6_0/schema/channels.py b/faststream/asyncapi/v2_6_0/schema/channels.py deleted file mode 100644 index 0c8af7e74a..0000000000 --- a/faststream/asyncapi/v2_6_0/schema/channels.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import List, Optional - -from pydantic import BaseModel - -from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding -from faststream.asyncapi.v2_6_0.schema.operations import Operation -from faststream.asyncapi.v2_6_0.schema.utils import Parameter - - -class Channel(BaseModel): - """A class to represent a channel. - - Attributes: - description : optional description of the channel - servers : optional list of servers associated with the channel - bindings : optional channel binding - subscribe : optional operation for subscribing to the channel - publish : optional operation for publishing to the channel - parameters : optional parameters associated with the channel - - Configurations: - model_config : configuration for the model (only applicable for Pydantic version 2) - Config : configuration for the class (only applicable for Pydantic version 1) - - """ - - description: Optional[str] = None - servers: Optional[List[str]] = None - bindings: Optional[ChannelBinding] = None - subscribe: Optional[Operation] = None - publish: Optional[Operation] = None - parameters: Optional[Parameter] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" diff --git a/faststream/asyncapi/v2_6_0/schema/operations.py b/faststream/asyncapi/v2_6_0/schema/operations.py deleted file mode 100644 index 54a2a2ac71..0000000000 --- a/faststream/asyncapi/v2_6_0/schema/operations.py +++ /dev/null @@ -1,54 +0,0 @@ -from typing import Any, Dict, List, Optional, Union - -from pydantic import BaseModel - -from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.v2_6_0.schema.bindings import OperationBinding -from faststream.asyncapi.v2_6_0.schema.message import Message -from faststream.asyncapi.v2_6_0.schema.utils import ( - ExternalDocs, - ExternalDocsDict, - Reference, - Tag, - TagDict, -) - - -class Operation(BaseModel): - """A class to represent an operation. - - Attributes: - operationId : ID of the operation - summary : summary of the operation - description : description of the operation - bindings : bindings of the operation - message : message of the operation - security : security details of the operation - tags : tags associated with the operation - externalDocs : external documentation for the operation - - """ - - operationId: Optional[str] = None - summary: Optional[str] = None - description: Optional[str] = None - - bindings: Optional[OperationBinding] = None - - message: Union[Message, Reference] - - security: Optional[Dict[str, List[str]]] = None - - # TODO - # traits - - tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = None - externalDocs: Optional[Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" diff --git a/faststream/asyncapi/v2_6_0/schema/schema.py b/faststream/asyncapi/v2_6_0/schema/schema.py deleted file mode 100644 index 143ed74288..0000000000 --- a/faststream/asyncapi/v2_6_0/schema/schema.py +++ /dev/null @@ -1,73 +0,0 @@ -from typing import Any, Dict, List, Optional, Union - -from faststream._compat import model_to_json, model_to_jsonable -from faststream.asyncapi.base import BaseSchema -from faststream.asyncapi.v2_6_0.schema.channels import Channel -from faststream.asyncapi.v2_6_0.schema.components import Components -from faststream.asyncapi.v2_6_0.schema.info import Info -from faststream.asyncapi.v2_6_0.schema.servers import Server -from faststream.asyncapi.v2_6_0.schema.utils import ( - ExternalDocs, - ExternalDocsDict, - Tag, - TagDict, -) -from faststream.asyncapi.version import AsyncAPIVersion - - -class Schema(BaseSchema): - """A class to represent a schema. - - Attributes: - asyncapi : version of the async API - id : optional ID - defaultContentType : optional default content type - info : information about the schema - servers : optional dictionary of servers - channels : dictionary of channels - components : optional components of the schema - tags : optional list of tags - externalDocs : optional external documentation - - Methods: - to_jsonable() -> Any: Convert the schema to a JSON-serializable object. - to_json() -> str: Convert the schema to a JSON string. - to_yaml() -> str: Convert the schema to a YAML string. - - """ - - asyncapi: AsyncAPIVersion = AsyncAPIVersion.v2_6 - id: Optional[str] = None - defaultContentType: Optional[str] = None - info: Info - servers: Optional[Dict[str, Server]] = None - channels: Dict[str, Channel] - components: Optional[Components] = None - tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = None - externalDocs: Optional[Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]] = None - - def to_jsonable(self) -> Any: - """Convert the schema to a JSON-serializable object.""" - return model_to_jsonable( - self, - by_alias=True, - exclude_none=True, - ) - - def to_json(self) -> str: - """Convert the schema to a JSON string.""" - return model_to_json( - self, - by_alias=True, - exclude_none=True, - ) - - def to_yaml(self) -> str: - """Convert the schema to a YAML string.""" - from io import StringIO - - import yaml - - io = StringIO(initial_value="", newline="\n") - yaml.dump(self.to_jsonable(), io, sort_keys=False) - return io.getvalue() diff --git a/faststream/asyncapi/v3_0_0/__init__.py b/faststream/asyncapi/v3_0_0/__init__.py deleted file mode 100644 index be8f2c412c..0000000000 --- a/faststream/asyncapi/v3_0_0/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from . import schema -from .generate import get_app_schema - -__all__ = ( - "schema", - "get_app_schema", -) diff --git a/faststream/asyncapi/v3_0_0/generate.py b/faststream/asyncapi/v3_0_0/generate.py deleted file mode 100644 index 6fd587225c..0000000000 --- a/faststream/asyncapi/v3_0_0/generate.py +++ /dev/null @@ -1,339 +0,0 @@ -from typing import TYPE_CHECKING, Any, Dict, List, Union -from urllib.parse import urlparse - -from faststream._compat import DEF_KEY, HAS_FASTAPI -from faststream.asyncapi.v2_6_0.schema import Reference -from faststream.asyncapi.v2_6_0.schema.message import Message -from faststream.asyncapi.v3_0_0.schema import ( - Channel, - Components, - Info, - Operation, - Schema, - Server, -) -from faststream.constants import ContentTypes - -if TYPE_CHECKING: - from faststream.app import FastStream - from faststream.broker.core.usecase import BrokerUsecase - from faststream.broker.types import ConnectionType, MsgType - - if HAS_FASTAPI: - from faststream.broker.fastapi.router import StreamRouter - - -def get_app_schema(app: Union["FastStream", "StreamRouter[Any]"]) -> Schema: - """Get the application schema.""" - broker = app.broker - if broker is None: # pragma: no cover - raise RuntimeError() - broker.setup() - - servers = get_broker_server(broker) - channels = get_broker_channels(broker) - operations = get_broker_operations(broker) - - messages: Dict[str, Message] = {} - payloads: Dict[str, Dict[str, Any]] = {} - - for channel_name, channel in channels.items(): - msgs: Dict[str, Union[Message, Reference]] = {} - for message_name, message in channel.messages.items(): - assert isinstance(message, Message) - - msgs[message_name] = _resolve_msg_payloads( - message_name, - message, - channel_name, - payloads, - messages - ) - - channel.messages = msgs - - channel.servers = [{"$ref": f"#/servers/{server_name}"} for server_name in list(servers.keys())] - - schema = Schema( - info=Info( - title=app.title, - version=app.version, - description=app.description, - termsOfService=app.terms_of_service, - contact=app.contact, - license=app.license, - tags=list(app.asyncapi_tags) if app.asyncapi_tags else None, - externalDocs=app.external_docs, - ), - defaultContentType=ContentTypes.json.value, - id=app.identifier, - servers=servers, - channels=channels, - operations=operations, - components=Components( - messages=messages, - schemas=payloads, - securitySchemes=None - if broker.security is None - else broker.security.get_schema(), - ), - ) - return schema - - -def get_broker_server( - broker: "BrokerUsecase[MsgType, ConnectionType]", -) -> Dict[str, Server]: - """Get the broker server for an application.""" - servers = {} - - broker_meta: Dict[str, Any] = { - "protocol": broker.protocol, - "protocolVersion": broker.protocol_version, - "description": broker.description, - "tags": broker.tags, - # TODO - # "variables": "", - # "bindings": "", - } - - if broker.security is not None: - broker_meta["security"] = broker.security.get_requirement() - - if isinstance(broker.url, str): - broker_url = broker.url - if "://" not in broker_url: - broker_url = "//" + broker_url - - url = urlparse(broker_url) - servers["development"] = Server( - host=url.netloc, - pathname=url.path, - **broker_meta, - ) - - elif len(broker.url) == 1: - broker_url = broker.url[0] - if "://" not in broker_url: - broker_url = "//" + broker_url - - url = urlparse(broker_url) - servers["development"] = Server( - host=url.netloc, - pathname=url.path, - **broker_meta, - ) - - else: - for i, broker_url in enumerate(broker.url, 1): - if "://" not in broker_url: - broker_url = "//" + broker_url - - parsed_url = urlparse(broker_url) - servers[f"Server{i}"] = Server( - host=parsed_url.netloc, - pathname=parsed_url.path, - **broker_meta, - ) - - return servers - - -def get_broker_operations( - broker: "BrokerUsecase[MsgType, ConnectionType]", -) -> Dict[str, Operation]: - """Get the broker operations for an application.""" - operations = {} - - for h in broker._subscribers.values(): - for channel_name, channel_2_6 in h.schema().items(): - if channel_2_6.subscribe is not None: - op = Operation( - action="receive", - summary=channel_2_6.subscribe.summary, - description=channel_2_6.subscribe.description, - bindings=channel_2_6.subscribe.bindings, - messages=[ - Reference( - **{"$ref": f"#/channels/{channel_name}/messages/SubscribeMessage"}, - ) - ], - channel=Reference( - **{"$ref": f"#/channels/{channel_name}"}, - ), - security=channel_2_6.subscribe.security, - ) - operations[f"{channel_name}Subscribe"] = op - - elif channel_2_6.publish is not None: - op = Operation( - action="send", - summary=channel_2_6.publish.summary, - description=channel_2_6.publish.description, - bindings=channel_2_6.publish.bindings, - messages=[ - Reference( - **{"$ref": f"#/channels/{channel_name}/messages/Message"}, - )] - , - channel=Reference( - **{"$ref": f"#/channels/{channel_name}"}, - ), - security=channel_2_6.publish.bindings, - ) - operations[f"{channel_name}"] = op - - for p in broker._publishers.values(): - for channel_name, channel_2_6 in p.schema().items(): - if channel_2_6.subscribe is not None: - op = Operation( - action="send", - summary=channel_2_6.subscribe.summary, - description=channel_2_6.subscribe.description, - bindings=channel_2_6.subscribe.bindings, - messages=[ - Reference( - **{"$ref": f"#/channels/{channel_name}/messages/SubscribeMessage"}, - ) - ], - channel=Reference( - **{"$ref": f"#/channels/{channel_name}"}, - ), - security=channel_2_6.subscribe.security, - ) - operations[f"{channel_name}Subscribe"] = op - - elif channel_2_6.publish is not None: - op = Operation( - action="send", - summary=channel_2_6.publish.summary, - description=channel_2_6.publish.description, - bindings=channel_2_6.publish.bindings, - messages=[ - Reference( - **{"$ref": f"#/channels/{channel_name}/messages/Message"}, - ) - ], - channel=Reference( - **{"$ref": f"#/channels/{channel_name}"}, - ), - security=channel_2_6.publish.security, - ) - operations[f"{channel_name}"] = op - - return operations - - -def get_broker_channels( - broker: "BrokerUsecase[MsgType, ConnectionType]", -) -> Dict[str, Channel]: - """Get the broker channels for an application.""" - channels = {} - - for h in broker._subscribers.values(): - channels_schema_v3_0 = {} - for channel_name, channel_v2_6 in h.schema().items(): - if channel_v2_6.subscribe: - channel_v3_0 = Channel( - address=channel_name, - messages={ - "SubscribeMessage": channel_v2_6.subscribe.message, - }, - description=channel_v2_6.description, - servers=channel_v2_6.servers, - bindings=channel_v2_6.bindings, - parameters=channel_v2_6.parameters - ) - - channels_schema_v3_0[channel_name] = channel_v3_0 - - channels.update(channels_schema_v3_0) - - for p in broker._publishers.values(): - channels_schema_v3_0 = {} - for channel_name, channel_v2_6 in p.schema().items(): - if channel_v2_6.publish: - channel_v3_0 = Channel( - address=channel_name, - messages={ - "Message": channel_v2_6.publish.message, - }, - description=channel_v2_6.description, - servers=channel_v2_6.servers, - bindings=channel_v2_6.bindings, - parameters=channel_v2_6.parameters - ) - - channels_schema_v3_0[channel_name] = channel_v3_0 - - channels.update(channels_schema_v3_0) - - return channels - - -def _resolve_msg_payloads( - message_name: str, - m: Message, - channel_name: str, - payloads: Dict[str, Any], - messages: Dict[str, Any], -) -> Reference: - assert isinstance(m.payload, dict) - - m.payload = _move_pydantic_refs(m.payload, DEF_KEY) - if DEF_KEY in m.payload: - payloads.update(m.payload.pop(DEF_KEY)) - - one_of = m.payload.get("oneOf", None) - if isinstance(one_of, dict): - one_of_list = [] - p: Dict[str, Dict[str, Any]] = {} - for name, payload in one_of.items(): - payloads.update(p.pop(DEF_KEY, {})) - p[name] = payload - one_of_list.append(Reference(**{"$ref": f"#/components/schemas/{name}"})) - - payloads.update(p) - m.payload["oneOf"] = one_of_list - assert m.title - messages[m.title] = m - return Reference(**{"$ref": f"#/components/messages/{channel_name}:{message_name}"}) - - else: - payloads.update(m.payload.pop(DEF_KEY, {})) - payload_name = m.payload.get("title", f"{channel_name}:{message_name}:Payload") - payloads[payload_name] = m.payload - m.payload = {"$ref": f"#/components/schemas/{payload_name}"} - assert m.title - messages[m.title] = m - return Reference(**{"$ref": f"#/components/messages/{channel_name}:{message_name}"}) - - -def _move_pydantic_refs( - original: Any, - key: str, -) -> Any: - """Remove pydantic references and replace them by real schemas.""" - if not isinstance(original, Dict): - return original - - data = original.copy() - - for k in data: - item = data[k] - - if isinstance(item, str): - if key in item: - data[k] = data[k].replace(key, "components/schemas") - - elif isinstance(item, dict): - data[k] = _move_pydantic_refs(data[k], key) - - elif isinstance(item, List): - for i in range(len(data[k])): - data[k][i] = _move_pydantic_refs(item[i], key) - - if isinstance(desciminator := data.get("discriminator"), dict): - data["discriminator"] = desciminator["propertyName"] - - return data diff --git a/faststream/asyncapi/v3_0_0/schema/channels.py b/faststream/asyncapi/v3_0_0/schema/channels.py deleted file mode 100644 index d0489ff12c..0000000000 --- a/faststream/asyncapi/v3_0_0/schema/channels.py +++ /dev/null @@ -1,40 +0,0 @@ -from typing import Dict, List, Optional, Union - -from pydantic import BaseModel - -from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.v2_6_0.schema.bindings import ChannelBinding -from faststream.asyncapi.v2_6_0.schema.message import Message -from faststream.asyncapi.v2_6_0.schema.utils import Parameter, Reference - - -class Channel(BaseModel): - """A class to represent a channel. - - Attributes: - address: A string representation of this channel's address. - description : optional description of the channel - servers : optional list of servers associated with the channel - bindings : optional channel binding - parameters : optional parameters associated with the channel - - Configurations: - model_config : configuration for the model (only applicable for Pydantic version 2) - Config : configuration for the class (only applicable for Pydantic version 1) - - """ - - address: str - description: Optional[str] = None - servers: Optional[List[Dict[str, str]]] = None - messages: Dict[str, Union[Message, Reference]] - bindings: Optional[ChannelBinding] = None - parameters: Optional[Parameter] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" diff --git a/faststream/asyncapi/v3_0_0/schema/operations.py b/faststream/asyncapi/v3_0_0/schema/operations.py deleted file mode 100644 index b727243713..0000000000 --- a/faststream/asyncapi/v3_0_0/schema/operations.py +++ /dev/null @@ -1,54 +0,0 @@ -from typing import Any, Dict, List, Literal, Optional, Union - -from pydantic import BaseModel - -from faststream._compat import PYDANTIC_V2 -from faststream.asyncapi.v2_6_0.schema.bindings import OperationBinding -from faststream.asyncapi.v2_6_0.schema.utils import ( - ExternalDocs, - ExternalDocsDict, - Reference, - Tag, - TagDict, -) -from faststream.asyncapi.v3_0_0.schema.channels import Channel - - -class Operation(BaseModel): - """A class to represent an operation. - - Attributes: - operationId : ID of the operation - summary : summary of the operation - description : description of the operation - bindings : bindings of the operation - message : message of the operation - security : security details of the operation - tags : tags associated with the operation - externalDocs : external documentation for the operation - - """ - action: Literal["send", "receive"] - summary: Optional[str] = None - description: Optional[str] = None - - bindings: Optional[OperationBinding] = None - - messages: List[Reference] - channel: Union[Channel, Reference] - - security: Optional[Dict[str, List[str]]] = None - - # TODO - # traits - - tags: Optional[List[Union[Tag, TagDict, Dict[str, Any]]]] = None - externalDocs: Optional[Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" diff --git a/faststream/broker/core/usecase.py b/faststream/broker/core/usecase.py index 826bd6773b..e6d7ea2f09 100644 --- a/faststream/broker/core/usecase.py +++ b/faststream/broker/core/usecase.py @@ -24,6 +24,7 @@ from faststream.broker.proto import SetupAble from faststream.broker.subscriber.proto import SubscriberProto from faststream.broker.types import ( + AsyncCustomCallable, BrokerMiddleware, ConnectionType, CustomCallable, @@ -41,7 +42,6 @@ from faststream.broker.message import StreamMessage from faststream.broker.publisher.proto import ProducerProto, PublisherProto - from faststream.broker.specification.tag import Tag, TagDict from faststream.security import BaseSecurity from faststream.specification.schema.tag import Tag, TagDict from faststream.types import AnyDict, Decorator, LoggerProto diff --git a/faststream/nats/subscriber/asyncapi.py b/faststream/nats/subscriber/asyncapi.py index a9f1195217..4c27116713 100644 --- a/faststream/nats/subscriber/asyncapi.py +++ b/faststream/nats/subscriber/asyncapi.py @@ -14,6 +14,10 @@ PullStreamSubscriber, PushStreamSubscription, ) +from faststream.specification.bindings import ChannelBinding, nats +from faststream.specification.channel import Channel +from faststream.specification.message import CorrelationId, Message +from faststream.specification.operation import Operation class AsyncAPISubscriber(LogicSubscriber[Any]): diff --git a/faststream/redis/schemas/proto.py b/faststream/redis/schemas/proto.py index 93fb6c08c1..56d56e171c 100644 --- a/faststream/redis/schemas/proto.py +++ b/faststream/redis/schemas/proto.py @@ -6,11 +6,16 @@ if TYPE_CHECKING: <<<<<<< HEAD +<<<<<<< HEAD ======= from faststream.asyncapi.v2_6_0.schema.bindings import redis >>>>>>> 2711d41d (AsyncAPI generation refactoring) from faststream.redis.schemas import ListSub, PubSub, StreamSub from faststream.specification.schema.bindings import redis +======= + from faststream.redis.schemas import ListSub, PubSub, StreamSub + from faststream.specification.bindings import redis +>>>>>>> 3361c325 (mypy satisfied) class RedisAsyncAPIProtocol(SpecificationProto): diff --git a/faststream/specification/__init__.py b/faststream/specification/__init__.py index e69de29bb2..3a92ffdba8 100644 --- a/faststream/specification/__init__.py +++ b/faststream/specification/__init__.py @@ -0,0 +1,15 @@ +from . import bindings +from . import channel +from . import docs +from . import message +from . import operation +from . import tag + +__all__ = ( + "bindings", + "channel", + "docs", + "message", + "operation", + "tag", +) diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index ebab19d19d..b56567ddcb 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -119,7 +119,7 @@ def get_broker_server( "protocol": broker.protocol, "protocolVersion": broker.protocol_version, "description": broker.description, - "tags": tags, + "tags": tags if tags else None, # TODO # "variables": "", # "bindings": "", @@ -163,7 +163,7 @@ def get_broker_channels( return channels -def _specs_channel_to_asyncapi(channel: SpecChannel) -> Channel: +def _specs_channel_to_asyncapi(channel: spec.channel.Channel) -> Channel: return Channel( description=channel.description, servers=channel.servers, @@ -179,7 +179,7 @@ def _specs_channel_to_asyncapi(channel: SpecChannel) -> Channel: ) -def _specs_channel_binding_to_asyncapi(binding: SpecChannelBinding) -> ChannelBinding: +def _specs_channel_binding_to_asyncapi(binding: spec.bindings.ChannelBinding) -> ChannelBinding: return ChannelBinding( amqp=amqp.ChannelBinding(**{ "is": binding.amqp.is_, @@ -218,7 +218,7 @@ def _specs_channel_binding_to_asyncapi(binding: SpecChannelBinding) -> ChannelBi ) -def _specs_operation_to_asyncapi(operation: SpecOperation) -> Operation: +def _specs_operation_to_asyncapi(operation: spec.operation.Operation) -> Operation: return Operation( operationId=operation.operationId, summary=operation.summary, @@ -257,7 +257,7 @@ def _specs_operation_to_asyncapi(operation: SpecOperation) -> Operation: ) -def _specs_operation_binding_to_asyncapi(binding: SpecOperationBinding) -> OperationBinding: +def _specs_operation_binding_to_asyncapi(binding: spec.bindings.OperationBinding) -> OperationBinding: return OperationBinding( amqp=amqp.OperationBinding(**asdict(binding.amqp)) if binding.amqp else None, @@ -277,12 +277,12 @@ def _specs_operation_binding_to_asyncapi(binding: SpecOperationBinding) -> Opera def _specs_tags_to_asyncapi( - tags: List[Union[SpecTag, SpecTagDict, Dict[str, Any]]] + tags: List[Union[spec.tag.Tag, spec.tag.TagDict, Dict[str, Any]]] ) -> List[Union[Tag, TagDict, Dict[str, Any]]]: - asyncapi_tags = [] + asyncapi_tags: List[Union[Tag, TagDict, Dict[str, Any]]] = [] for tag in tags: - if isinstance(tag, SpecTag): + if isinstance(tag, spec.tag.Tag): asyncapi_tags.append(Tag( name=tag.name, description=tag.description, @@ -291,7 +291,7 @@ def _specs_tags_to_asyncapi( if tag.externalDocs else None, )) elif isinstance(tag, dict): - asyncapi_tags.append(tag) + asyncapi_tags.append(dict(tag)) else: raise NotImplementedError @@ -299,14 +299,14 @@ def _specs_tags_to_asyncapi( def _specs_external_docs_to_asyncapi( - externalDocs: Union[SpecExternalDocs, SpecExternalDocsDict, Dict[str, Any]] -) -> Union[ExternalDocs, ExternalDocsDict, Dict[str, Any]]: - if isinstance(externalDocs, SpecExternalDocs): + externalDocs: Union[spec.docs.ExternalDocs, spec.docs.ExternalDocsDict, Dict[str, Any]] +) -> Union[ExternalDocs, Dict[str, Any]]: + if isinstance(externalDocs, spec.docs.ExternalDocs): return ExternalDocs( **asdict(externalDocs) ) else: - return externalDocs + return dict(externalDocs) def _resolve_msg_payloads( diff --git a/faststream/specification/schema/bindings/main.py b/faststream/specification/schema/bindings/main.py index 65622aaa76..e118139ef7 100644 --- a/faststream/specification/schema/bindings/main.py +++ b/faststream/specification/schema/bindings/main.py @@ -1,11 +1,19 @@ from dataclasses import dataclass from typing import Optional +<<<<<<<< HEAD:faststream/specification/schema/bindings/main.py from faststream.specification.schema.bindings import amqp as amqp_bindings from faststream.specification.schema.bindings import kafka as kafka_bindings from faststream.specification.schema.bindings import nats as nats_bindings from faststream.specification.schema.bindings import redis as redis_bindings from faststream.specification.schema.bindings import sqs as sqs_bindings +======== +from faststream.specification.bindings import amqp as amqp_bindings +from faststream.specification.bindings import kafka as kafka_bindings +from faststream.specification.bindings import nats as nats_bindings +from faststream.specification.bindings import redis as redis_bindings +from faststream.specification.bindings import sqs as sqs_bindings +>>>>>>>> 3361c325 (mypy satisfied):faststream/specification/bindings/main.py @dataclass diff --git a/faststream/specification/schema/channel.py b/faststream/specification/schema/channel.py index d5649a5c36..1f166c0155 100644 --- a/faststream/specification/schema/channel.py +++ b/faststream/specification/schema/channel.py @@ -1,8 +1,13 @@ from dataclasses import dataclass from typing import List, Optional +<<<<<<<< HEAD:faststream/specification/schema/channel.py from faststream.specification.schema.bindings import ChannelBinding from faststream.specification.schema.operation import Operation +======== +from faststream.specification.bindings import ChannelBinding +from faststream.specification.operation import Operation +>>>>>>>> 3361c325 (mypy satisfied):faststream/specification/channel.py @dataclass diff --git a/faststream/specification/schema/message.py b/faststream/specification/schema/message.py index bb000bbb96..cdfe3c271f 100644 --- a/faststream/specification/schema/message.py +++ b/faststream/specification/schema/message.py @@ -1,8 +1,13 @@ from dataclasses import dataclass from typing import Any, Dict, List, Optional, Union +<<<<<<<< HEAD:faststream/specification/schema/message.py from faststream.specification.schema.docs import ExternalDocs from faststream.specification.schema.tag import Tag +======== +from faststream.specification.docs import ExternalDocs +from faststream.specification.tag import Tag +>>>>>>>> 3361c325 (mypy satisfied):faststream/specification/message.py @dataclass diff --git a/faststream/specification/schema/operation.py b/faststream/specification/schema/operation.py index 71b56c5d16..1a70777be3 100644 --- a/faststream/specification/schema/operation.py +++ b/faststream/specification/schema/operation.py @@ -1,9 +1,16 @@ from dataclasses import dataclass from typing import Any, Dict, List, Optional, Union +<<<<<<<< HEAD:faststream/specification/schema/operation.py from faststream.specification.schema.bindings import OperationBinding from faststream.specification.schema.message import Message from faststream.specification.schema.tag import Tag +======== +from faststream.specification.bindings import OperationBinding +from faststream.specification.docs import ExternalDocs, ExternalDocsDict +from faststream.specification.message import Message +from faststream.specification.tag import Tag, TagDict +>>>>>>>> 3361c325 (mypy satisfied):faststream/specification/operation.py @dataclass diff --git a/faststream/specification/schema/tag.py b/faststream/specification/schema/tag.py index ff9509d2c8..97f6b4f952 100644 --- a/faststream/specification/schema/tag.py +++ b/faststream/specification/schema/tag.py @@ -3,7 +3,11 @@ from typing_extensions import Required, TypedDict +<<<<<<<< HEAD:faststream/specification/schema/tag.py from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict +======== +from faststream.specification.docs import ExternalDocs, ExternalDocsDict +>>>>>>>> 3361c325 (mypy satisfied):faststream/specification/tag.py class TagDict(TypedDict, total=False): From 230c910f11cd44c8a33643f27c8248ce297de1a5 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Tue, 13 Aug 2024 22:52:13 +0300 Subject: [PATCH 121/245] refactoring --- faststream/asgi/app.py | 7 +- faststream/nats/subscriber/asyncapi.py | 107 ------------------------- faststream/specification/__init__.py | 1 + 3 files changed, 5 insertions(+), 110 deletions(-) delete mode 100644 faststream/nats/subscriber/asyncapi.py diff --git a/faststream/asgi/app.py b/faststream/asgi/app.py index 1d3182a629..eebc1312af 100644 --- a/faststream/asgi/app.py +++ b/faststream/asgi/app.py @@ -18,12 +18,13 @@ from faststream.asgi.websocket import WebSocketClose from faststream.log.logging import logger + if TYPE_CHECKING: from faststream.asgi.types import ASGIApp, Receive, Scope, Send from faststream.broker.core.usecase import BrokerUsecase - from faststream.specification.contact import Contact, ContactDict - from faststream.specification.docs import ExternalDocs, ExternalDocsDict - from faststream.specification.license import License, LicenseDict + from faststream.specification.schema.contact import Contact, ContactDict + from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict + from faststream.specification.schema.license import License, LicenseDict from faststream.specification.schema.tag import Tag from faststream.types import ( AnyCallable, diff --git a/faststream/nats/subscriber/asyncapi.py b/faststream/nats/subscriber/asyncapi.py deleted file mode 100644 index 4c27116713..0000000000 --- a/faststream/nats/subscriber/asyncapi.py +++ /dev/null @@ -1,107 +0,0 @@ -from typing import Any, Dict - -from typing_extensions import override - -from faststream.nats.subscriber.usecase import ( - BatchPullStreamSubscriber, - ConcurrentCoreSubscriber, - ConcurrentPullStreamSubscriber, - ConcurrentPushStreamSubscriber, - CoreSubscriber, - KeyValueWatchSubscriber, - LogicSubscriber, - ObjStoreWatchSubscriber, - PullStreamSubscriber, - PushStreamSubscription, -) -from faststream.specification.bindings import ChannelBinding, nats -from faststream.specification.channel import Channel -from faststream.specification.message import CorrelationId, Message -from faststream.specification.operation import Operation - - -class AsyncAPISubscriber(LogicSubscriber[Any]): - """A class to represent a NATS handler.""" - - def get_name(self) -> str: - return f"{self.subject}:{self.call_name}" - - def get_schema(self) -> Dict[str, v2_6_0.Channel]: - payloads = self.get_payloads() - - return { - self.name: v2_6_0.Channel( - description=self.description, - subscribe=v2_6_0.Operation( - message=Message( - title=f"{self.name}:Message", - payload=resolve_payloads(payloads), - correlationId=CorrelationId( - location="$message.header#/correlation_id" - ), - ), - ), - bindings=ChannelBinding( - nats=nats.ChannelBinding( - subject=self.subject, - queue=getattr(self, "queue", "") or None, - ) - ), - ) - } - - -class AsyncAPICoreSubscriber(AsyncAPISubscriber, CoreSubscriber): - """One-message core consumer with AsyncAPI methods.""" - - -class AsyncAPIConcurrentCoreSubscriber(AsyncAPISubscriber, ConcurrentCoreSubscriber): - """One-message core concurrent consumer with AsyncAPI methods.""" - - -class AsyncAPIStreamSubscriber(AsyncAPISubscriber, PushStreamSubscription): - """One-message JS Push consumer with AsyncAPI methods.""" - - -class AsyncAPIConcurrentPushStreamSubscriber( - AsyncAPISubscriber, ConcurrentPushStreamSubscriber -): - """One-message JS Push concurrent consumer with AsyncAPI methods.""" - - -class AsyncAPIPullStreamSubscriber(AsyncAPISubscriber, PullStreamSubscriber): - """One-message JS Pull consumer with AsyncAPI methods.""" - - -class AsyncAPIConcurrentPullStreamSubscriber( - AsyncAPISubscriber, ConcurrentPullStreamSubscriber -): - """One-message JS Pull concurrent consumer with AsyncAPI methods.""" - - -class AsyncAPIBatchPullStreamSubscriber(AsyncAPISubscriber, BatchPullStreamSubscriber): - """Batch-message Pull consumer with AsyncAPI methods.""" - - -class AsyncAPIKeyValueWatchSubscriber(AsyncAPISubscriber, KeyValueWatchSubscriber): - """KeyValueWatch consumer with AsyncAPI methods.""" - - @override - def get_name(self) -> str: - return "" - - @override - def get_schema(self) -> Dict[str, v2_6_0.Channel]: - return {} - - -class AsyncAPIObjStoreWatchSubscriber(AsyncAPISubscriber, ObjStoreWatchSubscriber): - """ObjStoreWatch consumer with AsyncAPI methods.""" - - @override - def get_name(self) -> str: - return "" - - @override - def get_schema(self) -> Dict[str, v2_6_0.Channel]: - return {} diff --git a/faststream/specification/__init__.py b/faststream/specification/__init__.py index 3a92ffdba8..9994afc7fd 100644 --- a/faststream/specification/__init__.py +++ b/faststream/specification/__init__.py @@ -1,3 +1,4 @@ +<<<<<<< HEAD from . import bindings from . import channel from . import docs From caff67f7e0d0b02d420f3d3971dc66f6b1252cc9 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 7 Sep 2024 22:54:08 +0300 Subject: [PATCH 122/245] fix --- faststream/broker/fastapi/router.py | 2 +- faststream/cli/docs/__init__.py | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/faststream/broker/fastapi/router.py b/faststream/broker/fastapi/router.py index fb0ae1196a..1936857c47 100644 --- a/faststream/broker/fastapi/router.py +++ b/faststream/broker/fastapi/router.py @@ -302,7 +302,7 @@ async def start_broker_lifespan( from faststream.specification.asyncapi.generate import get_app_schema - self.schema = get_app_schema(self) + self.schema = get_app_schema(self, version=AsyncAPIVersion.v2_6) app.include_router(self.docs_router) diff --git a/faststream/cli/docs/__init__.py b/faststream/cli/docs/__init__.py index 7b29c77ca6..182c5264e9 100644 --- a/faststream/cli/docs/__init__.py +++ b/faststream/cli/docs/__init__.py @@ -1,5 +1 @@ from .app import asyncapi_app - -__all__ = ( - "asyncapi_app", -) From fbb0864c1f2257c91cd9412a2cefa163f20aa70e Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 18 Aug 2024 00:26:33 +0300 Subject: [PATCH 123/245] Tests update --- faststream/broker/fastapi/router.py | 2 +- faststream/cli/docs/__init__.py | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/faststream/broker/fastapi/router.py b/faststream/broker/fastapi/router.py index 1936857c47..fb0ae1196a 100644 --- a/faststream/broker/fastapi/router.py +++ b/faststream/broker/fastapi/router.py @@ -302,7 +302,7 @@ async def start_broker_lifespan( from faststream.specification.asyncapi.generate import get_app_schema - self.schema = get_app_schema(self, version=AsyncAPIVersion.v2_6) + self.schema = get_app_schema(self) app.include_router(self.docs_router) diff --git a/faststream/cli/docs/__init__.py b/faststream/cli/docs/__init__.py index 182c5264e9..7b29c77ca6 100644 --- a/faststream/cli/docs/__init__.py +++ b/faststream/cli/docs/__init__.py @@ -1 +1,5 @@ from .app import asyncapi_app + +__all__ = ( + "asyncapi_app", +) From 93ec7ec20d6d2173a7b6638da5787da29a9a7525 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 6 Sep 2024 23:15:06 +0300 Subject: [PATCH 124/245] Confluent gssapi security schema test fix --- tests/asyncapi/confluent/v2_6_0/test_security.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/asyncapi/confluent/v2_6_0/test_security.py b/tests/asyncapi/confluent/v2_6_0/test_security.py index 49144e6d88..946791dbb9 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_security.py +++ b/tests/asyncapi/confluent/v2_6_0/test_security.py @@ -210,7 +210,7 @@ def test_gssapi_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app).to_jsonable() + schema = get_app_schema(app, version="2.6.0").to_jsonable() gssapi_security_schema = deepcopy(basic_schema) gssapi_security_schema["servers"]["development"]["security"] = [{"gssapi": []}] From ec4534c5065c00fdc9a46448ea90f25ef195e4b1 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 7 Sep 2024 23:02:36 +0300 Subject: [PATCH 125/245] fix --- faststream/specification/asyncapi/base/schema/schema.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/faststream/specification/asyncapi/base/schema/schema.py b/faststream/specification/asyncapi/base/schema/schema.py index 09a5ce7031..49e8c90fd1 100644 --- a/faststream/specification/asyncapi/base/schema/schema.py +++ b/faststream/specification/asyncapi/base/schema/schema.py @@ -3,11 +3,7 @@ from pydantic import BaseModel from faststream._compat import model_to_json, model_to_jsonable -<<<<<<<< HEAD:faststream/specification/asyncapi/base/schema/schema.py from faststream.specification.asyncapi.base.schema.info import BaseInfo -======== -from faststream.asyncapi.base.info import BaseInfo ->>>>>>>> 2711d41d (AsyncAPI generation refactoring):faststream/asyncapi/base/schema.py class BaseSchema(BaseModel): From c0578b36a4009c5360148b8798e029be3bed5971 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 7 Sep 2024 23:04:28 +0300 Subject: [PATCH 126/245] fix --- faststream/redis/schemas/proto.py | 8 -------- faststream/specification/__init__.py | 1 - faststream/specification/schema/bindings/main.py | 8 -------- faststream/specification/schema/channel.py | 5 ----- faststream/specification/schema/message.py | 5 ----- faststream/specification/schema/operation.py | 8 +------- faststream/specification/schema/tag.py | 4 ---- 7 files changed, 1 insertion(+), 38 deletions(-) diff --git a/faststream/redis/schemas/proto.py b/faststream/redis/schemas/proto.py index 56d56e171c..ba358101d9 100644 --- a/faststream/redis/schemas/proto.py +++ b/faststream/redis/schemas/proto.py @@ -5,17 +5,9 @@ from faststream.specification.proto import SpecificationProto if TYPE_CHECKING: -<<<<<<< HEAD -<<<<<<< HEAD -======= - from faststream.asyncapi.v2_6_0.schema.bindings import redis ->>>>>>> 2711d41d (AsyncAPI generation refactoring) from faststream.redis.schemas import ListSub, PubSub, StreamSub from faststream.specification.schema.bindings import redis -======= from faststream.redis.schemas import ListSub, PubSub, StreamSub - from faststream.specification.bindings import redis ->>>>>>> 3361c325 (mypy satisfied) class RedisAsyncAPIProtocol(SpecificationProto): diff --git a/faststream/specification/__init__.py b/faststream/specification/__init__.py index 9994afc7fd..3a92ffdba8 100644 --- a/faststream/specification/__init__.py +++ b/faststream/specification/__init__.py @@ -1,4 +1,3 @@ -<<<<<<< HEAD from . import bindings from . import channel from . import docs diff --git a/faststream/specification/schema/bindings/main.py b/faststream/specification/schema/bindings/main.py index e118139ef7..65622aaa76 100644 --- a/faststream/specification/schema/bindings/main.py +++ b/faststream/specification/schema/bindings/main.py @@ -1,19 +1,11 @@ from dataclasses import dataclass from typing import Optional -<<<<<<<< HEAD:faststream/specification/schema/bindings/main.py from faststream.specification.schema.bindings import amqp as amqp_bindings from faststream.specification.schema.bindings import kafka as kafka_bindings from faststream.specification.schema.bindings import nats as nats_bindings from faststream.specification.schema.bindings import redis as redis_bindings from faststream.specification.schema.bindings import sqs as sqs_bindings -======== -from faststream.specification.bindings import amqp as amqp_bindings -from faststream.specification.bindings import kafka as kafka_bindings -from faststream.specification.bindings import nats as nats_bindings -from faststream.specification.bindings import redis as redis_bindings -from faststream.specification.bindings import sqs as sqs_bindings ->>>>>>>> 3361c325 (mypy satisfied):faststream/specification/bindings/main.py @dataclass diff --git a/faststream/specification/schema/channel.py b/faststream/specification/schema/channel.py index 1f166c0155..d5649a5c36 100644 --- a/faststream/specification/schema/channel.py +++ b/faststream/specification/schema/channel.py @@ -1,13 +1,8 @@ from dataclasses import dataclass from typing import List, Optional -<<<<<<<< HEAD:faststream/specification/schema/channel.py from faststream.specification.schema.bindings import ChannelBinding from faststream.specification.schema.operation import Operation -======== -from faststream.specification.bindings import ChannelBinding -from faststream.specification.operation import Operation ->>>>>>>> 3361c325 (mypy satisfied):faststream/specification/channel.py @dataclass diff --git a/faststream/specification/schema/message.py b/faststream/specification/schema/message.py index cdfe3c271f..bb000bbb96 100644 --- a/faststream/specification/schema/message.py +++ b/faststream/specification/schema/message.py @@ -1,13 +1,8 @@ from dataclasses import dataclass from typing import Any, Dict, List, Optional, Union -<<<<<<<< HEAD:faststream/specification/schema/message.py from faststream.specification.schema.docs import ExternalDocs from faststream.specification.schema.tag import Tag -======== -from faststream.specification.docs import ExternalDocs -from faststream.specification.tag import Tag ->>>>>>>> 3361c325 (mypy satisfied):faststream/specification/message.py @dataclass diff --git a/faststream/specification/schema/operation.py b/faststream/specification/schema/operation.py index 1a70777be3..eccd0eb12c 100644 --- a/faststream/specification/schema/operation.py +++ b/faststream/specification/schema/operation.py @@ -1,16 +1,10 @@ from dataclasses import dataclass from typing import Any, Dict, List, Optional, Union -<<<<<<<< HEAD:faststream/specification/schema/operation.py from faststream.specification.schema.bindings import OperationBinding from faststream.specification.schema.message import Message from faststream.specification.schema.tag import Tag -======== -from faststream.specification.bindings import OperationBinding -from faststream.specification.docs import ExternalDocs, ExternalDocsDict -from faststream.specification.message import Message -from faststream.specification.tag import Tag, TagDict ->>>>>>>> 3361c325 (mypy satisfied):faststream/specification/operation.py + @dataclass diff --git a/faststream/specification/schema/tag.py b/faststream/specification/schema/tag.py index 97f6b4f952..ff9509d2c8 100644 --- a/faststream/specification/schema/tag.py +++ b/faststream/specification/schema/tag.py @@ -3,11 +3,7 @@ from typing_extensions import Required, TypedDict -<<<<<<<< HEAD:faststream/specification/schema/tag.py from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict -======== -from faststream.specification.docs import ExternalDocs, ExternalDocsDict ->>>>>>>> 3361c325 (mypy satisfied):faststream/specification/tag.py class TagDict(TypedDict, total=False): From 08cce1c95b274d708aed3f6a7789349d94962cac Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 8 Sep 2024 00:06:22 +0300 Subject: [PATCH 127/245] fixes --- faststream/confluent/publisher/publisher.py | 6 +- faststream/confluent/subscriber/subscriber.py | 6 +- faststream/kafka/publisher/publisher.py | 6 +- faststream/kafka/subscriber/subscriber.py | 6 +- faststream/nats/publisher/publisher.py | 6 +- faststream/rabbit/publisher/publisher.py | 6 +- faststream/rabbit/subscriber/subscriber.py | 6 +- faststream/redis/publisher/publisher.py | 6 +- faststream/redis/subscriber/subscriber.py | 6 +- faststream/specification/__init__.py | 15 -- .../specification/asyncapi/v2_6_0/generate.py | 146 ------------------ .../v2_6_0/schema/bindings/amqp/channel.py | 11 ++ .../asyncapi/v2_6_0/schema/contact.py | 2 +- .../asyncapi/v2_6_0/schema/servers.py | 26 +++- .../asyncapi/v3_0_0/schema/__init__.py | 23 +-- 15 files changed, 67 insertions(+), 210 deletions(-) diff --git a/faststream/confluent/publisher/publisher.py b/faststream/confluent/publisher/publisher.py index 3eaebec7b5..a5e50759d9 100644 --- a/faststream/confluent/publisher/publisher.py +++ b/faststream/confluent/publisher/publisher.py @@ -38,13 +38,13 @@ class SpecificationPublisher(LogicPublisher[MsgType]): def get_name(self) -> str: return f"{self.topic}:Publisher" - def get_schema(self) -> Dict[str, v2_6_0.Channel]: + def get_schema(self) -> Dict[str, Channel]: payloads = self.get_payloads() return { - self.name: v2_6_0.Channel( + self.name: Channel( description=self.description, - publish=v2_6_0.Operation( + publish=Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads, "Publisher"), diff --git a/faststream/confluent/subscriber/subscriber.py b/faststream/confluent/subscriber/subscriber.py index 1c6a100acb..0b6783b1dc 100644 --- a/faststream/confluent/subscriber/subscriber.py +++ b/faststream/confluent/subscriber/subscriber.py @@ -27,16 +27,16 @@ class SpecificationSubscriber(LogicSubscriber[MsgType]): def get_name(self) -> str: return f'{",".join(self.topics)}:{self.call_name}' - def get_schema(self) -> Dict[str, v2_6_0.Channel]: + def get_schema(self) -> Dict[str, Channel]: channels = {} payloads = self.get_payloads() for t in self.topics: handler_name = self.title_ or f"{t}:{self.call_name}" - channels[handler_name] = v2_6_0.Channel( + channels[handler_name] = Channel( description=self.description, - subscribe=v2_6_0.Operation( + subscribe=Operation( message=Message( title=f"{handler_name}:Message", payload=resolve_payloads(payloads), diff --git a/faststream/kafka/publisher/publisher.py b/faststream/kafka/publisher/publisher.py index ed0a8fb9ec..e16a2693a8 100644 --- a/faststream/kafka/publisher/publisher.py +++ b/faststream/kafka/publisher/publisher.py @@ -38,13 +38,13 @@ class SpecificationPublisher(LogicPublisher[MsgType]): def get_name(self) -> str: return f"{self.topic}:Publisher" - def get_schema(self) -> Dict[str, v2_6_0.Channel]: + def get_schema(self) -> Dict[str, Channel]: payloads = self.get_payloads() return { - self.name: v2_6_0.Channel( + self.name: Channel( description=self.description, - publish=v2_6_0.Operation( + publish=Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads, "Publisher"), diff --git a/faststream/kafka/subscriber/subscriber.py b/faststream/kafka/subscriber/subscriber.py index b27247afd8..b10985bf15 100644 --- a/faststream/kafka/subscriber/subscriber.py +++ b/faststream/kafka/subscriber/subscriber.py @@ -27,7 +27,7 @@ class SpecificationSubscriber(LogicSubscriber[MsgType]): def get_name(self) -> str: return f'{",".join(self.topics)}:{self.call_name}' - def get_schema(self) -> Dict[str, v2_6_0.Channel]: + def get_schema(self) -> Dict[str, Channel]: channels = {} payloads = self.get_payloads() @@ -35,9 +35,9 @@ def get_schema(self) -> Dict[str, v2_6_0.Channel]: for t in self.topics: handler_name = self.title_ or f"{t}:{self.call_name}" - channels[handler_name] = v2_6_0.Channel( + channels[handler_name] = Channel( description=self.description, - subscribe=v2_6_0.Operation( + subscribe=Operation( message=Message( title=f"{handler_name}:Message", payload=resolve_payloads(payloads), diff --git a/faststream/nats/publisher/publisher.py b/faststream/nats/publisher/publisher.py index b430c939cf..c7862c50d1 100644 --- a/faststream/nats/publisher/publisher.py +++ b/faststream/nats/publisher/publisher.py @@ -23,13 +23,13 @@ class SpecificationPublisher(LogicPublisher): def get_name(self) -> str: return f"{self.subject}:Publisher" - def get_schema(self) -> Dict[str, v2_6_0.Channel]: + def get_schema(self) -> Dict[str, Channel]: payloads = self.get_payloads() return { - self.name: v2_6_0.Channel( + self.name: Channel( description=self.description, - publish=v2_6_0.Operation( + publish=Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads, "Publisher"), diff --git a/faststream/rabbit/publisher/publisher.py b/faststream/rabbit/publisher/publisher.py index 4821f1066c..69b80ca1ff 100644 --- a/faststream/rabbit/publisher/publisher.py +++ b/faststream/rabbit/publisher/publisher.py @@ -43,13 +43,13 @@ def get_name(self) -> str: return f"{routing}:{getattr(self.exchange, 'name', None) or '_'}:Publisher" - def get_schema(self) -> Dict[str, v2_6_0.Channel]: + def get_schema(self) -> Dict[str, Channel]: payloads = self.get_payloads() return { - self.name: v2_6_0.Channel( + self.name: Channel( description=self.description, # type: ignore[attr-defined] - publish=v2_6_0.Operation( + publish=Operation( bindings=OperationBinding( amqp=amqp.OperationBinding( cc=self.routing or None, diff --git a/faststream/rabbit/subscriber/subscriber.py b/faststream/rabbit/subscriber/subscriber.py index 6f8d835c4c..25d68d26e3 100644 --- a/faststream/rabbit/subscriber/subscriber.py +++ b/faststream/rabbit/subscriber/subscriber.py @@ -20,13 +20,13 @@ class SpecificationSubscriber(LogicSubscriber): def get_name(self) -> str: return f"{self.queue.name}:{getattr(self.exchange, 'name', None) or '_'}:{self.call_name}" - def get_schema(self) -> Dict[str, v2_6_0.Channel]: + def get_schema(self) -> Dict[str, Channel]: payloads = self.get_payloads() return { - self.name: v2_6_0.Channel( + self.name: Channel( description=self.description, # type: ignore[attr-defined] - subscribe=v2_6_0.Operation( + subscribe=Operation( bindings=OperationBinding( amqp=amqp.OperationBinding( cc=self.queue.routing, diff --git a/faststream/redis/publisher/publisher.py b/faststream/redis/publisher/publisher.py index ff74f7c921..4e75dab070 100644 --- a/faststream/redis/publisher/publisher.py +++ b/faststream/redis/publisher/publisher.py @@ -35,13 +35,13 @@ class SpecificationPublisher(LogicPublisher, RedisAsyncAPIProtocol): """A class to represent a Redis publisher.""" - def get_schema(self) -> Dict[str, v2_6_0.Channel]: + def get_schema(self) -> Dict[str, Channel]: payloads = self.get_payloads() return { - self.name: v2_6_0.Channel( + self.name: Channel( description=self.description, - publish=v2_6_0.Operation( + publish=Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads, "Publisher"), diff --git a/faststream/redis/subscriber/subscriber.py b/faststream/redis/subscriber/subscriber.py index 078b0283b3..695d5e247f 100644 --- a/faststream/redis/subscriber/subscriber.py +++ b/faststream/redis/subscriber/subscriber.py @@ -21,13 +21,13 @@ class SpecificationSubscriber(LogicSubscriber, RedisAsyncAPIProtocol): """A class to represent a Redis handler.""" - def get_schema(self) -> Dict[str, v2_6_0.Channel]: + def get_schema(self) -> Dict[str, Channel]: payloads = self.get_payloads() return { - self.name: v2_6_0.Channel( + self.name: Channel( description=self.description, - subscribe=v2_6_0.Operation( + subscribe=Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads), diff --git a/faststream/specification/__init__.py b/faststream/specification/__init__.py index 3a92ffdba8..e69de29bb2 100644 --- a/faststream/specification/__init__.py +++ b/faststream/specification/__init__.py @@ -1,15 +0,0 @@ -from . import bindings -from . import channel -from . import docs -from . import message -from . import operation -from . import tag - -__all__ = ( - "bindings", - "channel", - "docs", - "message", - "operation", - "tag", -) diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index b56567ddcb..bfeaa9d326 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -163,152 +163,6 @@ def get_broker_channels( return channels -def _specs_channel_to_asyncapi(channel: spec.channel.Channel) -> Channel: - return Channel( - description=channel.description, - servers=channel.servers, - - bindings=_specs_channel_binding_to_asyncapi(channel.bindings) - if channel.bindings else None, - - subscribe=_specs_operation_to_asyncapi(channel.subscribe) - if channel.subscribe else None, - - publish=_specs_operation_to_asyncapi(channel.publish) - if channel.publish else None, - ) - - -def _specs_channel_binding_to_asyncapi(binding: spec.bindings.ChannelBinding) -> ChannelBinding: - return ChannelBinding( - amqp=amqp.ChannelBinding(**{ - "is": binding.amqp.is_, - "bindingVersion": binding.amqp.bindingVersion, - "queue": amqp.Queue( - name=binding.amqp.queue.name, - durable=binding.amqp.queue.durable, - exclusive=binding.amqp.queue.exclusive, - autoDelete=binding.amqp.queue.autoDelete, - vhost=binding.amqp.queue.vhost, - ) - if binding.amqp.queue else None, - "exchange": amqp.Exchange( - name=binding.amqp.exchange.name, - type=binding.amqp.exchange.type, - durable=binding.amqp.exchange.durable, - autoDelete=binding.amqp.exchange.autoDelete, - vhost=binding.amqp.exchange.vhost - ) - if binding.amqp.exchange else None, - } - ) - if binding.amqp else None, - - kafka=kafka.ChannelBinding(**asdict(binding.kafka)) - if binding.kafka else None, - - sqs=sqs.ChannelBinding(**asdict(binding.sqs)) - if binding.sqs else None, - - nats=nats.ChannelBinding(**asdict(binding.nats)) - if binding.nats else None, - - redis=redis.ChannelBinding(**asdict(binding.redis)) - if binding.redis else None, - ) - - -def _specs_operation_to_asyncapi(operation: spec.operation.Operation) -> Operation: - return Operation( - operationId=operation.operationId, - summary=operation.summary, - description=operation.description, - - bindings=_specs_operation_binding_to_asyncapi(operation.bindings) - if operation.bindings else None, - - message=Message( - title=operation.message.title, - name=operation.message.name, - summary=operation.message.summary, - description=operation.message.description, - messageId=operation.message.messageId, - payload=operation.message.payload, - - correlationId=CorrelationId(**asdict(operation.message.correlationId)) - if operation.message.correlationId else None, - - contentType=operation.message.contentType, - - tags=_specs_tags_to_asyncapi(operation.tags) - if operation.tags else None, - - externalDocs=_specs_external_docs_to_asyncapi(operation.externalDocs) - if operation.externalDocs else None, - ), - - security=operation.security, - - tags=_specs_tags_to_asyncapi(operation.tags) - if operation.tags else None, - - externalDocs=_specs_external_docs_to_asyncapi(operation.externalDocs) - if operation.externalDocs else None, - ) - - -def _specs_operation_binding_to_asyncapi(binding: spec.bindings.OperationBinding) -> OperationBinding: - return OperationBinding( - amqp=amqp.OperationBinding(**asdict(binding.amqp)) - if binding.amqp else None, - - kafka=kafka.OperationBinding(**asdict(binding.kafka)) - if binding.kafka else None, - - sqs=kafka.OperationBinding(**asdict(binding.sqs)) - if binding.sqs else None, - - nats=kafka.OperationBinding(**asdict(binding.nats)) - if binding.nats else None, - - redis=kafka.OperationBinding(**asdict(binding.redis)) - if binding.redis else None, - ) - - -def _specs_tags_to_asyncapi( - tags: List[Union[spec.tag.Tag, spec.tag.TagDict, Dict[str, Any]]] -) -> List[Union[Tag, TagDict, Dict[str, Any]]]: - asyncapi_tags: List[Union[Tag, TagDict, Dict[str, Any]]] = [] - - for tag in tags: - if isinstance(tag, spec.tag.Tag): - asyncapi_tags.append(Tag( - name=tag.name, - description=tag.description, - - externalDocs=_specs_external_docs_to_asyncapi(tag.externalDocs) - if tag.externalDocs else None, - )) - elif isinstance(tag, dict): - asyncapi_tags.append(dict(tag)) - else: - raise NotImplementedError - - return asyncapi_tags - - -def _specs_external_docs_to_asyncapi( - externalDocs: Union[spec.docs.ExternalDocs, spec.docs.ExternalDocsDict, Dict[str, Any]] -) -> Union[ExternalDocs, Dict[str, Any]]: - if isinstance(externalDocs, spec.docs.ExternalDocs): - return ExternalDocs( - **asdict(externalDocs) - ) - else: - return dict(externalDocs) - - def _resolve_msg_payloads( m: Message, channel_name: str, diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py index 87c6bb8d2b..92938d5889 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py @@ -62,6 +62,17 @@ class Exchange(BaseModel): ] name: Optional[str] = None + type: Literal[ + "default", + "direct", + "topic", + "fanout", + "headers", + "x-delayed-message", + "x-consistent-hash", + "x-modulus-hash", + ] + durable: Optional[bool] = None autoDelete: Optional[bool] = None vhost: str = "/" diff --git a/faststream/specification/asyncapi/v2_6_0/schema/contact.py b/faststream/specification/asyncapi/v2_6_0/schema/contact.py index 8a4652d877..4cdcd7cbcd 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/contact.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/contact.py @@ -88,7 +88,7 @@ def __get_pydantic_core_schema__( source : the source handler : the handler """ - return with_info_plain_validator_function(cls._validate) # type: ignore[no-any-return] + return with_info_plain_validator_function(cls._validate) class Contact(BaseModel): diff --git a/faststream/specification/asyncapi/v2_6_0/schema/servers.py b/faststream/specification/asyncapi/v2_6_0/schema/servers.py index ea98852281..318e2a40c9 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/servers.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/servers.py @@ -3,7 +3,6 @@ from pydantic import BaseModel from faststream._compat import PYDANTIC_V2 -from faststream.specification.asyncapi.v2_6_0.schema import ServerVariable from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag from faststream.specification.asyncapi.v2_6_0.schema.utils import Reference from faststream.types import AnyDict @@ -11,6 +10,31 @@ SecurityRequirement = List[Dict[str, List[str]]] +class ServerVariable(BaseModel): + """A class to represent a server variable. + + Attributes: + enum : list of possible values for the server variable (optional) + default : default value for the server variable (optional) + description : description of the server variable (optional) + examples : list of example values for the server variable (optional) + + """ + + enum: Optional[List[str]] = None + default: Optional[str] = None + description: Optional[str] = None + examples: Optional[List[str]] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" + + class Server(BaseModel): """A class to represent a server. diff --git a/faststream/specification/asyncapi/v3_0_0/schema/__init__.py b/faststream/specification/asyncapi/v3_0_0/schema/__init__.py index eaface012e..0f84c1bae1 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/__init__.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/__init__.py @@ -1,15 +1,11 @@ -from . import bindings from .channels import Channel from .channels import from_spec as channel_from_spec from .components import Components -from .info import Contact, ContactDict, Info, License, LicenseDict -from .message import CorrelationId, Message +from .info import Info from .operations import Operation from .operations import from_spec as operation_from_spec from .schema import Schema -from .security import OauthFlowObj, OauthFlows, SecuritySchemaComponent -from .servers import Server, ServerVariable -from .utils import ExternalDocs, ExternalDocsDict, Parameter, Reference, Tag, TagDict +from .servers import Server __all__ = ( "Channel", @@ -19,20 +15,7 @@ "operation_from_spec", "Components", - "Info", "Schema", - "OauthFlowObj", - "OauthFlows", - "SecuritySchemaComponent", "Server", - "ServerVariable", - "Message", - "CorrelationId", - "ExternalDocsDict", - "ExternalDocs", - "TagDict", - "Tag", - "Reference", - "Parameter", - "bindings", + "Info", ) From b0314e10becf75505445645311ae8b8b5a7c15ff Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 8 Sep 2024 14:02:58 +0300 Subject: [PATCH 128/245] fixes --- faststream/broker/fastapi/route.py | 10 ---------- faststream/confluent/testing.py | 2 +- faststream/kafka/testing.py | 4 ++-- .../asyncapi/v2_6_0/schema/bindings/amqp/channel.py | 2 +- 4 files changed, 4 insertions(+), 14 deletions(-) diff --git a/faststream/broker/fastapi/route.py b/faststream/broker/fastapi/route.py index df774f749e..d8e39f96b2 100644 --- a/faststream/broker/fastapi/route.py +++ b/faststream/broker/fastapi/route.py @@ -210,17 +210,7 @@ async def app( **kwargs, ) -<<<<<<< HEAD raw_message.background = solved_result.background_tasks # type: ignore[attr-defined] -======= - ( - values, - errors, - raw_message.background, # type: ignore[attr-defined] - _response, - _dependency_cache, - ) = solved_result ->>>>>>> 2016de36 (feat: add broker.request method (#1649)) if solved_result.errors: raise_fastapi_validation_error(solved_result.errors, request._body) # type: ignore[arg-type] diff --git a/faststream/confluent/testing.py b/faststream/confluent/testing.py index b2945244a7..52475df401 100644 --- a/faststream/confluent/testing.py +++ b/faststream/confluent/testing.py @@ -15,9 +15,9 @@ from faststream.exceptions import SubscriberNotFound from faststream.testing.broker import TestBroker from faststream.utils.functions import timeout_scope +from faststream.confluent.subscriber.subscriber import SpecificationBatchSubscriber if TYPE_CHECKING: - from faststream.confluent.subscriber.subscriber import SpecificationBatchSubscriber from faststream.testing.broker import TestBroker, call_handler from faststream.broker.wrapper.call import HandlerCallWrapper from faststream.confluent.publisher.publisher import SpecificationPublisher diff --git a/faststream/kafka/testing.py b/faststream/kafka/testing.py index b0b3b51fb7..bda67071b2 100755 --- a/faststream/kafka/testing.py +++ b/faststream/kafka/testing.py @@ -17,11 +17,11 @@ from faststream.kafka.publisher.producer import AioKafkaFastProducer from faststream.testing.broker import TestBroker from faststream.utils.functions import timeout_scope +from faststream.kafka.publisher.publisher import SpecificationBatchPublisher +from faststream.kafka.subscriber.subscriber import SpecificationBatchSubscriber if TYPE_CHECKING: from faststream.kafka.publisher.producer import AioKafkaFastProducer - from faststream.kafka.publisher.publisher import SpecificationBatchPublisher - from faststream.kafka.subscriber.subscriber import SpecificationBatchSubscriber from faststream.testing.broker import TestBroker from faststream.kafka.publisher.publisher import SpecificationPublisher from faststream.kafka.subscriber.usecase import LogicSubscriber diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py index 92938d5889..4155bc2696 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py @@ -72,7 +72,7 @@ class Exchange(BaseModel): "x-consistent-hash", "x-modulus-hash", ] - + durable: Optional[bool] = None autoDelete: Optional[bool] = None vhost: str = "/" From c92d0f35a96dddb1722891f056d38ded34c4af54 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 8 Sep 2024 14:15:54 +0300 Subject: [PATCH 129/245] Ruff fixes --- faststream/app.py | 2 +- faststream/asgi/app.py | 1 - faststream/broker/subscriber/usecase.py | 2 +- faststream/confluent/publisher/publisher.py | 1 - faststream/confluent/subscriber/subscriber.py | 1 - faststream/confluent/testing.py | 5 ++--- faststream/kafka/publisher/publisher.py | 1 - faststream/kafka/subscriber/subscriber.py | 1 - faststream/kafka/testing.py | 6 +++--- faststream/nats/publisher/publisher.py | 1 - faststream/nats/testing.py | 3 +-- faststream/rabbit/publisher/publisher.py | 1 - faststream/rabbit/subscriber/subscriber.py | 1 - faststream/redis/publisher/publisher.py | 1 - faststream/redis/schemas/proto.py | 1 - faststream/redis/subscriber/subscriber.py | 1 - faststream/specification/schema/contact.py | 1 - faststream/specification/schema/operation.py | 1 - faststream/specification/schema/schema.py | 7 ------- 19 files changed, 8 insertions(+), 30 deletions(-) diff --git a/faststream/app.py b/faststream/app.py index 05c06a46f1..18462eac94 100644 --- a/faststream/app.py +++ b/faststream/app.py @@ -171,7 +171,7 @@ async def run( tg.start_soon(self._startup, log_level, run_extra_options) # TODO: mv it to event trigger after nats-py fixing - while not self.should_exit: # noqa: ASYNC110 + while not self.should_exit: await anyio.sleep(sleep_time) await self._shutdown(log_level) diff --git a/faststream/asgi/app.py b/faststream/asgi/app.py index eebc1312af..d1d84d7a55 100644 --- a/faststream/asgi/app.py +++ b/faststream/asgi/app.py @@ -18,7 +18,6 @@ from faststream.asgi.websocket import WebSocketClose from faststream.log.logging import logger - if TYPE_CHECKING: from faststream.asgi.types import ASGIApp, Receive, Scope, Send from faststream.broker.core.usecase import BrokerUsecase diff --git a/faststream/broker/subscriber/usecase.py b/faststream/broker/subscriber/usecase.py index e5ed1399d4..dbfeb0654f 100644 --- a/faststream/broker/subscriber/usecase.py +++ b/faststream/broker/subscriber/usecase.py @@ -27,9 +27,9 @@ ) from faststream.broker.utils import MultiLock, get_watcher_context, resolve_custom_func from faststream.broker.wrapper.call import HandlerCallWrapper +from faststream.exceptions import SetupError, StopConsume, SubscriberNotFound from faststream.specification.asyncapi.message import parse_handler_params from faststream.specification.asyncapi.utils import to_camelcase -from faststream.exceptions import SetupError, StopConsume, SubscriberNotFound from faststream.utils.context.repository import context from faststream.utils.functions import sync_fake_context, to_async diff --git a/faststream/confluent/publisher/publisher.py b/faststream/confluent/publisher/publisher.py index a5e50759d9..7be876ddf8 100644 --- a/faststream/confluent/publisher/publisher.py +++ b/faststream/confluent/publisher/publisher.py @@ -19,7 +19,6 @@ LogicPublisher, ) from faststream.exceptions import SetupError -from faststream.specification.asyncapi.v2_6_0 import schema as v2_6_0 from faststream.specification.asyncapi.utils import resolve_payloads from faststream.specification.schema.bindings import ChannelBinding, kafka from faststream.specification.schema.channel import Channel diff --git a/faststream/confluent/subscriber/subscriber.py b/faststream/confluent/subscriber/subscriber.py index 0b6783b1dc..b706a075bb 100644 --- a/faststream/confluent/subscriber/subscriber.py +++ b/faststream/confluent/subscriber/subscriber.py @@ -10,7 +10,6 @@ DefaultSubscriber, LogicSubscriber, ) -from faststream.specification.asyncapi.v2_6_0 import schema as v2_6_0 from faststream.specification.asyncapi.utils import resolve_payloads from faststream.specification.schema.bindings import ChannelBinding, kafka from faststream.specification.schema.channel import Channel diff --git a/faststream/confluent/testing.py b/faststream/confluent/testing.py index 52475df401..90ca2291fe 100644 --- a/faststream/confluent/testing.py +++ b/faststream/confluent/testing.py @@ -12,16 +12,15 @@ from faststream.confluent.publisher.producer import AsyncConfluentFastProducer from faststream.confluent.publisher.publisher import SpecificationBatchPublisher from faststream.confluent.schemas import TopicPartition +from faststream.confluent.subscriber.subscriber import SpecificationBatchSubscriber from faststream.exceptions import SubscriberNotFound from faststream.testing.broker import TestBroker from faststream.utils.functions import timeout_scope -from faststream.confluent.subscriber.subscriber import SpecificationBatchSubscriber if TYPE_CHECKING: - from faststream.testing.broker import TestBroker, call_handler - from faststream.broker.wrapper.call import HandlerCallWrapper from faststream.confluent.publisher.publisher import SpecificationPublisher from faststream.confluent.subscriber.usecase import LogicSubscriber + from faststream.testing.broker import TestBroker from faststream.types import SendableMessage __all__ = ( diff --git a/faststream/kafka/publisher/publisher.py b/faststream/kafka/publisher/publisher.py index e16a2693a8..f6ac82a709 100644 --- a/faststream/kafka/publisher/publisher.py +++ b/faststream/kafka/publisher/publisher.py @@ -21,7 +21,6 @@ ) from faststream.specification.asyncapi.utils import resolve_payloads from faststream.specification.schema.bindings import ChannelBinding, kafka -from faststream.specification.asyncapi.v2_6_0 import schema as v2_6_0 from faststream.specification.schema.channel import Channel from faststream.specification.schema.message import CorrelationId, Message from faststream.specification.schema.operation import Operation diff --git a/faststream/kafka/subscriber/subscriber.py b/faststream/kafka/subscriber/subscriber.py index b10985bf15..8931fe14c9 100644 --- a/faststream/kafka/subscriber/subscriber.py +++ b/faststream/kafka/subscriber/subscriber.py @@ -10,7 +10,6 @@ DefaultSubscriber, LogicSubscriber, ) -from faststream.specification.asyncapi.v2_6_0 import schema as v2_6_0 from faststream.specification.asyncapi.utils import resolve_payloads from faststream.specification.schema.bindings import ChannelBinding, kafka from faststream.specification.schema.channel import Channel diff --git a/faststream/kafka/testing.py b/faststream/kafka/testing.py index bda67071b2..90143ec388 100755 --- a/faststream/kafka/testing.py +++ b/faststream/kafka/testing.py @@ -15,16 +15,16 @@ from faststream.kafka.message import KafkaMessage from faststream.kafka.parser import AioKafkaParser from faststream.kafka.publisher.producer import AioKafkaFastProducer -from faststream.testing.broker import TestBroker -from faststream.utils.functions import timeout_scope from faststream.kafka.publisher.publisher import SpecificationBatchPublisher from faststream.kafka.subscriber.subscriber import SpecificationBatchSubscriber +from faststream.testing.broker import TestBroker +from faststream.utils.functions import timeout_scope if TYPE_CHECKING: from faststream.kafka.publisher.producer import AioKafkaFastProducer - from faststream.testing.broker import TestBroker from faststream.kafka.publisher.publisher import SpecificationPublisher from faststream.kafka.subscriber.usecase import LogicSubscriber + from faststream.testing.broker import TestBroker from faststream.types import SendableMessage __all__ = ("TestKafkaBroker",) diff --git a/faststream/nats/publisher/publisher.py b/faststream/nats/publisher/publisher.py index c7862c50d1..f86c12e142 100644 --- a/faststream/nats/publisher/publisher.py +++ b/faststream/nats/publisher/publisher.py @@ -5,7 +5,6 @@ from faststream.nats.publisher.usecase import LogicPublisher from faststream.specification.asyncapi.utils import resolve_payloads from faststream.specification.schema.bindings import ChannelBinding, nats -from faststream.specification.asyncapi.v2_6_0 import schema as v2_6_0 from faststream.specification.schema.channel import Channel from faststream.specification.schema.message import CorrelationId, Message from faststream.specification.schema.operation import Operation diff --git a/faststream/nats/testing.py b/faststream/nats/testing.py index 1c9548cf81..9de6c45a21 100644 --- a/faststream/nats/testing.py +++ b/faststream/nats/testing.py @@ -16,9 +16,8 @@ from faststream.utils.functions import timeout_scope if TYPE_CHECKING: - from faststream.nats.subscriber.usecase import LogicSubscriber - from faststream.broker.wrapper.call import HandlerCallWrapper from faststream.nats.publisher.publisher import SpecificationPublisher + from faststream.nats.subscriber.usecase import LogicSubscriber from faststream.types import AnyDict, SendableMessage __all__ = ("TestNatsBroker",) diff --git a/faststream/rabbit/publisher/publisher.py b/faststream/rabbit/publisher/publisher.py index 69b80ca1ff..be9d61f0f3 100644 --- a/faststream/rabbit/publisher/publisher.py +++ b/faststream/rabbit/publisher/publisher.py @@ -2,7 +2,6 @@ from typing_extensions import override -from faststream.specification.asyncapi.v2_6_0 import schema as v2_6_0 from faststream.rabbit.publisher.usecase import LogicPublisher, PublishKwargs from faststream.rabbit.utils import is_routing_exchange from faststream.specification.asyncapi.utils import resolve_payloads diff --git a/faststream/rabbit/subscriber/subscriber.py b/faststream/rabbit/subscriber/subscriber.py index 25d68d26e3..3e844ad77c 100644 --- a/faststream/rabbit/subscriber/subscriber.py +++ b/faststream/rabbit/subscriber/subscriber.py @@ -1,6 +1,5 @@ from typing import Dict -from faststream.specification.asyncapi.v2_6_0 import schema as v2_6_0 from faststream.rabbit.subscriber.usecase import LogicSubscriber from faststream.rabbit.utils import is_routing_exchange from faststream.specification.asyncapi.utils import resolve_payloads diff --git a/faststream/redis/publisher/publisher.py b/faststream/redis/publisher/publisher.py index 4e75dab070..759308872e 100644 --- a/faststream/redis/publisher/publisher.py +++ b/faststream/redis/publisher/publisher.py @@ -2,7 +2,6 @@ from typing_extensions import TypeAlias, override -from faststream.specification.asyncapi.v2_6_0 import schema as v2_6_0 from faststream.exceptions import SetupError from faststream.redis.publisher.usecase import ( ChannelPublisher, diff --git a/faststream/redis/schemas/proto.py b/faststream/redis/schemas/proto.py index ba358101d9..c130e07a23 100644 --- a/faststream/redis/schemas/proto.py +++ b/faststream/redis/schemas/proto.py @@ -7,7 +7,6 @@ if TYPE_CHECKING: from faststream.redis.schemas import ListSub, PubSub, StreamSub from faststream.specification.schema.bindings import redis - from faststream.redis.schemas import ListSub, PubSub, StreamSub class RedisAsyncAPIProtocol(SpecificationProto): diff --git a/faststream/redis/subscriber/subscriber.py b/faststream/redis/subscriber/subscriber.py index 695d5e247f..54a9b57578 100644 --- a/faststream/redis/subscriber/subscriber.py +++ b/faststream/redis/subscriber/subscriber.py @@ -1,6 +1,5 @@ from typing import Dict -from faststream.specification.asyncapi.v2_6_0 import schema as v2_6_0 from faststream.redis.schemas import ListSub, StreamSub from faststream.redis.schemas.proto import RedisAsyncAPIProtocol from faststream.redis.subscriber.usecase import ( diff --git a/faststream/specification/schema/contact.py b/faststream/specification/schema/contact.py index c0b43be7c4..dec0c5d5cc 100644 --- a/faststream/specification/schema/contact.py +++ b/faststream/specification/schema/contact.py @@ -18,7 +18,6 @@ ) from faststream.log import logger - try: import email_validator diff --git a/faststream/specification/schema/operation.py b/faststream/specification/schema/operation.py index eccd0eb12c..71b56c5d16 100644 --- a/faststream/specification/schema/operation.py +++ b/faststream/specification/schema/operation.py @@ -6,7 +6,6 @@ from faststream.specification.schema.tag import Tag - @dataclass class Operation: """A class to represent an operation. diff --git a/faststream/specification/schema/schema.py b/faststream/specification/schema/schema.py index 89a6b486bf..f3dafed01b 100644 --- a/faststream/specification/schema/schema.py +++ b/faststream/specification/schema/schema.py @@ -4,13 +4,6 @@ from faststream._compat import model_to_json, model_to_jsonable from faststream.specification.asyncapi.base.schema import BaseInfo -from faststream.specification.schema.channel import Channel -from faststream.specification.schema.components import Components -from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict -from faststream.specification.schema.info import Info -from faststream.specification.schema.servers import Server -from faststream.specification.schema.tag import Tag -from faststream._compat import model_to_json, model_to_jsonable class BaseSchema(BaseModel): From 21a0d62768c99fecd49cc024802183aa1f1659ea Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 8 Sep 2024 14:19:13 +0300 Subject: [PATCH 130/245] Fix kafka oauth test --- tests/asyncapi/kafka/v2_6_0/test_security.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/asyncapi/kafka/v2_6_0/test_security.py b/tests/asyncapi/kafka/v2_6_0/test_security.py index 87251b7f19..3dbeb0710c 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_security.py +++ b/tests/asyncapi/kafka/v2_6_0/test_security.py @@ -185,7 +185,7 @@ def test_oauthbearer_security_schema(): async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app).to_jsonable() + schema = get_app_schema(app, version="2.6.0").to_jsonable() sasl_oauthbearer_security_schema = deepcopy(basic_schema) sasl_oauthbearer_security_schema["servers"]["development"]["security"] = [ From 94adc4e6d81dd163922b8175b0d24e98b5eeef8f Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 8 Sep 2024 14:21:15 +0300 Subject: [PATCH 131/245] Revert start_test_env.sh script docker compose update --- scripts/start_test_env.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/start_test_env.sh b/scripts/start_test_env.sh index 906556db41..a0ae1627b8 100755 --- a/scripts/start_test_env.sh +++ b/scripts/start_test_env.sh @@ -2,4 +2,4 @@ source ./scripts/set_variables.sh -docker compose -p $DOCKER_COMPOSE_PROJECT -f docs/includes/docker-compose.yaml up -d --no-recreate +docker-compose -p $DOCKER_COMPOSE_PROJECT -f docs/includes/docker-compose.yaml up -d --no-recreate From 5dd2f7c16a920de6ffc30e1703176bfd47c9506b Mon Sep 17 00:00:00 2001 From: KrySeyt Date: Sun, 8 Sep 2024 11:25:20 +0000 Subject: [PATCH 132/245] docs: generate API References --- docs/docs/SUMMARY.md | 452 ++++++++++++------ .../asyncapi/proto/AsyncAPIApplication.md | 11 - .../asyncapi/proto/AsyncAPIProto.md | 11 - .../asyncapi/schema/ServerBinding.md | 11 - .../asyncapi/schema/bindings/ServerBinding.md | 11 - .../schema/bindings/amqp/ServerBinding.md | 11 - .../schema/bindings/kafka/ServerBinding.md | 11 - .../schema/bindings/main/ChannelBinding.md | 11 - .../schema/bindings/main/OperationBinding.md | 11 - .../schema/bindings/main/ServerBinding.md | 11 - .../schema/bindings/nats/ChannelBinding.md | 11 - .../schema/bindings/nats/OperationBinding.md | 11 - .../schema/bindings/nats/ServerBinding.md | 11 - .../schema/bindings/redis/ChannelBinding.md | 11 - .../schema/bindings/redis/OperationBinding.md | 11 - .../schema/bindings/redis/ServerBinding.md | 11 - .../schema/bindings/sqs/ChannelBinding.md | 11 - .../schema/bindings/sqs/OperationBinding.md | 11 - .../schema/bindings/sqs/ServerBinding.md | 11 - .../asyncapi/schema/info/ContactDict.md | 11 - .../asyncapi/schema/info/LicenseDict.md | 11 - .../security/SecuritySchemaComponent.md | 11 - .../asyncapi/schema/utils/ExternalDocsDict.md | 11 - .../asyncapi/schema/utils/TagDict.md | 11 - .../publisher/asyncapi/AsyncAPIPublisher.md | 11 - .../publisher/SpecificationBatchPublisher.md | 11 + .../SpecificationDefaultPublisher.md | 11 + .../publisher/SpecificationPublisher.md | 11 + .../subscriber/asyncapi/AsyncAPISubscriber.md | 11 - .../SpecificationBatchSubscriber.md | 11 + .../SpecificationDefaultSubscriber.md | 11 + .../SpecificationSubscriber.md} | 2 +- .../asyncapi/AsyncAPIBatchPublisher.md | 11 - .../publisher/asyncapi/AsyncAPIPublisher.md | 11 - .../publisher/SpecificationBatchPublisher.md} | 2 +- .../SpecificationDefaultPublisher.md | 11 + .../publisher/SpecificationPublisher.md | 11 + .../subscriber/asyncapi/AsyncAPISubscriber.md | 11 - .../SpecificationBatchSubscriber.md} | 2 +- .../SpecificationDefaultSubscriber.md} | 2 +- .../subscriber/SpecificationSubscriber.md} | 2 +- .../publisher/asyncapi/AsyncAPIPublisher.md | 11 - .../publisher/SpecificationPublisher.md | 11 + .../AsyncAPIConcurrentPullStreamSubscriber.md | 11 - .../AsyncAPIConcurrentPushStreamSubscriber.md | 11 - .../asyncapi/AsyncAPICoreSubscriber.md | 11 - .../asyncapi/AsyncAPIPullStreamSubscriber.md | 11 - .../subscriber/asyncapi/AsyncAPISubscriber.md | 11 - .../SpecificationBatchPullStreamSubscriber.md | 11 + .../SpecificationConcurrentCoreSubscriber.md | 11 + ...ificationConcurrentPullStreamSubscriber.md | 11 + ...ificationConcurrentPushStreamSubscriber.md | 11 + .../subscriber/SpecificationCoreSubscriber.md | 11 + .../SpecificationKeyValueWatchSubscriber.md | 11 + .../SpecificationObjStoreWatchSubscriber.md | 11 + .../SpecificationPullStreamSubscriber.md | 11 + .../SpecificationStreamSubscriber.md} | 2 +- .../subscriber/SpecificationSubscriber.md} | 2 +- .../publisher/asyncapi/AsyncAPIPublisher.md | 11 - .../publisher/SpecificationPublisher.md} | 2 +- .../subscriber/asyncapi/AsyncAPISubscriber.md | 11 - .../subscriber/SpecificationSubscriber.md | 11 + .../publisher/asyncapi/AsyncAPIPublisher.md | 11 - .../asyncapi/AsyncAPIStreamPublisher.md | 11 - .../publisher/AsyncAPIChannelPublisher.md | 11 + .../publisher/AsyncAPIListBatchPublisher.md | 11 + .../AsyncAPIListPublisher.md | 2 +- .../publisher/AsyncAPIStreamPublisher.md} | 2 +- .../publisher/SpecificationPublisher.md | 11 + .../asyncapi/AsyncAPIListBatchSubscriber.md | 11 - .../subscriber/asyncapi/AsyncAPISubscriber.md | 11 - .../subscriber/AsyncAPIChannelSubscriber.md} | 2 +- .../AsyncAPIListBatchSubscriber.md} | 2 +- .../AsyncAPIListSubscriber.md | 2 +- .../AsyncAPIStreamBatchSubscriber.md} | 2 +- .../subscriber/AsyncAPIStreamSubscriber.md | 11 + .../subscriber/SpecificationSubscriber.md} | 2 +- .../asyncapi/base/schema/BaseInfo.md | 11 + .../asyncapi/base/schema/BaseSchema.md | 11 + .../asyncapi/base/schema/info/BaseInfo.md | 11 + .../asyncapi/base/schema/schema/BaseSchema.md | 11 + .../asyncapi/generate/get_app_schema.md | 11 + .../asyncapi/get_app_schema.md | 2 +- .../asyncapi/get_asyncapi_html.md | 2 +- .../asyncapi/message/get_model_schema.md | 2 +- .../asyncapi/message/get_response_schema.md | 2 +- .../asyncapi/message/parse_handler_params.md | 2 +- .../asyncapi/site/get_asyncapi_html.md | 2 +- .../asyncapi/site/serve_app.md | 2 +- .../asyncapi/utils/resolve_payloads.md | 2 +- .../asyncapi/utils/to_camelcase.md | 2 +- .../v2_6_0/generate/get_app_schema.md | 11 + .../v2_6_0/generate/get_broker_channels.md | 11 + .../v2_6_0/generate/get_broker_server.md | 11 + .../v2_6_0/generate/move_pydantic_refs.md | 11 + .../generate/resolve_channel_messages.md | 11 + .../asyncapi/v2_6_0/get_app_schema.md | 11 + .../asyncapi/v2_6_0/schema}/Channel.md | 2 +- .../asyncapi/v2_6_0/schema}/Components.md | 2 +- .../asyncapi/v2_6_0/schema}/Contact.md | 2 +- .../asyncapi/v2_6_0/schema}/CorrelationId.md | 2 +- .../asyncapi/v2_6_0/schema/ExternalDocs.md} | 2 +- .../asyncapi/v2_6_0/schema}/Info.md | 2 +- .../asyncapi/v2_6_0/schema}/License.md | 2 +- .../asyncapi/v2_6_0/schema}/Message.md | 2 +- .../asyncapi/v2_6_0/schema}/Operation.md | 2 +- .../asyncapi/v2_6_0/schema}/Parameter.md | 2 +- .../asyncapi/v2_6_0}/schema/Reference.md | 2 +- .../asyncapi/v2_6_0}/schema/Schema.md | 2 +- .../asyncapi/v2_6_0/schema}/Server.md | 2 +- .../asyncapi/v2_6_0/schema/ServerVariable.md | 11 + .../asyncapi/v2_6_0/schema}/Tag.md | 2 +- .../v2_6_0/schema/bindings/ChannelBinding.md | 11 + .../schema/bindings/OperationBinding.md | 11 + .../schema/bindings/amqp/ChannelBinding.md | 11 + .../schema/bindings/amqp/OperationBinding.md | 11 + .../bindings/amqp/channel/ChannelBinding.md | 11 + .../schema/bindings/amqp/channel/Exchange.md | 11 + .../schema/bindings/amqp/channel/Queue.md | 11 + .../schema/bindings/amqp/channel/from_spec.md | 11 + .../amqp/channel_binding_from_spec.md | 11 + .../amqp/operation/OperationBinding.md | 11 + .../bindings/amqp/operation/from_spec.md | 11 + .../amqp/operation_binding_from_spec.md | 11 + .../bindings/channel_binding_from_spec.md | 11 + .../schema/bindings/kafka/ChannelBinding.md | 11 + .../schema/bindings/kafka/OperationBinding.md | 11 + .../bindings/kafka/channel/ChannelBinding.md | 11 + .../bindings/kafka/channel/from_spec.md | 11 + .../kafka/channel_binding_from_spec.md | 11 + .../kafka/operation/OperationBinding.md | 11 + .../bindings/kafka/operation/from_spec.md | 11 + .../kafka/operation_binding_from_spec.md | 11 + .../schema/bindings/main/ChannelBinding.md | 11 + .../schema/bindings/main/OperationBinding.md | 11 + .../bindings/main/channel/ChannelBinding.md | 11 + .../schema/bindings/main/channel/from_spec.md | 11 + .../main/channel_binding_from_spec.md | 11 + .../main/operation/OperationBinding.md | 11 + .../bindings/main/operation/from_spec.md | 11 + .../main/operation_binding_from_spec.md | 11 + .../schema/bindings/nats/ChannelBinding.md | 11 + .../schema/bindings/nats/OperationBinding.md | 11 + .../bindings/nats/channel/ChannelBinding.md | 11 + .../schema/bindings/nats/channel/from_spec.md | 11 + .../nats/channel_binding_from_spec.md | 11 + .../nats/operation/OperationBinding.md | 11 + .../bindings/nats/operation/from_spec.md | 11 + .../nats/operation_binding_from_spec.md | 11 + .../bindings/operation_binding_from_spec.md | 11 + .../schema/bindings/redis/ChannelBinding.md | 11 + .../schema/bindings/redis/OperationBinding.md | 11 + .../bindings/redis/channel/ChannelBinding.md | 11 + .../bindings/redis/channel/from_spec.md | 11 + .../redis/channel_binding_from_spec.md | 11 + .../redis/operation/OperationBinding.md | 11 + .../bindings/redis/operation/from_spec.md | 11 + .../redis/operation_binding_from_spec.md | 11 + .../schema/bindings/sqs/ChannelBinding.md | 11 + .../schema/bindings/sqs/OperationBinding.md | 11 + .../bindings/sqs/channel/ChannelBinding.md | 11 + .../schema/bindings/sqs/channel/from_spec.md | 11 + .../bindings/sqs/channel_binding_from_spec.md | 11 + .../sqs/operation/OperationBinding.md | 11 + .../bindings/sqs/operation/from_spec.md | 11 + .../sqs/operation_binding_from_spec.md | 11 + .../v2_6_0/schema/channel_from_spec.md | 11 + .../v2_6_0/schema/channels/Channel.md | 11 + .../v2_6_0/schema/channels/from_spec.md | 11 + .../v2_6_0/schema/components/Components.md | 11 + .../asyncapi/v2_6_0/schema/contact/Contact.md | 11 + .../v2_6_0/schema/contact/from_spec.md | 11 + .../v2_6_0/schema/contact_from_spec.md | 11 + .../v2_6_0/schema/docs}/ExternalDocs.md | 2 +- .../asyncapi/v2_6_0/schema/docs/from_spec.md | 11 + .../asyncapi/v2_6_0/schema/docs_from_spec.md | 11 + .../asyncapi/v2_6_0/schema/info/Info.md | 11 + .../asyncapi/v2_6_0/schema/license/License.md | 11 + .../v2_6_0/schema/license/from_spec.md | 11 + .../v2_6_0/schema/license_from_spec.md | 11 + .../v2_6_0/schema/message/CorrelationId.md | 11 + .../asyncapi/v2_6_0/schema/message/Message.md | 11 + .../v2_6_0/schema/message/from_spec.md | 11 + .../v2_6_0/schema/message_from_spec.md | 11 + .../v2_6_0/schema/operation_from_spec.md | 11 + .../v2_6_0/schema/operations/Operation.md | 11 + .../v2_6_0/schema/operations/from_spec.md | 11 + .../asyncapi/v2_6_0/schema/schema/Schema.md | 11 + .../asyncapi/v2_6_0/schema/servers/Server.md} | 2 +- .../v2_6_0/schema/servers/ServerVariable.md | 11 + .../asyncapi/v2_6_0/schema/tag/Tag.md | 11 + .../asyncapi/v2_6_0/schema/tag/from_spec.md | 11 + .../asyncapi/v2_6_0/schema/tag_from_spec.md | 11 + .../asyncapi/v2_6_0/schema/utils/Parameter.md | 11 + .../v2_6_0}/schema/utils/Reference.md | 2 +- .../v3_0_0/generate/get_app_schema.md | 11 + .../v3_0_0/generate/get_broker_channels.md | 11 + .../v3_0_0/generate/get_broker_operations.md | 11 + .../v3_0_0/generate/get_broker_server.md | 11 + .../asyncapi/v3_0_0/get_app_schema.md | 11 + .../asyncapi/v3_0_0/schema/Channel.md | 11 + .../asyncapi/v3_0_0/schema/Components.md | 11 + .../asyncapi/v3_0_0/schema/Info.md} | 2 +- .../asyncapi/v3_0_0/schema/Operation.md | 11 + .../asyncapi/v3_0_0/schema}/Schema.md | 2 +- .../asyncapi/v3_0_0/schema/Server.md | 11 + .../v3_0_0/schema/channel_from_spec.md | 11 + .../v3_0_0/schema/channels/Channel.md | 11 + .../v3_0_0/schema/channels/from_spec.md | 11 + .../v3_0_0/schema/components/Components.md | 11 + .../asyncapi/v3_0_0/schema/info/Info.md | 11 + .../v3_0_0/schema/operation_from_spec.md | 11 + .../v3_0_0/schema/operations/Action.md | 11 + .../v3_0_0/schema/operations/Operation.md | 11 + .../v3_0_0/schema/operations/from_spec.md | 11 + .../asyncapi/v3_0_0/schema/schema/Schema.md | 11 + .../asyncapi/v3_0_0/schema/servers/Server.md} | 2 +- .../proto/Application.md} | 2 +- .../proto/SpecificationProto.md} | 2 +- .../schema/bindings}/ChannelBinding.md | 2 +- .../schema/bindings}/OperationBinding.md | 2 +- .../schema/bindings/amqp/ChannelBinding.md} | 2 +- .../schema/bindings/amqp/Exchange.md | 2 +- .../schema/bindings/amqp/OperationBinding.md | 2 +- .../schema/bindings/amqp/Queue.md | 2 +- .../schema/bindings/kafka}/ChannelBinding.md | 2 +- .../schema/bindings/kafka/OperationBinding.md | 11 + .../schema/bindings/main/ChannelBinding.md | 11 + .../schema/bindings/main}/OperationBinding.md | 2 +- .../schema/bindings/nats/ChannelBinding.md | 11 + .../schema/bindings/nats/OperationBinding.md | 11 + .../schema/bindings/redis}/ChannelBinding.md | 2 +- .../schema/bindings/redis/OperationBinding.md | 11 + .../schema/bindings/sqs}/ChannelBinding.md | 2 +- .../schema/bindings/sqs}/OperationBinding.md | 2 +- .../schema/channel}/Channel.md | 2 +- .../schema/components}/Components.md | 2 +- .../schema/contact}/Contact.md | 2 +- .../schema/contact}/ContactDict.md | 2 +- .../schema/docs}/ExternalDocs.md | 2 +- .../schema/docs}/ExternalDocsDict.md | 2 +- .../schema/info}/Info.md | 2 +- .../schema/license}/License.md | 2 +- .../schema/license}/LicenseDict.md | 2 +- .../schema/message}/CorrelationId.md | 2 +- .../schema/message}/Message.md | 2 +- .../schema/operation}/Operation.md | 2 +- .../schema/schema/BaseSchema.md} | 2 +- .../schema/security/OauthFlowObj.md | 2 +- .../schema/security/OauthFlows.md | 2 +- .../security}/SecuritySchemaComponent.md | 2 +- .../schema/servers}/Server.md | 2 +- .../schema/servers/ServerVariable.md | 2 +- .../schema/tag}/Tag.md | 2 +- .../schema/tag}/TagDict.md | 2 +- 255 files changed, 1882 insertions(+), 671 deletions(-) delete mode 100644 docs/docs/en/api/faststream/asyncapi/proto/AsyncAPIApplication.md delete mode 100644 docs/docs/en/api/faststream/asyncapi/proto/AsyncAPIProto.md delete mode 100644 docs/docs/en/api/faststream/asyncapi/schema/ServerBinding.md delete mode 100644 docs/docs/en/api/faststream/asyncapi/schema/bindings/ServerBinding.md delete mode 100644 docs/docs/en/api/faststream/asyncapi/schema/bindings/amqp/ServerBinding.md delete mode 100644 docs/docs/en/api/faststream/asyncapi/schema/bindings/kafka/ServerBinding.md delete mode 100644 docs/docs/en/api/faststream/asyncapi/schema/bindings/main/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/asyncapi/schema/bindings/main/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/asyncapi/schema/bindings/main/ServerBinding.md delete mode 100644 docs/docs/en/api/faststream/asyncapi/schema/bindings/nats/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/asyncapi/schema/bindings/nats/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/asyncapi/schema/bindings/nats/ServerBinding.md delete mode 100644 docs/docs/en/api/faststream/asyncapi/schema/bindings/redis/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/asyncapi/schema/bindings/redis/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/asyncapi/schema/bindings/redis/ServerBinding.md delete mode 100644 docs/docs/en/api/faststream/asyncapi/schema/bindings/sqs/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/asyncapi/schema/bindings/sqs/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/asyncapi/schema/bindings/sqs/ServerBinding.md delete mode 100644 docs/docs/en/api/faststream/asyncapi/schema/info/ContactDict.md delete mode 100644 docs/docs/en/api/faststream/asyncapi/schema/info/LicenseDict.md delete mode 100644 docs/docs/en/api/faststream/asyncapi/schema/security/SecuritySchemaComponent.md delete mode 100644 docs/docs/en/api/faststream/asyncapi/schema/utils/ExternalDocsDict.md delete mode 100644 docs/docs/en/api/faststream/asyncapi/schema/utils/TagDict.md delete mode 100644 docs/docs/en/api/faststream/confluent/publisher/asyncapi/AsyncAPIPublisher.md create mode 100644 docs/docs/en/api/faststream/confluent/publisher/publisher/SpecificationBatchPublisher.md create mode 100644 docs/docs/en/api/faststream/confluent/publisher/publisher/SpecificationDefaultPublisher.md create mode 100644 docs/docs/en/api/faststream/confluent/publisher/publisher/SpecificationPublisher.md delete mode 100644 docs/docs/en/api/faststream/confluent/subscriber/asyncapi/AsyncAPISubscriber.md create mode 100644 docs/docs/en/api/faststream/confluent/subscriber/subscriber/SpecificationBatchSubscriber.md create mode 100644 docs/docs/en/api/faststream/confluent/subscriber/subscriber/SpecificationDefaultSubscriber.md rename docs/docs/en/api/faststream/confluent/subscriber/{asyncapi/AsyncAPIDefaultSubscriber.md => subscriber/SpecificationSubscriber.md} (64%) delete mode 100644 docs/docs/en/api/faststream/kafka/publisher/asyncapi/AsyncAPIBatchPublisher.md delete mode 100644 docs/docs/en/api/faststream/kafka/publisher/asyncapi/AsyncAPIPublisher.md rename docs/docs/en/api/faststream/{confluent/publisher/asyncapi/AsyncAPIDefaultPublisher.md => kafka/publisher/publisher/SpecificationBatchPublisher.md} (64%) create mode 100644 docs/docs/en/api/faststream/kafka/publisher/publisher/SpecificationDefaultPublisher.md create mode 100644 docs/docs/en/api/faststream/kafka/publisher/publisher/SpecificationPublisher.md delete mode 100644 docs/docs/en/api/faststream/kafka/subscriber/asyncapi/AsyncAPISubscriber.md rename docs/docs/en/api/faststream/{nats/subscriber/asyncapi/AsyncAPIKeyValueWatchSubscriber.md => kafka/subscriber/subscriber/SpecificationBatchSubscriber.md} (64%) rename docs/docs/en/api/faststream/{nats/subscriber/asyncapi/AsyncAPIBatchPullStreamSubscriber.md => kafka/subscriber/subscriber/SpecificationDefaultSubscriber.md} (65%) rename docs/docs/en/api/faststream/{confluent/publisher/asyncapi/AsyncAPIBatchPublisher.md => kafka/subscriber/subscriber/SpecificationSubscriber.md} (63%) delete mode 100644 docs/docs/en/api/faststream/nats/publisher/asyncapi/AsyncAPIPublisher.md create mode 100644 docs/docs/en/api/faststream/nats/publisher/publisher/SpecificationPublisher.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIConcurrentPullStreamSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIConcurrentPushStreamSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPICoreSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIPullStreamSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPISubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationBatchPullStreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationConcurrentCoreSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationConcurrentPullStreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationConcurrentPushStreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationCoreSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationKeyValueWatchSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationObjStoreWatchSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationPullStreamSubscriber.md rename docs/docs/en/api/faststream/nats/subscriber/{asyncapi/AsyncAPIObjStoreWatchSubscriber.md => subscriber/SpecificationStreamSubscriber.md} (64%) rename docs/docs/en/api/faststream/{redis/subscriber/asyncapi/AsyncAPIStreamSubscriber.md => nats/subscriber/subscriber/SpecificationSubscriber.md} (63%) delete mode 100644 docs/docs/en/api/faststream/rabbit/publisher/asyncapi/AsyncAPIPublisher.md rename docs/docs/en/api/faststream/{kafka/publisher/asyncapi/AsyncAPIDefaultPublisher.md => rabbit/publisher/publisher/SpecificationPublisher.md} (63%) delete mode 100644 docs/docs/en/api/faststream/rabbit/subscriber/asyncapi/AsyncAPISubscriber.md create mode 100644 docs/docs/en/api/faststream/rabbit/subscriber/subscriber/SpecificationSubscriber.md delete mode 100644 docs/docs/en/api/faststream/redis/publisher/asyncapi/AsyncAPIPublisher.md delete mode 100644 docs/docs/en/api/faststream/redis/publisher/asyncapi/AsyncAPIStreamPublisher.md create mode 100644 docs/docs/en/api/faststream/redis/publisher/publisher/AsyncAPIChannelPublisher.md create mode 100644 docs/docs/en/api/faststream/redis/publisher/publisher/AsyncAPIListBatchPublisher.md rename docs/docs/en/api/faststream/redis/publisher/{asyncapi => publisher}/AsyncAPIListPublisher.md (63%) rename docs/docs/en/api/faststream/{kafka/subscriber/asyncapi/AsyncAPIBatchSubscriber.md => redis/publisher/publisher/AsyncAPIStreamPublisher.md} (63%) create mode 100644 docs/docs/en/api/faststream/redis/publisher/publisher/SpecificationPublisher.md delete mode 100644 docs/docs/en/api/faststream/redis/subscriber/asyncapi/AsyncAPIListBatchSubscriber.md delete mode 100644 docs/docs/en/api/faststream/redis/subscriber/asyncapi/AsyncAPISubscriber.md rename docs/docs/en/api/faststream/{confluent/subscriber/asyncapi/AsyncAPIBatchSubscriber.md => redis/subscriber/subscriber/AsyncAPIChannelSubscriber.md} (64%) rename docs/docs/en/api/faststream/redis/subscriber/{asyncapi/AsyncAPIStreamBatchSubscriber.md => subscriber/AsyncAPIListBatchSubscriber.md} (64%) rename docs/docs/en/api/faststream/redis/subscriber/{asyncapi => subscriber}/AsyncAPIListSubscriber.md (62%) rename docs/docs/en/api/faststream/{nats/subscriber/asyncapi/AsyncAPIConcurrentCoreSubscriber.md => redis/subscriber/subscriber/AsyncAPIStreamBatchSubscriber.md} (65%) create mode 100644 docs/docs/en/api/faststream/redis/subscriber/subscriber/AsyncAPIStreamSubscriber.md rename docs/docs/en/api/faststream/{kafka/subscriber/asyncapi/AsyncAPIDefaultSubscriber.md => redis/subscriber/subscriber/SpecificationSubscriber.md} (63%) create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/base/schema/BaseInfo.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/base/schema/BaseSchema.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/base/schema/info/BaseInfo.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/base/schema/schema/BaseSchema.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/generate/get_app_schema.md rename docs/docs/en/api/faststream/{ => specification}/asyncapi/get_app_schema.md (67%) rename docs/docs/en/api/faststream/{ => specification}/asyncapi/get_asyncapi_html.md (66%) rename docs/docs/en/api/faststream/{ => specification}/asyncapi/message/get_model_schema.md (63%) rename docs/docs/en/api/faststream/{ => specification}/asyncapi/message/get_response_schema.md (62%) rename docs/docs/en/api/faststream/{ => specification}/asyncapi/message/parse_handler_params.md (62%) rename docs/docs/en/api/faststream/{ => specification}/asyncapi/site/get_asyncapi_html.md (64%) rename docs/docs/en/api/faststream/{ => specification}/asyncapi/site/serve_app.md (67%) rename docs/docs/en/api/faststream/{ => specification}/asyncapi/utils/resolve_payloads.md (64%) rename docs/docs/en/api/faststream/{ => specification}/asyncapi/utils/to_camelcase.md (65%) create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_app_schema.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_channels.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_server.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/move_pydantic_refs.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/resolve_channel_messages.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/get_app_schema.md rename docs/docs/en/api/faststream/{asyncapi/schema/channels => specification/asyncapi/v2_6_0/schema}/Channel.md (64%) rename docs/docs/en/api/faststream/{asyncapi/schema/main => specification/asyncapi/v2_6_0/schema}/Components.md (63%) rename docs/docs/en/api/faststream/{asyncapi/schema/info => specification/asyncapi/v2_6_0/schema}/Contact.md (64%) rename docs/docs/en/api/faststream/{asyncapi/schema/message => specification/asyncapi/v2_6_0/schema}/CorrelationId.md (62%) rename docs/docs/en/api/faststream/{nats/subscriber/asyncapi/AsyncAPIStreamSubscriber.md => specification/asyncapi/v2_6_0/schema/ExternalDocs.md} (63%) rename docs/docs/en/api/faststream/{asyncapi/schema/info => specification/asyncapi/v2_6_0/schema}/Info.md (65%) rename docs/docs/en/api/faststream/{asyncapi/schema/info => specification/asyncapi/v2_6_0/schema}/License.md (64%) rename docs/docs/en/api/faststream/{asyncapi/schema/message => specification/asyncapi/v2_6_0/schema}/Message.md (64%) rename docs/docs/en/api/faststream/{asyncapi/schema/operations => specification/asyncapi/v2_6_0/schema}/Operation.md (63%) rename docs/docs/en/api/faststream/{asyncapi/schema/utils => specification/asyncapi/v2_6_0/schema}/Parameter.md (63%) rename docs/docs/en/api/faststream/{asyncapi => specification/asyncapi/v2_6_0}/schema/Reference.md (63%) rename docs/docs/en/api/faststream/{asyncapi => specification/asyncapi/v2_6_0}/schema/Schema.md (65%) rename docs/docs/en/api/faststream/{asyncapi/schema/servers => specification/asyncapi/v2_6_0/schema}/Server.md (65%) create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ServerVariable.md rename docs/docs/en/api/faststream/{asyncapi/schema/utils => specification/asyncapi/v2_6_0/schema}/Tag.md (66%) create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Exchange.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Queue.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel_binding_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation_binding_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/channel_binding_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel_binding_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation_binding_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel_binding_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation_binding_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel_binding_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation_binding_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/operation_binding_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel_binding_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation_binding_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel_binding_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation_binding_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channel_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channels/Channel.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channels/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/components/Components.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact/Contact.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact_from_spec.md rename docs/docs/en/api/faststream/{asyncapi/schema/utils => specification/asyncapi/v2_6_0/schema/docs}/ExternalDocs.md (61%) create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/info/Info.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license/License.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/CorrelationId.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/Message.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operation_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operations/Operation.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operations/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/schema/Schema.md rename docs/docs/en/api/faststream/{redis/publisher/asyncapi/AsyncAPIListBatchPublisher.md => specification/asyncapi/v2_6_0/schema/servers/Server.md} (63%) create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/servers/ServerVariable.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag/Tag.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/utils/Parameter.md rename docs/docs/en/api/faststream/{asyncapi => specification/asyncapi/v2_6_0}/schema/utils/Reference.md (61%) create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_app_schema.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_channels.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_operations.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_server.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/get_app_schema.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Channel.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Components.md rename docs/docs/en/api/faststream/{asyncapi/generate/get_broker_server.md => specification/asyncapi/v3_0_0/schema/Info.md} (65%) create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Operation.md rename docs/docs/en/api/faststream/{asyncapi/schema/main => specification/asyncapi/v3_0_0/schema}/Schema.md (65%) create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Server.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channel_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channels/Channel.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channels/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/components/Components.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/info/Info.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operation_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/Action.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/Operation.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/schema/Schema.md rename docs/docs/en/api/faststream/{redis/subscriber/asyncapi/AsyncAPIChannelSubscriber.md => specification/asyncapi/v3_0_0/schema/servers/Server.md} (63%) rename docs/docs/en/api/faststream/{asyncapi/abc/AsyncAPIOperation.md => specification/proto/Application.md} (70%) rename docs/docs/en/api/faststream/{asyncapi/generate/get_app_schema.md => specification/proto/SpecificationProto.md} (67%) rename docs/docs/en/api/faststream/{asyncapi/schema => specification/schema/bindings}/ChannelBinding.md (64%) rename docs/docs/en/api/faststream/{asyncapi/schema => specification/schema/bindings}/OperationBinding.md (63%) rename docs/docs/en/api/faststream/{redis/publisher/asyncapi/AsyncAPIChannelPublisher.md => specification/schema/bindings/amqp/ChannelBinding.md} (63%) rename docs/docs/en/api/faststream/{asyncapi => specification}/schema/bindings/amqp/Exchange.md (65%) rename docs/docs/en/api/faststream/{asyncapi => specification}/schema/bindings/amqp/OperationBinding.md (62%) rename docs/docs/en/api/faststream/{asyncapi => specification}/schema/bindings/amqp/Queue.md (66%) rename docs/docs/en/api/faststream/{asyncapi/schema/bindings/amqp => specification/schema/bindings/kafka}/ChannelBinding.md (62%) create mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/kafka/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/main/ChannelBinding.md rename docs/docs/en/api/faststream/{asyncapi/schema/bindings/kafka => specification/schema/bindings/main}/OperationBinding.md (62%) create mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/nats/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/nats/OperationBinding.md rename docs/docs/en/api/faststream/{asyncapi/schema/bindings/kafka => specification/schema/bindings/redis}/ChannelBinding.md (62%) create mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/redis/OperationBinding.md rename docs/docs/en/api/faststream/{asyncapi/schema/bindings => specification/schema/bindings/sqs}/ChannelBinding.md (63%) rename docs/docs/en/api/faststream/{asyncapi/schema/bindings => specification/schema/bindings/sqs}/OperationBinding.md (62%) rename docs/docs/en/api/faststream/{asyncapi/schema => specification/schema/channel}/Channel.md (67%) rename docs/docs/en/api/faststream/{asyncapi/schema => specification/schema/components}/Components.md (65%) rename docs/docs/en/api/faststream/{asyncapi/schema => specification/schema/contact}/Contact.md (67%) rename docs/docs/en/api/faststream/{asyncapi/schema => specification/schema/contact}/ContactDict.md (66%) rename docs/docs/en/api/faststream/{asyncapi/schema => specification/schema/docs}/ExternalDocs.md (67%) rename docs/docs/en/api/faststream/{asyncapi/schema => specification/schema/docs}/ExternalDocsDict.md (65%) rename docs/docs/en/api/faststream/{asyncapi/schema => specification/schema/info}/Info.md (70%) rename docs/docs/en/api/faststream/{asyncapi/schema => specification/schema/license}/License.md (67%) rename docs/docs/en/api/faststream/{asyncapi/schema => specification/schema/license}/LicenseDict.md (66%) rename docs/docs/en/api/faststream/{asyncapi/schema => specification/schema/message}/CorrelationId.md (65%) rename docs/docs/en/api/faststream/{asyncapi/schema => specification/schema/message}/Message.md (67%) rename docs/docs/en/api/faststream/{asyncapi/schema => specification/schema/operation}/Operation.md (66%) rename docs/docs/en/api/faststream/{asyncapi/generate/get_broker_channels.md => specification/schema/schema/BaseSchema.md} (67%) rename docs/docs/en/api/faststream/{asyncapi => specification}/schema/security/OauthFlowObj.md (65%) rename docs/docs/en/api/faststream/{asyncapi => specification}/schema/security/OauthFlows.md (66%) rename docs/docs/en/api/faststream/{asyncapi/schema => specification/schema/security}/SecuritySchemaComponent.md (61%) rename docs/docs/en/api/faststream/{asyncapi/schema => specification/schema/servers}/Server.md (68%) rename docs/docs/en/api/faststream/{asyncapi => specification}/schema/servers/ServerVariable.md (65%) rename docs/docs/en/api/faststream/{asyncapi/schema => specification/schema/tag}/Tag.md (71%) rename docs/docs/en/api/faststream/{asyncapi/schema => specification/schema/tag}/TagDict.md (69%) diff --git a/docs/docs/SUMMARY.md b/docs/docs/SUMMARY.md index a5e41f0749..5307fef20f 100644 --- a/docs/docs/SUMMARY.md +++ b/docs/docs/SUMMARY.md @@ -131,9 +131,6 @@ search: - [get](public_api/faststream/asgi/get.md) - [make_asyncapi_asgi](public_api/faststream/asgi/make_asyncapi_asgi.md) - [make_ping_asgi](public_api/faststream/asgi/make_ping_asgi.md) - - asyncapi - - [get_app_schema](public_api/faststream/asyncapi/get_app_schema.md) - - [get_asyncapi_html](public_api/faststream/asyncapi/get_asyncapi_html.md) - confluent - [KafkaBroker](public_api/faststream/confluent/KafkaBroker.md) - [KafkaPublisher](public_api/faststream/confluent/KafkaPublisher.md) @@ -234,111 +231,6 @@ search: - [AsgiResponse](api/faststream/asgi/response/AsgiResponse.md) - websocket - [WebSocketClose](api/faststream/asgi/websocket/WebSocketClose.md) - - asyncapi - - [get_app_schema](api/faststream/asyncapi/get_app_schema.md) - - [get_asyncapi_html](api/faststream/asyncapi/get_asyncapi_html.md) - - abc - - [AsyncAPIOperation](api/faststream/asyncapi/abc/AsyncAPIOperation.md) - - generate - - [get_app_schema](api/faststream/asyncapi/generate/get_app_schema.md) - - [get_broker_channels](api/faststream/asyncapi/generate/get_broker_channels.md) - - [get_broker_server](api/faststream/asyncapi/generate/get_broker_server.md) - - message - - [get_model_schema](api/faststream/asyncapi/message/get_model_schema.md) - - [get_response_schema](api/faststream/asyncapi/message/get_response_schema.md) - - [parse_handler_params](api/faststream/asyncapi/message/parse_handler_params.md) - - proto - - [AsyncAPIApplication](api/faststream/asyncapi/proto/AsyncAPIApplication.md) - - [AsyncAPIProto](api/faststream/asyncapi/proto/AsyncAPIProto.md) - - schema - - [Channel](api/faststream/asyncapi/schema/Channel.md) - - [ChannelBinding](api/faststream/asyncapi/schema/ChannelBinding.md) - - [Components](api/faststream/asyncapi/schema/Components.md) - - [Contact](api/faststream/asyncapi/schema/Contact.md) - - [ContactDict](api/faststream/asyncapi/schema/ContactDict.md) - - [CorrelationId](api/faststream/asyncapi/schema/CorrelationId.md) - - [ExternalDocs](api/faststream/asyncapi/schema/ExternalDocs.md) - - [ExternalDocsDict](api/faststream/asyncapi/schema/ExternalDocsDict.md) - - [Info](api/faststream/asyncapi/schema/Info.md) - - [License](api/faststream/asyncapi/schema/License.md) - - [LicenseDict](api/faststream/asyncapi/schema/LicenseDict.md) - - [Message](api/faststream/asyncapi/schema/Message.md) - - [Operation](api/faststream/asyncapi/schema/Operation.md) - - [OperationBinding](api/faststream/asyncapi/schema/OperationBinding.md) - - [Reference](api/faststream/asyncapi/schema/Reference.md) - - [Schema](api/faststream/asyncapi/schema/Schema.md) - - [SecuritySchemaComponent](api/faststream/asyncapi/schema/SecuritySchemaComponent.md) - - [Server](api/faststream/asyncapi/schema/Server.md) - - [ServerBinding](api/faststream/asyncapi/schema/ServerBinding.md) - - [Tag](api/faststream/asyncapi/schema/Tag.md) - - [TagDict](api/faststream/asyncapi/schema/TagDict.md) - - bindings - - [ChannelBinding](api/faststream/asyncapi/schema/bindings/ChannelBinding.md) - - [OperationBinding](api/faststream/asyncapi/schema/bindings/OperationBinding.md) - - [ServerBinding](api/faststream/asyncapi/schema/bindings/ServerBinding.md) - - amqp - - [ChannelBinding](api/faststream/asyncapi/schema/bindings/amqp/ChannelBinding.md) - - [Exchange](api/faststream/asyncapi/schema/bindings/amqp/Exchange.md) - - [OperationBinding](api/faststream/asyncapi/schema/bindings/amqp/OperationBinding.md) - - [Queue](api/faststream/asyncapi/schema/bindings/amqp/Queue.md) - - [ServerBinding](api/faststream/asyncapi/schema/bindings/amqp/ServerBinding.md) - - kafka - - [ChannelBinding](api/faststream/asyncapi/schema/bindings/kafka/ChannelBinding.md) - - [OperationBinding](api/faststream/asyncapi/schema/bindings/kafka/OperationBinding.md) - - [ServerBinding](api/faststream/asyncapi/schema/bindings/kafka/ServerBinding.md) - - main - - [ChannelBinding](api/faststream/asyncapi/schema/bindings/main/ChannelBinding.md) - - [OperationBinding](api/faststream/asyncapi/schema/bindings/main/OperationBinding.md) - - [ServerBinding](api/faststream/asyncapi/schema/bindings/main/ServerBinding.md) - - nats - - [ChannelBinding](api/faststream/asyncapi/schema/bindings/nats/ChannelBinding.md) - - [OperationBinding](api/faststream/asyncapi/schema/bindings/nats/OperationBinding.md) - - [ServerBinding](api/faststream/asyncapi/schema/bindings/nats/ServerBinding.md) - - redis - - [ChannelBinding](api/faststream/asyncapi/schema/bindings/redis/ChannelBinding.md) - - [OperationBinding](api/faststream/asyncapi/schema/bindings/redis/OperationBinding.md) - - [ServerBinding](api/faststream/asyncapi/schema/bindings/redis/ServerBinding.md) - - sqs - - [ChannelBinding](api/faststream/asyncapi/schema/bindings/sqs/ChannelBinding.md) - - [OperationBinding](api/faststream/asyncapi/schema/bindings/sqs/OperationBinding.md) - - [ServerBinding](api/faststream/asyncapi/schema/bindings/sqs/ServerBinding.md) - - channels - - [Channel](api/faststream/asyncapi/schema/channels/Channel.md) - - info - - [Contact](api/faststream/asyncapi/schema/info/Contact.md) - - [ContactDict](api/faststream/asyncapi/schema/info/ContactDict.md) - - [EmailStr](api/faststream/asyncapi/schema/info/EmailStr.md) - - [Info](api/faststream/asyncapi/schema/info/Info.md) - - [License](api/faststream/asyncapi/schema/info/License.md) - - [LicenseDict](api/faststream/asyncapi/schema/info/LicenseDict.md) - - main - - [Components](api/faststream/asyncapi/schema/main/Components.md) - - [Schema](api/faststream/asyncapi/schema/main/Schema.md) - - message - - [CorrelationId](api/faststream/asyncapi/schema/message/CorrelationId.md) - - [Message](api/faststream/asyncapi/schema/message/Message.md) - - operations - - [Operation](api/faststream/asyncapi/schema/operations/Operation.md) - - security - - [OauthFlowObj](api/faststream/asyncapi/schema/security/OauthFlowObj.md) - - [OauthFlows](api/faststream/asyncapi/schema/security/OauthFlows.md) - - [SecuritySchemaComponent](api/faststream/asyncapi/schema/security/SecuritySchemaComponent.md) - - servers - - [Server](api/faststream/asyncapi/schema/servers/Server.md) - - [ServerVariable](api/faststream/asyncapi/schema/servers/ServerVariable.md) - - utils - - [ExternalDocs](api/faststream/asyncapi/schema/utils/ExternalDocs.md) - - [ExternalDocsDict](api/faststream/asyncapi/schema/utils/ExternalDocsDict.md) - - [Parameter](api/faststream/asyncapi/schema/utils/Parameter.md) - - [Reference](api/faststream/asyncapi/schema/utils/Reference.md) - - [Tag](api/faststream/asyncapi/schema/utils/Tag.md) - - [TagDict](api/faststream/asyncapi/schema/utils/TagDict.md) - - site - - [get_asyncapi_html](api/faststream/asyncapi/site/get_asyncapi_html.md) - - [serve_app](api/faststream/asyncapi/site/serve_app.md) - - utils - - [resolve_payloads](api/faststream/asyncapi/utils/resolve_payloads.md) - - [to_camelcase](api/faststream/asyncapi/utils/to_camelcase.md) - broker - acknowledgement_watcher - [BaseWatcher](api/faststream/broker/acknowledgement_watcher/BaseWatcher.md) @@ -520,12 +412,12 @@ search: - parser - [AsyncConfluentParser](api/faststream/confluent/parser/AsyncConfluentParser.md) - publisher - - asyncapi - - [AsyncAPIBatchPublisher](api/faststream/confluent/publisher/asyncapi/AsyncAPIBatchPublisher.md) - - [AsyncAPIDefaultPublisher](api/faststream/confluent/publisher/asyncapi/AsyncAPIDefaultPublisher.md) - - [AsyncAPIPublisher](api/faststream/confluent/publisher/asyncapi/AsyncAPIPublisher.md) - producer - [AsyncConfluentFastProducer](api/faststream/confluent/publisher/producer/AsyncConfluentFastProducer.md) + - publisher + - [SpecificationBatchPublisher](api/faststream/confluent/publisher/publisher/SpecificationBatchPublisher.md) + - [SpecificationDefaultPublisher](api/faststream/confluent/publisher/publisher/SpecificationDefaultPublisher.md) + - [SpecificationPublisher](api/faststream/confluent/publisher/publisher/SpecificationPublisher.md) - usecase - [BatchPublisher](api/faststream/confluent/publisher/usecase/BatchPublisher.md) - [DefaultPublisher](api/faststream/confluent/publisher/usecase/DefaultPublisher.md) @@ -545,12 +437,12 @@ search: - security - [parse_security](api/faststream/confluent/security/parse_security.md) - subscriber - - asyncapi - - [AsyncAPIBatchSubscriber](api/faststream/confluent/subscriber/asyncapi/AsyncAPIBatchSubscriber.md) - - [AsyncAPIDefaultSubscriber](api/faststream/confluent/subscriber/asyncapi/AsyncAPIDefaultSubscriber.md) - - [AsyncAPISubscriber](api/faststream/confluent/subscriber/asyncapi/AsyncAPISubscriber.md) - factory - [create_subscriber](api/faststream/confluent/subscriber/factory/create_subscriber.md) + - subscriber + - [SpecificationBatchSubscriber](api/faststream/confluent/subscriber/subscriber/SpecificationBatchSubscriber.md) + - [SpecificationDefaultSubscriber](api/faststream/confluent/subscriber/subscriber/SpecificationDefaultSubscriber.md) + - [SpecificationSubscriber](api/faststream/confluent/subscriber/subscriber/SpecificationSubscriber.md) - usecase - [BatchSubscriber](api/faststream/confluent/subscriber/usecase/BatchSubscriber.md) - [DefaultSubscriber](api/faststream/confluent/subscriber/usecase/DefaultSubscriber.md) @@ -616,12 +508,12 @@ search: - [AioKafkaBatchParser](api/faststream/kafka/parser/AioKafkaBatchParser.md) - [AioKafkaParser](api/faststream/kafka/parser/AioKafkaParser.md) - publisher - - asyncapi - - [AsyncAPIBatchPublisher](api/faststream/kafka/publisher/asyncapi/AsyncAPIBatchPublisher.md) - - [AsyncAPIDefaultPublisher](api/faststream/kafka/publisher/asyncapi/AsyncAPIDefaultPublisher.md) - - [AsyncAPIPublisher](api/faststream/kafka/publisher/asyncapi/AsyncAPIPublisher.md) - producer - [AioKafkaFastProducer](api/faststream/kafka/publisher/producer/AioKafkaFastProducer.md) + - publisher + - [SpecificationBatchPublisher](api/faststream/kafka/publisher/publisher/SpecificationBatchPublisher.md) + - [SpecificationDefaultPublisher](api/faststream/kafka/publisher/publisher/SpecificationDefaultPublisher.md) + - [SpecificationPublisher](api/faststream/kafka/publisher/publisher/SpecificationPublisher.md) - usecase - [BatchPublisher](api/faststream/kafka/publisher/usecase/BatchPublisher.md) - [DefaultPublisher](api/faststream/kafka/publisher/usecase/DefaultPublisher.md) @@ -638,12 +530,12 @@ search: - security - [parse_security](api/faststream/kafka/security/parse_security.md) - subscriber - - asyncapi - - [AsyncAPIBatchSubscriber](api/faststream/kafka/subscriber/asyncapi/AsyncAPIBatchSubscriber.md) - - [AsyncAPIDefaultSubscriber](api/faststream/kafka/subscriber/asyncapi/AsyncAPIDefaultSubscriber.md) - - [AsyncAPISubscriber](api/faststream/kafka/subscriber/asyncapi/AsyncAPISubscriber.md) - factory - [create_subscriber](api/faststream/kafka/subscriber/factory/create_subscriber.md) + - subscriber + - [SpecificationBatchSubscriber](api/faststream/kafka/subscriber/subscriber/SpecificationBatchSubscriber.md) + - [SpecificationDefaultSubscriber](api/faststream/kafka/subscriber/subscriber/SpecificationDefaultSubscriber.md) + - [SpecificationSubscriber](api/faststream/kafka/subscriber/subscriber/SpecificationSubscriber.md) - usecase - [BatchSubscriber](api/faststream/kafka/subscriber/usecase/BatchSubscriber.md) - [DefaultSubscriber](api/faststream/kafka/subscriber/usecase/DefaultSubscriber.md) @@ -729,11 +621,11 @@ search: - [NatsParser](api/faststream/nats/parser/NatsParser.md) - [ObjParser](api/faststream/nats/parser/ObjParser.md) - publisher - - asyncapi - - [AsyncAPIPublisher](api/faststream/nats/publisher/asyncapi/AsyncAPIPublisher.md) - producer - [NatsFastProducer](api/faststream/nats/publisher/producer/NatsFastProducer.md) - [NatsJSFastProducer](api/faststream/nats/publisher/producer/NatsJSFastProducer.md) + - publisher + - [SpecificationPublisher](api/faststream/nats/publisher/publisher/SpecificationPublisher.md) - usecase - [LogicPublisher](api/faststream/nats/publisher/usecase/LogicPublisher.md) - response @@ -760,19 +652,19 @@ search: - security - [parse_security](api/faststream/nats/security/parse_security.md) - subscriber - - asyncapi - - [AsyncAPIBatchPullStreamSubscriber](api/faststream/nats/subscriber/asyncapi/AsyncAPIBatchPullStreamSubscriber.md) - - [AsyncAPIConcurrentCoreSubscriber](api/faststream/nats/subscriber/asyncapi/AsyncAPIConcurrentCoreSubscriber.md) - - [AsyncAPIConcurrentPullStreamSubscriber](api/faststream/nats/subscriber/asyncapi/AsyncAPIConcurrentPullStreamSubscriber.md) - - [AsyncAPIConcurrentPushStreamSubscriber](api/faststream/nats/subscriber/asyncapi/AsyncAPIConcurrentPushStreamSubscriber.md) - - [AsyncAPICoreSubscriber](api/faststream/nats/subscriber/asyncapi/AsyncAPICoreSubscriber.md) - - [AsyncAPIKeyValueWatchSubscriber](api/faststream/nats/subscriber/asyncapi/AsyncAPIKeyValueWatchSubscriber.md) - - [AsyncAPIObjStoreWatchSubscriber](api/faststream/nats/subscriber/asyncapi/AsyncAPIObjStoreWatchSubscriber.md) - - [AsyncAPIPullStreamSubscriber](api/faststream/nats/subscriber/asyncapi/AsyncAPIPullStreamSubscriber.md) - - [AsyncAPIStreamSubscriber](api/faststream/nats/subscriber/asyncapi/AsyncAPIStreamSubscriber.md) - - [AsyncAPISubscriber](api/faststream/nats/subscriber/asyncapi/AsyncAPISubscriber.md) - factory - [create_subscriber](api/faststream/nats/subscriber/factory/create_subscriber.md) + - subscriber + - [SpecificationBatchPullStreamSubscriber](api/faststream/nats/subscriber/subscriber/SpecificationBatchPullStreamSubscriber.md) + - [SpecificationConcurrentCoreSubscriber](api/faststream/nats/subscriber/subscriber/SpecificationConcurrentCoreSubscriber.md) + - [SpecificationConcurrentPullStreamSubscriber](api/faststream/nats/subscriber/subscriber/SpecificationConcurrentPullStreamSubscriber.md) + - [SpecificationConcurrentPushStreamSubscriber](api/faststream/nats/subscriber/subscriber/SpecificationConcurrentPushStreamSubscriber.md) + - [SpecificationCoreSubscriber](api/faststream/nats/subscriber/subscriber/SpecificationCoreSubscriber.md) + - [SpecificationKeyValueWatchSubscriber](api/faststream/nats/subscriber/subscriber/SpecificationKeyValueWatchSubscriber.md) + - [SpecificationObjStoreWatchSubscriber](api/faststream/nats/subscriber/subscriber/SpecificationObjStoreWatchSubscriber.md) + - [SpecificationPullStreamSubscriber](api/faststream/nats/subscriber/subscriber/SpecificationPullStreamSubscriber.md) + - [SpecificationStreamSubscriber](api/faststream/nats/subscriber/subscriber/SpecificationStreamSubscriber.md) + - [SpecificationSubscriber](api/faststream/nats/subscriber/subscriber/SpecificationSubscriber.md) - subscription - [UnsubscribeAdapter](api/faststream/nats/subscriber/subscription/UnsubscribeAdapter.md) - [Unsubscriptable](api/faststream/nats/subscriber/subscription/Unsubscriptable.md) @@ -842,10 +734,10 @@ search: - parser - [AioPikaParser](api/faststream/rabbit/parser/AioPikaParser.md) - publisher - - asyncapi - - [AsyncAPIPublisher](api/faststream/rabbit/publisher/asyncapi/AsyncAPIPublisher.md) - producer - [AioPikaFastProducer](api/faststream/rabbit/publisher/producer/AioPikaFastProducer.md) + - publisher + - [SpecificationPublisher](api/faststream/rabbit/publisher/publisher/SpecificationPublisher.md) - usecase - [LogicPublisher](api/faststream/rabbit/publisher/usecase/LogicPublisher.md) - [PublishKwargs](api/faststream/rabbit/publisher/usecase/PublishKwargs.md) @@ -875,10 +767,10 @@ search: - security - [parse_security](api/faststream/rabbit/security/parse_security.md) - subscriber - - asyncapi - - [AsyncAPISubscriber](api/faststream/rabbit/subscriber/asyncapi/AsyncAPISubscriber.md) - factory - [create_subscriber](api/faststream/rabbit/subscriber/factory/create_subscriber.md) + - subscriber + - [SpecificationSubscriber](api/faststream/rabbit/subscriber/subscriber/SpecificationSubscriber.md) - usecase - [LogicSubscriber](api/faststream/rabbit/subscriber/usecase/LogicSubscriber.md) - testing @@ -943,14 +835,14 @@ search: - [RedisStreamParser](api/faststream/redis/parser/RedisStreamParser.md) - [SimpleParser](api/faststream/redis/parser/SimpleParser.md) - publisher - - asyncapi - - [AsyncAPIChannelPublisher](api/faststream/redis/publisher/asyncapi/AsyncAPIChannelPublisher.md) - - [AsyncAPIListBatchPublisher](api/faststream/redis/publisher/asyncapi/AsyncAPIListBatchPublisher.md) - - [AsyncAPIListPublisher](api/faststream/redis/publisher/asyncapi/AsyncAPIListPublisher.md) - - [AsyncAPIPublisher](api/faststream/redis/publisher/asyncapi/AsyncAPIPublisher.md) - - [AsyncAPIStreamPublisher](api/faststream/redis/publisher/asyncapi/AsyncAPIStreamPublisher.md) - producer - [RedisFastProducer](api/faststream/redis/publisher/producer/RedisFastProducer.md) + - publisher + - [AsyncAPIChannelPublisher](api/faststream/redis/publisher/publisher/AsyncAPIChannelPublisher.md) + - [AsyncAPIListBatchPublisher](api/faststream/redis/publisher/publisher/AsyncAPIListBatchPublisher.md) + - [AsyncAPIListPublisher](api/faststream/redis/publisher/publisher/AsyncAPIListPublisher.md) + - [AsyncAPIStreamPublisher](api/faststream/redis/publisher/publisher/AsyncAPIStreamPublisher.md) + - [SpecificationPublisher](api/faststream/redis/publisher/publisher/SpecificationPublisher.md) - usecase - [ChannelPublisher](api/faststream/redis/publisher/usecase/ChannelPublisher.md) - [ListBatchPublisher](api/faststream/redis/publisher/usecase/ListBatchPublisher.md) @@ -979,15 +871,15 @@ search: - security - [parse_security](api/faststream/redis/security/parse_security.md) - subscriber - - asyncapi - - [AsyncAPIChannelSubscriber](api/faststream/redis/subscriber/asyncapi/AsyncAPIChannelSubscriber.md) - - [AsyncAPIListBatchSubscriber](api/faststream/redis/subscriber/asyncapi/AsyncAPIListBatchSubscriber.md) - - [AsyncAPIListSubscriber](api/faststream/redis/subscriber/asyncapi/AsyncAPIListSubscriber.md) - - [AsyncAPIStreamBatchSubscriber](api/faststream/redis/subscriber/asyncapi/AsyncAPIStreamBatchSubscriber.md) - - [AsyncAPIStreamSubscriber](api/faststream/redis/subscriber/asyncapi/AsyncAPIStreamSubscriber.md) - - [AsyncAPISubscriber](api/faststream/redis/subscriber/asyncapi/AsyncAPISubscriber.md) - factory - [create_subscriber](api/faststream/redis/subscriber/factory/create_subscriber.md) + - subscriber + - [AsyncAPIChannelSubscriber](api/faststream/redis/subscriber/subscriber/AsyncAPIChannelSubscriber.md) + - [AsyncAPIListBatchSubscriber](api/faststream/redis/subscriber/subscriber/AsyncAPIListBatchSubscriber.md) + - [AsyncAPIListSubscriber](api/faststream/redis/subscriber/subscriber/AsyncAPIListSubscriber.md) + - [AsyncAPIStreamBatchSubscriber](api/faststream/redis/subscriber/subscriber/AsyncAPIStreamBatchSubscriber.md) + - [AsyncAPIStreamSubscriber](api/faststream/redis/subscriber/subscriber/AsyncAPIStreamSubscriber.md) + - [SpecificationSubscriber](api/faststream/redis/subscriber/subscriber/SpecificationSubscriber.md) - usecase - [BatchListSubscriber](api/faststream/redis/subscriber/usecase/BatchListSubscriber.md) - [BatchStreamSubscriber](api/faststream/redis/subscriber/usecase/BatchStreamSubscriber.md) @@ -1010,6 +902,258 @@ search: - [SASLPlaintext](api/faststream/security/SASLPlaintext.md) - [SASLScram256](api/faststream/security/SASLScram256.md) - [SASLScram512](api/faststream/security/SASLScram512.md) + - specification + - asyncapi + - [get_app_schema](api/faststream/specification/asyncapi/get_app_schema.md) + - [get_asyncapi_html](api/faststream/specification/asyncapi/get_asyncapi_html.md) + - base + - schema + - [BaseInfo](api/faststream/specification/asyncapi/base/schema/BaseInfo.md) + - [BaseSchema](api/faststream/specification/asyncapi/base/schema/BaseSchema.md) + - info + - [BaseInfo](api/faststream/specification/asyncapi/base/schema/info/BaseInfo.md) + - schema + - [BaseSchema](api/faststream/specification/asyncapi/base/schema/schema/BaseSchema.md) + - generate + - [get_app_schema](api/faststream/specification/asyncapi/generate/get_app_schema.md) + - message + - [get_model_schema](api/faststream/specification/asyncapi/message/get_model_schema.md) + - [get_response_schema](api/faststream/specification/asyncapi/message/get_response_schema.md) + - [parse_handler_params](api/faststream/specification/asyncapi/message/parse_handler_params.md) + - site + - [get_asyncapi_html](api/faststream/specification/asyncapi/site/get_asyncapi_html.md) + - [serve_app](api/faststream/specification/asyncapi/site/serve_app.md) + - utils + - [resolve_payloads](api/faststream/specification/asyncapi/utils/resolve_payloads.md) + - [to_camelcase](api/faststream/specification/asyncapi/utils/to_camelcase.md) + - v2_6_0 + - [get_app_schema](api/faststream/specification/asyncapi/v2_6_0/get_app_schema.md) + - generate + - [get_app_schema](api/faststream/specification/asyncapi/v2_6_0/generate/get_app_schema.md) + - [get_broker_channels](api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_channels.md) + - [get_broker_server](api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_server.md) + - [move_pydantic_refs](api/faststream/specification/asyncapi/v2_6_0/generate/move_pydantic_refs.md) + - [resolve_channel_messages](api/faststream/specification/asyncapi/v2_6_0/generate/resolve_channel_messages.md) + - schema + - [Channel](api/faststream/specification/asyncapi/v2_6_0/schema/Channel.md) + - [Components](api/faststream/specification/asyncapi/v2_6_0/schema/Components.md) + - [Contact](api/faststream/specification/asyncapi/v2_6_0/schema/Contact.md) + - [CorrelationId](api/faststream/specification/asyncapi/v2_6_0/schema/CorrelationId.md) + - [ExternalDocs](api/faststream/specification/asyncapi/v2_6_0/schema/ExternalDocs.md) + - [Info](api/faststream/specification/asyncapi/v2_6_0/schema/Info.md) + - [License](api/faststream/specification/asyncapi/v2_6_0/schema/License.md) + - [Message](api/faststream/specification/asyncapi/v2_6_0/schema/Message.md) + - [Operation](api/faststream/specification/asyncapi/v2_6_0/schema/Operation.md) + - [Parameter](api/faststream/specification/asyncapi/v2_6_0/schema/Parameter.md) + - [Reference](api/faststream/specification/asyncapi/v2_6_0/schema/Reference.md) + - [Schema](api/faststream/specification/asyncapi/v2_6_0/schema/Schema.md) + - [Server](api/faststream/specification/asyncapi/v2_6_0/schema/Server.md) + - [ServerVariable](api/faststream/specification/asyncapi/v2_6_0/schema/ServerVariable.md) + - [Tag](api/faststream/specification/asyncapi/v2_6_0/schema/Tag.md) + - [channel_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/channel_from_spec.md) + - [contact_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/contact_from_spec.md) + - [docs_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/docs_from_spec.md) + - [license_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/license_from_spec.md) + - [message_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/message_from_spec.md) + - [operation_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/operation_from_spec.md) + - [tag_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/tag_from_spec.md) + - bindings + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/OperationBinding.md) + - [channel_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/channel_binding_from_spec.md) + - [operation_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/operation_binding_from_spec.md) + - amqp + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/OperationBinding.md) + - [channel_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel_binding_from_spec.md) + - [operation_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation_binding_from_spec.md) + - channel + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/ChannelBinding.md) + - [Exchange](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Exchange.md) + - [Queue](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Queue.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/from_spec.md) + - operation + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/OperationBinding.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/from_spec.md) + - kafka + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/OperationBinding.md) + - [channel_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel_binding_from_spec.md) + - [operation_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation_binding_from_spec.md) + - channel + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel/ChannelBinding.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel/from_spec.md) + - operation + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/OperationBinding.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/from_spec.md) + - main + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/OperationBinding.md) + - [channel_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel_binding_from_spec.md) + - [operation_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation_binding_from_spec.md) + - channel + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/ChannelBinding.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/from_spec.md) + - operation + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/OperationBinding.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/from_spec.md) + - nats + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/OperationBinding.md) + - [channel_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel_binding_from_spec.md) + - [operation_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation_binding_from_spec.md) + - channel + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel/ChannelBinding.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel/from_spec.md) + - operation + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/OperationBinding.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/from_spec.md) + - redis + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/OperationBinding.md) + - [channel_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel_binding_from_spec.md) + - [operation_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation_binding_from_spec.md) + - channel + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel/ChannelBinding.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel/from_spec.md) + - operation + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/OperationBinding.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/from_spec.md) + - sqs + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/OperationBinding.md) + - [channel_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel_binding_from_spec.md) + - [operation_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation_binding_from_spec.md) + - channel + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/ChannelBinding.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/from_spec.md) + - operation + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/OperationBinding.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/from_spec.md) + - channels + - [Channel](api/faststream/specification/asyncapi/v2_6_0/schema/channels/Channel.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/channels/from_spec.md) + - components + - [Components](api/faststream/specification/asyncapi/v2_6_0/schema/components/Components.md) + - contact + - [Contact](api/faststream/specification/asyncapi/v2_6_0/schema/contact/Contact.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/contact/from_spec.md) + - docs + - [ExternalDocs](api/faststream/specification/asyncapi/v2_6_0/schema/docs/ExternalDocs.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/docs/from_spec.md) + - info + - [Info](api/faststream/specification/asyncapi/v2_6_0/schema/info/Info.md) + - license + - [License](api/faststream/specification/asyncapi/v2_6_0/schema/license/License.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/license/from_spec.md) + - message + - [CorrelationId](api/faststream/specification/asyncapi/v2_6_0/schema/message/CorrelationId.md) + - [Message](api/faststream/specification/asyncapi/v2_6_0/schema/message/Message.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/message/from_spec.md) + - operations + - [Operation](api/faststream/specification/asyncapi/v2_6_0/schema/operations/Operation.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/operations/from_spec.md) + - schema + - [Schema](api/faststream/specification/asyncapi/v2_6_0/schema/schema/Schema.md) + - servers + - [Server](api/faststream/specification/asyncapi/v2_6_0/schema/servers/Server.md) + - [ServerVariable](api/faststream/specification/asyncapi/v2_6_0/schema/servers/ServerVariable.md) + - tag + - [Tag](api/faststream/specification/asyncapi/v2_6_0/schema/tag/Tag.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/tag/from_spec.md) + - utils + - [Parameter](api/faststream/specification/asyncapi/v2_6_0/schema/utils/Parameter.md) + - [Reference](api/faststream/specification/asyncapi/v2_6_0/schema/utils/Reference.md) + - v3_0_0 + - [get_app_schema](api/faststream/specification/asyncapi/v3_0_0/get_app_schema.md) + - generate + - [get_app_schema](api/faststream/specification/asyncapi/v3_0_0/generate/get_app_schema.md) + - [get_broker_channels](api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_channels.md) + - [get_broker_operations](api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_operations.md) + - [get_broker_server](api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_server.md) + - schema + - [Channel](api/faststream/specification/asyncapi/v3_0_0/schema/Channel.md) + - [Components](api/faststream/specification/asyncapi/v3_0_0/schema/Components.md) + - [Info](api/faststream/specification/asyncapi/v3_0_0/schema/Info.md) + - [Operation](api/faststream/specification/asyncapi/v3_0_0/schema/Operation.md) + - [Schema](api/faststream/specification/asyncapi/v3_0_0/schema/Schema.md) + - [Server](api/faststream/specification/asyncapi/v3_0_0/schema/Server.md) + - [channel_from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/channel_from_spec.md) + - [operation_from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/operation_from_spec.md) + - channels + - [Channel](api/faststream/specification/asyncapi/v3_0_0/schema/channels/Channel.md) + - [from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/channels/from_spec.md) + - components + - [Components](api/faststream/specification/asyncapi/v3_0_0/schema/components/Components.md) + - info + - [Info](api/faststream/specification/asyncapi/v3_0_0/schema/info/Info.md) + - operations + - [Action](api/faststream/specification/asyncapi/v3_0_0/schema/operations/Action.md) + - [Operation](api/faststream/specification/asyncapi/v3_0_0/schema/operations/Operation.md) + - [from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/operations/from_spec.md) + - schema + - [Schema](api/faststream/specification/asyncapi/v3_0_0/schema/schema/Schema.md) + - servers + - [Server](api/faststream/specification/asyncapi/v3_0_0/schema/servers/Server.md) + - proto + - [Application](api/faststream/specification/proto/Application.md) + - [SpecificationProto](api/faststream/specification/proto/SpecificationProto.md) + - schema + - bindings + - [ChannelBinding](api/faststream/specification/schema/bindings/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/schema/bindings/OperationBinding.md) + - amqp + - [ChannelBinding](api/faststream/specification/schema/bindings/amqp/ChannelBinding.md) + - [Exchange](api/faststream/specification/schema/bindings/amqp/Exchange.md) + - [OperationBinding](api/faststream/specification/schema/bindings/amqp/OperationBinding.md) + - [Queue](api/faststream/specification/schema/bindings/amqp/Queue.md) + - kafka + - [ChannelBinding](api/faststream/specification/schema/bindings/kafka/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/schema/bindings/kafka/OperationBinding.md) + - main + - [ChannelBinding](api/faststream/specification/schema/bindings/main/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/schema/bindings/main/OperationBinding.md) + - nats + - [ChannelBinding](api/faststream/specification/schema/bindings/nats/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/schema/bindings/nats/OperationBinding.md) + - redis + - [ChannelBinding](api/faststream/specification/schema/bindings/redis/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/schema/bindings/redis/OperationBinding.md) + - sqs + - [ChannelBinding](api/faststream/specification/schema/bindings/sqs/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/schema/bindings/sqs/OperationBinding.md) + - channel + - [Channel](api/faststream/specification/schema/channel/Channel.md) + - components + - [Components](api/faststream/specification/schema/components/Components.md) + - contact + - [Contact](api/faststream/specification/schema/contact/Contact.md) + - [ContactDict](api/faststream/specification/schema/contact/ContactDict.md) + - docs + - [ExternalDocs](api/faststream/specification/schema/docs/ExternalDocs.md) + - [ExternalDocsDict](api/faststream/specification/schema/docs/ExternalDocsDict.md) + - info + - [Info](api/faststream/specification/schema/info/Info.md) + - license + - [License](api/faststream/specification/schema/license/License.md) + - [LicenseDict](api/faststream/specification/schema/license/LicenseDict.md) + - message + - [CorrelationId](api/faststream/specification/schema/message/CorrelationId.md) + - [Message](api/faststream/specification/schema/message/Message.md) + - operation + - [Operation](api/faststream/specification/schema/operation/Operation.md) + - schema + - [BaseSchema](api/faststream/specification/schema/schema/BaseSchema.md) + - security + - [OauthFlowObj](api/faststream/specification/schema/security/OauthFlowObj.md) + - [OauthFlows](api/faststream/specification/schema/security/OauthFlows.md) + - [SecuritySchemaComponent](api/faststream/specification/schema/security/SecuritySchemaComponent.md) + - servers + - [Server](api/faststream/specification/schema/servers/Server.md) + - [ServerVariable](api/faststream/specification/schema/servers/ServerVariable.md) + - tag + - [Tag](api/faststream/specification/schema/tag/Tag.md) + - [TagDict](api/faststream/specification/schema/tag/TagDict.md) - testing - [TestApp](api/faststream/testing/TestApp.md) - app diff --git a/docs/docs/en/api/faststream/asyncapi/proto/AsyncAPIApplication.md b/docs/docs/en/api/faststream/asyncapi/proto/AsyncAPIApplication.md deleted file mode 100644 index da1715119d..0000000000 --- a/docs/docs/en/api/faststream/asyncapi/proto/AsyncAPIApplication.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asyncapi.proto.AsyncAPIApplication diff --git a/docs/docs/en/api/faststream/asyncapi/proto/AsyncAPIProto.md b/docs/docs/en/api/faststream/asyncapi/proto/AsyncAPIProto.md deleted file mode 100644 index 6905c2d82f..0000000000 --- a/docs/docs/en/api/faststream/asyncapi/proto/AsyncAPIProto.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asyncapi.proto.AsyncAPIProto diff --git a/docs/docs/en/api/faststream/asyncapi/schema/ServerBinding.md b/docs/docs/en/api/faststream/asyncapi/schema/ServerBinding.md deleted file mode 100644 index 8dcaba6701..0000000000 --- a/docs/docs/en/api/faststream/asyncapi/schema/ServerBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asyncapi.schema.ServerBinding diff --git a/docs/docs/en/api/faststream/asyncapi/schema/bindings/ServerBinding.md b/docs/docs/en/api/faststream/asyncapi/schema/bindings/ServerBinding.md deleted file mode 100644 index d91efbfe52..0000000000 --- a/docs/docs/en/api/faststream/asyncapi/schema/bindings/ServerBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asyncapi.schema.bindings.ServerBinding diff --git a/docs/docs/en/api/faststream/asyncapi/schema/bindings/amqp/ServerBinding.md b/docs/docs/en/api/faststream/asyncapi/schema/bindings/amqp/ServerBinding.md deleted file mode 100644 index 0daa6510ec..0000000000 --- a/docs/docs/en/api/faststream/asyncapi/schema/bindings/amqp/ServerBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asyncapi.schema.bindings.amqp.ServerBinding diff --git a/docs/docs/en/api/faststream/asyncapi/schema/bindings/kafka/ServerBinding.md b/docs/docs/en/api/faststream/asyncapi/schema/bindings/kafka/ServerBinding.md deleted file mode 100644 index e52855bd45..0000000000 --- a/docs/docs/en/api/faststream/asyncapi/schema/bindings/kafka/ServerBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asyncapi.schema.bindings.kafka.ServerBinding diff --git a/docs/docs/en/api/faststream/asyncapi/schema/bindings/main/ChannelBinding.md b/docs/docs/en/api/faststream/asyncapi/schema/bindings/main/ChannelBinding.md deleted file mode 100644 index a2a8872d64..0000000000 --- a/docs/docs/en/api/faststream/asyncapi/schema/bindings/main/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asyncapi.schema.bindings.main.ChannelBinding diff --git a/docs/docs/en/api/faststream/asyncapi/schema/bindings/main/OperationBinding.md b/docs/docs/en/api/faststream/asyncapi/schema/bindings/main/OperationBinding.md deleted file mode 100644 index 1e597b1757..0000000000 --- a/docs/docs/en/api/faststream/asyncapi/schema/bindings/main/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asyncapi.schema.bindings.main.OperationBinding diff --git a/docs/docs/en/api/faststream/asyncapi/schema/bindings/main/ServerBinding.md b/docs/docs/en/api/faststream/asyncapi/schema/bindings/main/ServerBinding.md deleted file mode 100644 index 4dacad7825..0000000000 --- a/docs/docs/en/api/faststream/asyncapi/schema/bindings/main/ServerBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asyncapi.schema.bindings.main.ServerBinding diff --git a/docs/docs/en/api/faststream/asyncapi/schema/bindings/nats/ChannelBinding.md b/docs/docs/en/api/faststream/asyncapi/schema/bindings/nats/ChannelBinding.md deleted file mode 100644 index 11135ad968..0000000000 --- a/docs/docs/en/api/faststream/asyncapi/schema/bindings/nats/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asyncapi.schema.bindings.nats.ChannelBinding diff --git a/docs/docs/en/api/faststream/asyncapi/schema/bindings/nats/OperationBinding.md b/docs/docs/en/api/faststream/asyncapi/schema/bindings/nats/OperationBinding.md deleted file mode 100644 index 8e0cd8acb1..0000000000 --- a/docs/docs/en/api/faststream/asyncapi/schema/bindings/nats/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asyncapi.schema.bindings.nats.OperationBinding diff --git a/docs/docs/en/api/faststream/asyncapi/schema/bindings/nats/ServerBinding.md b/docs/docs/en/api/faststream/asyncapi/schema/bindings/nats/ServerBinding.md deleted file mode 100644 index 7d95811c44..0000000000 --- a/docs/docs/en/api/faststream/asyncapi/schema/bindings/nats/ServerBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asyncapi.schema.bindings.nats.ServerBinding diff --git a/docs/docs/en/api/faststream/asyncapi/schema/bindings/redis/ChannelBinding.md b/docs/docs/en/api/faststream/asyncapi/schema/bindings/redis/ChannelBinding.md deleted file mode 100644 index fef00d4e8a..0000000000 --- a/docs/docs/en/api/faststream/asyncapi/schema/bindings/redis/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asyncapi.schema.bindings.redis.ChannelBinding diff --git a/docs/docs/en/api/faststream/asyncapi/schema/bindings/redis/OperationBinding.md b/docs/docs/en/api/faststream/asyncapi/schema/bindings/redis/OperationBinding.md deleted file mode 100644 index 81b906045b..0000000000 --- a/docs/docs/en/api/faststream/asyncapi/schema/bindings/redis/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asyncapi.schema.bindings.redis.OperationBinding diff --git a/docs/docs/en/api/faststream/asyncapi/schema/bindings/redis/ServerBinding.md b/docs/docs/en/api/faststream/asyncapi/schema/bindings/redis/ServerBinding.md deleted file mode 100644 index 7d12316c85..0000000000 --- a/docs/docs/en/api/faststream/asyncapi/schema/bindings/redis/ServerBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asyncapi.schema.bindings.redis.ServerBinding diff --git a/docs/docs/en/api/faststream/asyncapi/schema/bindings/sqs/ChannelBinding.md b/docs/docs/en/api/faststream/asyncapi/schema/bindings/sqs/ChannelBinding.md deleted file mode 100644 index 4a255559db..0000000000 --- a/docs/docs/en/api/faststream/asyncapi/schema/bindings/sqs/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asyncapi.schema.bindings.sqs.ChannelBinding diff --git a/docs/docs/en/api/faststream/asyncapi/schema/bindings/sqs/OperationBinding.md b/docs/docs/en/api/faststream/asyncapi/schema/bindings/sqs/OperationBinding.md deleted file mode 100644 index 6a438685b4..0000000000 --- a/docs/docs/en/api/faststream/asyncapi/schema/bindings/sqs/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asyncapi.schema.bindings.sqs.OperationBinding diff --git a/docs/docs/en/api/faststream/asyncapi/schema/bindings/sqs/ServerBinding.md b/docs/docs/en/api/faststream/asyncapi/schema/bindings/sqs/ServerBinding.md deleted file mode 100644 index f6a200b3f7..0000000000 --- a/docs/docs/en/api/faststream/asyncapi/schema/bindings/sqs/ServerBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asyncapi.schema.bindings.sqs.ServerBinding diff --git a/docs/docs/en/api/faststream/asyncapi/schema/info/ContactDict.md b/docs/docs/en/api/faststream/asyncapi/schema/info/ContactDict.md deleted file mode 100644 index adcd40891f..0000000000 --- a/docs/docs/en/api/faststream/asyncapi/schema/info/ContactDict.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asyncapi.schema.info.ContactDict diff --git a/docs/docs/en/api/faststream/asyncapi/schema/info/LicenseDict.md b/docs/docs/en/api/faststream/asyncapi/schema/info/LicenseDict.md deleted file mode 100644 index 29fab879e4..0000000000 --- a/docs/docs/en/api/faststream/asyncapi/schema/info/LicenseDict.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asyncapi.schema.info.LicenseDict diff --git a/docs/docs/en/api/faststream/asyncapi/schema/security/SecuritySchemaComponent.md b/docs/docs/en/api/faststream/asyncapi/schema/security/SecuritySchemaComponent.md deleted file mode 100644 index 779e70fdd6..0000000000 --- a/docs/docs/en/api/faststream/asyncapi/schema/security/SecuritySchemaComponent.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asyncapi.schema.security.SecuritySchemaComponent diff --git a/docs/docs/en/api/faststream/asyncapi/schema/utils/ExternalDocsDict.md b/docs/docs/en/api/faststream/asyncapi/schema/utils/ExternalDocsDict.md deleted file mode 100644 index fc5cedfb73..0000000000 --- a/docs/docs/en/api/faststream/asyncapi/schema/utils/ExternalDocsDict.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asyncapi.schema.utils.ExternalDocsDict diff --git a/docs/docs/en/api/faststream/asyncapi/schema/utils/TagDict.md b/docs/docs/en/api/faststream/asyncapi/schema/utils/TagDict.md deleted file mode 100644 index 412546da6f..0000000000 --- a/docs/docs/en/api/faststream/asyncapi/schema/utils/TagDict.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asyncapi.schema.utils.TagDict diff --git a/docs/docs/en/api/faststream/confluent/publisher/asyncapi/AsyncAPIPublisher.md b/docs/docs/en/api/faststream/confluent/publisher/asyncapi/AsyncAPIPublisher.md deleted file mode 100644 index f76d27ccd0..0000000000 --- a/docs/docs/en/api/faststream/confluent/publisher/asyncapi/AsyncAPIPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.publisher.asyncapi.AsyncAPIPublisher diff --git a/docs/docs/en/api/faststream/confluent/publisher/publisher/SpecificationBatchPublisher.md b/docs/docs/en/api/faststream/confluent/publisher/publisher/SpecificationBatchPublisher.md new file mode 100644 index 0000000000..d666c31641 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/publisher/publisher/SpecificationBatchPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.publisher.publisher.SpecificationBatchPublisher diff --git a/docs/docs/en/api/faststream/confluent/publisher/publisher/SpecificationDefaultPublisher.md b/docs/docs/en/api/faststream/confluent/publisher/publisher/SpecificationDefaultPublisher.md new file mode 100644 index 0000000000..2755e26b87 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/publisher/publisher/SpecificationDefaultPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.publisher.publisher.SpecificationDefaultPublisher diff --git a/docs/docs/en/api/faststream/confluent/publisher/publisher/SpecificationPublisher.md b/docs/docs/en/api/faststream/confluent/publisher/publisher/SpecificationPublisher.md new file mode 100644 index 0000000000..d4f8b18d7c --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/publisher/publisher/SpecificationPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.publisher.publisher.SpecificationPublisher diff --git a/docs/docs/en/api/faststream/confluent/subscriber/asyncapi/AsyncAPISubscriber.md b/docs/docs/en/api/faststream/confluent/subscriber/asyncapi/AsyncAPISubscriber.md deleted file mode 100644 index b22facc06a..0000000000 --- a/docs/docs/en/api/faststream/confluent/subscriber/asyncapi/AsyncAPISubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.subscriber.asyncapi.AsyncAPISubscriber diff --git a/docs/docs/en/api/faststream/confluent/subscriber/subscriber/SpecificationBatchSubscriber.md b/docs/docs/en/api/faststream/confluent/subscriber/subscriber/SpecificationBatchSubscriber.md new file mode 100644 index 0000000000..c41a863145 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/subscriber/subscriber/SpecificationBatchSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.subscriber.subscriber.SpecificationBatchSubscriber diff --git a/docs/docs/en/api/faststream/confluent/subscriber/subscriber/SpecificationDefaultSubscriber.md b/docs/docs/en/api/faststream/confluent/subscriber/subscriber/SpecificationDefaultSubscriber.md new file mode 100644 index 0000000000..71c9c19ece --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/subscriber/subscriber/SpecificationDefaultSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.subscriber.subscriber.SpecificationDefaultSubscriber diff --git a/docs/docs/en/api/faststream/confluent/subscriber/asyncapi/AsyncAPIDefaultSubscriber.md b/docs/docs/en/api/faststream/confluent/subscriber/subscriber/SpecificationSubscriber.md similarity index 64% rename from docs/docs/en/api/faststream/confluent/subscriber/asyncapi/AsyncAPIDefaultSubscriber.md rename to docs/docs/en/api/faststream/confluent/subscriber/subscriber/SpecificationSubscriber.md index 12641d32ce..de67fe6ca8 100644 --- a/docs/docs/en/api/faststream/confluent/subscriber/asyncapi/AsyncAPIDefaultSubscriber.md +++ b/docs/docs/en/api/faststream/confluent/subscriber/subscriber/SpecificationSubscriber.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.confluent.subscriber.asyncapi.AsyncAPIDefaultSubscriber +::: faststream.confluent.subscriber.subscriber.SpecificationSubscriber diff --git a/docs/docs/en/api/faststream/kafka/publisher/asyncapi/AsyncAPIBatchPublisher.md b/docs/docs/en/api/faststream/kafka/publisher/asyncapi/AsyncAPIBatchPublisher.md deleted file mode 100644 index 8d796523e6..0000000000 --- a/docs/docs/en/api/faststream/kafka/publisher/asyncapi/AsyncAPIBatchPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.publisher.asyncapi.AsyncAPIBatchPublisher diff --git a/docs/docs/en/api/faststream/kafka/publisher/asyncapi/AsyncAPIPublisher.md b/docs/docs/en/api/faststream/kafka/publisher/asyncapi/AsyncAPIPublisher.md deleted file mode 100644 index 7d914809c2..0000000000 --- a/docs/docs/en/api/faststream/kafka/publisher/asyncapi/AsyncAPIPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.publisher.asyncapi.AsyncAPIPublisher diff --git a/docs/docs/en/api/faststream/confluent/publisher/asyncapi/AsyncAPIDefaultPublisher.md b/docs/docs/en/api/faststream/kafka/publisher/publisher/SpecificationBatchPublisher.md similarity index 64% rename from docs/docs/en/api/faststream/confluent/publisher/asyncapi/AsyncAPIDefaultPublisher.md rename to docs/docs/en/api/faststream/kafka/publisher/publisher/SpecificationBatchPublisher.md index 32685d612d..456dd5e1f1 100644 --- a/docs/docs/en/api/faststream/confluent/publisher/asyncapi/AsyncAPIDefaultPublisher.md +++ b/docs/docs/en/api/faststream/kafka/publisher/publisher/SpecificationBatchPublisher.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.confluent.publisher.asyncapi.AsyncAPIDefaultPublisher +::: faststream.kafka.publisher.publisher.SpecificationBatchPublisher diff --git a/docs/docs/en/api/faststream/kafka/publisher/publisher/SpecificationDefaultPublisher.md b/docs/docs/en/api/faststream/kafka/publisher/publisher/SpecificationDefaultPublisher.md new file mode 100644 index 0000000000..3b6fa9b980 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/publisher/publisher/SpecificationDefaultPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.publisher.publisher.SpecificationDefaultPublisher diff --git a/docs/docs/en/api/faststream/kafka/publisher/publisher/SpecificationPublisher.md b/docs/docs/en/api/faststream/kafka/publisher/publisher/SpecificationPublisher.md new file mode 100644 index 0000000000..59fc5e9a94 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/publisher/publisher/SpecificationPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.publisher.publisher.SpecificationPublisher diff --git a/docs/docs/en/api/faststream/kafka/subscriber/asyncapi/AsyncAPISubscriber.md b/docs/docs/en/api/faststream/kafka/subscriber/asyncapi/AsyncAPISubscriber.md deleted file mode 100644 index 330a621bf5..0000000000 --- a/docs/docs/en/api/faststream/kafka/subscriber/asyncapi/AsyncAPISubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.subscriber.asyncapi.AsyncAPISubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIKeyValueWatchSubscriber.md b/docs/docs/en/api/faststream/kafka/subscriber/subscriber/SpecificationBatchSubscriber.md similarity index 64% rename from docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIKeyValueWatchSubscriber.md rename to docs/docs/en/api/faststream/kafka/subscriber/subscriber/SpecificationBatchSubscriber.md index b006854b0b..269bf4a3c4 100644 --- a/docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIKeyValueWatchSubscriber.md +++ b/docs/docs/en/api/faststream/kafka/subscriber/subscriber/SpecificationBatchSubscriber.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.nats.subscriber.asyncapi.AsyncAPIKeyValueWatchSubscriber +::: faststream.kafka.subscriber.subscriber.SpecificationBatchSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIBatchPullStreamSubscriber.md b/docs/docs/en/api/faststream/kafka/subscriber/subscriber/SpecificationDefaultSubscriber.md similarity index 65% rename from docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIBatchPullStreamSubscriber.md rename to docs/docs/en/api/faststream/kafka/subscriber/subscriber/SpecificationDefaultSubscriber.md index 15bceeedbc..5e9fb682fd 100644 --- a/docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIBatchPullStreamSubscriber.md +++ b/docs/docs/en/api/faststream/kafka/subscriber/subscriber/SpecificationDefaultSubscriber.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.nats.subscriber.asyncapi.AsyncAPIBatchPullStreamSubscriber +::: faststream.kafka.subscriber.subscriber.SpecificationDefaultSubscriber diff --git a/docs/docs/en/api/faststream/confluent/publisher/asyncapi/AsyncAPIBatchPublisher.md b/docs/docs/en/api/faststream/kafka/subscriber/subscriber/SpecificationSubscriber.md similarity index 63% rename from docs/docs/en/api/faststream/confluent/publisher/asyncapi/AsyncAPIBatchPublisher.md rename to docs/docs/en/api/faststream/kafka/subscriber/subscriber/SpecificationSubscriber.md index 62ae234697..c8ee640280 100644 --- a/docs/docs/en/api/faststream/confluent/publisher/asyncapi/AsyncAPIBatchPublisher.md +++ b/docs/docs/en/api/faststream/kafka/subscriber/subscriber/SpecificationSubscriber.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.confluent.publisher.asyncapi.AsyncAPIBatchPublisher +::: faststream.kafka.subscriber.subscriber.SpecificationSubscriber diff --git a/docs/docs/en/api/faststream/nats/publisher/asyncapi/AsyncAPIPublisher.md b/docs/docs/en/api/faststream/nats/publisher/asyncapi/AsyncAPIPublisher.md deleted file mode 100644 index 6ea394db59..0000000000 --- a/docs/docs/en/api/faststream/nats/publisher/asyncapi/AsyncAPIPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.publisher.asyncapi.AsyncAPIPublisher diff --git a/docs/docs/en/api/faststream/nats/publisher/publisher/SpecificationPublisher.md b/docs/docs/en/api/faststream/nats/publisher/publisher/SpecificationPublisher.md new file mode 100644 index 0000000000..59aeffa6ab --- /dev/null +++ b/docs/docs/en/api/faststream/nats/publisher/publisher/SpecificationPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.publisher.publisher.SpecificationPublisher diff --git a/docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIConcurrentPullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIConcurrentPullStreamSubscriber.md deleted file mode 100644 index b5ebf86f93..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIConcurrentPullStreamSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.asyncapi.AsyncAPIConcurrentPullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIConcurrentPushStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIConcurrentPushStreamSubscriber.md deleted file mode 100644 index 7bb4a6e088..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIConcurrentPushStreamSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.asyncapi.AsyncAPIConcurrentPushStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPICoreSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPICoreSubscriber.md deleted file mode 100644 index 8819adebab..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPICoreSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.asyncapi.AsyncAPICoreSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIPullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIPullStreamSubscriber.md deleted file mode 100644 index e9650bef94..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIPullStreamSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.asyncapi.AsyncAPIPullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPISubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPISubscriber.md deleted file mode 100644 index 4fcbab6ea6..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPISubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.asyncapi.AsyncAPISubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationBatchPullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationBatchPullStreamSubscriber.md new file mode 100644 index 0000000000..7329cf824b --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationBatchPullStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.subscriber.SpecificationBatchPullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationConcurrentCoreSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationConcurrentCoreSubscriber.md new file mode 100644 index 0000000000..861a569292 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationConcurrentCoreSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.subscriber.SpecificationConcurrentCoreSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationConcurrentPullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationConcurrentPullStreamSubscriber.md new file mode 100644 index 0000000000..4437e07663 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationConcurrentPullStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.subscriber.SpecificationConcurrentPullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationConcurrentPushStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationConcurrentPushStreamSubscriber.md new file mode 100644 index 0000000000..1381a591c1 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationConcurrentPushStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.subscriber.SpecificationConcurrentPushStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationCoreSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationCoreSubscriber.md new file mode 100644 index 0000000000..55256d5f70 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationCoreSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.subscriber.SpecificationCoreSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationKeyValueWatchSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationKeyValueWatchSubscriber.md new file mode 100644 index 0000000000..1b46711a00 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationKeyValueWatchSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.subscriber.SpecificationKeyValueWatchSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationObjStoreWatchSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationObjStoreWatchSubscriber.md new file mode 100644 index 0000000000..91ce924e87 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationObjStoreWatchSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.subscriber.SpecificationObjStoreWatchSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationPullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationPullStreamSubscriber.md new file mode 100644 index 0000000000..1465f7cca0 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationPullStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.subscriber.SpecificationPullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIObjStoreWatchSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationStreamSubscriber.md similarity index 64% rename from docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIObjStoreWatchSubscriber.md rename to docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationStreamSubscriber.md index 0a9157ed55..bf9aea4bd4 100644 --- a/docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIObjStoreWatchSubscriber.md +++ b/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationStreamSubscriber.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.nats.subscriber.asyncapi.AsyncAPIObjStoreWatchSubscriber +::: faststream.nats.subscriber.subscriber.SpecificationStreamSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/asyncapi/AsyncAPIStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationSubscriber.md similarity index 63% rename from docs/docs/en/api/faststream/redis/subscriber/asyncapi/AsyncAPIStreamSubscriber.md rename to docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationSubscriber.md index 3d85ce9587..f62b166e92 100644 --- a/docs/docs/en/api/faststream/redis/subscriber/asyncapi/AsyncAPIStreamSubscriber.md +++ b/docs/docs/en/api/faststream/nats/subscriber/subscriber/SpecificationSubscriber.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.redis.subscriber.asyncapi.AsyncAPIStreamSubscriber +::: faststream.nats.subscriber.subscriber.SpecificationSubscriber diff --git a/docs/docs/en/api/faststream/rabbit/publisher/asyncapi/AsyncAPIPublisher.md b/docs/docs/en/api/faststream/rabbit/publisher/asyncapi/AsyncAPIPublisher.md deleted file mode 100644 index 6ece65cfed..0000000000 --- a/docs/docs/en/api/faststream/rabbit/publisher/asyncapi/AsyncAPIPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.publisher.asyncapi.AsyncAPIPublisher diff --git a/docs/docs/en/api/faststream/kafka/publisher/asyncapi/AsyncAPIDefaultPublisher.md b/docs/docs/en/api/faststream/rabbit/publisher/publisher/SpecificationPublisher.md similarity index 63% rename from docs/docs/en/api/faststream/kafka/publisher/asyncapi/AsyncAPIDefaultPublisher.md rename to docs/docs/en/api/faststream/rabbit/publisher/publisher/SpecificationPublisher.md index 7e4e54d030..d19f4e84ef 100644 --- a/docs/docs/en/api/faststream/kafka/publisher/asyncapi/AsyncAPIDefaultPublisher.md +++ b/docs/docs/en/api/faststream/rabbit/publisher/publisher/SpecificationPublisher.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.kafka.publisher.asyncapi.AsyncAPIDefaultPublisher +::: faststream.rabbit.publisher.publisher.SpecificationPublisher diff --git a/docs/docs/en/api/faststream/rabbit/subscriber/asyncapi/AsyncAPISubscriber.md b/docs/docs/en/api/faststream/rabbit/subscriber/asyncapi/AsyncAPISubscriber.md deleted file mode 100644 index 4d11c4b8e0..0000000000 --- a/docs/docs/en/api/faststream/rabbit/subscriber/asyncapi/AsyncAPISubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.subscriber.asyncapi.AsyncAPISubscriber diff --git a/docs/docs/en/api/faststream/rabbit/subscriber/subscriber/SpecificationSubscriber.md b/docs/docs/en/api/faststream/rabbit/subscriber/subscriber/SpecificationSubscriber.md new file mode 100644 index 0000000000..76c3fbe14f --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/subscriber/subscriber/SpecificationSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.subscriber.subscriber.SpecificationSubscriber diff --git a/docs/docs/en/api/faststream/redis/publisher/asyncapi/AsyncAPIPublisher.md b/docs/docs/en/api/faststream/redis/publisher/asyncapi/AsyncAPIPublisher.md deleted file mode 100644 index 4243308fb7..0000000000 --- a/docs/docs/en/api/faststream/redis/publisher/asyncapi/AsyncAPIPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.publisher.asyncapi.AsyncAPIPublisher diff --git a/docs/docs/en/api/faststream/redis/publisher/asyncapi/AsyncAPIStreamPublisher.md b/docs/docs/en/api/faststream/redis/publisher/asyncapi/AsyncAPIStreamPublisher.md deleted file mode 100644 index 29fb6329f3..0000000000 --- a/docs/docs/en/api/faststream/redis/publisher/asyncapi/AsyncAPIStreamPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.publisher.asyncapi.AsyncAPIStreamPublisher diff --git a/docs/docs/en/api/faststream/redis/publisher/publisher/AsyncAPIChannelPublisher.md b/docs/docs/en/api/faststream/redis/publisher/publisher/AsyncAPIChannelPublisher.md new file mode 100644 index 0000000000..c802c5471f --- /dev/null +++ b/docs/docs/en/api/faststream/redis/publisher/publisher/AsyncAPIChannelPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.publisher.publisher.AsyncAPIChannelPublisher diff --git a/docs/docs/en/api/faststream/redis/publisher/publisher/AsyncAPIListBatchPublisher.md b/docs/docs/en/api/faststream/redis/publisher/publisher/AsyncAPIListBatchPublisher.md new file mode 100644 index 0000000000..005a6c863f --- /dev/null +++ b/docs/docs/en/api/faststream/redis/publisher/publisher/AsyncAPIListBatchPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.publisher.publisher.AsyncAPIListBatchPublisher diff --git a/docs/docs/en/api/faststream/redis/publisher/asyncapi/AsyncAPIListPublisher.md b/docs/docs/en/api/faststream/redis/publisher/publisher/AsyncAPIListPublisher.md similarity index 63% rename from docs/docs/en/api/faststream/redis/publisher/asyncapi/AsyncAPIListPublisher.md rename to docs/docs/en/api/faststream/redis/publisher/publisher/AsyncAPIListPublisher.md index 0c233cc74b..2aa117e912 100644 --- a/docs/docs/en/api/faststream/redis/publisher/asyncapi/AsyncAPIListPublisher.md +++ b/docs/docs/en/api/faststream/redis/publisher/publisher/AsyncAPIListPublisher.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.redis.publisher.asyncapi.AsyncAPIListPublisher +::: faststream.redis.publisher.publisher.AsyncAPIListPublisher diff --git a/docs/docs/en/api/faststream/kafka/subscriber/asyncapi/AsyncAPIBatchSubscriber.md b/docs/docs/en/api/faststream/redis/publisher/publisher/AsyncAPIStreamPublisher.md similarity index 63% rename from docs/docs/en/api/faststream/kafka/subscriber/asyncapi/AsyncAPIBatchSubscriber.md rename to docs/docs/en/api/faststream/redis/publisher/publisher/AsyncAPIStreamPublisher.md index 3ce948d2e2..53fc7fbd3a 100644 --- a/docs/docs/en/api/faststream/kafka/subscriber/asyncapi/AsyncAPIBatchSubscriber.md +++ b/docs/docs/en/api/faststream/redis/publisher/publisher/AsyncAPIStreamPublisher.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.kafka.subscriber.asyncapi.AsyncAPIBatchSubscriber +::: faststream.redis.publisher.publisher.AsyncAPIStreamPublisher diff --git a/docs/docs/en/api/faststream/redis/publisher/publisher/SpecificationPublisher.md b/docs/docs/en/api/faststream/redis/publisher/publisher/SpecificationPublisher.md new file mode 100644 index 0000000000..755f5c6939 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/publisher/publisher/SpecificationPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.publisher.publisher.SpecificationPublisher diff --git a/docs/docs/en/api/faststream/redis/subscriber/asyncapi/AsyncAPIListBatchSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/asyncapi/AsyncAPIListBatchSubscriber.md deleted file mode 100644 index 26aa621262..0000000000 --- a/docs/docs/en/api/faststream/redis/subscriber/asyncapi/AsyncAPIListBatchSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.subscriber.asyncapi.AsyncAPIListBatchSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/asyncapi/AsyncAPISubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/asyncapi/AsyncAPISubscriber.md deleted file mode 100644 index c957f32688..0000000000 --- a/docs/docs/en/api/faststream/redis/subscriber/asyncapi/AsyncAPISubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.subscriber.asyncapi.AsyncAPISubscriber diff --git a/docs/docs/en/api/faststream/confluent/subscriber/asyncapi/AsyncAPIBatchSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/subscriber/AsyncAPIChannelSubscriber.md similarity index 64% rename from docs/docs/en/api/faststream/confluent/subscriber/asyncapi/AsyncAPIBatchSubscriber.md rename to docs/docs/en/api/faststream/redis/subscriber/subscriber/AsyncAPIChannelSubscriber.md index f6fc81226a..f14fc9956e 100644 --- a/docs/docs/en/api/faststream/confluent/subscriber/asyncapi/AsyncAPIBatchSubscriber.md +++ b/docs/docs/en/api/faststream/redis/subscriber/subscriber/AsyncAPIChannelSubscriber.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.confluent.subscriber.asyncapi.AsyncAPIBatchSubscriber +::: faststream.redis.subscriber.subscriber.AsyncAPIChannelSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/asyncapi/AsyncAPIStreamBatchSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/subscriber/AsyncAPIListBatchSubscriber.md similarity index 64% rename from docs/docs/en/api/faststream/redis/subscriber/asyncapi/AsyncAPIStreamBatchSubscriber.md rename to docs/docs/en/api/faststream/redis/subscriber/subscriber/AsyncAPIListBatchSubscriber.md index 099f0a4ff2..a1126ce719 100644 --- a/docs/docs/en/api/faststream/redis/subscriber/asyncapi/AsyncAPIStreamBatchSubscriber.md +++ b/docs/docs/en/api/faststream/redis/subscriber/subscriber/AsyncAPIListBatchSubscriber.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.redis.subscriber.asyncapi.AsyncAPIStreamBatchSubscriber +::: faststream.redis.subscriber.subscriber.AsyncAPIListBatchSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/asyncapi/AsyncAPIListSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/subscriber/AsyncAPIListSubscriber.md similarity index 62% rename from docs/docs/en/api/faststream/redis/subscriber/asyncapi/AsyncAPIListSubscriber.md rename to docs/docs/en/api/faststream/redis/subscriber/subscriber/AsyncAPIListSubscriber.md index c65ba472d5..d1c36ae1a1 100644 --- a/docs/docs/en/api/faststream/redis/subscriber/asyncapi/AsyncAPIListSubscriber.md +++ b/docs/docs/en/api/faststream/redis/subscriber/subscriber/AsyncAPIListSubscriber.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.redis.subscriber.asyncapi.AsyncAPIListSubscriber +::: faststream.redis.subscriber.subscriber.AsyncAPIListSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIConcurrentCoreSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/subscriber/AsyncAPIStreamBatchSubscriber.md similarity index 65% rename from docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIConcurrentCoreSubscriber.md rename to docs/docs/en/api/faststream/redis/subscriber/subscriber/AsyncAPIStreamBatchSubscriber.md index f88e14f817..5dd6ad995a 100644 --- a/docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIConcurrentCoreSubscriber.md +++ b/docs/docs/en/api/faststream/redis/subscriber/subscriber/AsyncAPIStreamBatchSubscriber.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.nats.subscriber.asyncapi.AsyncAPIConcurrentCoreSubscriber +::: faststream.redis.subscriber.subscriber.AsyncAPIStreamBatchSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/subscriber/AsyncAPIStreamSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/subscriber/AsyncAPIStreamSubscriber.md new file mode 100644 index 0000000000..e4c474fde0 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/subscriber/subscriber/AsyncAPIStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.subscriber.subscriber.AsyncAPIStreamSubscriber diff --git a/docs/docs/en/api/faststream/kafka/subscriber/asyncapi/AsyncAPIDefaultSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/subscriber/SpecificationSubscriber.md similarity index 63% rename from docs/docs/en/api/faststream/kafka/subscriber/asyncapi/AsyncAPIDefaultSubscriber.md rename to docs/docs/en/api/faststream/redis/subscriber/subscriber/SpecificationSubscriber.md index ef10b05e80..1187a36173 100644 --- a/docs/docs/en/api/faststream/kafka/subscriber/asyncapi/AsyncAPIDefaultSubscriber.md +++ b/docs/docs/en/api/faststream/redis/subscriber/subscriber/SpecificationSubscriber.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.kafka.subscriber.asyncapi.AsyncAPIDefaultSubscriber +::: faststream.redis.subscriber.subscriber.SpecificationSubscriber diff --git a/docs/docs/en/api/faststream/specification/asyncapi/base/schema/BaseInfo.md b/docs/docs/en/api/faststream/specification/asyncapi/base/schema/BaseInfo.md new file mode 100644 index 0000000000..24ca320131 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/base/schema/BaseInfo.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.base.schema.BaseInfo diff --git a/docs/docs/en/api/faststream/specification/asyncapi/base/schema/BaseSchema.md b/docs/docs/en/api/faststream/specification/asyncapi/base/schema/BaseSchema.md new file mode 100644 index 0000000000..553072fb35 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/base/schema/BaseSchema.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.base.schema.BaseSchema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/base/schema/info/BaseInfo.md b/docs/docs/en/api/faststream/specification/asyncapi/base/schema/info/BaseInfo.md new file mode 100644 index 0000000000..b3ba410f70 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/base/schema/info/BaseInfo.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.base.schema.info.BaseInfo diff --git a/docs/docs/en/api/faststream/specification/asyncapi/base/schema/schema/BaseSchema.md b/docs/docs/en/api/faststream/specification/asyncapi/base/schema/schema/BaseSchema.md new file mode 100644 index 0000000000..b41b1ab894 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/base/schema/schema/BaseSchema.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.base.schema.schema.BaseSchema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/generate/get_app_schema.md b/docs/docs/en/api/faststream/specification/asyncapi/generate/get_app_schema.md new file mode 100644 index 0000000000..f878844de5 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/generate/get_app_schema.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.generate.get_app_schema diff --git a/docs/docs/en/api/faststream/asyncapi/get_app_schema.md b/docs/docs/en/api/faststream/specification/asyncapi/get_app_schema.md similarity index 67% rename from docs/docs/en/api/faststream/asyncapi/get_app_schema.md rename to docs/docs/en/api/faststream/specification/asyncapi/get_app_schema.md index 03d7e4466b..3b4991f8e3 100644 --- a/docs/docs/en/api/faststream/asyncapi/get_app_schema.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/get_app_schema.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.get_app_schema +::: faststream.specification.asyncapi.get_app_schema diff --git a/docs/docs/en/api/faststream/asyncapi/get_asyncapi_html.md b/docs/docs/en/api/faststream/specification/asyncapi/get_asyncapi_html.md similarity index 66% rename from docs/docs/en/api/faststream/asyncapi/get_asyncapi_html.md rename to docs/docs/en/api/faststream/specification/asyncapi/get_asyncapi_html.md index 1ed4ce5500..02a5bf12cb 100644 --- a/docs/docs/en/api/faststream/asyncapi/get_asyncapi_html.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/get_asyncapi_html.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.get_asyncapi_html +::: faststream.specification.asyncapi.get_asyncapi_html diff --git a/docs/docs/en/api/faststream/asyncapi/message/get_model_schema.md b/docs/docs/en/api/faststream/specification/asyncapi/message/get_model_schema.md similarity index 63% rename from docs/docs/en/api/faststream/asyncapi/message/get_model_schema.md rename to docs/docs/en/api/faststream/specification/asyncapi/message/get_model_schema.md index 0099721324..83b5c9026e 100644 --- a/docs/docs/en/api/faststream/asyncapi/message/get_model_schema.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/message/get_model_schema.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.message.get_model_schema +::: faststream.specification.asyncapi.message.get_model_schema diff --git a/docs/docs/en/api/faststream/asyncapi/message/get_response_schema.md b/docs/docs/en/api/faststream/specification/asyncapi/message/get_response_schema.md similarity index 62% rename from docs/docs/en/api/faststream/asyncapi/message/get_response_schema.md rename to docs/docs/en/api/faststream/specification/asyncapi/message/get_response_schema.md index e297370d01..d283b28902 100644 --- a/docs/docs/en/api/faststream/asyncapi/message/get_response_schema.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/message/get_response_schema.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.message.get_response_schema +::: faststream.specification.asyncapi.message.get_response_schema diff --git a/docs/docs/en/api/faststream/asyncapi/message/parse_handler_params.md b/docs/docs/en/api/faststream/specification/asyncapi/message/parse_handler_params.md similarity index 62% rename from docs/docs/en/api/faststream/asyncapi/message/parse_handler_params.md rename to docs/docs/en/api/faststream/specification/asyncapi/message/parse_handler_params.md index ffaf1cf7dc..cb6c4416f8 100644 --- a/docs/docs/en/api/faststream/asyncapi/message/parse_handler_params.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/message/parse_handler_params.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.message.parse_handler_params +::: faststream.specification.asyncapi.message.parse_handler_params diff --git a/docs/docs/en/api/faststream/asyncapi/site/get_asyncapi_html.md b/docs/docs/en/api/faststream/specification/asyncapi/site/get_asyncapi_html.md similarity index 64% rename from docs/docs/en/api/faststream/asyncapi/site/get_asyncapi_html.md rename to docs/docs/en/api/faststream/specification/asyncapi/site/get_asyncapi_html.md index 69af839e6c..837b931af7 100644 --- a/docs/docs/en/api/faststream/asyncapi/site/get_asyncapi_html.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/site/get_asyncapi_html.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.site.get_asyncapi_html +::: faststream.specification.asyncapi.site.get_asyncapi_html diff --git a/docs/docs/en/api/faststream/asyncapi/site/serve_app.md b/docs/docs/en/api/faststream/specification/asyncapi/site/serve_app.md similarity index 67% rename from docs/docs/en/api/faststream/asyncapi/site/serve_app.md rename to docs/docs/en/api/faststream/specification/asyncapi/site/serve_app.md index c5a1a726e8..279e9eb8e0 100644 --- a/docs/docs/en/api/faststream/asyncapi/site/serve_app.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/site/serve_app.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.site.serve_app +::: faststream.specification.asyncapi.site.serve_app diff --git a/docs/docs/en/api/faststream/asyncapi/utils/resolve_payloads.md b/docs/docs/en/api/faststream/specification/asyncapi/utils/resolve_payloads.md similarity index 64% rename from docs/docs/en/api/faststream/asyncapi/utils/resolve_payloads.md rename to docs/docs/en/api/faststream/specification/asyncapi/utils/resolve_payloads.md index 23aeedd082..d92d1850f3 100644 --- a/docs/docs/en/api/faststream/asyncapi/utils/resolve_payloads.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/utils/resolve_payloads.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.utils.resolve_payloads +::: faststream.specification.asyncapi.utils.resolve_payloads diff --git a/docs/docs/en/api/faststream/asyncapi/utils/to_camelcase.md b/docs/docs/en/api/faststream/specification/asyncapi/utils/to_camelcase.md similarity index 65% rename from docs/docs/en/api/faststream/asyncapi/utils/to_camelcase.md rename to docs/docs/en/api/faststream/specification/asyncapi/utils/to_camelcase.md index 42cbdf9f29..5a260c9cca 100644 --- a/docs/docs/en/api/faststream/asyncapi/utils/to_camelcase.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/utils/to_camelcase.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.utils.to_camelcase +::: faststream.specification.asyncapi.utils.to_camelcase diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_app_schema.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_app_schema.md new file mode 100644 index 0000000000..ef0e191d3d --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_app_schema.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.generate.get_app_schema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_channels.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_channels.md new file mode 100644 index 0000000000..03fc069dc1 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_channels.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.generate.get_broker_channels diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_server.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_server.md new file mode 100644 index 0000000000..c7b9007c14 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_server.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.generate.get_broker_server diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/move_pydantic_refs.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/move_pydantic_refs.md new file mode 100644 index 0000000000..3494537e25 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/move_pydantic_refs.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.generate.move_pydantic_refs diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/resolve_channel_messages.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/resolve_channel_messages.md new file mode 100644 index 0000000000..91abb99b8b --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/resolve_channel_messages.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.generate.resolve_channel_messages diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/get_app_schema.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/get_app_schema.md new file mode 100644 index 0000000000..234b4b8bda --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/get_app_schema.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.get_app_schema diff --git a/docs/docs/en/api/faststream/asyncapi/schema/channels/Channel.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Channel.md similarity index 64% rename from docs/docs/en/api/faststream/asyncapi/schema/channels/Channel.md rename to docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Channel.md index 7e8a913786..76da65a973 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/channels/Channel.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Channel.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.channels.Channel +::: faststream.specification.asyncapi.v2_6_0.schema.Channel diff --git a/docs/docs/en/api/faststream/asyncapi/schema/main/Components.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Components.md similarity index 63% rename from docs/docs/en/api/faststream/asyncapi/schema/main/Components.md rename to docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Components.md index 782ed0e625..12ba1a0a30 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/main/Components.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Components.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.main.Components +::: faststream.specification.asyncapi.v2_6_0.schema.Components diff --git a/docs/docs/en/api/faststream/asyncapi/schema/info/Contact.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Contact.md similarity index 64% rename from docs/docs/en/api/faststream/asyncapi/schema/info/Contact.md rename to docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Contact.md index 2dfb0d074e..7eba14d8b1 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/info/Contact.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Contact.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.info.Contact +::: faststream.specification.asyncapi.v2_6_0.schema.Contact diff --git a/docs/docs/en/api/faststream/asyncapi/schema/message/CorrelationId.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/CorrelationId.md similarity index 62% rename from docs/docs/en/api/faststream/asyncapi/schema/message/CorrelationId.md rename to docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/CorrelationId.md index 7693915525..3173309f51 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/message/CorrelationId.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/CorrelationId.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.message.CorrelationId +::: faststream.specification.asyncapi.v2_6_0.schema.CorrelationId diff --git a/docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIStreamSubscriber.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ExternalDocs.md similarity index 63% rename from docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIStreamSubscriber.md rename to docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ExternalDocs.md index 6d448d3af5..2df43d1016 100644 --- a/docs/docs/en/api/faststream/nats/subscriber/asyncapi/AsyncAPIStreamSubscriber.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ExternalDocs.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.nats.subscriber.asyncapi.AsyncAPIStreamSubscriber +::: faststream.specification.asyncapi.v2_6_0.schema.ExternalDocs diff --git a/docs/docs/en/api/faststream/asyncapi/schema/info/Info.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Info.md similarity index 65% rename from docs/docs/en/api/faststream/asyncapi/schema/info/Info.md rename to docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Info.md index 88201af129..a721edf50a 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/info/Info.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Info.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.info.Info +::: faststream.specification.asyncapi.v2_6_0.schema.Info diff --git a/docs/docs/en/api/faststream/asyncapi/schema/info/License.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/License.md similarity index 64% rename from docs/docs/en/api/faststream/asyncapi/schema/info/License.md rename to docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/License.md index ad564b3886..3f17b11448 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/info/License.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/License.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.info.License +::: faststream.specification.asyncapi.v2_6_0.schema.License diff --git a/docs/docs/en/api/faststream/asyncapi/schema/message/Message.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Message.md similarity index 64% rename from docs/docs/en/api/faststream/asyncapi/schema/message/Message.md rename to docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Message.md index e3959190b0..f6247931d4 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/message/Message.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Message.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.message.Message +::: faststream.specification.asyncapi.v2_6_0.schema.Message diff --git a/docs/docs/en/api/faststream/asyncapi/schema/operations/Operation.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Operation.md similarity index 63% rename from docs/docs/en/api/faststream/asyncapi/schema/operations/Operation.md rename to docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Operation.md index 0af1c63cfe..e25d0e8ff2 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/operations/Operation.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Operation.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.operations.Operation +::: faststream.specification.asyncapi.v2_6_0.schema.Operation diff --git a/docs/docs/en/api/faststream/asyncapi/schema/utils/Parameter.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Parameter.md similarity index 63% rename from docs/docs/en/api/faststream/asyncapi/schema/utils/Parameter.md rename to docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Parameter.md index 05cc2f3ba3..fac8aa5ee7 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/utils/Parameter.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Parameter.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.utils.Parameter +::: faststream.specification.asyncapi.v2_6_0.schema.Parameter diff --git a/docs/docs/en/api/faststream/asyncapi/schema/Reference.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Reference.md similarity index 63% rename from docs/docs/en/api/faststream/asyncapi/schema/Reference.md rename to docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Reference.md index 778b70e548..c469faf891 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/Reference.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Reference.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.Reference +::: faststream.specification.asyncapi.v2_6_0.schema.Reference diff --git a/docs/docs/en/api/faststream/asyncapi/schema/Schema.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Schema.md similarity index 65% rename from docs/docs/en/api/faststream/asyncapi/schema/Schema.md rename to docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Schema.md index a496f56769..929fbef551 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/Schema.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Schema.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.Schema +::: faststream.specification.asyncapi.v2_6_0.schema.Schema diff --git a/docs/docs/en/api/faststream/asyncapi/schema/servers/Server.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Server.md similarity index 65% rename from docs/docs/en/api/faststream/asyncapi/schema/servers/Server.md rename to docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Server.md index 5af6199d20..82bc1ddb32 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/servers/Server.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Server.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.servers.Server +::: faststream.specification.asyncapi.v2_6_0.schema.Server diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ServerVariable.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ServerVariable.md new file mode 100644 index 0000000000..06639f3ec5 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ServerVariable.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.ServerVariable diff --git a/docs/docs/en/api/faststream/asyncapi/schema/utils/Tag.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Tag.md similarity index 66% rename from docs/docs/en/api/faststream/asyncapi/schema/utils/Tag.md rename to docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Tag.md index cf558e756d..35baa89db7 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/utils/Tag.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Tag.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.utils.Tag +::: faststream.specification.asyncapi.v2_6_0.schema.Tag diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/ChannelBinding.md new file mode 100644 index 0000000000..36874fc37c --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/OperationBinding.md new file mode 100644 index 0000000000..eb11d6b550 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/ChannelBinding.md new file mode 100644 index 0000000000..263e89f51b --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/OperationBinding.md new file mode 100644 index 0000000000..350a96b413 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/ChannelBinding.md new file mode 100644 index 0000000000..6b4f8d6d93 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Exchange.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Exchange.md new file mode 100644 index 0000000000..dbd3288b64 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Exchange.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.channel.Exchange diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Queue.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Queue.md new file mode 100644 index 0000000000..31de312529 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Queue.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.channel.Queue diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/from_spec.md new file mode 100644 index 0000000000..a1217d16ed --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.channel.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel_binding_from_spec.md new file mode 100644 index 0000000000..b23b92754d --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel_binding_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.channel_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/OperationBinding.md new file mode 100644 index 0000000000..937cda8820 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/from_spec.md new file mode 100644 index 0000000000..b9f6bb0bad --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.operation.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation_binding_from_spec.md new file mode 100644 index 0000000000..9d6d922417 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation_binding_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.operation_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/channel_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/channel_binding_from_spec.md new file mode 100644 index 0000000000..b6b5acc218 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/channel_binding_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.channel_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/ChannelBinding.md new file mode 100644 index 0000000000..7792a2bef7 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/OperationBinding.md new file mode 100644 index 0000000000..21c35af99f --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel/ChannelBinding.md new file mode 100644 index 0000000000..82b2556711 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel/from_spec.md new file mode 100644 index 0000000000..5b5f07e785 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka.channel.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel_binding_from_spec.md new file mode 100644 index 0000000000..12cec52d31 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel_binding_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka.channel_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/OperationBinding.md new file mode 100644 index 0000000000..49e28f86ef --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/from_spec.md new file mode 100644 index 0000000000..b272f8b9c8 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka.operation.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation_binding_from_spec.md new file mode 100644 index 0000000000..6f21621ca9 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation_binding_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka.operation_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/ChannelBinding.md new file mode 100644 index 0000000000..a044af926c --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.main.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/OperationBinding.md new file mode 100644 index 0000000000..9cf2d46f59 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.main.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/ChannelBinding.md new file mode 100644 index 0000000000..c7d4ecef03 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.main.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/from_spec.md new file mode 100644 index 0000000000..a585d16f8f --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.main.channel.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel_binding_from_spec.md new file mode 100644 index 0000000000..8bdcd11238 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel_binding_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.main.channel_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/OperationBinding.md new file mode 100644 index 0000000000..b464bbb356 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.main.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/from_spec.md new file mode 100644 index 0000000000..5c5fbed4b9 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.main.operation.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation_binding_from_spec.md new file mode 100644 index 0000000000..ff97aa268d --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation_binding_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.main.operation_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/ChannelBinding.md new file mode 100644 index 0000000000..8380c4571d --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.nats.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/OperationBinding.md new file mode 100644 index 0000000000..c48ff3bad7 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.nats.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel/ChannelBinding.md new file mode 100644 index 0000000000..ebc06a51b8 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.nats.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel/from_spec.md new file mode 100644 index 0000000000..942832cb44 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.nats.channel.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel_binding_from_spec.md new file mode 100644 index 0000000000..3ad06c3ee2 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel_binding_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.nats.channel_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/OperationBinding.md new file mode 100644 index 0000000000..10ebc684ce --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.nats.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/from_spec.md new file mode 100644 index 0000000000..208641ea9b --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.nats.operation.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation_binding_from_spec.md new file mode 100644 index 0000000000..a96dc2df87 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation_binding_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.nats.operation_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/operation_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/operation_binding_from_spec.md new file mode 100644 index 0000000000..3ca4781fb7 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/operation_binding_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.operation_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/ChannelBinding.md new file mode 100644 index 0000000000..49402a3533 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.redis.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/OperationBinding.md new file mode 100644 index 0000000000..4a41fede12 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.redis.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel/ChannelBinding.md new file mode 100644 index 0000000000..4c859b133e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.redis.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel/from_spec.md new file mode 100644 index 0000000000..54540e817f --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.redis.channel.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel_binding_from_spec.md new file mode 100644 index 0000000000..550f068d5c --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel_binding_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.redis.channel_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/OperationBinding.md new file mode 100644 index 0000000000..5e7ef90817 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.redis.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/from_spec.md new file mode 100644 index 0000000000..f046e5bbe4 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.redis.operation.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation_binding_from_spec.md new file mode 100644 index 0000000000..8bd9df5f63 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation_binding_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.redis.operation_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/ChannelBinding.md new file mode 100644 index 0000000000..efd54e587e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/OperationBinding.md new file mode 100644 index 0000000000..4f3babf6a5 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/ChannelBinding.md new file mode 100644 index 0000000000..274f800ea8 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/from_spec.md new file mode 100644 index 0000000000..6890ca0373 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.channel.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel_binding_from_spec.md new file mode 100644 index 0000000000..82d3c125b1 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel_binding_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.channel_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/OperationBinding.md new file mode 100644 index 0000000000..931067bfef --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/from_spec.md new file mode 100644 index 0000000000..b8a69ffcc0 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.operation.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation_binding_from_spec.md new file mode 100644 index 0000000000..e42a8bdedb --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation_binding_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.operation_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channel_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channel_from_spec.md new file mode 100644 index 0000000000..7f5747228e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channel_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.channel_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channels/Channel.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channels/Channel.md new file mode 100644 index 0000000000..520d156b96 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channels/Channel.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.channels.Channel diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channels/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channels/from_spec.md new file mode 100644 index 0000000000..64b96ac9a6 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channels/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.channels.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/components/Components.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/components/Components.md new file mode 100644 index 0000000000..215edc3e69 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/components/Components.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.components.Components diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact/Contact.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact/Contact.md new file mode 100644 index 0000000000..14b7574d92 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact/Contact.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.contact.Contact diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact/from_spec.md new file mode 100644 index 0000000000..bb218f2cfb --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.contact.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact_from_spec.md new file mode 100644 index 0000000000..31b181d86e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.contact_from_spec diff --git a/docs/docs/en/api/faststream/asyncapi/schema/utils/ExternalDocs.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs/ExternalDocs.md similarity index 61% rename from docs/docs/en/api/faststream/asyncapi/schema/utils/ExternalDocs.md rename to docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs/ExternalDocs.md index 207668a5c5..8b66a2c5f3 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/utils/ExternalDocs.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs/ExternalDocs.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.utils.ExternalDocs +::: faststream.specification.asyncapi.v2_6_0.schema.docs.ExternalDocs diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs/from_spec.md new file mode 100644 index 0000000000..a604f0734a --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.docs.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs_from_spec.md new file mode 100644 index 0000000000..343fbfdb3c --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.docs_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/info/Info.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/info/Info.md new file mode 100644 index 0000000000..9865afcb70 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/info/Info.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.info.Info diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license/License.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license/License.md new file mode 100644 index 0000000000..d9d4102522 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license/License.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.license.License diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license/from_spec.md new file mode 100644 index 0000000000..f3e154561d --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.license.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license_from_spec.md new file mode 100644 index 0000000000..0281ab3755 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.license_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/CorrelationId.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/CorrelationId.md new file mode 100644 index 0000000000..bbfc2f40d8 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/CorrelationId.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.message.CorrelationId diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/Message.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/Message.md new file mode 100644 index 0000000000..9667e77e8e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/Message.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.message.Message diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/from_spec.md new file mode 100644 index 0000000000..4d3923d382 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.message.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message_from_spec.md new file mode 100644 index 0000000000..25fec8161b --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.message_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operation_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operation_from_spec.md new file mode 100644 index 0000000000..750a7d5f66 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operation_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.operation_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operations/Operation.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operations/Operation.md new file mode 100644 index 0000000000..3d750e5f3e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operations/Operation.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.operations.Operation diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operations/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operations/from_spec.md new file mode 100644 index 0000000000..70119aae06 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operations/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.operations.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/schema/Schema.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/schema/Schema.md new file mode 100644 index 0000000000..5f7dc7f43e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/schema/Schema.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.schema.Schema diff --git a/docs/docs/en/api/faststream/redis/publisher/asyncapi/AsyncAPIListBatchPublisher.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/servers/Server.md similarity index 63% rename from docs/docs/en/api/faststream/redis/publisher/asyncapi/AsyncAPIListBatchPublisher.md rename to docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/servers/Server.md index ab4361bd85..a50c1a5cf1 100644 --- a/docs/docs/en/api/faststream/redis/publisher/asyncapi/AsyncAPIListBatchPublisher.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/servers/Server.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.redis.publisher.asyncapi.AsyncAPIListBatchPublisher +::: faststream.specification.asyncapi.v2_6_0.schema.servers.Server diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/servers/ServerVariable.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/servers/ServerVariable.md new file mode 100644 index 0000000000..8606288a32 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/servers/ServerVariable.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.servers.ServerVariable diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag/Tag.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag/Tag.md new file mode 100644 index 0000000000..c3d9025966 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag/Tag.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.tag.Tag diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag/from_spec.md new file mode 100644 index 0000000000..0269c70d4c --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.tag.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag_from_spec.md new file mode 100644 index 0000000000..8f349787b1 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.tag_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/utils/Parameter.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/utils/Parameter.md new file mode 100644 index 0000000000..c2971d5485 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/utils/Parameter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.utils.Parameter diff --git a/docs/docs/en/api/faststream/asyncapi/schema/utils/Reference.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/utils/Reference.md similarity index 61% rename from docs/docs/en/api/faststream/asyncapi/schema/utils/Reference.md rename to docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/utils/Reference.md index a47fd931df..2737907b0e 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/utils/Reference.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/utils/Reference.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.utils.Reference +::: faststream.specification.asyncapi.v2_6_0.schema.utils.Reference diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_app_schema.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_app_schema.md new file mode 100644 index 0000000000..0faa97ba94 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_app_schema.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.generate.get_app_schema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_channels.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_channels.md new file mode 100644 index 0000000000..d43691125d --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_channels.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.generate.get_broker_channels diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_operations.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_operations.md new file mode 100644 index 0000000000..eea75e44cb --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_operations.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.generate.get_broker_operations diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_server.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_server.md new file mode 100644 index 0000000000..1c71db1292 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_server.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.generate.get_broker_server diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/get_app_schema.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/get_app_schema.md new file mode 100644 index 0000000000..977c46289d --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/get_app_schema.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.get_app_schema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Channel.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Channel.md new file mode 100644 index 0000000000..f213110586 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Channel.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.Channel diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Components.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Components.md new file mode 100644 index 0000000000..bce8d6e93e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Components.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.Components diff --git a/docs/docs/en/api/faststream/asyncapi/generate/get_broker_server.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Info.md similarity index 65% rename from docs/docs/en/api/faststream/asyncapi/generate/get_broker_server.md rename to docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Info.md index 5f652d5b59..78a6f784de 100644 --- a/docs/docs/en/api/faststream/asyncapi/generate/get_broker_server.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Info.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.generate.get_broker_server +::: faststream.specification.asyncapi.v3_0_0.schema.Info diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Operation.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Operation.md new file mode 100644 index 0000000000..a46ecefb8d --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Operation.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.Operation diff --git a/docs/docs/en/api/faststream/asyncapi/schema/main/Schema.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Schema.md similarity index 65% rename from docs/docs/en/api/faststream/asyncapi/schema/main/Schema.md rename to docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Schema.md index 1280877df1..680b107ea3 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/main/Schema.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Schema.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.main.Schema +::: faststream.specification.asyncapi.v3_0_0.schema.Schema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Server.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Server.md new file mode 100644 index 0000000000..d41ebe84c3 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Server.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.Server diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channel_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channel_from_spec.md new file mode 100644 index 0000000000..109f18f748 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channel_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.channel_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channels/Channel.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channels/Channel.md new file mode 100644 index 0000000000..b3b425a350 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channels/Channel.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.channels.Channel diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channels/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channels/from_spec.md new file mode 100644 index 0000000000..949ff18a73 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channels/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.channels.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/components/Components.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/components/Components.md new file mode 100644 index 0000000000..db5c489f43 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/components/Components.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.components.Components diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/info/Info.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/info/Info.md new file mode 100644 index 0000000000..b3ddac50c0 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/info/Info.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.info.Info diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operation_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operation_from_spec.md new file mode 100644 index 0000000000..178bf36c4a --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operation_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.operation_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/Action.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/Action.md new file mode 100644 index 0000000000..c5a9956348 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/Action.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.operations.Action diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/Operation.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/Operation.md new file mode 100644 index 0000000000..1ac73f73da --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/Operation.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.operations.Operation diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/from_spec.md new file mode 100644 index 0000000000..9b9b197889 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.operations.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/schema/Schema.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/schema/Schema.md new file mode 100644 index 0000000000..16a72b4b01 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/schema/Schema.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.schema.Schema diff --git a/docs/docs/en/api/faststream/redis/subscriber/asyncapi/AsyncAPIChannelSubscriber.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/servers/Server.md similarity index 63% rename from docs/docs/en/api/faststream/redis/subscriber/asyncapi/AsyncAPIChannelSubscriber.md rename to docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/servers/Server.md index 7cb7260111..1d9f1168d9 100644 --- a/docs/docs/en/api/faststream/redis/subscriber/asyncapi/AsyncAPIChannelSubscriber.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/servers/Server.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.redis.subscriber.asyncapi.AsyncAPIChannelSubscriber +::: faststream.specification.asyncapi.v3_0_0.schema.servers.Server diff --git a/docs/docs/en/api/faststream/asyncapi/abc/AsyncAPIOperation.md b/docs/docs/en/api/faststream/specification/proto/Application.md similarity index 70% rename from docs/docs/en/api/faststream/asyncapi/abc/AsyncAPIOperation.md rename to docs/docs/en/api/faststream/specification/proto/Application.md index 1e80c37541..c6889ac3b8 100644 --- a/docs/docs/en/api/faststream/asyncapi/abc/AsyncAPIOperation.md +++ b/docs/docs/en/api/faststream/specification/proto/Application.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.abc.AsyncAPIOperation +::: faststream.specification.proto.Application diff --git a/docs/docs/en/api/faststream/asyncapi/generate/get_app_schema.md b/docs/docs/en/api/faststream/specification/proto/SpecificationProto.md similarity index 67% rename from docs/docs/en/api/faststream/asyncapi/generate/get_app_schema.md rename to docs/docs/en/api/faststream/specification/proto/SpecificationProto.md index 07475ef5a8..6258cfcd19 100644 --- a/docs/docs/en/api/faststream/asyncapi/generate/get_app_schema.md +++ b/docs/docs/en/api/faststream/specification/proto/SpecificationProto.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.generate.get_app_schema +::: faststream.specification.proto.SpecificationProto diff --git a/docs/docs/en/api/faststream/asyncapi/schema/ChannelBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/ChannelBinding.md similarity index 64% rename from docs/docs/en/api/faststream/asyncapi/schema/ChannelBinding.md rename to docs/docs/en/api/faststream/specification/schema/bindings/ChannelBinding.md index 4aaf57e584..cb7f566dc1 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/ChannelBinding.md +++ b/docs/docs/en/api/faststream/specification/schema/bindings/ChannelBinding.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.ChannelBinding +::: faststream.specification.schema.bindings.ChannelBinding diff --git a/docs/docs/en/api/faststream/asyncapi/schema/OperationBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/OperationBinding.md similarity index 63% rename from docs/docs/en/api/faststream/asyncapi/schema/OperationBinding.md rename to docs/docs/en/api/faststream/specification/schema/bindings/OperationBinding.md index 0dc2099b66..6fcad5ea7e 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/OperationBinding.md +++ b/docs/docs/en/api/faststream/specification/schema/bindings/OperationBinding.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.OperationBinding +::: faststream.specification.schema.bindings.OperationBinding diff --git a/docs/docs/en/api/faststream/redis/publisher/asyncapi/AsyncAPIChannelPublisher.md b/docs/docs/en/api/faststream/specification/schema/bindings/amqp/ChannelBinding.md similarity index 63% rename from docs/docs/en/api/faststream/redis/publisher/asyncapi/AsyncAPIChannelPublisher.md rename to docs/docs/en/api/faststream/specification/schema/bindings/amqp/ChannelBinding.md index a3bef9a56c..194c68f536 100644 --- a/docs/docs/en/api/faststream/redis/publisher/asyncapi/AsyncAPIChannelPublisher.md +++ b/docs/docs/en/api/faststream/specification/schema/bindings/amqp/ChannelBinding.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.redis.publisher.asyncapi.AsyncAPIChannelPublisher +::: faststream.specification.schema.bindings.amqp.ChannelBinding diff --git a/docs/docs/en/api/faststream/asyncapi/schema/bindings/amqp/Exchange.md b/docs/docs/en/api/faststream/specification/schema/bindings/amqp/Exchange.md similarity index 65% rename from docs/docs/en/api/faststream/asyncapi/schema/bindings/amqp/Exchange.md rename to docs/docs/en/api/faststream/specification/schema/bindings/amqp/Exchange.md index b81a881827..355222c2bb 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/bindings/amqp/Exchange.md +++ b/docs/docs/en/api/faststream/specification/schema/bindings/amqp/Exchange.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.bindings.amqp.Exchange +::: faststream.specification.schema.bindings.amqp.Exchange diff --git a/docs/docs/en/api/faststream/asyncapi/schema/bindings/amqp/OperationBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/amqp/OperationBinding.md similarity index 62% rename from docs/docs/en/api/faststream/asyncapi/schema/bindings/amqp/OperationBinding.md rename to docs/docs/en/api/faststream/specification/schema/bindings/amqp/OperationBinding.md index 5b9b34dd78..6bb90ca8ae 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/bindings/amqp/OperationBinding.md +++ b/docs/docs/en/api/faststream/specification/schema/bindings/amqp/OperationBinding.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.bindings.amqp.OperationBinding +::: faststream.specification.schema.bindings.amqp.OperationBinding diff --git a/docs/docs/en/api/faststream/asyncapi/schema/bindings/amqp/Queue.md b/docs/docs/en/api/faststream/specification/schema/bindings/amqp/Queue.md similarity index 66% rename from docs/docs/en/api/faststream/asyncapi/schema/bindings/amqp/Queue.md rename to docs/docs/en/api/faststream/specification/schema/bindings/amqp/Queue.md index 395a7aedb0..54c9493d0e 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/bindings/amqp/Queue.md +++ b/docs/docs/en/api/faststream/specification/schema/bindings/amqp/Queue.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.bindings.amqp.Queue +::: faststream.specification.schema.bindings.amqp.Queue diff --git a/docs/docs/en/api/faststream/asyncapi/schema/bindings/amqp/ChannelBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/kafka/ChannelBinding.md similarity index 62% rename from docs/docs/en/api/faststream/asyncapi/schema/bindings/amqp/ChannelBinding.md rename to docs/docs/en/api/faststream/specification/schema/bindings/kafka/ChannelBinding.md index 6c5c546126..2561bf2e72 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/bindings/amqp/ChannelBinding.md +++ b/docs/docs/en/api/faststream/specification/schema/bindings/kafka/ChannelBinding.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.bindings.amqp.ChannelBinding +::: faststream.specification.schema.bindings.kafka.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/kafka/OperationBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/kafka/OperationBinding.md new file mode 100644 index 0000000000..0746cedd33 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/bindings/kafka/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.bindings.kafka.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/main/ChannelBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/main/ChannelBinding.md new file mode 100644 index 0000000000..73bfc4bb40 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/bindings/main/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.bindings.main.ChannelBinding diff --git a/docs/docs/en/api/faststream/asyncapi/schema/bindings/kafka/OperationBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/main/OperationBinding.md similarity index 62% rename from docs/docs/en/api/faststream/asyncapi/schema/bindings/kafka/OperationBinding.md rename to docs/docs/en/api/faststream/specification/schema/bindings/main/OperationBinding.md index adaa645db0..f4ebb70b9c 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/bindings/kafka/OperationBinding.md +++ b/docs/docs/en/api/faststream/specification/schema/bindings/main/OperationBinding.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.bindings.kafka.OperationBinding +::: faststream.specification.schema.bindings.main.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/nats/ChannelBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/nats/ChannelBinding.md new file mode 100644 index 0000000000..4495e21ac2 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/bindings/nats/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.bindings.nats.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/nats/OperationBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/nats/OperationBinding.md new file mode 100644 index 0000000000..fde8061b86 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/bindings/nats/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.bindings.nats.OperationBinding diff --git a/docs/docs/en/api/faststream/asyncapi/schema/bindings/kafka/ChannelBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/redis/ChannelBinding.md similarity index 62% rename from docs/docs/en/api/faststream/asyncapi/schema/bindings/kafka/ChannelBinding.md rename to docs/docs/en/api/faststream/specification/schema/bindings/redis/ChannelBinding.md index f327d3147e..0f991824da 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/bindings/kafka/ChannelBinding.md +++ b/docs/docs/en/api/faststream/specification/schema/bindings/redis/ChannelBinding.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.bindings.kafka.ChannelBinding +::: faststream.specification.schema.bindings.redis.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/redis/OperationBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/redis/OperationBinding.md new file mode 100644 index 0000000000..95e3ca446a --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/bindings/redis/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.bindings.redis.OperationBinding diff --git a/docs/docs/en/api/faststream/asyncapi/schema/bindings/ChannelBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/sqs/ChannelBinding.md similarity index 63% rename from docs/docs/en/api/faststream/asyncapi/schema/bindings/ChannelBinding.md rename to docs/docs/en/api/faststream/specification/schema/bindings/sqs/ChannelBinding.md index 51a5ed6586..521a6f5560 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/bindings/ChannelBinding.md +++ b/docs/docs/en/api/faststream/specification/schema/bindings/sqs/ChannelBinding.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.bindings.ChannelBinding +::: faststream.specification.schema.bindings.sqs.ChannelBinding diff --git a/docs/docs/en/api/faststream/asyncapi/schema/bindings/OperationBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/sqs/OperationBinding.md similarity index 62% rename from docs/docs/en/api/faststream/asyncapi/schema/bindings/OperationBinding.md rename to docs/docs/en/api/faststream/specification/schema/bindings/sqs/OperationBinding.md index 37a28843be..a70995cb7f 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/bindings/OperationBinding.md +++ b/docs/docs/en/api/faststream/specification/schema/bindings/sqs/OperationBinding.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.bindings.OperationBinding +::: faststream.specification.schema.bindings.sqs.OperationBinding diff --git a/docs/docs/en/api/faststream/asyncapi/schema/Channel.md b/docs/docs/en/api/faststream/specification/schema/channel/Channel.md similarity index 67% rename from docs/docs/en/api/faststream/asyncapi/schema/Channel.md rename to docs/docs/en/api/faststream/specification/schema/channel/Channel.md index 4d3b7e83a3..054f3a7524 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/Channel.md +++ b/docs/docs/en/api/faststream/specification/schema/channel/Channel.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.Channel +::: faststream.specification.schema.channel.Channel diff --git a/docs/docs/en/api/faststream/asyncapi/schema/Components.md b/docs/docs/en/api/faststream/specification/schema/components/Components.md similarity index 65% rename from docs/docs/en/api/faststream/asyncapi/schema/Components.md rename to docs/docs/en/api/faststream/specification/schema/components/Components.md index 9dc785c35e..aee53e9aeb 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/Components.md +++ b/docs/docs/en/api/faststream/specification/schema/components/Components.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.Components +::: faststream.specification.schema.components.Components diff --git a/docs/docs/en/api/faststream/asyncapi/schema/Contact.md b/docs/docs/en/api/faststream/specification/schema/contact/Contact.md similarity index 67% rename from docs/docs/en/api/faststream/asyncapi/schema/Contact.md rename to docs/docs/en/api/faststream/specification/schema/contact/Contact.md index ded05c314d..5db25a7342 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/Contact.md +++ b/docs/docs/en/api/faststream/specification/schema/contact/Contact.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.Contact +::: faststream.specification.schema.contact.Contact diff --git a/docs/docs/en/api/faststream/asyncapi/schema/ContactDict.md b/docs/docs/en/api/faststream/specification/schema/contact/ContactDict.md similarity index 66% rename from docs/docs/en/api/faststream/asyncapi/schema/ContactDict.md rename to docs/docs/en/api/faststream/specification/schema/contact/ContactDict.md index 4170e564f6..6e03ef208b 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/ContactDict.md +++ b/docs/docs/en/api/faststream/specification/schema/contact/ContactDict.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.ContactDict +::: faststream.specification.schema.contact.ContactDict diff --git a/docs/docs/en/api/faststream/asyncapi/schema/ExternalDocs.md b/docs/docs/en/api/faststream/specification/schema/docs/ExternalDocs.md similarity index 67% rename from docs/docs/en/api/faststream/asyncapi/schema/ExternalDocs.md rename to docs/docs/en/api/faststream/specification/schema/docs/ExternalDocs.md index 7899164431..641eab0547 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/ExternalDocs.md +++ b/docs/docs/en/api/faststream/specification/schema/docs/ExternalDocs.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.ExternalDocs +::: faststream.specification.schema.docs.ExternalDocs diff --git a/docs/docs/en/api/faststream/asyncapi/schema/ExternalDocsDict.md b/docs/docs/en/api/faststream/specification/schema/docs/ExternalDocsDict.md similarity index 65% rename from docs/docs/en/api/faststream/asyncapi/schema/ExternalDocsDict.md rename to docs/docs/en/api/faststream/specification/schema/docs/ExternalDocsDict.md index d80a12b10f..7639fe848b 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/ExternalDocsDict.md +++ b/docs/docs/en/api/faststream/specification/schema/docs/ExternalDocsDict.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.ExternalDocsDict +::: faststream.specification.schema.docs.ExternalDocsDict diff --git a/docs/docs/en/api/faststream/asyncapi/schema/Info.md b/docs/docs/en/api/faststream/specification/schema/info/Info.md similarity index 70% rename from docs/docs/en/api/faststream/asyncapi/schema/Info.md rename to docs/docs/en/api/faststream/specification/schema/info/Info.md index 62eb9e4832..23d6ddec87 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/Info.md +++ b/docs/docs/en/api/faststream/specification/schema/info/Info.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.Info +::: faststream.specification.schema.info.Info diff --git a/docs/docs/en/api/faststream/asyncapi/schema/License.md b/docs/docs/en/api/faststream/specification/schema/license/License.md similarity index 67% rename from docs/docs/en/api/faststream/asyncapi/schema/License.md rename to docs/docs/en/api/faststream/specification/schema/license/License.md index adb11654e4..bad1afae02 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/License.md +++ b/docs/docs/en/api/faststream/specification/schema/license/License.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.License +::: faststream.specification.schema.license.License diff --git a/docs/docs/en/api/faststream/asyncapi/schema/LicenseDict.md b/docs/docs/en/api/faststream/specification/schema/license/LicenseDict.md similarity index 66% rename from docs/docs/en/api/faststream/asyncapi/schema/LicenseDict.md rename to docs/docs/en/api/faststream/specification/schema/license/LicenseDict.md index 7c200c4ac7..2ed6323a54 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/LicenseDict.md +++ b/docs/docs/en/api/faststream/specification/schema/license/LicenseDict.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.LicenseDict +::: faststream.specification.schema.license.LicenseDict diff --git a/docs/docs/en/api/faststream/asyncapi/schema/CorrelationId.md b/docs/docs/en/api/faststream/specification/schema/message/CorrelationId.md similarity index 65% rename from docs/docs/en/api/faststream/asyncapi/schema/CorrelationId.md rename to docs/docs/en/api/faststream/specification/schema/message/CorrelationId.md index cd12cdbba6..7f283d5a73 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/CorrelationId.md +++ b/docs/docs/en/api/faststream/specification/schema/message/CorrelationId.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.CorrelationId +::: faststream.specification.schema.message.CorrelationId diff --git a/docs/docs/en/api/faststream/asyncapi/schema/Message.md b/docs/docs/en/api/faststream/specification/schema/message/Message.md similarity index 67% rename from docs/docs/en/api/faststream/asyncapi/schema/Message.md rename to docs/docs/en/api/faststream/specification/schema/message/Message.md index f04adf939f..1c2fd0ceb8 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/Message.md +++ b/docs/docs/en/api/faststream/specification/schema/message/Message.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.Message +::: faststream.specification.schema.message.Message diff --git a/docs/docs/en/api/faststream/asyncapi/schema/Operation.md b/docs/docs/en/api/faststream/specification/schema/operation/Operation.md similarity index 66% rename from docs/docs/en/api/faststream/asyncapi/schema/Operation.md rename to docs/docs/en/api/faststream/specification/schema/operation/Operation.md index 2d43f05b89..23088a80f0 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/Operation.md +++ b/docs/docs/en/api/faststream/specification/schema/operation/Operation.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.Operation +::: faststream.specification.schema.operation.Operation diff --git a/docs/docs/en/api/faststream/asyncapi/generate/get_broker_channels.md b/docs/docs/en/api/faststream/specification/schema/schema/BaseSchema.md similarity index 67% rename from docs/docs/en/api/faststream/asyncapi/generate/get_broker_channels.md rename to docs/docs/en/api/faststream/specification/schema/schema/BaseSchema.md index f5788bae0b..0b0a288e80 100644 --- a/docs/docs/en/api/faststream/asyncapi/generate/get_broker_channels.md +++ b/docs/docs/en/api/faststream/specification/schema/schema/BaseSchema.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.generate.get_broker_channels +::: faststream.specification.schema.schema.BaseSchema diff --git a/docs/docs/en/api/faststream/asyncapi/schema/security/OauthFlowObj.md b/docs/docs/en/api/faststream/specification/schema/security/OauthFlowObj.md similarity index 65% rename from docs/docs/en/api/faststream/asyncapi/schema/security/OauthFlowObj.md rename to docs/docs/en/api/faststream/specification/schema/security/OauthFlowObj.md index ea6ad87db9..9fad152d4e 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/security/OauthFlowObj.md +++ b/docs/docs/en/api/faststream/specification/schema/security/OauthFlowObj.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.security.OauthFlowObj +::: faststream.specification.schema.security.OauthFlowObj diff --git a/docs/docs/en/api/faststream/asyncapi/schema/security/OauthFlows.md b/docs/docs/en/api/faststream/specification/schema/security/OauthFlows.md similarity index 66% rename from docs/docs/en/api/faststream/asyncapi/schema/security/OauthFlows.md rename to docs/docs/en/api/faststream/specification/schema/security/OauthFlows.md index 0c429487fb..3b4bee7938 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/security/OauthFlows.md +++ b/docs/docs/en/api/faststream/specification/schema/security/OauthFlows.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.security.OauthFlows +::: faststream.specification.schema.security.OauthFlows diff --git a/docs/docs/en/api/faststream/asyncapi/schema/SecuritySchemaComponent.md b/docs/docs/en/api/faststream/specification/schema/security/SecuritySchemaComponent.md similarity index 61% rename from docs/docs/en/api/faststream/asyncapi/schema/SecuritySchemaComponent.md rename to docs/docs/en/api/faststream/specification/schema/security/SecuritySchemaComponent.md index 61c0a83bf7..78395ed097 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/SecuritySchemaComponent.md +++ b/docs/docs/en/api/faststream/specification/schema/security/SecuritySchemaComponent.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.SecuritySchemaComponent +::: faststream.specification.schema.security.SecuritySchemaComponent diff --git a/docs/docs/en/api/faststream/asyncapi/schema/Server.md b/docs/docs/en/api/faststream/specification/schema/servers/Server.md similarity index 68% rename from docs/docs/en/api/faststream/asyncapi/schema/Server.md rename to docs/docs/en/api/faststream/specification/schema/servers/Server.md index e0d028314e..9885a049b8 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/Server.md +++ b/docs/docs/en/api/faststream/specification/schema/servers/Server.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.Server +::: faststream.specification.schema.servers.Server diff --git a/docs/docs/en/api/faststream/asyncapi/schema/servers/ServerVariable.md b/docs/docs/en/api/faststream/specification/schema/servers/ServerVariable.md similarity index 65% rename from docs/docs/en/api/faststream/asyncapi/schema/servers/ServerVariable.md rename to docs/docs/en/api/faststream/specification/schema/servers/ServerVariable.md index 51f99bd3bc..2831c07069 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/servers/ServerVariable.md +++ b/docs/docs/en/api/faststream/specification/schema/servers/ServerVariable.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.servers.ServerVariable +::: faststream.specification.schema.servers.ServerVariable diff --git a/docs/docs/en/api/faststream/asyncapi/schema/Tag.md b/docs/docs/en/api/faststream/specification/schema/tag/Tag.md similarity index 71% rename from docs/docs/en/api/faststream/asyncapi/schema/Tag.md rename to docs/docs/en/api/faststream/specification/schema/tag/Tag.md index 0c32584f58..00ead386cb 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/Tag.md +++ b/docs/docs/en/api/faststream/specification/schema/tag/Tag.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.Tag +::: faststream.specification.schema.tag.Tag diff --git a/docs/docs/en/api/faststream/asyncapi/schema/TagDict.md b/docs/docs/en/api/faststream/specification/schema/tag/TagDict.md similarity index 69% rename from docs/docs/en/api/faststream/asyncapi/schema/TagDict.md rename to docs/docs/en/api/faststream/specification/schema/tag/TagDict.md index ebb68351e0..e76b92e43b 100644 --- a/docs/docs/en/api/faststream/asyncapi/schema/TagDict.md +++ b/docs/docs/en/api/faststream/specification/schema/tag/TagDict.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.asyncapi.schema.TagDict +::: faststream.specification.schema.tag.TagDict From 531e2682dde10b9723045e50528e12058ffec56f Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 8 Sep 2024 15:00:07 +0300 Subject: [PATCH 133/245] Fix specification bindings amqp channel Exchange --- .../asyncapi/v2_6_0/schema/bindings/amqp/channel.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py index 4155bc2696..4d0b0f8dd5 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py @@ -50,17 +50,6 @@ class Exchange(BaseModel): vhost : virtual host of the exchange, default is "/" """ - type: Literal[ - "default", - "direct", - "topic", - "fanout", - "headers", - "x-delayed-message", - "x-consistent-hash", - "x-modulus-hash", - ] - name: Optional[str] = None type: Literal[ "default", @@ -72,7 +61,6 @@ class Exchange(BaseModel): "x-consistent-hash", "x-modulus-hash", ] - durable: Optional[bool] = None autoDelete: Optional[bool] = None vhost: str = "/" From 697328ad5637e6bcf59ed3bea86c8677e6a03e39 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 8 Sep 2024 15:01:55 +0300 Subject: [PATCH 134/245] Remove unused type: ignore comments --- faststream/rabbit/publisher/publisher.py | 2 +- faststream/rabbit/subscriber/subscriber.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/faststream/rabbit/publisher/publisher.py b/faststream/rabbit/publisher/publisher.py index be9d61f0f3..b6e2f922aa 100644 --- a/faststream/rabbit/publisher/publisher.py +++ b/faststream/rabbit/publisher/publisher.py @@ -47,7 +47,7 @@ def get_schema(self) -> Dict[str, Channel]: return { self.name: Channel( - description=self.description, # type: ignore[attr-defined] + description=self.description, publish=Operation( bindings=OperationBinding( amqp=amqp.OperationBinding( diff --git a/faststream/rabbit/subscriber/subscriber.py b/faststream/rabbit/subscriber/subscriber.py index 3e844ad77c..5ed253a8e2 100644 --- a/faststream/rabbit/subscriber/subscriber.py +++ b/faststream/rabbit/subscriber/subscriber.py @@ -24,7 +24,7 @@ def get_schema(self) -> Dict[str, Channel]: return { self.name: Channel( - description=self.description, # type: ignore[attr-defined] + description=self.description, subscribe=Operation( bindings=OperationBinding( amqp=amqp.OperationBinding( From 4e9cab75572685c8e511f4988be770525a28e666 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 8 Sep 2024 15:04:56 +0300 Subject: [PATCH 135/245] type: ignore[override] --- faststream/kafka/publisher/usecase.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/faststream/kafka/publisher/usecase.py b/faststream/kafka/publisher/usecase.py index d7258182a8..edb6bd0d12 100644 --- a/faststream/kafka/publisher/usecase.py +++ b/faststream/kafka/publisher/usecase.py @@ -319,7 +319,7 @@ async def publish( ) @override - async def request( + async def request( # type: ignore[override] self, message: Annotated[ "SendableMessage", @@ -396,7 +396,7 @@ async def request( ) @override - async def request( + async def request( # type: ignore[override] self, message: Annotated[ "SendableMessage", From 917f7cf605ec0cbcd87e50231c1ed7138b4e1557 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 8 Sep 2024 15:15:37 +0300 Subject: [PATCH 136/245] mypy satisfied --- faststream/rabbit/publisher/publisher.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/faststream/rabbit/publisher/publisher.py b/faststream/rabbit/publisher/publisher.py index b6e2f922aa..f61d069fde 100644 --- a/faststream/rabbit/publisher/publisher.py +++ b/faststream/rabbit/publisher/publisher.py @@ -53,9 +53,9 @@ def get_schema(self) -> Dict[str, Channel]: amqp=amqp.OperationBinding( cc=self.routing or None, deliveryMode=2 if self.message_kwargs.get("persist") else 1, - mandatory=self.message_kwargs.get("mandatory"), - replyTo=self.message_kwargs.get("reply_to"), - priority=self.message_kwargs.get("priority"), + mandatory=self.message_kwargs.get("mandatory"), # type: ignore[arg-type] + replyTo=self.message_kwargs.get("reply_to"), # type: ignore[arg-type] + priority=self.message_kwargs.get("priority"), # type: ignore[arg-type] ), ) if is_routing_exchange(self.exchange) From 6111e5332c0a0978ea4ace163192b0753a908c8f Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 8 Sep 2024 15:18:38 +0300 Subject: [PATCH 137/245] mypy satisfied --- faststream/kafka/publisher/usecase.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/faststream/kafka/publisher/usecase.py b/faststream/kafka/publisher/usecase.py index edb6bd0d12..c065b2e8ba 100644 --- a/faststream/kafka/publisher/usecase.py +++ b/faststream/kafka/publisher/usecase.py @@ -319,7 +319,7 @@ async def publish( ) @override - async def request( # type: ignore[override] + async def request( self, message: Annotated[ "SendableMessage", @@ -396,7 +396,7 @@ async def request( # type: ignore[override] ) @override - async def request( # type: ignore[override] + async def request( # type: ignore[no-redef] self, message: Annotated[ "SendableMessage", From da646d5c40677c0da6ffc921b6db60c231adf0dc Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 8 Sep 2024 15:28:12 +0300 Subject: [PATCH 138/245] fixes --- faststream/confluent/testing.py | 1 - faststream/kafka/publisher/usecase.py | 2 +- faststream/kafka/testing.py | 2 -- .../specification/asyncapi/v2_6_0/schema/bindings/sqs.py | 1 - tests/asyncapi/base/v2_6_0/fastapi.py | 2 +- tests/asyncapi/base/v3_0_0/fastapi.py | 8 ++++---- 6 files changed, 6 insertions(+), 10 deletions(-) diff --git a/faststream/confluent/testing.py b/faststream/confluent/testing.py index 90ca2291fe..a3d52d9412 100644 --- a/faststream/confluent/testing.py +++ b/faststream/confluent/testing.py @@ -20,7 +20,6 @@ if TYPE_CHECKING: from faststream.confluent.publisher.publisher import SpecificationPublisher from faststream.confluent.subscriber.usecase import LogicSubscriber - from faststream.testing.broker import TestBroker from faststream.types import SendableMessage __all__ = ( diff --git a/faststream/kafka/publisher/usecase.py b/faststream/kafka/publisher/usecase.py index c065b2e8ba..4fb95cd7ef 100644 --- a/faststream/kafka/publisher/usecase.py +++ b/faststream/kafka/publisher/usecase.py @@ -396,7 +396,7 @@ async def request( ) @override - async def request( # type: ignore[no-redef] + async def request( # type: ignore[override] self, message: Annotated[ "SendableMessage", diff --git a/faststream/kafka/testing.py b/faststream/kafka/testing.py index 90143ec388..881edc3269 100755 --- a/faststream/kafka/testing.py +++ b/faststream/kafka/testing.py @@ -21,10 +21,8 @@ from faststream.utils.functions import timeout_scope if TYPE_CHECKING: - from faststream.kafka.publisher.producer import AioKafkaFastProducer from faststream.kafka.publisher.publisher import SpecificationPublisher from faststream.kafka.subscriber.usecase import LogicSubscriber - from faststream.testing.broker import TestBroker from faststream.types import SendableMessage __all__ = ("TestKafkaBroker",) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs.py index 81562726f6..52cc73cf3d 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs.py @@ -48,4 +48,3 @@ def from_spec(cls, binding: spec.bindings.sqs.OperationBinding) -> Self: replyTo=binding.replyTo, bindingVersion=binding.bindingVersion, ) - diff --git a/tests/asyncapi/base/v2_6_0/fastapi.py b/tests/asyncapi/base/v2_6_0/fastapi.py index 0f351db34b..2b9415268c 100644 --- a/tests/asyncapi/base/v2_6_0/fastapi.py +++ b/tests/asyncapi/base/v2_6_0/fastapi.py @@ -68,7 +68,7 @@ async def test_fastapi_full_information(self): "components": {"messages": {}, "schemas": {}}, } - @pytest.mark.skip() + @pytest.mark.skip @pytest.mark.asyncio async def test_fastapi_asyncapi_routes(self): broker = self.broker_class(schema_url="/asyncapi_schema") diff --git a/tests/asyncapi/base/v3_0_0/fastapi.py b/tests/asyncapi/base/v3_0_0/fastapi.py index 6206e988e4..699a03c0ba 100644 --- a/tests/asyncapi/base/v3_0_0/fastapi.py +++ b/tests/asyncapi/base/v3_0_0/fastapi.py @@ -15,7 +15,7 @@ class FastAPITestCase: router_factory: Type[StreamRouter[MsgType]] broker_wrapper: Callable[[BrokerUsecase[MsgType, Any]], BrokerUsecase[MsgType, Any]] - @pytest.mark.asyncio() + @pytest.mark.asyncio async def test_fastapi_full_information(self): broker = self.router_factory( protocol="custom", @@ -77,7 +77,7 @@ async def test_fastapi_full_information(self): } } - @pytest.mark.asyncio() + @pytest.mark.asyncio async def test_fastapi_asyncapi_routes(self): broker = self.router_factory(schema_url="/asyncapi_schema") @@ -100,7 +100,7 @@ async def handler(): ... response_html = client.get("/asyncapi_schema") assert response_html.status_code == 200 - @pytest.mark.asyncio() + @pytest.mark.asyncio async def test_fastapi_asyncapi_not_fount(self): broker = self.router_factory(include_in_schema=False) @@ -118,7 +118,7 @@ async def test_fastapi_asyncapi_not_fount(self): response_html = client.get("/asyncapi") assert response_html.status_code == 404 - @pytest.mark.asyncio() + @pytest.mark.asyncio async def test_fastapi_asyncapi_not_fount_by_url(self): broker = self.router_factory(schema_url=None) From d8a21d904c7eaa7219ccfa5861ea5dc23aff786e Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 8 Sep 2024 15:29:51 +0300 Subject: [PATCH 139/245] rm debug statement --- tests/asyncapi/base/v3_0_0/arguments.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/asyncapi/base/v3_0_0/arguments.py b/tests/asyncapi/base/v3_0_0/arguments.py index d5b9e63756..88a4d277b4 100644 --- a/tests/asyncapi/base/v3_0_0/arguments.py +++ b/tests/asyncapi/base/v3_0_0/arguments.py @@ -483,9 +483,6 @@ async def handle(user: descriminator): ... key = next(iter(schema["components"]["messages"].keys())) assert key == IsStr(regex=r"test[\w:]*:Handle:Message") - with open("schema5.json", "w") as file: - json.dump(schema["components"], file, indent=4) - assert schema["components"] == { "messages": { key: { From c48b3e1709dc642ac77bf16b377debd00d4de1bf Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 8 Sep 2024 15:36:34 +0300 Subject: [PATCH 140/245] fixes --- faststream/kafka/publisher/usecase.py | 77 ------------------------- tests/asyncapi/base/v3_0_0/arguments.py | 1 - 2 files changed, 78 deletions(-) diff --git a/faststream/kafka/publisher/usecase.py b/faststream/kafka/publisher/usecase.py index 4fb95cd7ef..709aea898b 100644 --- a/faststream/kafka/publisher/usecase.py +++ b/faststream/kafka/publisher/usecase.py @@ -395,83 +395,6 @@ async def request( _extra_middlewares=_extra_middlewares, ) - @override - async def request( # type: ignore[override] - self, - message: Annotated[ - "SendableMessage", - Doc("Message body to send."), - ], - topic: Annotated[ - str, - Doc("Topic where the message will be published."), - ] = "", - *, - key: Annotated[ - Union[bytes, Any, None], - Doc( - """ - A key to associate with the message. Can be used to - determine which partition to send the message to. If partition - is `None` (and producer's partitioner config is left as default), - then messages with the same key will be delivered to the same - partition (but if key is `None`, partition is chosen randomly). - Must be type `bytes`, or be serializable to bytes via configured - `key_serializer`. - """ - ), - ] = None, - partition: Annotated[ - Optional[int], - Doc( - """ - Specify a partition. If not set, the partition will be - selected using the configured `partitioner`. - """ - ), - ] = None, - timestamp_ms: Annotated[ - Optional[int], - Doc( - """ - Epoch milliseconds (from Jan 1 1970 UTC) to use as - the message timestamp. Defaults to current time. - """ - ), - ] = None, - headers: Annotated[ - Optional[Dict[str, str]], - Doc("Message headers to store metainformation."), - ] = None, - correlation_id: Annotated[ - Optional[str], - Doc( - "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages." - ), - ] = None, - timeout: Annotated[ - float, - Doc("Timeout to send RPC request."), - ] = 0.5, - # publisher specific - _extra_middlewares: Annotated[ - Iterable["PublisherMiddleware"], - Doc("Extra middlewares to wrap publishing process."), - ] = (), - ) -> "KafkaMessage": - return await super().request( - message=message, - topic=topic, - key=key or self.key, - partition=partition, - timestamp_ms=timestamp_ms, - headers=headers, - correlation_id=correlation_id, - timeout=timeout, - _extra_middlewares=_extra_middlewares, - ) - class BatchPublisher(LogicPublisher[Tuple["ConsumerRecord", ...]]): @override diff --git a/tests/asyncapi/base/v3_0_0/arguments.py b/tests/asyncapi/base/v3_0_0/arguments.py index 88a4d277b4..02de75fb76 100644 --- a/tests/asyncapi/base/v3_0_0/arguments.py +++ b/tests/asyncapi/base/v3_0_0/arguments.py @@ -1,4 +1,3 @@ -import json from dataclasses import dataclass from enum import Enum from typing import Optional, Union From 9bb421ffc7a7e404805fd1382f3f808907fb5ac6 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 8 Sep 2024 15:54:54 +0300 Subject: [PATCH 141/245] remove unused code --- faststream/asyncapi/schema/info.py | 188 ----------------------------- 1 file changed, 188 deletions(-) delete mode 100644 faststream/asyncapi/schema/info.py diff --git a/faststream/asyncapi/schema/info.py b/faststream/asyncapi/schema/info.py deleted file mode 100644 index e22f4361a6..0000000000 --- a/faststream/asyncapi/schema/info.py +++ /dev/null @@ -1,188 +0,0 @@ -from typing import ( - Any, - Callable, - Iterable, - Optional, - Type, -) - -from pydantic import AnyHttpUrl, BaseModel -from typing_extensions import Required, TypedDict - -from faststream._compat import ( - PYDANTIC_V2, - CoreSchema, - GetJsonSchemaHandler, - JsonSchemaValue, - with_info_plain_validator_function, -) -from faststream.log import logger - -try: - import email_validator - - if email_validator is None: - raise ImportError - from pydantic import EmailStr - -except ImportError: # pragma: no cover - # NOTE: EmailStr mock was copied from the FastAPI - # https://github.com/tiangolo/fastapi/blob/master/fastapi/openapi/models.py#24 - class EmailStr(str): # type: ignore - """EmailStr is a string that should be an email. - - Note: EmailStr mock was copied from the FastAPI: - https://github.com/tiangolo/fastapi/blob/master/fastapi/openapi/models.py#24 - - """ - - @classmethod - def __get_validators__(cls) -> Iterable[Callable[..., Any]]: - """Returns the validators for the EmailStr class.""" - yield cls.validate - - @classmethod - def validate(cls, v: Any) -> str: - """Validates the EmailStr class.""" - logger.warning( - "email-validator bot installed, email fields will be treated as str.\n" - "To install, run: pip install email-validator" - ) - return str(v) - - @classmethod - def _validate(cls, __input_value: Any, _: Any) -> str: - logger.warning( - "email-validator bot installed, email fields will be treated as str.\n" - "To install, run: pip install email-validator" - ) - return str(__input_value) - - @classmethod - def __get_pydantic_json_schema__( - cls, - core_schema: CoreSchema, - handler: GetJsonSchemaHandler, - ) -> JsonSchemaValue: - """Returns the JSON schema for the EmailStr class. - - Args: - core_schema : the core schema - handler : the handler - """ - return {"type": "string", "format": "email"} - - @classmethod - def __get_pydantic_core_schema__( - cls, - source: Type[Any], - handler: Callable[[Any], CoreSchema], - ) -> JsonSchemaValue: - """Returns the core schema for the EmailStr class. - - Args: - source : the source - handler : the handler - """ - return with_info_plain_validator_function(cls._validate) - - -class ContactDict(TypedDict, total=False): - """A class to represent a dictionary of contact information. - - Attributes: - name : required name of the contact (type: str) - url : URL of the contact (type: AnyHttpUrl) - email : email address of the contact (type: EmailStr) - - """ - - name: Required[str] - url: AnyHttpUrl - email: EmailStr - - -class Contact(BaseModel): - """A class to represent a contact. - - Attributes: - name : name of the contact (str) - url : URL of the contact (Optional[AnyHttpUrl]) - email : email of the contact (Optional[EmailStr]) - - """ - - name: str - url: Optional[AnyHttpUrl] = None - email: Optional[EmailStr] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" - - -class LicenseDict(TypedDict, total=False): - """A dictionary-like class to represent a license. - - Attributes: - name : required name of the license (type: str) - url : URL of the license (type: AnyHttpUrl) - - """ - - name: Required[str] - url: AnyHttpUrl - - -class License(BaseModel): - """A class to represent a license. - - Attributes: - name : name of the license - url : URL of the license (optional) - - Config: - extra : allow additional attributes in the model (PYDANTIC_V2) - - """ - - name: str - url: Optional[AnyHttpUrl] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" - - -class BaseInfo(BaseModel): - """A class to represent information. - - Attributes: - title : title of the information - version : version of the information (default: "1.0.0") - description : description of the information (default: "") - termsOfService : terms of service for the information (default: None) - contact : contact information for the information (default: None) - license : license information for the information (default: None) - - """ - - title: str - version: str = "1.0.0" - description: str = "" - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" From ec2a9620c93c69b04f9310fcf28bab3dab47b334 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 8 Sep 2024 18:35:44 +0300 Subject: [PATCH 142/245] Fix AsyncAPI 3.0.0 specs error --- faststream/confluent/subscriber/subscriber.py | 2 +- faststream/kafka/subscriber/subscriber.py | 2 +- faststream/nats/subscriber/subscriber.py | 2 +- faststream/rabbit/subscriber/subscriber.py | 2 +- faststream/redis/subscriber/subscriber.py | 2 +- faststream/specification/asyncapi/site.py | 1 + 6 files changed, 6 insertions(+), 5 deletions(-) diff --git a/faststream/confluent/subscriber/subscriber.py b/faststream/confluent/subscriber/subscriber.py index b706a075bb..63d00f3980 100644 --- a/faststream/confluent/subscriber/subscriber.py +++ b/faststream/confluent/subscriber/subscriber.py @@ -37,7 +37,7 @@ def get_schema(self) -> Dict[str, Channel]: description=self.description, subscribe=Operation( message=Message( - title=f"{handler_name}:Message", + title=f"{handler_name}:SubscribeMessage", payload=resolve_payloads(payloads), correlationId=CorrelationId( location="$message.header#/correlation_id" diff --git a/faststream/kafka/subscriber/subscriber.py b/faststream/kafka/subscriber/subscriber.py index 8931fe14c9..1242baa06e 100644 --- a/faststream/kafka/subscriber/subscriber.py +++ b/faststream/kafka/subscriber/subscriber.py @@ -38,7 +38,7 @@ def get_schema(self) -> Dict[str, Channel]: description=self.description, subscribe=Operation( message=Message( - title=f"{handler_name}:Message", + title=f"{handler_name}:SubscribeMessage", payload=resolve_payloads(payloads), correlationId=CorrelationId( location="$message.header#/correlation_id" diff --git a/faststream/nats/subscriber/subscriber.py b/faststream/nats/subscriber/subscriber.py index c01705daeb..c75ef938e7 100644 --- a/faststream/nats/subscriber/subscriber.py +++ b/faststream/nats/subscriber/subscriber.py @@ -35,7 +35,7 @@ def get_schema(self) -> Dict[str, Channel]: description=self.description, subscribe=Operation( message=Message( - title=f"{self.name}:Message", + title=f"{self.name}:SubscribeMessage", payload=resolve_payloads(payloads), correlationId=CorrelationId( location="$message.header#/correlation_id" diff --git a/faststream/rabbit/subscriber/subscriber.py b/faststream/rabbit/subscriber/subscriber.py index 5ed253a8e2..c937fa0859 100644 --- a/faststream/rabbit/subscriber/subscriber.py +++ b/faststream/rabbit/subscriber/subscriber.py @@ -34,7 +34,7 @@ def get_schema(self) -> Dict[str, Channel]: if is_routing_exchange(self.exchange) else None, message=Message( - title=f"{self.name}:Message", + title=f"{self.name}:SubscribeMessage", payload=resolve_payloads(payloads), correlationId=CorrelationId( location="$message.header#/correlation_id" diff --git a/faststream/redis/subscriber/subscriber.py b/faststream/redis/subscriber/subscriber.py index 54a9b57578..88343d3c3b 100644 --- a/faststream/redis/subscriber/subscriber.py +++ b/faststream/redis/subscriber/subscriber.py @@ -28,7 +28,7 @@ def get_schema(self) -> Dict[str, Channel]: description=self.description, subscribe=Operation( message=Message( - title=f"{self.name}:Message", + title=f"{self.name}:SubscribeMessage", payload=resolve_payloads(payloads), correlationId=CorrelationId( location="$message.header#/correlation_id" diff --git a/faststream/specification/asyncapi/site.py b/faststream/specification/asyncapi/site.py index 278b059e3a..f02935565f 100644 --- a/faststream/specification/asyncapi/site.py +++ b/faststream/specification/asyncapi/site.py @@ -32,6 +32,7 @@ def get_asyncapi_html( asyncapi_css_url: str = ASYNCAPI_CSS_DEFAULT_URL, ) -> str: """Generate HTML for displaying an AsyncAPI document.""" + schema_json = schema.to_json() config = { From feaf2cca84be6a036a6872c7f23e19236251a813 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sun, 8 Sep 2024 20:35:25 +0300 Subject: [PATCH 143/245] Refactoring AsyncAPI specs generation --- faststream/confluent/subscriber/subscriber.py | 2 +- faststream/kafka/subscriber/subscriber.py | 2 +- faststream/nats/subscriber/subscriber.py | 2 +- faststream/rabbit/subscriber/subscriber.py | 2 +- faststream/redis/subscriber/subscriber.py | 2 +- faststream/specification/asyncapi/v3_0_0/generate.py | 2 ++ 6 files changed, 7 insertions(+), 5 deletions(-) diff --git a/faststream/confluent/subscriber/subscriber.py b/faststream/confluent/subscriber/subscriber.py index 63d00f3980..b706a075bb 100644 --- a/faststream/confluent/subscriber/subscriber.py +++ b/faststream/confluent/subscriber/subscriber.py @@ -37,7 +37,7 @@ def get_schema(self) -> Dict[str, Channel]: description=self.description, subscribe=Operation( message=Message( - title=f"{handler_name}:SubscribeMessage", + title=f"{handler_name}:Message", payload=resolve_payloads(payloads), correlationId=CorrelationId( location="$message.header#/correlation_id" diff --git a/faststream/kafka/subscriber/subscriber.py b/faststream/kafka/subscriber/subscriber.py index 1242baa06e..8931fe14c9 100644 --- a/faststream/kafka/subscriber/subscriber.py +++ b/faststream/kafka/subscriber/subscriber.py @@ -38,7 +38,7 @@ def get_schema(self) -> Dict[str, Channel]: description=self.description, subscribe=Operation( message=Message( - title=f"{handler_name}:SubscribeMessage", + title=f"{handler_name}:Message", payload=resolve_payloads(payloads), correlationId=CorrelationId( location="$message.header#/correlation_id" diff --git a/faststream/nats/subscriber/subscriber.py b/faststream/nats/subscriber/subscriber.py index c75ef938e7..c01705daeb 100644 --- a/faststream/nats/subscriber/subscriber.py +++ b/faststream/nats/subscriber/subscriber.py @@ -35,7 +35,7 @@ def get_schema(self) -> Dict[str, Channel]: description=self.description, subscribe=Operation( message=Message( - title=f"{self.name}:SubscribeMessage", + title=f"{self.name}:Message", payload=resolve_payloads(payloads), correlationId=CorrelationId( location="$message.header#/correlation_id" diff --git a/faststream/rabbit/subscriber/subscriber.py b/faststream/rabbit/subscriber/subscriber.py index c937fa0859..5ed253a8e2 100644 --- a/faststream/rabbit/subscriber/subscriber.py +++ b/faststream/rabbit/subscriber/subscriber.py @@ -34,7 +34,7 @@ def get_schema(self) -> Dict[str, Channel]: if is_routing_exchange(self.exchange) else None, message=Message( - title=f"{self.name}:SubscribeMessage", + title=f"{self.name}:Message", payload=resolve_payloads(payloads), correlationId=CorrelationId( location="$message.header#/correlation_id" diff --git a/faststream/redis/subscriber/subscriber.py b/faststream/redis/subscriber/subscriber.py index 88343d3c3b..54a9b57578 100644 --- a/faststream/redis/subscriber/subscriber.py +++ b/faststream/redis/subscriber/subscriber.py @@ -28,7 +28,7 @@ def get_schema(self) -> Dict[str, Channel]: description=self.description, subscribe=Operation( message=Message( - title=f"{self.name}:SubscribeMessage", + title=f"{self.name}:Message", payload=resolve_payloads(payloads), correlationId=CorrelationId( location="$message.header#/correlation_id" diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index a5ad948651..b924d8f48b 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -178,6 +178,8 @@ def get_broker_channels( channels_schema_v3_0 = {} for channel_name, specs_channel in h.schema().items(): if specs_channel.subscribe: + *left, right = specs_channel.subscribe.message.title.split(":") + specs_channel.subscribe.message.title = ":".join(left) + f":Subscribe{right}" channels_schema_v3_0[channel_name] = channel_from_spec( specs_channel, specs_channel.subscribe.message, From 3eaf13704178b195bc235fc37bd443ee8a5a06bd Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Mon, 9 Sep 2024 15:43:03 +0300 Subject: [PATCH 144/245] Fix AsyncAPI 3.0 tests --- tests/asyncapi/base/v3_0_0/arguments.py | 4 +-- tests/asyncapi/base/v3_0_0/naming.py | 26 +++++++++---------- .../asyncapi/confluent/v3_0_0/test_naming.py | 4 +-- .../asyncapi/confluent/v3_0_0/test_router.py | 4 +-- .../confluent/v3_0_0/test_security.py | 4 +-- tests/asyncapi/kafka/v3_0_0/test_naming.py | 4 +-- tests/asyncapi/kafka/v3_0_0/test_router.py | 4 +-- tests/asyncapi/kafka/v3_0_0/test_security.py | 4 +-- tests/asyncapi/nats/v3_0_0/test_naming.py | 4 +-- tests/asyncapi/nats/v3_0_0/test_router.py | 4 +-- tests/asyncapi/rabbit/v3_0_0/test_naming.py | 6 ++--- tests/asyncapi/rabbit/v3_0_0/test_router.py | 4 +-- tests/asyncapi/redis/v3_0_0/test_naming.py | 4 +-- tests/asyncapi/redis/v3_0_0/test_router.py | 4 +-- 14 files changed, 40 insertions(+), 40 deletions(-) diff --git a/tests/asyncapi/base/v3_0_0/arguments.py b/tests/asyncapi/base/v3_0_0/arguments.py index 02de75fb76..c1fd75c74d 100644 --- a/tests/asyncapi/base/v3_0_0/arguments.py +++ b/tests/asyncapi/base/v3_0_0/arguments.py @@ -480,7 +480,7 @@ async def handle(user: descriminator): ... schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() key = next(iter(schema["components"]["messages"].keys())) - assert key == IsStr(regex=r"test[\w:]*:Handle:Message") + assert key == IsStr(regex=r"test[\w:]*:Handle:SubscribeMessage") assert schema["components"] == { "messages": { @@ -539,7 +539,7 @@ async def handle(user: Model): ... schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() key = next(iter(schema["components"]["messages"].keys())) - assert key == IsStr(regex=r"test[\w:]*:Handle:Message") + assert key == IsStr(regex=r"test[\w:]*:Handle:SubscribeMessage") assert schema["components"] == { "messages": { key: { diff --git a/tests/asyncapi/base/v3_0_0/naming.py b/tests/asyncapi/base/v3_0_0/naming.py index 69982e0d53..c4d3a8e6e1 100644 --- a/tests/asyncapi/base/v3_0_0/naming.py +++ b/tests/asyncapi/base/v3_0_0/naming.py @@ -26,7 +26,7 @@ async def handle_user_created(msg: str): ... ] assert list(schema["components"]["messages"].keys()) == [ - IsStr(regex=r"test[\w:]*:HandleUserCreated:Message") + IsStr(regex=r"test[\w:]*:HandleUserCreated:SubscribeMessage") ] assert list(schema["components"]["schemas"].keys()) == [ @@ -46,7 +46,7 @@ async def handle_user_created(msg: create_model("SimpleModel")): ... ] assert list(schema["components"]["messages"].keys()) == [ - IsStr(regex=r"test[\w:]*:HandleUserCreated:Message") + IsStr(regex=r"test[\w:]*:HandleUserCreated:SubscribeMessage") ] assert list(schema["components"]["schemas"].keys()) == ["SimpleModel"] @@ -66,8 +66,8 @@ async def handle_user_created(msg: str): ... ] assert list(schema["components"]["messages"].keys()) == [ - IsStr(regex=r"test[\w:]*:HandleUserCreated:Message"), - IsStr(regex=r"test2[\w:]*:HandleUserCreated:Message"), + IsStr(regex=r"test[\w:]*:HandleUserCreated:SubscribeMessage"), + IsStr(regex=r"test2[\w:]*:HandleUserCreated:SubscribeMessage"), ] assert list(schema["components"]["schemas"].keys()) == [ @@ -84,7 +84,7 @@ async def handle_user_created(msg: str): ... assert list(schema["channels"].keys()) == ["custom"] - assert list(schema["components"]["messages"].keys()) == ["custom:Message"] + assert list(schema["components"]["messages"].keys()) == ["custom:SubscribeMessage"] assert list(schema["components"]["schemas"].keys()) == [ "custom:Message:Payload" @@ -102,7 +102,7 @@ def test_subscriber_naming_default(self): ] assert list(schema["components"]["messages"].keys()) == [ - IsStr(regex=r"test[\w:]*:Subscriber:Message") + IsStr(regex=r"test[\w:]*:Subscriber:SubscribeMessage") ] for key, v in schema["components"]["schemas"].items(): @@ -118,7 +118,7 @@ def test_subscriber_naming_default_with_title(self): assert list(schema["channels"].keys()) == ["custom"] - assert list(schema["components"]["messages"].keys()) == ["custom:Message"] + assert list(schema["components"]["messages"].keys()) == ["custom:SubscribeMessage"] assert list(schema["components"]["schemas"].keys()) == [ "custom:Message:Payload" @@ -146,9 +146,9 @@ async def handle_user_created(msg: str): ... ] assert list(schema["components"]["messages"].keys()) == [ - IsStr(regex=r"test[\w:]*:HandleUserCreated:Message"), - IsStr(regex=r"test2[\w:]*:Subscriber:Message"), - IsStr(regex=r"test3[\w:]*:Subscriber:Message"), + IsStr(regex=r"test[\w:]*:HandleUserCreated:SubscribeMessage"), + IsStr(regex=r"test2[\w:]*:Subscriber:SubscribeMessage"), + IsStr(regex=r"test3[\w:]*:Subscriber:SubscribeMessage"), ] assert list(schema["components"]["schemas"].keys()) == [ @@ -178,7 +178,7 @@ async def handle_user_id(msg: int): ... ] assert list(schema["components"]["messages"].keys()) == [ - IsStr(regex=r"test[\w:]*:HandleUserCreated:Message") + IsStr(regex=r"test[\w:]*:HandleUserCreated:SubscribeMessage") ] assert list(schema["components"]["schemas"].keys()) == [ @@ -202,7 +202,7 @@ async def handle_user_id(msg: int): ... ] assert list(schema["components"]["messages"].keys()) == [ - IsStr(regex=r"test[\w:]*:HandleUserCreated:Message") + IsStr(regex=r"test[\w:]*:HandleUserCreated:SubscribeMessage") ] assert list(schema["components"]["schemas"].keys()) == [ @@ -223,7 +223,7 @@ async def handle_user_id(msg: int): ... assert list(schema["channels"].keys()) == ["custom"] - assert list(schema["components"]["messages"].keys()) == ["custom:Message"] + assert list(schema["components"]["messages"].keys()) == ["custom:SubscribeMessage"] assert list(schema["components"]["schemas"].keys()) == [ "HandleUserCreated:Message:Payload", diff --git a/tests/asyncapi/confluent/v3_0_0/test_naming.py b/tests/asyncapi/confluent/v3_0_0/test_naming.py index 525487824a..e599cc5f8e 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_naming.py +++ b/tests/asyncapi/confluent/v3_0_0/test_naming.py @@ -58,8 +58,8 @@ async def handle(): ... }, "components": { "messages": { - "test:Handle:Message": { - "title": "test:Handle:Message", + "test:Handle:SubscribeMessage": { + "title": "test:Handle:SubscribeMessage", "correlationId": { "location": "$message.header#/correlation_id" }, diff --git a/tests/asyncapi/confluent/v3_0_0/test_router.py b/tests/asyncapi/confluent/v3_0_0/test_router.py index 7d4a18a5a2..f27af9f76c 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_router.py +++ b/tests/asyncapi/confluent/v3_0_0/test_router.py @@ -76,8 +76,8 @@ async def handle(msg): ... }, "components": { "messages": { - "test_test:Handle:Message": { - "title": "test_test:Handle:Message", + "test_test:Handle:SubscribeMessage": { + "title": "test_test:Handle:SubscribeMessage", "correlationId": { "location": "$message.header#/correlation_id" }, diff --git a/tests/asyncapi/confluent/v3_0_0/test_security.py b/tests/asyncapi/confluent/v3_0_0/test_security.py index 7c1d841180..c33b474264 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_security.py +++ b/tests/asyncapi/confluent/v3_0_0/test_security.py @@ -94,8 +94,8 @@ }, "components": { "messages": { - "test_1:TestTopic:Message": { - "title": "test_1:TestTopic:Message", + "test_1:TestTopic:SubscribeMessage": { + "title": "test_1:TestTopic:SubscribeMessage", "correlationId": { "location": "$message.header#/correlation_id" }, diff --git a/tests/asyncapi/kafka/v3_0_0/test_naming.py b/tests/asyncapi/kafka/v3_0_0/test_naming.py index f3c050429e..d843d5a192 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_naming.py +++ b/tests/asyncapi/kafka/v3_0_0/test_naming.py @@ -58,8 +58,8 @@ async def handle(): ... }, "components": { "messages": { - "test:Handle:Message": { - "title": "test:Handle:Message", + "test:Handle:SubscribeMessage": { + "title": "test:Handle:SubscribeMessage", "correlationId": { "location": "$message.header#/correlation_id" }, diff --git a/tests/asyncapi/kafka/v3_0_0/test_router.py b/tests/asyncapi/kafka/v3_0_0/test_router.py index 7a9b4ace06..ec7cfafc68 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_router.py +++ b/tests/asyncapi/kafka/v3_0_0/test_router.py @@ -76,8 +76,8 @@ async def handle(msg): ... }, "components": { "messages": { - "test_test:Handle:Message": { - "title": "test_test:Handle:Message", + "test_test:Handle:SubscribeMessage": { + "title": "test_test:Handle:SubscribeMessage", "correlationId": { "location": "$message.header#/correlation_id" }, diff --git a/tests/asyncapi/kafka/v3_0_0/test_security.py b/tests/asyncapi/kafka/v3_0_0/test_security.py index 0b66cb88e4..0a5890b3da 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_security.py +++ b/tests/asyncapi/kafka/v3_0_0/test_security.py @@ -94,8 +94,8 @@ }, "components": { "messages": { - "test_1:TestTopic:Message": { - "title": "test_1:TestTopic:Message", + "test_1:TestTopic:SubscribeMessage": { + "title": "test_1:TestTopic:SubscribeMessage", "correlationId": { "location": "$message.header#/correlation_id" }, diff --git a/tests/asyncapi/nats/v3_0_0/test_naming.py b/tests/asyncapi/nats/v3_0_0/test_naming.py index ef47d5e763..3c6241432c 100644 --- a/tests/asyncapi/nats/v3_0_0/test_naming.py +++ b/tests/asyncapi/nats/v3_0_0/test_naming.py @@ -60,8 +60,8 @@ async def handle(): ... }, "components": { "messages": { - "test:Handle:Message": { - "title": "test:Handle:Message", + "test:Handle:SubscribeMessage": { + "title": "test:Handle:SubscribeMessage", "correlationId": { "location": "$message.header#/correlation_id" }, diff --git a/tests/asyncapi/nats/v3_0_0/test_router.py b/tests/asyncapi/nats/v3_0_0/test_router.py index 2197684c8e..c6a791c512 100644 --- a/tests/asyncapi/nats/v3_0_0/test_router.py +++ b/tests/asyncapi/nats/v3_0_0/test_router.py @@ -76,8 +76,8 @@ async def handle(msg): ... }, "components": { "messages": { - "test_test:Handle:Message": { - "title": "test_test:Handle:Message", + "test_test:Handle:SubscribeMessage": { + "title": "test_test:Handle:SubscribeMessage", "correlationId": { "location": "$message.header#/correlation_id" }, diff --git a/tests/asyncapi/rabbit/v3_0_0/test_naming.py b/tests/asyncapi/rabbit/v3_0_0/test_naming.py index f741041df2..c70c6c716b 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_naming.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_naming.py @@ -20,7 +20,7 @@ async def handle(): ... assert list(schema["channels"].keys()) == ["test:exchange:Handle"] assert list(schema["components"]["messages"].keys()) == [ - "test:exchange:Handle:Message" + "test:exchange:Handle:SubscribeMessage" ] def test_publisher_with_exchange(self): @@ -110,8 +110,8 @@ async def handle(): ... }, "components": { "messages": { - "test:_:Handle:Message": { - "title": "test:_:Handle:Message", + "test:_:Handle:SubscribeMessage": { + "title": "test:_:Handle:SubscribeMessage", "correlationId": { "location": "$message.header#/correlation_id" }, diff --git a/tests/asyncapi/rabbit/v3_0_0/test_router.py b/tests/asyncapi/rabbit/v3_0_0/test_router.py index 967a61f4dd..49708d0a12 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_router.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_router.py @@ -102,8 +102,8 @@ async def handle(msg): ... }, "components": { "messages": { - "test_test:_:Handle:Message": { - "title": "test_test:_:Handle:Message", + "test_test:_:Handle:SubscribeMessage": { + "title": "test_test:_:Handle:SubscribeMessage", "correlationId": { "location": "$message.header#/correlation_id" }, diff --git a/tests/asyncapi/redis/v3_0_0/test_naming.py b/tests/asyncapi/redis/v3_0_0/test_naming.py index 0d8c102940..595a787139 100644 --- a/tests/asyncapi/redis/v3_0_0/test_naming.py +++ b/tests/asyncapi/redis/v3_0_0/test_naming.py @@ -54,12 +54,12 @@ async def handle(): ... }, "components": { "messages": { - "test:Handle:Message": { + "test:Handle:SubscribeMessage": { "correlationId": { "location": "$message.header#/correlation_id" }, "payload": {"$ref": "#/components/schemas/EmptyPayload"}, - "title": "test:Handle:Message", + "title": "test:Handle:SubscribeMessage", } }, "schemas": {"EmptyPayload": {"title": "EmptyPayload", "type": "null"}}, diff --git a/tests/asyncapi/redis/v3_0_0/test_router.py b/tests/asyncapi/redis/v3_0_0/test_router.py index e33937a700..08b5ed8a54 100644 --- a/tests/asyncapi/redis/v3_0_0/test_router.py +++ b/tests/asyncapi/redis/v3_0_0/test_router.py @@ -77,8 +77,8 @@ async def handle(msg): ... }, "components": { "messages": { - "test_test:Handle:Message": { - "title": "test_test:Handle:Message", + "test_test:Handle:SubscribeMessage": { + "title": "test_test:Handle:SubscribeMessage", "correlationId": { "location": "$message.header#/correlation_id" }, From ffa76cb192b5645308b8fe3be77bb7ebc0596383 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Mon, 9 Sep 2024 15:52:37 +0300 Subject: [PATCH 145/245] Add oauth and gssapi AsyncAPI 3.0.0 tests for Kafka and Confluent --- .../confluent/v3_0_0/test_security.py | 53 +++++++++++++++++- tests/asyncapi/kafka/v3_0_0/test_security.py | 54 ++++++++++++++++++- 2 files changed, 105 insertions(+), 2 deletions(-) diff --git a/tests/asyncapi/confluent/v3_0_0/test_security.py b/tests/asyncapi/confluent/v3_0_0/test_security.py index c33b474264..2b4267a377 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_security.py +++ b/tests/asyncapi/confluent/v3_0_0/test_security.py @@ -7,7 +7,7 @@ BaseSecurity, SASLPlaintext, SASLScram256, - SASLScram512, + SASLScram512, SASLGSSAPI, SASLOAuthBearer, ) from faststream.specification.asyncapi.generate import get_app_schema @@ -226,3 +226,54 @@ async def test_topic(msg: str) -> str: } assert schema == sasl512_security_schema + + +def test_oauthbearer_security_schema(): + ssl_context = ssl.create_default_context() + security = SASLOAuthBearer( + ssl_context=ssl_context, + ) + + broker = KafkaBroker("localhost:9092", security=security) + app = FastStream(broker) + + @broker.publisher("test_2") + @broker.subscriber("test_1") + async def test_topic(msg: str) -> str: + pass + + schema = get_app_schema(app, version="3.0.0").to_jsonable() + + sasl_oauthbearer_security_schema = deepcopy(basic_schema) + sasl_oauthbearer_security_schema["servers"]["development"]["security"] = [ + {"oauthbearer": []} + ] + sasl_oauthbearer_security_schema["components"]["securitySchemes"] = { + "oauthbearer": {"type": "oauthBearer"} + } + + assert schema == sasl_oauthbearer_security_schema + + +def test_gssapi_security_schema(): + ssl_context = ssl.create_default_context() + security = SASLGSSAPI(ssl_context=ssl_context) + + broker = KafkaBroker("localhost:9092", security=security) + app = FastStream(broker) + + @broker.publisher("test_2") + @broker.subscriber("test_1") + async def test_topic(msg: str) -> str: + pass + + schema = get_app_schema(app, version="3.0.0").to_jsonable() + + gssapi_security_schema = deepcopy(basic_schema) + gssapi_security_schema["servers"]["development"]["security"] = [{"gssapi": []}] + gssapi_security_schema["components"]["securitySchemes"] = { + "gssapi": {"type": "gssapi"} + } + + assert schema == gssapi_security_schema + diff --git a/tests/asyncapi/kafka/v3_0_0/test_security.py b/tests/asyncapi/kafka/v3_0_0/test_security.py index 0a5890b3da..25466041f6 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_security.py +++ b/tests/asyncapi/kafka/v3_0_0/test_security.py @@ -7,7 +7,7 @@ BaseSecurity, SASLPlaintext, SASLScram256, - SASLScram512, + SASLScram512, SASLGSSAPI, SASLOAuthBearer, ) from faststream.specification.asyncapi.generate import get_app_schema @@ -226,3 +226,55 @@ async def test_topic(msg: str) -> str: } assert schema == sasl512_security_schema + + +def test_oauthbearer_security_schema(): + ssl_context = ssl.create_default_context() + security = SASLOAuthBearer( + ssl_context=ssl_context, + ) + + broker = KafkaBroker("localhost:9092", security=security) + app = FastStream(broker) + + @broker.publisher("test_2") + @broker.subscriber("test_1") + async def test_topic(msg: str) -> str: + pass + + schema = get_app_schema(app, version="3.0.0").to_jsonable() + + sasl_oauthbearer_security_schema = deepcopy(basic_schema) + sasl_oauthbearer_security_schema["servers"]["development"]["security"] = [ + {"oauthbearer": []} + ] + sasl_oauthbearer_security_schema["components"]["securitySchemes"] = { + "oauthbearer": {"type": "oauthBearer"} + } + + assert schema == sasl_oauthbearer_security_schema + + +def test_gssapi_security_schema(): + ssl_context = ssl.create_default_context() + security = SASLGSSAPI( + ssl_context=ssl_context, + ) + + broker = KafkaBroker("localhost:9092", security=security) + app = FastStream(broker) + + @broker.publisher("test_2") + @broker.subscriber("test_1") + async def test_topic(msg: str) -> str: + pass + + schema = get_app_schema(app, version="3.0.0").to_jsonable() + + gssapi_security_schema = deepcopy(basic_schema) + gssapi_security_schema["servers"]["development"]["security"] = [{"gssapi": []}] + gssapi_security_schema["components"]["securitySchemes"] = { + "gssapi": {"type": "gssapi"} + } + + assert schema == gssapi_security_schema From 4cb07074a997f059197db3fd6c9b7bbcea694e4c Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Mon, 9 Sep 2024 21:12:38 +0300 Subject: [PATCH 146/245] refactoring --- faststream/specification/asyncapi/v3_0_0/generate.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index b924d8f48b..5a1cc8b566 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -177,9 +177,9 @@ def get_broker_channels( for h in broker._subscribers.values(): channels_schema_v3_0 = {} for channel_name, specs_channel in h.schema().items(): + *left, right = specs_channel.subscribe.message.title.split(":") + specs_channel.subscribe.message.title = ":".join(left) + f":Subscribe{right}" if specs_channel.subscribe: - *left, right = specs_channel.subscribe.message.title.split(":") - specs_channel.subscribe.message.title = ":".join(left) + f":Subscribe{right}" channels_schema_v3_0[channel_name] = channel_from_spec( specs_channel, specs_channel.subscribe.message, From 2e1212ed064183420c67a87749f2d9b718daa467 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Mon, 9 Sep 2024 21:18:29 +0300 Subject: [PATCH 147/245] refactoring --- faststream/specification/asyncapi/v3_0_0/generate.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index 5a1cc8b566..e8968a92c8 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -177,12 +177,16 @@ def get_broker_channels( for h in broker._subscribers.values(): channels_schema_v3_0 = {} for channel_name, specs_channel in h.schema().items(): - *left, right = specs_channel.subscribe.message.title.split(":") - specs_channel.subscribe.message.title = ":".join(left) + f":Subscribe{right}" if specs_channel.subscribe: + message = specs_channel.subscribe.message + assert message.title + + *left, right = message.title.split(":") + message.title = ":".join(left) + f":Subscribe{right}" + channels_schema_v3_0[channel_name] = channel_from_spec( specs_channel, - specs_channel.subscribe.message, + message, channel_name, "SubscribeMessage", ) From ceb80c693028dcff7a1bd33b3875f5a64cf3b66f Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Mon, 9 Sep 2024 21:20:54 +0300 Subject: [PATCH 148/245] refactoring --- faststream/specification/asyncapi/v3_0_0/generate.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index e8968a92c8..083dd5917c 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -174,9 +174,9 @@ def get_broker_channels( """Get the broker channels for an application.""" channels = {} - for h in broker._subscribers.values(): + for sub in broker._subscribers.values(): channels_schema_v3_0 = {} - for channel_name, specs_channel in h.schema().items(): + for channel_name, specs_channel in sub.schema().items(): if specs_channel.subscribe: message = specs_channel.subscribe.message assert message.title @@ -193,9 +193,9 @@ def get_broker_channels( channels.update(channels_schema_v3_0) - for p in broker._publishers.values(): + for pub in broker._publishers.values(): channels_schema_v3_0 = {} - for channel_name, specs_channel in p.schema().items(): + for channel_name, specs_channel in pub.schema().items(): if specs_channel.publish: channels_schema_v3_0[channel_name] = channel_from_spec( specs_channel, From aae844bd9d4609eef50ec183ec9c1583a9e5f83e Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Mon, 9 Sep 2024 21:22:23 +0300 Subject: [PATCH 149/245] fix --- faststream/specification/asyncapi/site.py | 1 - 1 file changed, 1 deletion(-) diff --git a/faststream/specification/asyncapi/site.py b/faststream/specification/asyncapi/site.py index f02935565f..278b059e3a 100644 --- a/faststream/specification/asyncapi/site.py +++ b/faststream/specification/asyncapi/site.py @@ -32,7 +32,6 @@ def get_asyncapi_html( asyncapi_css_url: str = ASYNCAPI_CSS_DEFAULT_URL, ) -> str: """Generate HTML for displaying an AsyncAPI document.""" - schema_json = schema.to_json() config = { From 171064b4965e74c6eac9abb27739ecc4be183678 Mon Sep 17 00:00:00 2001 From: Lancetnik Date: Tue, 10 Sep 2024 20:07:27 +0000 Subject: [PATCH 150/245] docs: generate API References --- docs/docs/en/release.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/docs/docs/en/release.md b/docs/docs/en/release.md index 267c80b262..e50c67b207 100644 --- a/docs/docs/en/release.md +++ b/docs/docs/en/release.md @@ -12,6 +12,40 @@ hide: --- # Release Notes +## 0.5.23 + +### What's Changed + +We made last release just a few days ago, but there are some big changes here already! + +1. First of all - you can't use `faststream run ...` command without `pip install faststream[cli]` distribution anymore. It was made to minify default (and production) distribution by removing **typer** (**rich** and **click**) dependencies. **CLI** is a development-time feature, so if you don't need - just don't install! Special thanks to @RubenRibGarcia for this change + +2. The next big change - **Kafka** publish confirmations by default! Previous **FastStream** version was working in *publish & forgot* style, but the new one blocks your `broker.publish(...)` call until **Kafka** confirmation frame received. To fallback to previous logic just use a new flag `broker.publish(..., no_confirm=True)` + +3. Also, we made one more step forward to our **1.0.0** features plan! @KrySeyt implements `get_one` feature. Now you can use any broker subscriber to get messages in imperative style: + +```python +subscriber = broker.subscriber("in") +... +msg = await subscriber.get_one(timeout=5.0) +``` + +4. And the last one: @draincoder continues to develop OTEL support! Now he provides us with an ability to use **OTEL spans** and **baggage** in a comfortable **FastStream**-style. Just take a look at the [new documentation section](https://faststream.airt.ai/latest/getting-started/opentelemetry/#baggage) + +Big thanks to all new and old contributors who makes such a great release! + +* feat: AsgiFastStream hooks init options by @Lancetnik in https://github.com/airtai/faststream/pull/1768 +* fix (#1748): add Kafka publish no_confirm option by @Lancetnik in https://github.com/airtai/faststream/pull/1749 +* Fix GeneralExceptionHandler typehint by @sheldygg in https://github.com/airtai/faststream/pull/1773 +* Add `broker.subscriber().get_one()` by @KrySeyt in https://github.com/airtai/faststream/pull/1726 +* Add OTel baggage support by @draincoder in https://github.com/airtai/faststream/pull/1692 +* build(#1430): separate cli faststream to its own distribution by @RubenRibGarcia in https://github.com/airtai/faststream/pull/1769 + +### New Contributors +* @RubenRibGarcia made their first contribution in https://github.com/airtai/faststream/pull/1769 + +**Full Changelog**: https://github.com/airtai/faststream/compare/0.5.22...0.5.23 + ## 0.5.22 ### What's Changed From dc8deeffe1bd0dcfb4daaaf6065f6e06ddd0d6ee Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Fri, 13 Sep 2024 18:29:10 +0300 Subject: [PATCH 151/245] refactor: change project structura --- .../confluent/publisher_object/example.py | 2 +- .../kafka/publisher_object/example.py | 2 +- faststream/__init__.py | 22 ++- faststream/__main__.py | 2 +- .../{broker/core => _internal}/__init__.py | 0 faststream/{ => _internal}/_compat.py | 2 +- .../{types.py => _internal/basic_types.py} | 16 +- faststream/{ => _internal}/broker/__init__.py | 0 .../abc.py => _internal/broker/abc_broker.py} | 14 +- .../usecase.py => _internal/broker/broker.py} | 28 ++-- .../broker/logging_mixin.py} | 9 +- faststream/{ => _internal}/broker/router.py | 14 +- .../publisher => _internal/cli}/__init__.py | 0 .../{ => _internal}/cli/docs/__init__.py | 0 faststream/{ => _internal}/cli/docs/app.py | 6 +- faststream/{ => _internal}/cli/main.py | 16 +- .../cli/supervisors}/__init__.py | 0 .../cli/supervisors/basereload.py | 6 +- .../cli/supervisors/multiprocess.py | 6 +- .../{ => _internal}/cli/supervisors/utils.py | 2 +- .../cli/supervisors/watchfiles.py | 6 +- .../cli/utils}/__init__.py | 0 .../{ => _internal}/cli/utils/imports.py | 0 faststream/{ => _internal}/cli/utils/logs.py | 2 +- .../{ => _internal}/cli/utils/parser.py | 2 +- faststream/_internal/constants.py | 25 +++ faststream/_internal/context/__init__.py | 8 + .../context/context_type.py} | 27 +--- .../context/repository.py | 9 +- faststream/_internal/context/resolve.py | 26 +++ faststream/_internal/fastapi/__init__.py | 7 + .../{broker => _internal}/fastapi/_compat.py | 2 +- .../{broker => _internal}/fastapi/context.py | 6 +- .../fastapi/get_dependant.py | 4 +- .../{broker => _internal}/fastapi/route.py | 10 +- .../{broker => _internal}/fastapi/router.py | 30 ++-- faststream/_internal/log/__init__.py | 3 + faststream/{ => _internal}/log/formatter.py | 0 faststream/{ => _internal}/log/logging.py | 4 +- .../{broker/schemas.py => _internal/proto.py} | 14 +- .../{cli => _internal/publisher}/__init__.py | 0 .../{broker => _internal}/publisher/fake.py | 6 +- .../{broker => _internal}/publisher/proto.py | 10 +- .../publisher/usecase.py | 12 +- .../subscriber}/__init__.py | 0 .../subscriber}/acknowledgement_watcher.py | 6 +- .../subscriber/call_item.py | 12 +- .../subscriber/call_wrapper}/__init__.py | 0 .../subscriber/call_wrapper}/call.py | 10 +- .../subscriber/call_wrapper}/proto.py | 4 +- .../{broker => _internal}/subscriber/proto.py | 23 +-- .../subscriber/usecase.py | 51 +++--- .../{broker => _internal/subscriber}/utils.py | 15 +- faststream/_internal/testing/__init__.py | 3 + faststream/{ => _internal}/testing/app.py | 4 +- .../{utils => _internal/testing}/ast.py | 20 +-- faststream/{ => _internal}/testing/broker.py | 10 +- faststream/{broker => _internal}/types.py | 6 +- faststream/_internal/utils/__init__.py | 3 + faststream/_internal/utils/data.py | 12 ++ faststream/{ => _internal}/utils/functions.py | 2 +- faststream/{ => _internal}/utils/nuid.py | 0 faststream/{ => _internal}/utils/path.py | 0 faststream/annotations.py | 10 +- faststream/app.py | 38 +++-- faststream/asgi/app.py | 16 +- faststream/asgi/factories.py | 2 +- faststream/broker/fastapi/__init__.py | 7 - faststream/broker/message.py | 152 ------------------ faststream/broker/middlewares/__init__.py | 4 - faststream/broker/proto.py | 12 -- faststream/confluent/__init__.py | 2 +- faststream/confluent/annotations.py | 5 +- faststream/confluent/broker/broker.py | 22 +-- faststream/confluent/broker/logging.py | 8 +- faststream/confluent/broker/registrator.py | 54 +------ faststream/confluent/client.py | 8 +- faststream/confluent/config.py | 2 +- faststream/confluent/fastapi/__init__.py | 2 +- faststream/confluent/fastapi/fastapi.py | 55 +------ faststream/confluent/message.py | 2 +- .../confluent/opentelemetry/provider.py | 6 +- faststream/confluent/parser.py | 12 +- faststream/confluent/publisher/producer.py | 10 +- faststream/confluent/publisher/publisher.py | 4 +- faststream/confluent/publisher/usecase.py | 12 +- faststream/confluent/response.py | 4 +- faststream/confluent/router.py | 26 +-- faststream/confluent/security.py | 2 +- faststream/confluent/subscriber/factory.py | 4 +- faststream/confluent/subscriber/subscriber.py | 2 +- faststream/confluent/subscriber/usecase.py | 16 +- faststream/confluent/testing.py | 10 +- faststream/constants.py | 10 -- faststream/exceptions.py | 17 ++ faststream/kafka/__init__.py | 2 +- faststream/kafka/annotations.py | 5 +- faststream/kafka/broker/broker.py | 20 +-- faststream/kafka/broker/logging.py | 8 +- faststream/kafka/broker/registrator.py | 54 +------ faststream/kafka/fastapi/__init__.py | 2 +- faststream/kafka/fastapi/fastapi.py | 55 +------ faststream/kafka/message.py | 2 +- faststream/kafka/opentelemetry/provider.py | 6 +- faststream/kafka/parser.py | 12 +- faststream/kafka/publisher/producer.py | 10 +- faststream/kafka/publisher/publisher.py | 4 +- faststream/kafka/publisher/usecase.py | 12 +- faststream/kafka/response.py | 4 +- faststream/kafka/router.py | 26 +-- faststream/kafka/security.py | 2 +- faststream/kafka/subscriber/factory.py | 4 +- faststream/kafka/subscriber/subscriber.py | 2 +- faststream/kafka/subscriber/usecase.py | 16 +- faststream/kafka/testing.py | 10 +- faststream/log/__init__.py | 3 - faststream/message/__init__.py | 10 ++ faststream/message/message.py | 73 +++++++++ faststream/message/utils.py | 78 +++++++++ faststream/middlewares/__init__.py | 4 + faststream/{broker => }/middlewares/base.py | 4 +- .../{broker => }/middlewares/exception.py | 11 +- .../{broker => }/middlewares/logging.py | 9 +- faststream/nats/__init__.py | 2 +- faststream/nats/annotations.py | 5 +- faststream/nats/broker/broker.py | 22 +-- faststream/nats/broker/logging.py | 8 +- faststream/nats/broker/registrator.py | 25 +-- faststream/nats/fastapi/__init__.py | 2 +- faststream/nats/fastapi/fastapi.py | 27 +--- faststream/nats/message.py | 2 +- faststream/nats/opentelemetry/provider.py | 6 +- faststream/nats/parser.py | 17 +- faststream/nats/publisher/producer.py | 12 +- faststream/nats/publisher/publisher.py | 2 +- faststream/nats/publisher/usecase.py | 10 +- faststream/nats/response.py | 4 +- faststream/nats/router.py | 31 ++-- faststream/nats/schemas/js_stream.py | 4 +- faststream/nats/schemas/kv_watch.py | 2 +- faststream/nats/security.py | 2 +- faststream/nats/subscriber/factory.py | 4 +- faststream/nats/subscriber/usecase.py | 23 +-- faststream/nats/testing.py | 10 +- faststream/opentelemetry/baggage.py | 8 +- faststream/opentelemetry/middleware.py | 4 +- faststream/opentelemetry/provider.py | 6 +- faststream/params/__init__.py | 12 ++ faststream/{utils => params}/no_cast.py | 12 +- .../context/builders.py => params/params.py} | 4 +- faststream/rabbit/__init__.py | 4 +- faststream/rabbit/annotations.py | 5 +- faststream/rabbit/broker/broker.py | 8 +- faststream/rabbit/broker/logging.py | 8 +- faststream/rabbit/broker/registrator.py | 33 +--- faststream/rabbit/fastapi/__init__.py | 2 +- faststream/rabbit/fastapi/router.py | 33 +--- faststream/rabbit/message.py | 2 +- faststream/rabbit/opentelemetry/provider.py | 4 +- faststream/rabbit/parser.py | 4 +- faststream/rabbit/publisher/producer.py | 10 +- faststream/rabbit/publisher/publisher.py | 2 +- faststream/rabbit/publisher/usecase.py | 10 +- faststream/rabbit/response.py | 4 +- faststream/rabbit/router.py | 37 +---- faststream/rabbit/schemas/__init__.py | 2 - faststream/rabbit/schemas/exchange.py | 4 +- faststream/rabbit/schemas/queue.py | 6 +- faststream/rabbit/schemas/reply.py | 46 ------ faststream/rabbit/security.py | 2 +- faststream/rabbit/subscriber/factory.py | 20 +-- faststream/rabbit/subscriber/usecase.py | 17 +- faststream/rabbit/testing.py | 8 +- faststream/rabbit/types.py | 2 +- faststream/redis/__init__.py | 2 +- faststream/redis/annotations.py | 5 +- faststream/redis/broker/broker.py | 20 +-- faststream/redis/broker/logging.py | 8 +- faststream/redis/broker/registrator.py | 22 +-- faststream/redis/fastapi/__init__.py | 2 +- faststream/redis/fastapi/fastapi.py | 22 +-- faststream/redis/message.py | 4 +- faststream/redis/opentelemetry/provider.py | 4 +- faststream/redis/parser.py | 10 +- faststream/redis/publisher/producer.py | 12 +- faststream/redis/publisher/publisher.py | 4 +- faststream/redis/publisher/usecase.py | 10 +- faststream/redis/response.py | 4 +- faststream/redis/router.py | 26 +-- faststream/redis/schemas/list_sub.py | 2 +- faststream/redis/schemas/pub_sub.py | 4 +- faststream/redis/schemas/stream_sub.py | 2 +- faststream/redis/security.py | 2 +- faststream/redis/subscriber/factory.py | 2 +- faststream/redis/subscriber/usecase.py | 14 +- faststream/redis/testing.py | 10 +- faststream/response/__init__.py | 7 + faststream/{broker => response}/response.py | 13 +- faststream/response/utils.py | 10 ++ faststream/security.py | 2 +- .../asyncapi/base/schema/info.py | 2 +- .../asyncapi/base/schema/schema.py | 2 +- faststream/specification/asyncapi/message.py | 9 +- faststream/specification/asyncapi/site.py | 4 +- faststream/specification/asyncapi/utils.py | 2 +- .../specification/asyncapi/v2_6_0/generate.py | 10 +- .../v2_6_0/schema/bindings/kafka/operation.py | 2 +- .../v2_6_0/schema/bindings/main/channel.py | 2 +- .../v2_6_0/schema/bindings/main/operation.py | 2 +- .../v2_6_0/schema/bindings/nats/operation.py | 2 +- .../v2_6_0/schema/bindings/redis/operation.py | 2 +- .../asyncapi/v2_6_0/schema/bindings/sqs.py | 2 +- .../v2_6_0/schema/bindings/sqs/channel.py | 2 +- .../v2_6_0/schema/bindings/sqs/operation.py | 2 +- .../asyncapi/v2_6_0/schema/channels.py | 2 +- .../asyncapi/v2_6_0/schema/components.py | 4 +- .../asyncapi/v2_6_0/schema/contact.py | 6 +- .../asyncapi/v2_6_0/schema/docs.py | 4 +- .../asyncapi/v2_6_0/schema/info.py | 2 +- .../asyncapi/v2_6_0/schema/license.py | 4 +- .../asyncapi/v2_6_0/schema/message.py | 4 +- .../asyncapi/v2_6_0/schema/operations.py | 4 +- .../asyncapi/v2_6_0/schema/schema.py | 2 +- .../asyncapi/v2_6_0/schema/servers.py | 4 +- .../asyncapi/v2_6_0/schema/tag.py | 4 +- .../specification/asyncapi/v3_0_0/generate.py | 10 +- .../asyncapi/v3_0_0/schema/channels.py | 2 +- .../asyncapi/v3_0_0/schema/components.py | 4 +- .../asyncapi/v3_0_0/schema/info.py | 6 +- .../asyncapi/v3_0_0/schema/operations.py | 4 +- .../asyncapi/v3_0_0/schema/servers.py | 4 +- faststream/specification/proto.py | 10 +- faststream/specification/schema/components.py | 2 +- faststream/specification/schema/contact.py | 4 +- faststream/specification/schema/license.py | 2 +- faststream/specification/schema/schema.py | 2 +- faststream/specification/schema/security.py | 2 +- faststream/specification/schema/servers.py | 2 +- faststream/testing/__init__.py | 3 - faststream/utils/__init__.py | 16 -- faststream/utils/classes.py | 40 ----- faststream/utils/context/__init__.py | 10 -- faststream/utils/data.py | 21 --- pyproject.toml | 8 +- tests/a_docs/confluent/basic/test_cmd_run.py | 2 +- tests/a_docs/kafka/basic/test_cmd_run.py | 2 +- tests/asyncapi/base/v2_6_0/arguments.py | 68 ++++---- tests/asyncapi/base/v2_6_0/fastapi.py | 6 +- tests/asyncapi/base/v2_6_0/naming.py | 2 +- tests/asyncapi/base/v2_6_0/publisher.py | 2 +- tests/asyncapi/base/v2_6_0/router.py | 8 +- tests/asyncapi/base/v3_0_0/arguments.py | 13 +- tests/asyncapi/base/v3_0_0/fastapi.py | 6 +- tests/asyncapi/base/v3_0_0/naming.py | 2 +- tests/asyncapi/base/v3_0_0/publisher.py | 4 +- tests/asyncapi/base/v3_0_0/router.py | 8 +- tests/brokers/base/connection.py | 2 +- tests/brokers/base/consume.py | 2 +- tests/brokers/base/fastapi.py | 77 ++++----- tests/brokers/base/middlewares.py | 6 +- tests/brokers/base/parser.py | 13 +- tests/brokers/base/publish.py | 4 +- tests/brokers/base/router.py | 10 +- tests/brokers/base/rpc.py | 131 --------------- tests/brokers/base/testclient.py | 7 +- tests/brokers/confluent/test_logger.py | 2 +- tests/brokers/nats/test_fastapi.py | 7 +- tests/brokers/nats/test_publish.py | 4 +- tests/brokers/nats/test_router.py | 18 +-- tests/brokers/nats/test_rpc.py | 26 --- tests/brokers/nats/test_test_client.py | 12 -- tests/brokers/rabbit/core/test_depends.py | 8 +- tests/brokers/rabbit/test_fastapi.py | 7 +- tests/brokers/rabbit/test_publish.py | 14 +- tests/brokers/rabbit/test_router.py | 6 +- tests/brokers/rabbit/test_rpc.py | 10 -- tests/brokers/rabbit/test_test_client.py | 41 +++-- tests/brokers/redis/test_fastapi.py | 7 +- tests/brokers/redis/test_publish.py | 4 +- tests/brokers/redis/test_router.py | 18 +-- tests/brokers/redis/test_rpc.py | 25 --- tests/brokers/redis/test_test_client.py | 17 +- tests/brokers/test_pushback.py | 2 +- tests/brokers/test_response.py | 2 +- tests/cli/rabbit/test_app.py | 4 +- tests/cli/rabbit/test_logs.py | 2 +- tests/cli/supervisors/test_base_reloader.py | 2 +- tests/cli/supervisors/test_multiprocess.py | 2 +- tests/cli/supervisors/test_watchfiles.py | 2 +- tests/cli/test_asyncapi_docs.py | 2 +- tests/cli/test_publish.py | 24 ++- tests/cli/test_version.py | 2 +- tests/cli/utils/test_imports.py | 6 +- tests/cli/utils/test_parser.py | 2 +- tests/conftest.py | 2 +- tests/log/test_formatter.py | 2 +- tests/marks.py | 2 +- tests/mypy/kafka.py | 2 +- tests/mypy/nats.py | 2 +- tests/mypy/rabbit.py | 2 +- tests/mypy/redis.py | 2 +- tests/opentelemetry/basic.py | 2 +- tests/utils/context/test_alias.py | 3 +- tests/utils/context/test_depends.py | 3 +- tests/utils/context/test_headers.py | 21 +-- tests/utils/context/test_main.py | 3 +- tests/utils/context/test_path.py | 67 ++++---- tests/utils/test_ast.py | 2 +- tests/utils/test_classes.py | 11 -- tests/utils/test_functions.py | 2 +- tests/utils/test_handler_lock.py | 2 +- tests/utils/type_cast/test_base.py | 2 +- tests/utils/type_cast/test_model.py | 2 +- 313 files changed, 1348 insertions(+), 1963 deletions(-) rename faststream/{broker/core => _internal}/__init__.py (100%) rename faststream/{ => _internal}/_compat.py (98%) rename faststream/{types.py => _internal/basic_types.py} (87%) rename faststream/{ => _internal}/broker/__init__.py (100%) rename faststream/{broker/core/abc.py => _internal/broker/abc_broker.py} (94%) rename faststream/{broker/core/usecase.py => _internal/broker/broker.py} (93%) rename faststream/{broker/core/logging.py => _internal/broker/logging_mixin.py} (92%) rename faststream/{ => _internal}/broker/router.py (88%) rename faststream/{broker/publisher => _internal/cli}/__init__.py (100%) rename faststream/{ => _internal}/cli/docs/__init__.py (100%) rename faststream/{ => _internal}/cli/docs/app.py (96%) rename faststream/{ => _internal}/cli/main.py (92%) rename faststream/{broker/subscriber => _internal/cli/supervisors}/__init__.py (100%) rename faststream/{ => _internal}/cli/supervisors/basereload.py (90%) rename faststream/{ => _internal}/cli/supervisors/multiprocess.py (91%) rename faststream/{ => _internal}/cli/supervisors/utils.py (96%) rename faststream/{ => _internal}/cli/supervisors/watchfiles.py (92%) rename faststream/{broker/wrapper => _internal/cli/utils}/__init__.py (100%) rename faststream/{ => _internal}/cli/utils/imports.py (100%) rename faststream/{ => _internal}/cli/utils/logs.py (96%) rename faststream/{ => _internal}/cli/utils/parser.py (96%) create mode 100644 faststream/_internal/constants.py create mode 100644 faststream/_internal/context/__init__.py rename faststream/{utils/context/types.py => _internal/context/context_type.py} (78%) rename faststream/{utils => _internal}/context/repository.py (95%) create mode 100644 faststream/_internal/context/resolve.py create mode 100644 faststream/_internal/fastapi/__init__.py rename faststream/{broker => _internal}/fastapi/_compat.py (98%) rename faststream/{broker => _internal}/fastapi/context.py (77%) rename faststream/{broker => _internal}/fastapi/get_dependant.py (97%) rename faststream/{broker => _internal}/fastapi/route.py (96%) rename faststream/{broker => _internal}/fastapi/router.py (95%) create mode 100644 faststream/_internal/log/__init__.py rename faststream/{ => _internal}/log/formatter.py (100%) rename faststream/{ => _internal}/log/logging.py (93%) rename faststream/{broker/schemas.py => _internal/proto.py} (79%) rename faststream/{cli => _internal/publisher}/__init__.py (100%) rename faststream/{broker => _internal}/publisher/fake.py (87%) rename faststream/{broker => _internal}/publisher/proto.py (91%) rename faststream/{broker => _internal}/publisher/usecase.py (93%) rename faststream/{cli/supervisors => _internal/subscriber}/__init__.py (100%) rename faststream/{broker => _internal/subscriber}/acknowledgement_watcher.py (97%) rename faststream/{broker => _internal}/subscriber/call_item.py (93%) rename faststream/{cli/utils => _internal/subscriber/call_wrapper}/__init__.py (100%) rename faststream/{broker/wrapper => _internal/subscriber/call_wrapper}/call.py (95%) rename faststream/{broker/wrapper => _internal/subscriber/call_wrapper}/proto.py (95%) rename faststream/{broker => _internal}/subscriber/proto.py (80%) rename faststream/{broker => _internal}/subscriber/usecase.py (92%) rename faststream/{broker => _internal/subscriber}/utils.py (91%) create mode 100644 faststream/_internal/testing/__init__.py rename faststream/{ => _internal}/testing/app.py (94%) rename faststream/{utils => _internal/testing}/ast.py (61%) rename faststream/{ => _internal}/testing/broker.py (94%) rename faststream/{broker => _internal}/types.py (91%) create mode 100644 faststream/_internal/utils/__init__.py create mode 100644 faststream/_internal/utils/data.py rename faststream/{ => _internal}/utils/functions.py (96%) rename faststream/{ => _internal}/utils/nuid.py (100%) rename faststream/{ => _internal}/utils/path.py (100%) delete mode 100644 faststream/broker/fastapi/__init__.py delete mode 100644 faststream/broker/message.py delete mode 100644 faststream/broker/middlewares/__init__.py delete mode 100644 faststream/broker/proto.py delete mode 100644 faststream/constants.py delete mode 100644 faststream/log/__init__.py create mode 100644 faststream/message/__init__.py create mode 100644 faststream/message/message.py create mode 100644 faststream/message/utils.py create mode 100644 faststream/middlewares/__init__.py rename faststream/{broker => }/middlewares/base.py (96%) rename faststream/{broker => }/middlewares/exception.py (94%) rename faststream/{broker => }/middlewares/logging.py (90%) create mode 100644 faststream/params/__init__.py rename faststream/{utils => params}/no_cast.py (60%) rename faststream/{utils/context/builders.py => params/params.py} (88%) delete mode 100644 faststream/rabbit/schemas/reply.py create mode 100644 faststream/response/__init__.py rename faststream/{broker => response}/response.py (74%) create mode 100644 faststream/response/utils.py delete mode 100644 faststream/testing/__init__.py delete mode 100644 faststream/utils/__init__.py delete mode 100644 faststream/utils/classes.py delete mode 100644 faststream/utils/context/__init__.py delete mode 100644 faststream/utils/data.py delete mode 100644 tests/brokers/base/rpc.py delete mode 100644 tests/brokers/nats/test_rpc.py delete mode 100644 tests/brokers/rabbit/test_rpc.py delete mode 100644 tests/brokers/redis/test_rpc.py delete mode 100644 tests/utils/test_classes.py diff --git a/docs/docs_src/confluent/publisher_object/example.py b/docs/docs_src/confluent/publisher_object/example.py index a242c6e2fe..f54f6931bc 100644 --- a/docs/docs_src/confluent/publisher_object/example.py +++ b/docs/docs_src/confluent/publisher_object/example.py @@ -2,7 +2,7 @@ from pydantic import BaseModel, Field, NonNegativeFloat from faststream import FastStream, Logger -from faststream._compat import model_to_json +from faststream._internal._compat import model_to_json from faststream.confluent import KafkaBroker, TestKafkaBroker broker = KafkaBroker("localhost:9092") diff --git a/docs/docs_src/kafka/publisher_object/example.py b/docs/docs_src/kafka/publisher_object/example.py index 4bb6c5a957..0cf213a64b 100644 --- a/docs/docs_src/kafka/publisher_object/example.py +++ b/docs/docs_src/kafka/publisher_object/example.py @@ -2,7 +2,7 @@ from pydantic import BaseModel, Field, NonNegativeFloat from faststream import FastStream, Logger -from faststream._compat import model_to_json +from faststream._internal._compat import model_to_json from faststream.kafka import KafkaBroker, TestKafkaBroker broker = KafkaBroker("localhost:9092") diff --git a/faststream/__init__.py b/faststream/__init__.py index d3e1dde09e..cc3c8a159b 100644 --- a/faststream/__init__.py +++ b/faststream/__init__.py @@ -1,11 +1,19 @@ """A Python framework for building services interacting with Apache Kafka, RabbitMQ, NATS and Redis.""" -from faststream.annotations import ContextRepo, Logger, NoCast +from faststream._internal.context import context +from faststream._internal.testing.app import TestApp +from faststream._internal.utils import apply_types +from faststream.annotations import ContextRepo, Logger from faststream.app import FastStream -from faststream.broker.middlewares import BaseMiddleware, ExceptionMiddleware -from faststream.broker.response import Response -from faststream.testing.app import TestApp -from faststream.utils import Context, Depends, Header, Path, apply_types, context +from faststream.middlewares import BaseMiddleware, ExceptionMiddleware +from faststream.params import ( + Context, + Depends, + Header, + NoCast, + Path, +) +from faststream.response import Response __all__ = ( # app @@ -13,15 +21,17 @@ "TestApp", # utils "apply_types", + # context "context", + # params "Context", "Header", "Path", "Depends", + "NoCast", # annotations "Logger", "ContextRepo", - "NoCast", # middlewares "BaseMiddleware", "ExceptionMiddleware", diff --git a/faststream/__main__.py b/faststream/__main__.py index 04378c618e..f5a5846c3e 100644 --- a/faststream/__main__.py +++ b/faststream/__main__.py @@ -3,7 +3,7 @@ import warnings try: - from faststream.cli.main import cli + from faststream._internal.cli.main import cli except ImportError: has_typer = False else: diff --git a/faststream/broker/core/__init__.py b/faststream/_internal/__init__.py similarity index 100% rename from faststream/broker/core/__init__.py rename to faststream/_internal/__init__.py diff --git a/faststream/_compat.py b/faststream/_internal/_compat.py similarity index 98% rename from faststream/_compat.py rename to faststream/_internal/_compat.py index e605f64ece..df88be24b6 100644 --- a/faststream/_compat.py +++ b/faststream/_internal/_compat.py @@ -10,7 +10,7 @@ ) from pydantic import BaseModel as BaseModel -from faststream.types import AnyDict +from faststream._internal.basic_types import AnyDict IS_WINDOWS = ( sys.platform == "win32" or sys.platform == "cygwin" or sys.platform == "msys" diff --git a/faststream/types.py b/faststream/_internal/basic_types.py similarity index 87% rename from faststream/types.py rename to faststream/_internal/basic_types.py index 6404614db7..8a44384081 100644 --- a/faststream/types.py +++ b/faststream/_internal/basic_types.py @@ -76,7 +76,7 @@ class StandardDataclass(Protocol): ] try: - from faststream._compat import BaseModel + from faststream._internal._compat import BaseModel SendableMessage: TypeAlias = Union[ BaseModel, @@ -107,17 +107,3 @@ def log( exc_info: Any = None, extra: Optional[Mapping[str, Any]] = None, ) -> None: ... - - -class _EmptyPlaceholder: - def __repr__(self) -> str: - return "EMPTY" - - def __eq__(self, other: object) -> bool: - if not isinstance(other, _EmptyPlaceholder): - return NotImplemented - - return True - - -EMPTY: Any = _EmptyPlaceholder() diff --git a/faststream/broker/__init__.py b/faststream/_internal/broker/__init__.py similarity index 100% rename from faststream/broker/__init__.py rename to faststream/_internal/broker/__init__.py diff --git a/faststream/broker/core/abc.py b/faststream/_internal/broker/abc_broker.py similarity index 94% rename from faststream/broker/core/abc.py rename to faststream/_internal/broker/abc_broker.py index eb1a49bb7b..e3998c75d5 100644 --- a/faststream/broker/core/abc.py +++ b/faststream/_internal/broker/abc_broker.py @@ -8,17 +8,17 @@ Optional, ) -from faststream.broker.types import MsgType +from ..types import ( + BrokerMiddleware, + CustomCallable, + MsgType, +) if TYPE_CHECKING: from fast_depends.dependencies import Depends - from faststream.broker.publisher.proto import PublisherProto - from faststream.broker.subscriber.proto import SubscriberProto - from faststream.broker.types import ( - BrokerMiddleware, - CustomCallable, - ) + from faststream._internal.publisher.proto import PublisherProto + from faststream._internal.subscriber.proto import SubscriberProto class ABCBroker(Generic[MsgType]): diff --git a/faststream/broker/core/usecase.py b/faststream/_internal/broker/broker.py similarity index 93% rename from faststream/broker/core/usecase.py rename to faststream/_internal/broker/broker.py index e6d7ea2f09..54aa0acd22 100644 --- a/faststream/broker/core/usecase.py +++ b/faststream/_internal/broker/broker.py @@ -18,33 +18,37 @@ from typing_extensions import Annotated, Doc, Self -from faststream._compat import is_test_env -from faststream.broker.core.logging import LoggingBroker -from faststream.broker.middlewares.logging import CriticalLogMiddleware -from faststream.broker.proto import SetupAble -from faststream.broker.subscriber.proto import SubscriberProto -from faststream.broker.types import ( +from faststream._internal._compat import is_test_env +from faststream._internal.context.repository import context +from faststream._internal.log.logging import set_logger_fmt +from faststream._internal.proto import SetupAble +from faststream._internal.subscriber.proto import SubscriberProto +from faststream._internal.types import ( AsyncCustomCallable, BrokerMiddleware, ConnectionType, CustomCallable, MsgType, ) +from faststream._internal.utils.functions import return_input, to_async from faststream.exceptions import NOT_CONNECTED_YET -from faststream.log.logging import set_logger_fmt -from faststream.utils.context.repository import context -from faststream.utils.functions import return_input, to_async +from faststream.middlewares.logging import CriticalLogMiddleware + +from .logging_mixin import LoggingBroker if TYPE_CHECKING: from types import TracebackType from fast_depends.dependencies import Depends - from faststream.broker.message import StreamMessage - from faststream.broker.publisher.proto import ProducerProto, PublisherProto + from faststream._internal.basic_types import AnyDict, Decorator, LoggerProto + from faststream._internal.publisher.proto import ( + ProducerProto, + PublisherProto, + ) + from faststream.message import StreamMessage from faststream.security import BaseSecurity from faststream.specification.schema.tag import Tag, TagDict - from faststream.types import AnyDict, Decorator, LoggerProto class BrokerUsecase( diff --git a/faststream/broker/core/logging.py b/faststream/_internal/broker/logging_mixin.py similarity index 92% rename from faststream/broker/core/logging.py rename to faststream/_internal/broker/logging_mixin.py index 06412bf7f2..43ab11a4e1 100644 --- a/faststream/broker/core/logging.py +++ b/faststream/_internal/broker/logging_mixin.py @@ -4,12 +4,13 @@ from typing_extensions import Annotated, Doc -from faststream.broker.core.abc import ABCBroker -from faststream.broker.types import MsgType -from faststream.types import EMPTY +from faststream._internal.constants import EMPTY + +from ..types import MsgType +from .abc_broker import ABCBroker if TYPE_CHECKING: - from faststream.types import AnyDict, LoggerProto + from faststream._internal.basic_types import AnyDict, LoggerProto class LoggingBroker(ABCBroker[MsgType]): diff --git a/faststream/broker/router.py b/faststream/_internal/broker/router.py similarity index 88% rename from faststream/broker/router.py rename to faststream/_internal/broker/router.py index dfab000974..12d0eb3b76 100644 --- a/faststream/broker/router.py +++ b/faststream/_internal/broker/router.py @@ -6,17 +6,17 @@ Optional, ) -from faststream.broker.core.abc import ABCBroker -from faststream.broker.types import MsgType +from ..types import ( + BrokerMiddleware, + CustomCallable, + MsgType, +) +from .abc_broker import ABCBroker if TYPE_CHECKING: from fast_depends.dependencies import Depends - from faststream.broker.types import ( - BrokerMiddleware, - CustomCallable, - ) - from faststream.types import AnyDict + from faststream._internal.basic_types import AnyDict class ArgsContainer: diff --git a/faststream/broker/publisher/__init__.py b/faststream/_internal/cli/__init__.py similarity index 100% rename from faststream/broker/publisher/__init__.py rename to faststream/_internal/cli/__init__.py diff --git a/faststream/cli/docs/__init__.py b/faststream/_internal/cli/docs/__init__.py similarity index 100% rename from faststream/cli/docs/__init__.py rename to faststream/_internal/cli/docs/__init__.py diff --git a/faststream/cli/docs/app.py b/faststream/_internal/cli/docs/app.py similarity index 96% rename from faststream/cli/docs/app.py rename to faststream/_internal/cli/docs/app.py index 64c462fba0..e3b729b5d5 100644 --- a/faststream/cli/docs/app.py +++ b/faststream/_internal/cli/docs/app.py @@ -8,8 +8,8 @@ import typer from pydantic import ValidationError -from faststream._compat import json_dumps, model_parse -from faststream.cli.utils.imports import import_from_string +from faststream._internal._compat import json_dumps, model_parse +from faststream._internal.cli.utils.imports import import_from_string from faststream.exceptions import INSTALL_WATCHFILES, INSTALL_YAML, SCHEMA_NOT_SUPPORTED from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.site import serve_app @@ -71,7 +71,7 @@ def serve( if reload: try: - from faststream.cli.supervisors.watchfiles import WatchReloader + from faststream._internal.cli.supervisors.watchfiles import WatchReloader except ImportError: warnings.warn(INSTALL_WATCHFILES, category=ImportWarning, stacklevel=1) diff --git a/faststream/cli/main.py b/faststream/_internal/cli/main.py similarity index 92% rename from faststream/cli/main.py rename to faststream/_internal/cli/main.py index fcbb8f5208..5920055485 100644 --- a/faststream/cli/main.py +++ b/faststream/_internal/cli/main.py @@ -11,15 +11,15 @@ from faststream import FastStream from faststream.__about__ import __version__ -from faststream.cli.docs import asyncapi_app -from faststream.cli.utils.imports import import_from_string -from faststream.cli.utils.logs import LogLevels, get_log_level, set_log_level -from faststream.cli.utils.parser import parse_cli_args +from faststream._internal.cli.docs import asyncapi_app +from faststream._internal.cli.utils.imports import import_from_string +from faststream._internal.cli.utils.logs import LogLevels, get_log_level, set_log_level +from faststream._internal.cli.utils.parser import parse_cli_args from faststream.exceptions import INSTALL_WATCHFILES, SetupError, ValidationError if TYPE_CHECKING: - from faststream.broker.core.usecase import BrokerUsecase - from faststream.types import AnyDict, SettingField + from faststream._internal.basic_types import AnyDict, SettingField + from faststream._internal.broker.broker import BrokerUsecase cli = typer.Typer(pretty_exceptions_short=True) cli.add_typer(asyncapi_app, name="docs", help="Documentations commands") @@ -120,7 +120,7 @@ def run( if reload: try: - from faststream.cli.supervisors.watchfiles import WatchReloader + from faststream._internal.cli.supervisors.watchfiles import WatchReloader except ImportError: warnings.warn(INSTALL_WATCHFILES, category=ImportWarning, stacklevel=1) _run(*args) @@ -140,7 +140,7 @@ def run( ).run() elif workers > 1: - from faststream.cli.supervisors.multiprocess import Multiprocess + from faststream._internal.cli.supervisors.multiprocess import Multiprocess Multiprocess( target=_run, diff --git a/faststream/broker/subscriber/__init__.py b/faststream/_internal/cli/supervisors/__init__.py similarity index 100% rename from faststream/broker/subscriber/__init__.py rename to faststream/_internal/cli/supervisors/__init__.py diff --git a/faststream/cli/supervisors/basereload.py b/faststream/_internal/cli/supervisors/basereload.py similarity index 90% rename from faststream/cli/supervisors/basereload.py rename to faststream/_internal/cli/supervisors/basereload.py index d0906cb56f..ffc76e80da 100644 --- a/faststream/cli/supervisors/basereload.py +++ b/faststream/_internal/cli/supervisors/basereload.py @@ -3,11 +3,11 @@ from multiprocessing.context import SpawnProcess from typing import TYPE_CHECKING, Any, Optional, Tuple -from faststream.cli.supervisors.utils import get_subprocess, set_exit -from faststream.log import logger +from faststream._internal.cli.supervisors.utils import get_subprocess, set_exit +from faststream._internal.log import logger if TYPE_CHECKING: - from faststream.types import DecoratedCallable + from faststream._internal.basic_types import DecoratedCallable class BaseReload: diff --git a/faststream/cli/supervisors/multiprocess.py b/faststream/_internal/cli/supervisors/multiprocess.py similarity index 91% rename from faststream/cli/supervisors/multiprocess.py rename to faststream/_internal/cli/supervisors/multiprocess.py index a08fc5f273..1ebcb1c772 100644 --- a/faststream/cli/supervisors/multiprocess.py +++ b/faststream/_internal/cli/supervisors/multiprocess.py @@ -1,13 +1,13 @@ import signal from typing import TYPE_CHECKING, Any, List, Tuple -from faststream.cli.supervisors.basereload import BaseReload -from faststream.log import logger +from faststream._internal.cli.supervisors.basereload import BaseReload +from faststream._internal.log import logger if TYPE_CHECKING: from multiprocessing.context import SpawnProcess - from faststream.types import DecoratedCallable + from faststream._internal.basic_types import DecoratedCallable class Multiprocess(BaseReload): diff --git a/faststream/cli/supervisors/utils.py b/faststream/_internal/cli/supervisors/utils.py similarity index 96% rename from faststream/cli/supervisors/utils.py rename to faststream/_internal/cli/supervisors/utils.py index 0d39460bd8..5d01aca299 100644 --- a/faststream/cli/supervisors/utils.py +++ b/faststream/_internal/cli/supervisors/utils.py @@ -10,7 +10,7 @@ from multiprocessing.context import SpawnProcess from types import FrameType - from faststream.types import DecoratedCallableNone + from faststream._internal.basic_types import DecoratedCallableNone multiprocessing.allow_connection_pickling() spawn = multiprocessing.get_context("spawn") diff --git a/faststream/cli/supervisors/watchfiles.py b/faststream/_internal/cli/supervisors/watchfiles.py similarity index 92% rename from faststream/cli/supervisors/watchfiles.py rename to faststream/_internal/cli/supervisors/watchfiles.py index 9b70dbff5b..dbd3be23ab 100644 --- a/faststream/cli/supervisors/watchfiles.py +++ b/faststream/_internal/cli/supervisors/watchfiles.py @@ -3,11 +3,11 @@ import watchfiles -from faststream.cli.supervisors.basereload import BaseReload -from faststream.log import logger +from faststream._internal.cli.supervisors.basereload import BaseReload +from faststream._internal.log import logger if TYPE_CHECKING: - from faststream.types import DecoratedCallable + from faststream._internal.basic_types import DecoratedCallable class ExtendedFilter(watchfiles.PythonFilter): diff --git a/faststream/broker/wrapper/__init__.py b/faststream/_internal/cli/utils/__init__.py similarity index 100% rename from faststream/broker/wrapper/__init__.py rename to faststream/_internal/cli/utils/__init__.py diff --git a/faststream/cli/utils/imports.py b/faststream/_internal/cli/utils/imports.py similarity index 100% rename from faststream/cli/utils/imports.py rename to faststream/_internal/cli/utils/imports.py diff --git a/faststream/cli/utils/logs.py b/faststream/_internal/cli/utils/logs.py similarity index 96% rename from faststream/cli/utils/logs.py rename to faststream/_internal/cli/utils/logs.py index b576db49ee..96f9f48bfd 100644 --- a/faststream/cli/utils/logs.py +++ b/faststream/_internal/cli/utils/logs.py @@ -4,8 +4,8 @@ from typing import TYPE_CHECKING, DefaultDict, Optional, Union if TYPE_CHECKING: + from faststream._internal.basic_types import LoggerProto from faststream.app import FastStream - from faststream.types import LoggerProto class LogLevels(str, Enum): diff --git a/faststream/cli/utils/parser.py b/faststream/_internal/cli/utils/parser.py similarity index 96% rename from faststream/cli/utils/parser.py rename to faststream/_internal/cli/utils/parser.py index 00c904d774..1310e115ec 100644 --- a/faststream/cli/utils/parser.py +++ b/faststream/_internal/cli/utils/parser.py @@ -2,7 +2,7 @@ from typing import TYPE_CHECKING, Dict, List, Tuple if TYPE_CHECKING: - from faststream.types import SettingField + from faststream._internal.basic_types import SettingField def parse_cli_args(*args: str) -> Tuple[str, Dict[str, "SettingField"]]: diff --git a/faststream/_internal/constants.py b/faststream/_internal/constants.py new file mode 100644 index 0000000000..16c6a90415 --- /dev/null +++ b/faststream/_internal/constants.py @@ -0,0 +1,25 @@ +from enum import Enum +from typing import Any + +ContentType = str + + +class ContentTypes(str, Enum): + """A class to represent content types.""" + + text = "text/plain" + json = "application/json" + + +class _EmptyPlaceholder: + def __repr__(self) -> str: + return "EMPTY" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, _EmptyPlaceholder): + return NotImplemented + + return True + + +EMPTY: Any = _EmptyPlaceholder() diff --git a/faststream/_internal/context/__init__.py b/faststream/_internal/context/__init__.py new file mode 100644 index 0000000000..202ba06363 --- /dev/null +++ b/faststream/_internal/context/__init__.py @@ -0,0 +1,8 @@ +from .context_type import Context +from .repository import ContextRepo, context + +__all__ = ( + "context", + "Context", + "ContextRepo", +) diff --git a/faststream/utils/context/types.py b/faststream/_internal/context/context_type.py similarity index 78% rename from faststream/utils/context/types.py rename to faststream/_internal/context/context_type.py index b176132217..59e22ebd14 100644 --- a/faststream/utils/context/types.py +++ b/faststream/_internal/context/context_type.py @@ -2,8 +2,10 @@ from fast_depends.library import CustomField -from faststream.types import EMPTY, AnyDict -from faststream.utils.context.repository import context +from faststream._internal.basic_types import AnyDict +from faststream._internal.constants import EMPTY + +from .resolve import resolve_context_by_name class Context(CustomField): @@ -73,24 +75,3 @@ def use(self, /, **kwargs: Any) -> AnyDict: kwargs.pop(self.param_name, None) return kwargs - - -def resolve_context_by_name( - name: str, - default: Any, - initial: Optional[Callable[..., Any]], -) -> Any: - value: Any = EMPTY - - try: - value = context.resolve(name) - - except (KeyError, AttributeError): - if default != EMPTY: - value = default - - elif initial is not None: - value = initial() - context.set_global(name, value) - - return value diff --git a/faststream/utils/context/repository.py b/faststream/_internal/context/repository.py similarity index 95% rename from faststream/utils/context/repository.py rename to faststream/_internal/context/repository.py index 034d2a504c..24654844b7 100644 --- a/faststream/utils/context/repository.py +++ b/faststream/_internal/context/repository.py @@ -2,13 +2,14 @@ from contextvars import ContextVar, Token from typing import Any, Dict, Iterator, Mapping -from faststream.types import EMPTY, AnyDict -from faststream.utils.classes import Singleton +from faststream._internal.basic_types import AnyDict +from faststream._internal.constants import EMPTY +from faststream.exceptions import ContextError __all__ = ("ContextRepo", "context") -class ContextRepo(Singleton): +class ContextRepo: """A class to represent a context repository.""" _global_context: AnyDict @@ -160,7 +161,7 @@ def resolve(self, argument: str) -> Any: first, *keys = argument.split(".") if (v := self.get(first, EMPTY)) is EMPTY: - raise KeyError(f"`{self.context}` does not contains `{first}` key") + raise ContextError(self.context, first) for i in keys: v = v[i] if isinstance(v, Mapping) else getattr(v, i) diff --git a/faststream/_internal/context/resolve.py b/faststream/_internal/context/resolve.py new file mode 100644 index 0000000000..23af1b057c --- /dev/null +++ b/faststream/_internal/context/resolve.py @@ -0,0 +1,26 @@ +from typing import Any, Callable, Optional + +from faststream._internal.constants import EMPTY + +from .repository import context + + +def resolve_context_by_name( + name: str, + default: Any, + initial: Optional[Callable[..., Any]], +) -> Any: + value: Any = EMPTY + + try: + value = context.resolve(name) + + except (KeyError, AttributeError): + if default != EMPTY: + value = default + + elif initial is not None: + value = initial() + context.set_global(name, value) + + return value diff --git a/faststream/_internal/fastapi/__init__.py b/faststream/_internal/fastapi/__init__.py new file mode 100644 index 0000000000..011777a593 --- /dev/null +++ b/faststream/_internal/fastapi/__init__.py @@ -0,0 +1,7 @@ +from faststream._internal.fastapi.route import StreamMessage +from faststream._internal.fastapi.router import StreamRouter + +__all__ = ( + "StreamMessage", + "StreamRouter", +) diff --git a/faststream/broker/fastapi/_compat.py b/faststream/_internal/fastapi/_compat.py similarity index 98% rename from faststream/broker/fastapi/_compat.py rename to faststream/_internal/fastapi/_compat.py index 206aff52ef..b673c0d110 100644 --- a/faststream/broker/fastapi/_compat.py +++ b/faststream/_internal/fastapi/_compat.py @@ -6,7 +6,7 @@ from starlette.background import BackgroundTasks from typing_extensions import Never -from faststream.types import AnyDict +from faststream._internal.basic_types import AnyDict if TYPE_CHECKING: from fastapi.dependencies.models import Dependant diff --git a/faststream/broker/fastapi/context.py b/faststream/_internal/fastapi/context.py similarity index 77% rename from faststream/broker/fastapi/context.py rename to faststream/_internal/fastapi/context.py index 25edd313b7..1422448b4f 100644 --- a/faststream/broker/fastapi/context.py +++ b/faststream/_internal/fastapi/context.py @@ -4,9 +4,9 @@ from fastapi import params from typing_extensions import Annotated -from faststream.types import EMPTY -from faststream.utils.context import ContextRepo as CR -from faststream.utils.context.types import resolve_context_by_name +from faststream._internal.constants import EMPTY +from faststream._internal.context import ContextRepo as CR +from faststream._internal.context.resolve import resolve_context_by_name def Context( # noqa: N802 diff --git a/faststream/broker/fastapi/get_dependant.py b/faststream/_internal/fastapi/get_dependant.py similarity index 97% rename from faststream/broker/fastapi/get_dependant.py rename to faststream/_internal/fastapi/get_dependant.py index 45d5aaba30..ca40aae455 100644 --- a/faststream/broker/fastapi/get_dependant.py +++ b/faststream/_internal/fastapi/get_dependant.py @@ -2,7 +2,7 @@ from fastapi.dependencies.utils import get_dependant, get_parameterless_sub_dependant -from faststream._compat import PYDANTIC_V2 +from faststream._internal._compat import PYDANTIC_V2 if TYPE_CHECKING: from fastapi import params @@ -47,7 +47,7 @@ def _patch_fastapi_dependent(dependant: "Dependant") -> "Dependant": """Patch FastAPI by adding fields for AsyncAPI schema generation.""" from pydantic import Field, create_model # FastAPI always has pydantic - from faststream._compat import PydanticUndefined + from faststream._internal._compat import PydanticUndefined params = dependant.query_params + dependant.body_params diff --git a/faststream/broker/fastapi/route.py b/faststream/_internal/fastapi/route.py similarity index 96% rename from faststream/broker/fastapi/route.py rename to faststream/_internal/fastapi/route.py index d8e39f96b2..791afc9610 100644 --- a/faststream/broker/fastapi/route.py +++ b/faststream/_internal/fastapi/route.py @@ -17,8 +17,10 @@ from fastapi.routing import run_endpoint_function, serialize_response from starlette.requests import Request -from faststream.broker.fastapi.get_dependant import get_fastapi_native_dependant -from faststream.broker.types import P_HandlerParams, T_HandlerReturn +from faststream._internal.fastapi.get_dependant import ( + get_fastapi_native_dependant, +) +from faststream._internal.types import P_HandlerParams, T_HandlerReturn from ._compat import ( FASTAPI_V106, @@ -33,8 +35,8 @@ from fastapi.dependencies.models import Dependant from fastapi.types import IncEx - from faststream.broker.message import StreamMessage as NativeMessage - from faststream.types import AnyDict + from faststream._internal.basic_types import AnyDict + from faststream.message import StreamMessage as NativeMessage class StreamMessage(Request): diff --git a/faststream/broker/fastapi/router.py b/faststream/_internal/fastapi/router.py similarity index 95% rename from faststream/broker/fastapi/router.py rename to faststream/_internal/fastapi/router.py index bc1cedda8f..7bf691b96d 100644 --- a/faststream/broker/fastapi/router.py +++ b/faststream/_internal/fastapi/router.py @@ -30,19 +30,21 @@ from starlette.responses import JSONResponse, Response from starlette.routing import BaseRoute, _DefaultLifespan -from faststream.broker.fastapi.get_dependant import get_fastapi_dependant -from faststream.broker.fastapi.route import wrap_callable_to_fastapi_compatible -from faststream.broker.middlewares import BaseMiddleware -from faststream.broker.router import BrokerRouter -from faststream.broker.types import ( +from faststream._internal.broker.router import BrokerRouter +from faststream._internal.context.repository import context +from faststream._internal.fastapi.get_dependant import get_fastapi_dependant +from faststream._internal.fastapi.route import ( + wrap_callable_to_fastapi_compatible, +) +from faststream._internal.types import ( MsgType, P_HandlerParams, T_HandlerReturn, ) +from faststream._internal.utils.functions import fake_context, to_async +from faststream.middlewares import BaseMiddleware from faststream.specification.asyncapi.site import get_asyncapi_html from faststream.specification.proto import Application -from faststream.utils.context.repository import context -from faststream.utils.functions import fake_context, to_async if TYPE_CHECKING: from types import TracebackType @@ -52,15 +54,15 @@ from starlette import routing from starlette.types import ASGIApp, AppType, Lifespan - from faststream.broker.core.usecase import BrokerUsecase - from faststream.broker.message import StreamMessage - from faststream.broker.publisher.proto import PublisherProto - from faststream.broker.schemas import NameRequired - from faststream.broker.types import BrokerMiddleware - from faststream.broker.wrapper.call import HandlerCallWrapper + from faststream._internal.basic_types import AnyDict + from faststream._internal.broker.broker import BrokerUsecase + from faststream._internal.proto import NameRequired + from faststream._internal.publisher.proto import PublisherProto + from faststream._internal.subscriber.call_wrapper.call import HandlerCallWrapper + from faststream._internal.types import BrokerMiddleware + from faststream.message import StreamMessage from faststream.specification.asyncapi.base.schema import BaseSchema from faststream.specification.schema.tag import Tag, TagDict - from faststream.types import AnyDict class _BackgroundMiddleware(BaseMiddleware): diff --git a/faststream/_internal/log/__init__.py b/faststream/_internal/log/__init__.py new file mode 100644 index 0000000000..c9139b092b --- /dev/null +++ b/faststream/_internal/log/__init__.py @@ -0,0 +1,3 @@ +from faststream._internal.log.logging import logger + +__all__ = ("logger",) diff --git a/faststream/log/formatter.py b/faststream/_internal/log/formatter.py similarity index 100% rename from faststream/log/formatter.py rename to faststream/_internal/log/formatter.py diff --git a/faststream/log/logging.py b/faststream/_internal/log/logging.py similarity index 93% rename from faststream/log/logging.py rename to faststream/_internal/log/logging.py index d10852c440..a6139a0f2d 100644 --- a/faststream/log/logging.py +++ b/faststream/_internal/log/logging.py @@ -3,8 +3,8 @@ from logging import LogRecord from typing import Mapping -from faststream.log.formatter import ColourizedFormatter -from faststream.utils.context.repository import context +from faststream._internal.context.repository import context +from faststream._internal.log.formatter import ColourizedFormatter logger = logging.getLogger("faststream") logger.setLevel(logging.INFO) diff --git a/faststream/broker/schemas.py b/faststream/_internal/proto.py similarity index 79% rename from faststream/broker/schemas.py rename to faststream/_internal/proto.py index 75b624df87..54d988a763 100644 --- a/faststream/broker/schemas.py +++ b/faststream/_internal/proto.py @@ -1,4 +1,16 @@ -from typing import Any, Optional, Type, TypeVar, Union, overload +from abc import abstractmethod +from typing import Any, Optional, Protocol, Type, TypeVar, Union, overload + + +class SetupAble(Protocol): + @abstractmethod + def setup(self) -> None: ... + + +class Endpoint(SetupAble, Protocol): + @abstractmethod + def add_prefix(self, prefix: str) -> None: ... + NameRequiredCls = TypeVar("NameRequiredCls", bound="NameRequired") diff --git a/faststream/cli/__init__.py b/faststream/_internal/publisher/__init__.py similarity index 100% rename from faststream/cli/__init__.py rename to faststream/_internal/publisher/__init__.py diff --git a/faststream/broker/publisher/fake.py b/faststream/_internal/publisher/fake.py similarity index 87% rename from faststream/broker/publisher/fake.py rename to faststream/_internal/publisher/fake.py index 7ef19903d3..89f87ed4c2 100644 --- a/faststream/broker/publisher/fake.py +++ b/faststream/_internal/publisher/fake.py @@ -2,11 +2,11 @@ from itertools import chain from typing import TYPE_CHECKING, Any, Iterable, Optional -from faststream.broker.publisher.proto import BasePublisherProto +from faststream._internal.publisher.proto import BasePublisherProto if TYPE_CHECKING: - from faststream.broker.types import PublisherMiddleware - from faststream.types import AnyDict, AsyncFunc, SendableMessage + from faststream._internal.basic_types import AnyDict, AsyncFunc, SendableMessage + from faststream._internal.types import PublisherMiddleware class FakePublisher(BasePublisherProto): diff --git a/faststream/broker/publisher/proto.py b/faststream/_internal/publisher/proto.py similarity index 91% rename from faststream/broker/publisher/proto.py rename to faststream/_internal/publisher/proto.py index b268c2771a..86addc8b35 100644 --- a/faststream/broker/publisher/proto.py +++ b/faststream/_internal/publisher/proto.py @@ -3,19 +3,19 @@ from typing_extensions import override -from faststream.broker.proto import EndpointProto -from faststream.broker.types import MsgType +from faststream._internal.proto import Endpoint +from faststream._internal.types import MsgType from faststream.specification.proto import SpecificationProto if TYPE_CHECKING: - from faststream.broker.types import ( + from faststream._internal.basic_types import SendableMessage + from faststream._internal.types import ( AsyncCallable, BrokerMiddleware, P_HandlerParams, PublisherMiddleware, T_HandlerReturn, ) - from faststream.types import SendableMessage class ProducerProto(Protocol): @@ -73,7 +73,7 @@ async def request( class PublisherProto( SpecificationProto, - EndpointProto, + Endpoint, BasePublisherProto, Generic[MsgType], ): diff --git a/faststream/broker/publisher/usecase.py b/faststream/_internal/publisher/usecase.py similarity index 93% rename from faststream/broker/publisher/usecase.py rename to faststream/_internal/publisher/usecase.py index 1305aa169f..71333dfbd9 100644 --- a/faststream/broker/publisher/usecase.py +++ b/faststream/_internal/publisher/usecase.py @@ -14,23 +14,23 @@ from fast_depends.core import CallModel, build_call_model from typing_extensions import Annotated, Doc, override -from faststream.broker.publisher.proto import PublisherProto -from faststream.broker.types import ( +from faststream._internal.publisher.proto import PublisherProto +from faststream._internal.subscriber.call_wrapper.call import HandlerCallWrapper +from faststream._internal.types import ( MsgType, P_HandlerParams, T_HandlerReturn, ) -from faststream.broker.wrapper.call import HandlerCallWrapper from faststream.specification.asyncapi.message import get_response_schema from faststream.specification.asyncapi.utils import to_camelcase if TYPE_CHECKING: - from faststream.broker.publisher.proto import ProducerProto - from faststream.broker.types import ( + from faststream._internal.basic_types import AnyDict + from faststream._internal.publisher.proto import ProducerProto + from faststream._internal.types import ( BrokerMiddleware, PublisherMiddleware, ) - from faststream.types import AnyDict class PublisherUsecase( diff --git a/faststream/cli/supervisors/__init__.py b/faststream/_internal/subscriber/__init__.py similarity index 100% rename from faststream/cli/supervisors/__init__.py rename to faststream/_internal/subscriber/__init__.py diff --git a/faststream/broker/acknowledgement_watcher.py b/faststream/_internal/subscriber/acknowledgement_watcher.py similarity index 97% rename from faststream/broker/acknowledgement_watcher.py rename to faststream/_internal/subscriber/acknowledgement_watcher.py index 4084274095..04d7e03cde 100644 --- a/faststream/broker/acknowledgement_watcher.py +++ b/faststream/_internal/subscriber/acknowledgement_watcher.py @@ -15,9 +15,9 @@ if TYPE_CHECKING: from types import TracebackType - from faststream.broker.message import StreamMessage - from faststream.broker.types import MsgType - from faststream.types import LoggerProto + from faststream._internal.basic_types import LoggerProto + from faststream._internal.types import MsgType + from faststream.message import StreamMessage class BaseWatcher(ABC): diff --git a/faststream/broker/subscriber/call_item.py b/faststream/_internal/subscriber/call_item.py similarity index 93% rename from faststream/broker/subscriber/call_item.py rename to faststream/_internal/subscriber/call_item.py index c7c32b3609..6ffa691fdc 100644 --- a/faststream/broker/subscriber/call_item.py +++ b/faststream/_internal/subscriber/call_item.py @@ -14,22 +14,22 @@ from typing_extensions import override -from faststream.broker.proto import SetupAble -from faststream.broker.types import MsgType +from faststream._internal.proto import SetupAble +from faststream._internal.types import MsgType from faststream.exceptions import IgnoredException, SetupError if TYPE_CHECKING: from fast_depends.dependencies import Depends - from faststream.broker.message import StreamMessage - from faststream.broker.types import ( + from faststream._internal.basic_types import AsyncFuncAny, Decorator + from faststream._internal.subscriber.call_wrapper.call import HandlerCallWrapper + from faststream._internal.types import ( AsyncCallable, AsyncFilter, CustomCallable, SubscriberMiddleware, ) - from faststream.broker.wrapper.call import HandlerCallWrapper - from faststream.types import AsyncFuncAny, Decorator + from faststream.message import StreamMessage class HandlerItem(SetupAble, Generic[MsgType]): diff --git a/faststream/cli/utils/__init__.py b/faststream/_internal/subscriber/call_wrapper/__init__.py similarity index 100% rename from faststream/cli/utils/__init__.py rename to faststream/_internal/subscriber/call_wrapper/__init__.py diff --git a/faststream/broker/wrapper/call.py b/faststream/_internal/subscriber/call_wrapper/call.py similarity index 95% rename from faststream/broker/wrapper/call.py rename to faststream/_internal/subscriber/call_wrapper/call.py index 1ae083dd7f..ba0ef40daa 100644 --- a/faststream/broker/wrapper/call.py +++ b/faststream/_internal/subscriber/call_wrapper/call.py @@ -18,20 +18,20 @@ from fast_depends.core import CallModel, build_call_model from fast_depends.use import _InjectWrapper, inject -from faststream.broker.types import ( +from faststream._internal.types import ( MsgType, P_HandlerParams, T_HandlerReturn, ) +from faststream._internal.utils.functions import to_async from faststream.exceptions import SetupError -from faststream.utils.functions import to_async if TYPE_CHECKING: from fast_depends.dependencies import Depends - from faststream.broker.message import StreamMessage - from faststream.broker.publisher.proto import PublisherProto - from faststream.types import Decorator + from faststream._internal.basic_types import Decorator + from faststream._internal.publisher.proto import PublisherProto + from faststream.message import StreamMessage class HandlerCallWrapper(Generic[MsgType, P_HandlerParams, T_HandlerReturn]): diff --git a/faststream/broker/wrapper/proto.py b/faststream/_internal/subscriber/call_wrapper/proto.py similarity index 95% rename from faststream/broker/wrapper/proto.py rename to faststream/_internal/subscriber/call_wrapper/proto.py index 725e31ceee..2fb8591497 100644 --- a/faststream/broker/wrapper/proto.py +++ b/faststream/_internal/subscriber/call_wrapper/proto.py @@ -9,7 +9,7 @@ overload, ) -from faststream.broker.types import ( +from faststream._internal.types import ( CustomCallable, Filter, MsgType, @@ -21,7 +21,7 @@ if TYPE_CHECKING: from fast_depends.dependencies import Depends - from faststream.broker.wrapper.call import HandlerCallWrapper + from .call import HandlerCallWrapper class WrapperProto(Protocol[MsgType]): diff --git a/faststream/broker/subscriber/proto.py b/faststream/_internal/subscriber/proto.py similarity index 80% rename from faststream/broker/subscriber/proto.py rename to faststream/_internal/subscriber/proto.py index eb62bf8ea8..60ab953863 100644 --- a/faststream/broker/subscriber/proto.py +++ b/faststream/_internal/subscriber/proto.py @@ -3,30 +3,33 @@ from typing_extensions import Self, override -from faststream.broker.proto import EndpointProto -from faststream.broker.types import MsgType -from faststream.broker.wrapper.proto import WrapperProto +from faststream._internal.proto import Endpoint +from faststream._internal.subscriber.call_wrapper.proto import WrapperProto +from faststream._internal.types import MsgType from faststream.specification.proto import SpecificationProto if TYPE_CHECKING: from fast_depends.dependencies import Depends - from faststream.broker.message import StreamMessage - from faststream.broker.publisher.proto import BasePublisherProto, ProducerProto - from faststream.broker.response import Response - from faststream.broker.subscriber.call_item import HandlerItem - from faststream.broker.types import ( + from faststream._internal.basic_types import AnyDict, Decorator, LoggerProto + from faststream._internal.publisher.proto import ( + BasePublisherProto, + ProducerProto, + ) + from faststream._internal.subscriber.call_item import HandlerItem + from faststream._internal.types import ( BrokerMiddleware, CustomCallable, Filter, SubscriberMiddleware, ) - from faststream.types import AnyDict, Decorator, LoggerProto + from faststream.message import StreamMessage + from faststream.response import Response class SubscriberProto( SpecificationProto, - EndpointProto, + Endpoint, WrapperProto[MsgType], ): calls: List["HandlerItem[MsgType]"] diff --git a/faststream/broker/subscriber/usecase.py b/faststream/_internal/subscriber/usecase.py similarity index 92% rename from faststream/broker/subscriber/usecase.py rename to faststream/_internal/subscriber/usecase.py index 12a007880e..eefcd18c0c 100644 --- a/faststream/broker/subscriber/usecase.py +++ b/faststream/_internal/subscriber/usecase.py @@ -17,42 +17,49 @@ from typing_extensions import Self, override -from faststream.broker.response import ensure_response -from faststream.broker.subscriber.call_item import HandlerItem -from faststream.broker.subscriber.proto import SubscriberProto -from faststream.broker.types import ( +from faststream._internal.context.repository import context +from faststream._internal.subscriber.call_item import HandlerItem +from faststream._internal.subscriber.call_wrapper.call import HandlerCallWrapper +from faststream._internal.subscriber.proto import SubscriberProto +from faststream._internal.subscriber.utils import ( + MultiLock, + default_filter, + get_watcher_context, + resolve_custom_func, +) +from faststream._internal.types import ( MsgType, P_HandlerParams, T_HandlerReturn, ) -from faststream.broker.utils import MultiLock, get_watcher_context, resolve_custom_func -from faststream.broker.wrapper.call import HandlerCallWrapper +from faststream._internal.utils.functions import sync_fake_context, to_async from faststream.exceptions import SetupError, StopConsume, SubscriberNotFound +from faststream.response import ensure_response from faststream.specification.asyncapi.message import parse_handler_params from faststream.specification.asyncapi.utils import to_camelcase -from faststream.utils.context.repository import context -from faststream.utils.functions import sync_fake_context, to_async if TYPE_CHECKING: from fast_depends.dependencies import Depends - from faststream.broker.message import StreamMessage - from faststream.broker.middlewares import BaseMiddleware - from faststream.broker.publisher.proto import BasePublisherProto, ProducerProto - from faststream.broker.response import Response - from faststream.broker.types import ( + from faststream._internal.basic_types import AnyDict, Decorator, LoggerProto + from faststream._internal.publisher.proto import ( + BasePublisherProto, + ProducerProto, + ) + from faststream._internal.types import ( AsyncCallable, BrokerMiddleware, CustomCallable, Filter, SubscriberMiddleware, ) - from faststream.types import AnyDict, Decorator, LoggerProto + from faststream.message import StreamMessage + from faststream.middlewares import BaseMiddleware + from faststream.response import Response class _CallOptions: __slots__ = ( - "filter", "parser", "decoder", "middlewares", @@ -62,13 +69,11 @@ class _CallOptions: def __init__( self, *, - filter: "Filter[Any]", parser: Optional["CustomCallable"], decoder: Optional["CustomCallable"], middlewares: Iterable["SubscriberMiddleware[Any]"], dependencies: Iterable["Depends"], ) -> None: - self.filter = filter self.parser = parser self.decoder = decoder self.middlewares = middlewares @@ -206,14 +211,12 @@ async def close(self) -> None: def add_call( self, *, - filter_: "Filter[Any]", parser_: Optional["CustomCallable"], decoder_: Optional["CustomCallable"], middlewares_: Iterable["SubscriberMiddleware[Any]"], dependencies_: Iterable["Depends"], ) -> Self: self._call_options = _CallOptions( - filter=filter_, parser=parser_, decoder=decoder_, middlewares=middlewares_, @@ -226,7 +229,7 @@ def __call__( self, func: None = None, *, - filter: Optional["Filter[Any]"] = None, + filter: "Filter[Any]" = default_filter, parser: Optional["CustomCallable"] = None, decoder: Optional["CustomCallable"] = None, middlewares: Iterable["SubscriberMiddleware[Any]"] = (), @@ -241,7 +244,7 @@ def __call__( self, func: Callable[P_HandlerParams, T_HandlerReturn], *, - filter: Optional["Filter[Any]"] = None, + filter: "Filter[Any]" = default_filter, parser: Optional["CustomCallable"] = None, decoder: Optional["CustomCallable"] = None, middlewares: Iterable["SubscriberMiddleware[Any]"] = (), @@ -252,7 +255,7 @@ def __call__( self, func: Optional[Callable[P_HandlerParams, T_HandlerReturn]] = None, *, - filter: Optional["Filter[Any]"] = None, + filter: "Filter[Any]" = default_filter, parser: Optional["CustomCallable"] = None, decoder: Optional["CustomCallable"] = None, middlewares: Iterable["SubscriberMiddleware[Any]"] = (), @@ -265,6 +268,7 @@ def __call__( total_deps = (*options.dependencies, *dependencies) total_middlewares = (*options.middlewares, *middlewares) + async_filter = to_async(filter) def real_wrapper( func: Callable[P_HandlerParams, T_HandlerReturn], @@ -272,11 +276,10 @@ def real_wrapper( handler = HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]( func ) - self.calls.append( HandlerItem[MsgType]( handler=handler, - filter=to_async(filter or options.filter), + filter=async_filter, item_parser=parser or options.parser, item_decoder=decoder or options.decoder, item_middlewares=total_middlewares, diff --git a/faststream/broker/utils.py b/faststream/_internal/subscriber/utils.py similarity index 91% rename from faststream/broker/utils.py rename to faststream/_internal/subscriber/utils.py index c12c3fc967..174139848d 100644 --- a/faststream/broker/utils.py +++ b/faststream/_internal/subscriber/utils.py @@ -18,21 +18,24 @@ import anyio from typing_extensions import Literal, Self, overload -from faststream.broker.acknowledgement_watcher import WatcherContext, get_watcher -from faststream.broker.types import MsgType -from faststream.utils.functions import fake_context, return_input, to_async +from faststream._internal.subscriber.acknowledgement_watcher import ( + WatcherContext, + get_watcher, +) +from faststream._internal.types import MsgType +from faststream._internal.utils.functions import fake_context, return_input, to_async if TYPE_CHECKING: from types import TracebackType - from faststream.broker.message import StreamMessage - from faststream.broker.types import ( + from faststream._internal.basic_types import LoggerProto + from faststream._internal.types import ( AsyncCallable, BrokerMiddleware, CustomCallable, SyncCallable, ) - from faststream.types import LoggerProto + from faststream.message import StreamMessage @overload diff --git a/faststream/_internal/testing/__init__.py b/faststream/_internal/testing/__init__.py new file mode 100644 index 0000000000..b4f7ac676d --- /dev/null +++ b/faststream/_internal/testing/__init__.py @@ -0,0 +1,3 @@ +from faststream._internal.testing.app import TestApp + +__all__ = ("TestApp",) diff --git a/faststream/testing/app.py b/faststream/_internal/testing/app.py similarity index 94% rename from faststream/testing/app.py rename to faststream/_internal/testing/app.py index c9fc4aa632..629558d13d 100644 --- a/faststream/testing/app.py +++ b/faststream/_internal/testing/app.py @@ -4,13 +4,13 @@ from anyio.from_thread import start_blocking_portal -from faststream.broker.core.usecase import BrokerUsecase +from faststream._internal.broker.broker import BrokerUsecase if TYPE_CHECKING: from types import TracebackType + from faststream._internal.basic_types import SettingField from faststream.app import FastStream - from faststream.types import SettingField Broker = TypeVar("Broker", bound=BrokerUsecase[Any, Any]) diff --git a/faststream/utils/ast.py b/faststream/_internal/testing/ast.py similarity index 61% rename from faststream/utils/ast.py rename to faststream/_internal/testing/ast.py index 6063dbeb7b..6120681df8 100644 --- a/faststream/utils/ast.py +++ b/faststream/_internal/testing/ast.py @@ -7,9 +7,9 @@ def is_contains_context_name(scip_name: str, name: str) -> bool: stack = traceback.extract_stack()[-3] - tree = read_source_ast(stack.filename) - node = cast(Union[ast.With, ast.AsyncWith], find_ast_node(tree, stack.lineno)) - context_calls = get_withitem_calls(node) + tree = _read_source_ast(stack.filename) + node = cast(Union[ast.With, ast.AsyncWith], _find_ast_node(tree, stack.lineno)) + context_calls = _get_withitem_calls(node) try: pos = context_calls.index(scip_name) @@ -20,34 +20,34 @@ def is_contains_context_name(scip_name: str, name: str) -> bool: @lru_cache -def read_source_ast(filename: str) -> ast.Module: +def _read_source_ast(filename: str) -> ast.Module: return ast.parse(Path(filename).read_text()) -def find_ast_node(module: ast.Module, lineno: Optional[int]) -> Optional[ast.AST]: +def _find_ast_node(module: ast.Module, lineno: Optional[int]) -> Optional[ast.AST]: if lineno is not None: # pragma: no branch for i in getattr(module, "body", ()): if i.lineno == lineno: return cast(ast.AST, i) - r = find_ast_node(i, lineno) + r = _find_ast_node(i, lineno) if r is not None: return r return None -def find_withitems(node: Union[ast.With, ast.AsyncWith]) -> Iterator[ast.withitem]: +def _find_withitems(node: Union[ast.With, ast.AsyncWith]) -> Iterator[ast.withitem]: if isinstance(node, (ast.With, ast.AsyncWith)): yield from node.items for i in getattr(node, "body", ()): - yield from find_withitems(i) + yield from _find_withitems(i) -def get_withitem_calls(node: Union[ast.With, ast.AsyncWith]) -> List[str]: +def _get_withitem_calls(node: Union[ast.With, ast.AsyncWith]) -> List[str]: return [ id - for i in find_withitems(node) + for i in _find_withitems(node) if (id := getattr(i.context_expr.func, "id", None)) # type: ignore[attr-defined] ] diff --git a/faststream/testing/broker.py b/faststream/_internal/testing/broker.py similarity index 94% rename from faststream/testing/broker.py rename to faststream/_internal/testing/broker.py index d27eacf1f0..fbe040b6ae 100644 --- a/faststream/testing/broker.py +++ b/faststream/_internal/testing/broker.py @@ -17,15 +17,15 @@ from unittest import mock from unittest.mock import MagicMock -from faststream.broker.core.usecase import BrokerUsecase -from faststream.testing.app import TestApp -from faststream.utils.ast import is_contains_context_name -from faststream.utils.functions import sync_fake_context +from faststream._internal.broker.broker import BrokerUsecase +from faststream._internal.testing.app import TestApp +from faststream._internal.testing.ast import is_contains_context_name +from faststream._internal.utils.functions import sync_fake_context if TYPE_CHECKING: from types import TracebackType - from faststream.broker.subscriber.proto import SubscriberProto + from faststream._internal.subscriber.proto import SubscriberProto Broker = TypeVar("Broker", bound=BrokerUsecase[Any, Any]) diff --git a/faststream/broker/types.py b/faststream/_internal/types.py similarity index 91% rename from faststream/broker/types.py rename to faststream/_internal/types.py index 145a37418e..11179bb503 100644 --- a/faststream/broker/types.py +++ b/faststream/_internal/types.py @@ -10,9 +10,9 @@ from typing_extensions import ParamSpec, TypeAlias -from faststream.broker.message import StreamMessage -from faststream.broker.middlewares import BaseMiddleware -from faststream.types import AsyncFunc, AsyncFuncAny +from faststream._internal.basic_types import AsyncFunc, AsyncFuncAny +from faststream.message import StreamMessage +from faststream.middlewares import BaseMiddleware MsgType = TypeVar("MsgType") StreamMsg = TypeVar("StreamMsg", bound=StreamMessage[Any]) diff --git a/faststream/_internal/utils/__init__.py b/faststream/_internal/utils/__init__.py new file mode 100644 index 0000000000..58684b7fdc --- /dev/null +++ b/faststream/_internal/utils/__init__.py @@ -0,0 +1,3 @@ +from fast_depends import inject as apply_types + +__all__ = ("apply_types",) diff --git a/faststream/_internal/utils/data.py b/faststream/_internal/utils/data.py new file mode 100644 index 0000000000..305648bb73 --- /dev/null +++ b/faststream/_internal/utils/data.py @@ -0,0 +1,12 @@ +from typing import Type, TypeVar + +from faststream._internal.basic_types import AnyDict + +TypedDictCls = TypeVar("TypedDictCls") + + +def filter_by_dict(typed_dict: Type[TypedDictCls], data: AnyDict) -> TypedDictCls: + annotations = typed_dict.__annotations__ + return typed_dict( # type: ignore + {k: v for k, v in data.items() if k in annotations} + ) diff --git a/faststream/utils/functions.py b/faststream/_internal/utils/functions.py similarity index 96% rename from faststream/utils/functions.py rename to faststream/_internal/utils/functions.py index 453c70ffc7..ebfb349444 100644 --- a/faststream/utils/functions.py +++ b/faststream/_internal/utils/functions.py @@ -16,7 +16,7 @@ from fast_depends.core import CallModel from fast_depends.utils import run_async as call_or_await -from faststream.types import F_Return, F_Spec +from faststream._internal.basic_types import F_Return, F_Spec __all__ = ( "call_or_await", diff --git a/faststream/utils/nuid.py b/faststream/_internal/utils/nuid.py similarity index 100% rename from faststream/utils/nuid.py rename to faststream/_internal/utils/nuid.py diff --git a/faststream/utils/path.py b/faststream/_internal/utils/path.py similarity index 100% rename from faststream/utils/path.py rename to faststream/_internal/utils/path.py diff --git a/faststream/annotations.py b/faststream/annotations.py index 5532daf9f5..55f3cbac98 100644 --- a/faststream/annotations.py +++ b/faststream/annotations.py @@ -1,16 +1,12 @@ import logging -from typing import TypeVar from typing_extensions import Annotated +from faststream._internal.context import ContextRepo as CR from faststream.app import FastStream as FS -from faststream.utils.context import Context -from faststream.utils.context import ContextRepo as CR -from faststream.utils.no_cast import NoCast as NC - -_NoCastType = TypeVar("_NoCastType") +from faststream.params import Context +from faststream.params import NoCast as NoCast Logger = Annotated[logging.Logger, Context("logger")] ContextRepo = Annotated[CR, Context("context")] -NoCast = Annotated[_NoCastType, NC()] FastStream = Annotated[FS, Context("app")] diff --git a/faststream/app.py b/faststream/app.py index 33c8ac450f..cea10b9449 100644 --- a/faststream/app.py +++ b/faststream/app.py @@ -13,27 +13,27 @@ ) import anyio -from typing_extensions import Annotated, ParamSpec, deprecated - -from faststream._compat import ExceptionGroup -from faststream.cli.supervisors.utils import set_exit +from typing_extensions import ParamSpec + +from faststream._internal._compat import ExceptionGroup +from faststream._internal.cli.supervisors.utils import set_exit +from faststream._internal.context import context +from faststream._internal.log.logging import logger +from faststream._internal.utils import apply_types +from faststream._internal.utils.functions import ( + drop_response_type, + fake_context, + to_async, +) from faststream.exceptions import ValidationError -from faststream.log.logging import logger from faststream.specification.proto import Application -from faststream.utils import apply_types, context -from faststream.utils.functions import drop_response_type, fake_context, to_async P_HookParams = ParamSpec("P_HookParams") T_HookReturn = TypeVar("T_HookReturn") if TYPE_CHECKING: - from faststream.broker.core.usecase import BrokerUsecase - from faststream.specification.schema.contact import Contact, ContactDict - from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict - from faststream.specification.schema.license import License, LicenseDict - from faststream.specification.schema.tag import Tag - from faststream.types import ( + from faststream._internal.basic_types import ( AnyCallable, AnyDict, AnyHttpUrl, @@ -42,6 +42,11 @@ LoggerProto, SettingField, ) + from faststream._internal.broker.broker import BrokerUsecase + from faststream.specification.schema.contact import Contact, ContactDict + from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict + from faststream.specification.schema.license import License, LicenseDict + from faststream.specification.schema.tag import Tag class FastStream(Application): @@ -156,13 +161,6 @@ async def run( self, log_level: int = logging.INFO, run_extra_options: Optional[Dict[str, "SettingField"]] = None, - sleep_time: Annotated[ - float, - deprecated( - "Deprecated in **FastStream 0.5.24**. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = 0.1, ) -> None: """Run FastStream Application.""" assert self.broker, "You should setup a broker" # nosec B101 diff --git a/faststream/asgi/app.py b/faststream/asgi/app.py index d1d84d7a55..6ab53b77cc 100644 --- a/faststream/asgi/app.py +++ b/faststream/asgi/app.py @@ -12,26 +12,26 @@ import anyio +from faststream._internal.log.logging import logger from faststream.app import FastStream from faststream.asgi.factories import make_asyncapi_asgi from faststream.asgi.response import AsgiResponse from faststream.asgi.websocket import WebSocketClose -from faststream.log.logging import logger if TYPE_CHECKING: - from faststream.asgi.types import ASGIApp, Receive, Scope, Send - from faststream.broker.core.usecase import BrokerUsecase - from faststream.specification.schema.contact import Contact, ContactDict - from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict - from faststream.specification.schema.license import License, LicenseDict - from faststream.specification.schema.tag import Tag - from faststream.types import ( + from faststream._internal.basic_types import ( AnyCallable, AnyDict, AnyHttpUrl, Lifespan, LoggerProto, ) + from faststream._internal.broker.broker import BrokerUsecase + from faststream.asgi.types import ASGIApp, Receive, Scope, Send + from faststream.specification.schema.contact import Contact, ContactDict + from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict + from faststream.specification.schema.license import License, LicenseDict + from faststream.specification.schema.tag import Tag class AsgiFastStream(FastStream): diff --git a/faststream/asgi/factories.py b/faststream/asgi/factories.py index ff4be95e47..f07df32a29 100644 --- a/faststream/asgi/factories.py +++ b/faststream/asgi/factories.py @@ -14,8 +14,8 @@ ) if TYPE_CHECKING: + from faststream._internal.broker.broker import BrokerUsecase from faststream.asgi.types import ASGIApp, Scope - from faststream.broker.core.usecase import BrokerUsecase from faststream.specification.proto import Application diff --git a/faststream/broker/fastapi/__init__.py b/faststream/broker/fastapi/__init__.py deleted file mode 100644 index 4b683d238c..0000000000 --- a/faststream/broker/fastapi/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from faststream.broker.fastapi.route import StreamMessage -from faststream.broker.fastapi.router import StreamRouter - -__all__ = ( - "StreamMessage", - "StreamRouter", -) diff --git a/faststream/broker/message.py b/faststream/broker/message.py deleted file mode 100644 index 82593e7cdc..0000000000 --- a/faststream/broker/message.py +++ /dev/null @@ -1,152 +0,0 @@ -import json -from contextlib import suppress -from dataclasses import dataclass, field -from enum import Enum -from typing import ( - TYPE_CHECKING, - Any, - Generic, - List, - Optional, - Sequence, - Tuple, - TypeVar, - Union, - cast, -) -from uuid import uuid4 - -from typing_extensions import deprecated - -from faststream._compat import dump_json, json_loads -from faststream.constants import ContentTypes -from faststream.types import EMPTY - -if TYPE_CHECKING: - from faststream.types import AnyDict, DecodedMessage, SendableMessage - -# prevent circular imports -MsgType = TypeVar("MsgType") - - -class AckStatus(str, Enum): - acked = "acked" - nacked = "nacked" - rejected = "rejected" - - -def gen_cor_id() -> str: - """Generate random string to use as ID.""" - return str(uuid4()) - - -@dataclass -class StreamMessage(Generic[MsgType]): - """Generic class to represent a stream message.""" - - raw_message: "MsgType" - - body: Union[bytes, Any] - headers: "AnyDict" = field(default_factory=dict) - batch_headers: List["AnyDict"] = field(default_factory=list) - path: "AnyDict" = field(default_factory=dict) - - content_type: Optional[str] = None - reply_to: str = "" - message_id: str = field(default_factory=gen_cor_id) # pragma: no cover - correlation_id: str = field( - default_factory=gen_cor_id # pragma: no cover - ) - - processed: bool = field(default=False, init=False) - committed: Optional[AckStatus] = field(default=None, init=False) - _decoded_body: Optional["DecodedMessage"] = field(default=None, init=False) - - async def ack(self) -> None: - self.committed = AckStatus.acked - - async def nack(self) -> None: - self.committed = AckStatus.nacked - - async def reject(self) -> None: - self.committed = AckStatus.rejected - - async def decode(self) -> Optional["DecodedMessage"]: - """Serialize the message by lazy decoder.""" - # TODO: make it lazy after `decoded_body` removed - return self._decoded_body - - @property - @deprecated( - "Deprecated in **FastStream 0.5.19**. " - "Please, use `decode` lazy method instead. " - "Argument will be removed in **FastStream 0.6.0**.", - category=DeprecationWarning, - stacklevel=1, - ) - def decoded_body(self) -> Optional["DecodedMessage"]: - return self._decoded_body - - @decoded_body.setter - @deprecated( - "Deprecated in **FastStream 0.5.19**. " - "Please, use `decode` lazy method instead. " - "Argument will be removed in **FastStream 0.6.0**.", - category=DeprecationWarning, - stacklevel=1, - ) - def decoded_body(self, value: Optional["DecodedMessage"]) -> None: - self._decoded_body = value - - -def decode_message(message: "StreamMessage[Any]") -> "DecodedMessage": - """Decodes a message.""" - body: Any = getattr(message, "body", message) - m: DecodedMessage = body - - if (content_type := getattr(message, "content_type", EMPTY)) is not EMPTY: - content_type = cast(Optional[str], content_type) - - if not content_type: - with suppress(json.JSONDecodeError, UnicodeDecodeError): - m = json_loads(body) - - elif ContentTypes.text.value in content_type: - m = body.decode() - - elif ContentTypes.json.value in content_type: - m = json_loads(body) - - else: - with suppress(json.JSONDecodeError, UnicodeDecodeError): - m = json_loads(body) - - return m - - -def encode_message( - msg: Union[Sequence["SendableMessage"], "SendableMessage"], -) -> Tuple[bytes, Optional[str]]: - """Encodes a message.""" - if msg is None: - return ( - b"", - None, - ) - - if isinstance(msg, bytes): - return ( - msg, - None, - ) - - if isinstance(msg, str): - return ( - msg.encode(), - ContentTypes.text.value, - ) - - return ( - dump_json(msg), - ContentTypes.json.value, - ) diff --git a/faststream/broker/middlewares/__init__.py b/faststream/broker/middlewares/__init__.py deleted file mode 100644 index c10aa33c3d..0000000000 --- a/faststream/broker/middlewares/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from faststream.broker.middlewares.base import BaseMiddleware -from faststream.broker.middlewares.exception import ExceptionMiddleware - -__all__ = ("BaseMiddleware", "ExceptionMiddleware") diff --git a/faststream/broker/proto.py b/faststream/broker/proto.py deleted file mode 100644 index c1083a92ba..0000000000 --- a/faststream/broker/proto.py +++ /dev/null @@ -1,12 +0,0 @@ -from abc import abstractmethod -from typing import Hashable, Protocol - - -class SetupAble(Protocol): - @abstractmethod - def setup(self) -> None: ... - - -class EndpointProto(SetupAble, Hashable, Protocol): - @abstractmethod - def add_prefix(self, prefix: str) -> None: ... diff --git a/faststream/confluent/__init__.py b/faststream/confluent/__init__.py index a7961b35b3..77c1b20280 100644 --- a/faststream/confluent/__init__.py +++ b/faststream/confluent/__init__.py @@ -1,10 +1,10 @@ +from faststream._internal.testing.app import TestApp from faststream.confluent.annotations import KafkaMessage from faststream.confluent.broker import KafkaBroker from faststream.confluent.response import KafkaResponse from faststream.confluent.router import KafkaPublisher, KafkaRoute, KafkaRouter from faststream.confluent.schemas import TopicPartition from faststream.confluent.testing import TestKafkaBroker -from faststream.testing.app import TestApp __all__ = ( "KafkaBroker", diff --git a/faststream/confluent/annotations.py b/faststream/confluent/annotations.py index 27d0b68688..1d7739445a 100644 --- a/faststream/confluent/annotations.py +++ b/faststream/confluent/annotations.py @@ -1,10 +1,11 @@ from typing_extensions import Annotated -from faststream.annotations import ContextRepo, Logger, NoCast +from faststream._internal.context import Context +from faststream.annotations import ContextRepo, Logger from faststream.confluent.broker import KafkaBroker as KB from faststream.confluent.message import KafkaMessage as KM from faststream.confluent.publisher.producer import AsyncConfluentFastProducer -from faststream.utils.context import Context +from faststream.params import NoCast __all__ = ( "Logger", diff --git a/faststream/confluent/broker/broker.py b/faststream/confluent/broker/broker.py index 15b9814f45..7b31cdf5ae 100644 --- a/faststream/confluent/broker/broker.py +++ b/faststream/confluent/broker/broker.py @@ -19,7 +19,8 @@ from typing_extensions import Annotated, Doc, override from faststream.__about__ import SERVICE_NAME -from faststream.broker.message import gen_cor_id +from faststream._internal.constants import EMPTY +from faststream._internal.utils.data import filter_by_dict from faststream.confluent.broker.logging import KafkaLoggingBroker from faststream.confluent.broker.registrator import KafkaRegistrator from faststream.confluent.client import ( @@ -31,8 +32,7 @@ from faststream.confluent.schemas.params import ConsumerConnectionParams from faststream.confluent.security import parse_security from faststream.exceptions import NOT_CONNECTED_YET -from faststream.types import EMPTY -from faststream.utils.data import filter_by_dict +from faststream.message import gen_cor_id if TYPE_CHECKING: from types import TracebackType @@ -40,20 +40,20 @@ from confluent_kafka import Message from fast_depends.dependencies import Depends - from faststream.broker.types import ( - BrokerMiddleware, - CustomCallable, - ) - from faststream.confluent.config import ConfluentConfig - from faststream.security import BaseSecurity - from faststream.specification.schema.tag import Tag, TagDict - from faststream.types import ( + from faststream._internal.basic_types import ( AnyDict, AsyncFunc, Decorator, LoggerProto, SendableMessage, ) + from faststream._internal.types import ( + BrokerMiddleware, + CustomCallable, + ) + from faststream.confluent.config import ConfluentConfig + from faststream.security import BaseSecurity + from faststream.specification.schema.tag import Tag, TagDict Partition = TypeVar("Partition") diff --git a/faststream/confluent/broker/logging.py b/faststream/confluent/broker/logging.py index 758e4285ba..6c549f5dc6 100644 --- a/faststream/confluent/broker/logging.py +++ b/faststream/confluent/broker/logging.py @@ -1,15 +1,15 @@ import logging from typing import TYPE_CHECKING, Any, Callable, ClassVar, Optional, Tuple, Union -from faststream.broker.core.usecase import BrokerUsecase +from faststream._internal.broker.broker import BrokerUsecase +from faststream._internal.constants import EMPTY +from faststream._internal.log.logging import get_broker_logger from faststream.confluent.client import AsyncConfluentConsumer -from faststream.log.logging import get_broker_logger -from faststream.types import EMPTY if TYPE_CHECKING: import confluent_kafka - from faststream.types import LoggerProto + from faststream._internal.basic_types import LoggerProto class KafkaLoggingBroker( diff --git a/faststream/confluent/broker/registrator.py b/faststream/confluent/broker/registrator.py index f787a3bcfb..c674166124 100644 --- a/faststream/confluent/broker/registrator.py +++ b/faststream/confluent/broker/registrator.py @@ -12,10 +12,9 @@ overload, ) -from typing_extensions import Annotated, Doc, deprecated, override +from typing_extensions import Annotated, Doc, override -from faststream.broker.core.abc import ABCBroker -from faststream.broker.utils import default_filter +from faststream._internal.broker.abc_broker import ABCBroker from faststream.confluent.publisher.publisher import SpecificationPublisher from faststream.confluent.subscriber.factory import create_subscriber from faststream.exceptions import SetupError @@ -24,9 +23,8 @@ from confluent_kafka import Message from fast_depends.dependencies import Depends - from faststream.broker.types import ( + from faststream._internal.types import ( CustomCallable, - Filter, PublisherMiddleware, SubscriberMiddleware, ) @@ -298,17 +296,6 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - "Filter[KafkaMessage]", - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, retry: Annotated[ bool, Doc("Whether to `nack` message at processing exception."), @@ -580,17 +567,6 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - "Filter[KafkaMessage]", - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, retry: Annotated[ bool, Doc("Whether to `nack` message at processing exception."), @@ -862,17 +838,6 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - "Filter[KafkaMessage]", - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, retry: Annotated[ bool, Doc("Whether to `nack` message at processing exception."), @@ -1147,17 +1112,6 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - "Filter[KafkaMessage]", - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, retry: Annotated[ bool, Doc("Whether to `nack` message at processing exception."), @@ -1235,7 +1189,6 @@ def subscriber( if batch: return cast("SpecificationBatchSubscriber", subscriber).add_call( - filter_=filter, parser_=parser or self._parser, decoder_=decoder or self._decoder, dependencies_=dependencies, @@ -1243,7 +1196,6 @@ def subscriber( ) else: return cast("SpecificationDefaultSubscriber", subscriber).add_call( - filter_=filter, parser_=parser or self._parser, decoder_=decoder or self._decoder, dependencies_=dependencies, diff --git a/faststream/confluent/client.py b/faststream/confluent/client.py index 3bf60f205d..2c62873ef3 100644 --- a/faststream/confluent/client.py +++ b/faststream/confluent/client.py @@ -19,17 +19,17 @@ from confluent_kafka import Consumer, KafkaError, KafkaException, Message, Producer from confluent_kafka.admin import AdminClient, NewTopic +from faststream._internal.constants import EMPTY +from faststream._internal.log import logger as faststream_logger +from faststream._internal.utils.functions import call_or_await from faststream.confluent import config as config_module from faststream.confluent.schemas import TopicPartition from faststream.exceptions import SetupError -from faststream.log import logger as faststream_logger -from faststream.types import EMPTY -from faststream.utils.functions import call_or_await if TYPE_CHECKING: from typing_extensions import NotRequired, TypedDict - from faststream.types import AnyDict, LoggerProto + from faststream._internal.basic_types import AnyDict, LoggerProto class _SendKwargs(TypedDict): value: Optional[Union[str, bytes]] diff --git a/faststream/confluent/config.py b/faststream/confluent/config.py index 16de28b3f1..4474ff300a 100644 --- a/faststream/confluent/config.py +++ b/faststream/confluent/config.py @@ -4,7 +4,7 @@ from typing_extensions import TypedDict if TYPE_CHECKING: - from faststream.types import AnyDict + from faststream._internal.basic_types import AnyDict class BuiltinFeatures(str, Enum): diff --git a/faststream/confluent/fastapi/__init__.py b/faststream/confluent/fastapi/__init__.py index 11fcd167df..d29709ebb8 100644 --- a/faststream/confluent/fastapi/__init__.py +++ b/faststream/confluent/fastapi/__init__.py @@ -1,6 +1,6 @@ from typing_extensions import Annotated -from faststream.broker.fastapi.context import Context, ContextRepo, Logger +from faststream._internal.fastapi.context import Context, ContextRepo, Logger from faststream.confluent.broker import KafkaBroker as KB from faststream.confluent.fastapi.fastapi import KafkaRouter from faststream.confluent.message import KafkaMessage as KM diff --git a/faststream/confluent/fastapi/fastapi.py b/faststream/confluent/fastapi/fastapi.py index 6339a7c862..b792c63a5d 100644 --- a/faststream/confluent/fastapi/fastapi.py +++ b/faststream/confluent/fastapi/fastapi.py @@ -26,10 +26,9 @@ from typing_extensions import Annotated, Doc, deprecated, override from faststream.__about__ import SERVICE_NAME -from faststream.broker.fastapi.router import StreamRouter -from faststream.broker.utils import default_filter +from faststream._internal.constants import EMPTY +from faststream._internal.fastapi.router import StreamRouter from faststream.confluent.broker.broker import KafkaBroker as KB -from faststream.types import EMPTY if TYPE_CHECKING: from enum import Enum @@ -38,10 +37,10 @@ from fastapi.types import IncEx from starlette.types import ASGIApp, Lifespan - from faststream.broker.types import ( + from faststream._internal.basic_types import AnyDict, LoggerProto + from faststream._internal.types import ( BrokerMiddleware, CustomCallable, - Filter, PublisherMiddleware, SubscriberMiddleware, ) @@ -58,7 +57,6 @@ ) from faststream.security import BaseSecurity from faststream.specification.schema.tag import Tag, TagDict - from faststream.types import AnyDict, LoggerProto Partition = TypeVar("Partition") @@ -839,17 +837,6 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - "Filter[KafkaMessage]", - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, retry: Annotated[ bool, Doc("Whether to `nack` message at processing exception."), @@ -1244,17 +1231,6 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - "Filter[KafkaMessage]", - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, # Specification args title: Annotated[ Optional[str], @@ -1635,17 +1611,6 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - "Filter[KafkaMessage]", - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, retry: Annotated[ bool, Doc("Whether to `nack` message at processing exception."), @@ -2043,17 +2008,6 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - "Filter[KafkaMessage]", - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, retry: Annotated[ bool, Doc("Whether to `nack` message at processing exception."), @@ -2237,7 +2191,6 @@ def subscriber( parser=parser, decoder=decoder, middlewares=middlewares, - filter=filter, retry=retry, no_ack=no_ack, no_reply=no_reply, diff --git a/faststream/confluent/message.py b/faststream/confluent/message.py index 14fe05ae7b..6365932ff4 100644 --- a/faststream/confluent/message.py +++ b/faststream/confluent/message.py @@ -1,6 +1,6 @@ from typing import TYPE_CHECKING, Any, Optional, Protocol, Tuple, Union -from faststream.broker.message import StreamMessage +from faststream.message import StreamMessage if TYPE_CHECKING: from confluent_kafka import Message diff --git a/faststream/confluent/opentelemetry/provider.py b/faststream/confluent/opentelemetry/provider.py index 3c157851d9..ea1d96cac7 100644 --- a/faststream/confluent/opentelemetry/provider.py +++ b/faststream/confluent/opentelemetry/provider.py @@ -2,15 +2,15 @@ from opentelemetry.semconv.trace import SpanAttributes -from faststream.broker.types import MsgType +from faststream._internal.types import MsgType from faststream.opentelemetry import TelemetrySettingsProvider from faststream.opentelemetry.consts import MESSAGING_DESTINATION_PUBLISH_NAME if TYPE_CHECKING: from confluent_kafka import Message - from faststream.broker.message import StreamMessage - from faststream.types import AnyDict + from faststream._internal.basic_types import AnyDict + from faststream.message import StreamMessage class BaseConfluentTelemetrySettingsProvider(TelemetrySettingsProvider[MsgType]): diff --git a/faststream/confluent/parser.py b/faststream/confluent/parser.py index 24f3de19ce..f868cab0b1 100644 --- a/faststream/confluent/parser.py +++ b/faststream/confluent/parser.py @@ -1,15 +1,15 @@ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Sequence, Tuple, Union -from faststream.broker.message import decode_message, gen_cor_id +from faststream._internal.context.repository import context from faststream.confluent.message import FAKE_CONSUMER, KafkaMessage -from faststream.utils.context.repository import context +from faststream.message import decode_message if TYPE_CHECKING: from confluent_kafka import Message - from faststream.broker.message import StreamMessage + from faststream._internal.basic_types import DecodedMessage from faststream.confluent.subscriber.usecase import LogicSubscriber - from faststream.types import DecodedMessage + from faststream.message import StreamMessage class AsyncConfluentParser: @@ -34,7 +34,7 @@ async def parse_message( reply_to=headers.get("reply_to", ""), content_type=headers.get("content-type"), message_id=f"{offset}-{timestamp}", - correlation_id=headers.get("correlation_id", gen_cor_id()), + correlation_id=headers.get("correlation_id"), raw_message=message, consumer=getattr(handler, "consumer", None) or FAKE_CONSUMER, is_manual=getattr(handler, "is_manual", True), @@ -68,7 +68,7 @@ async def parse_message_batch( reply_to=headers.get("reply_to", ""), content_type=headers.get("content-type"), message_id=f"{first.offset()}-{last.offset()}-{first_timestamp}", - correlation_id=headers.get("correlation_id", gen_cor_id()), + correlation_id=headers.get("correlation_id"), raw_message=message, consumer=getattr(handler, "consumer", None) or FAKE_CONSUMER, is_manual=getattr(handler, "is_manual", True), diff --git a/faststream/confluent/publisher/producer.py b/faststream/confluent/publisher/producer.py index 6e3d25259e..bb162d720f 100644 --- a/faststream/confluent/publisher/producer.py +++ b/faststream/confluent/publisher/producer.py @@ -2,16 +2,16 @@ from typing_extensions import override -from faststream.broker.message import encode_message -from faststream.broker.publisher.proto import ProducerProto -from faststream.broker.utils import resolve_custom_func +from faststream._internal.publisher.proto import ProducerProto +from faststream._internal.subscriber.utils import resolve_custom_func from faststream.confluent.parser import AsyncConfluentParser from faststream.exceptions import OperationForbiddenError +from faststream.message import encode_message if TYPE_CHECKING: - from faststream.broker.types import CustomCallable + from faststream._internal.basic_types import SendableMessage + from faststream._internal.types import CustomCallable from faststream.confluent.client import AsyncConfluentProducer - from faststream.types import SendableMessage class AsyncConfluentFastProducer(ProducerProto): diff --git a/faststream/confluent/publisher/publisher.py b/faststream/confluent/publisher/publisher.py index 7be876ddf8..f66dc21c26 100644 --- a/faststream/confluent/publisher/publisher.py +++ b/faststream/confluent/publisher/publisher.py @@ -12,7 +12,7 @@ from typing_extensions import override -from faststream.broker.types import MsgType +from faststream._internal.types import MsgType from faststream.confluent.publisher.usecase import ( BatchPublisher, DefaultPublisher, @@ -28,7 +28,7 @@ if TYPE_CHECKING: from confluent_kafka import Message as ConfluentMsg - from faststream.broker.types import BrokerMiddleware, PublisherMiddleware + from faststream._internal.types import BrokerMiddleware, PublisherMiddleware class SpecificationPublisher(LogicPublisher[MsgType]): diff --git a/faststream/confluent/publisher/usecase.py b/faststream/confluent/publisher/usecase.py index 60fc8329df..d745c9144a 100644 --- a/faststream/confluent/publisher/usecase.py +++ b/faststream/confluent/publisher/usecase.py @@ -17,17 +17,17 @@ from confluent_kafka import Message from typing_extensions import override -from faststream.broker.message import gen_cor_id -from faststream.broker.publisher.usecase import PublisherUsecase -from faststream.broker.types import MsgType +from faststream._internal.publisher.usecase import PublisherUsecase +from faststream._internal.types import MsgType +from faststream._internal.utils.functions import return_input from faststream.exceptions import NOT_CONNECTED_YET -from faststream.utils.functions import return_input +from faststream.message import gen_cor_id if TYPE_CHECKING: - from faststream.broker.types import BrokerMiddleware, PublisherMiddleware + from faststream._internal.basic_types import AnyDict, AsyncFunc, SendableMessage + from faststream._internal.types import BrokerMiddleware, PublisherMiddleware from faststream.confluent.message import KafkaMessage from faststream.confluent.publisher.producer import AsyncConfluentFastProducer - from faststream.types import AnyDict, AsyncFunc, SendableMessage class LogicPublisher(PublisherUsecase[MsgType]): diff --git a/faststream/confluent/response.py b/faststream/confluent/response.py index da420aa286..353ac8251a 100644 --- a/faststream/confluent/response.py +++ b/faststream/confluent/response.py @@ -2,10 +2,10 @@ from typing_extensions import override -from faststream.broker.response import Response +from faststream.response import Response if TYPE_CHECKING: - from faststream.types import AnyDict, SendableMessage + from faststream._internal.basic_types import AnyDict, SendableMessage class KafkaResponse(Response): diff --git a/faststream/confluent/router.py b/faststream/confluent/router.py index 2c66a38992..c7b89bf226 100644 --- a/faststream/confluent/router.py +++ b/faststream/confluent/router.py @@ -12,26 +12,28 @@ Union, ) -from typing_extensions import Annotated, Doc, deprecated +from typing_extensions import Annotated, Doc -from faststream.broker.router import ArgsContainer, BrokerRouter, SubscriberRoute -from faststream.broker.utils import default_filter +from faststream._internal.broker.router import ( + ArgsContainer, + BrokerRouter, + SubscriberRoute, +) from faststream.confluent.broker.registrator import KafkaRegistrator if TYPE_CHECKING: from confluent_kafka import Message from fast_depends.dependencies import Depends - from faststream.broker.types import ( + from faststream._internal.basic_types import SendableMessage + from faststream._internal.types import ( BrokerMiddleware, CustomCallable, - Filter, PublisherMiddleware, SubscriberMiddleware, ) from faststream.confluent.message import KafkaMessage from faststream.confluent.schemas import TopicPartition - from faststream.types import SendableMessage class KafkaPublisher(ArgsContainer): @@ -381,17 +383,6 @@ def __init__( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - "Filter[KafkaMessage]", - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, retry: Annotated[ bool, Doc("Whether to `nack` message at processing exception."), @@ -451,7 +442,6 @@ def __init__( parser=parser, decoder=decoder, middlewares=middlewares, - filter=filter, no_reply=no_reply, # AsyncAPI args title=title, diff --git a/faststream/confluent/security.py b/faststream/confluent/security.py index 4e3e0c0e48..7648acc6a4 100644 --- a/faststream/confluent/security.py +++ b/faststream/confluent/security.py @@ -12,7 +12,7 @@ ) if TYPE_CHECKING: - from faststream.types import AnyDict + from faststream._internal.basic_types import AnyDict def parse_security(security: Optional[BaseSecurity]) -> "AnyDict": diff --git a/faststream/confluent/subscriber/factory.py b/faststream/confluent/subscriber/factory.py index d846f18861..b6c0068c3d 100644 --- a/faststream/confluent/subscriber/factory.py +++ b/faststream/confluent/subscriber/factory.py @@ -18,9 +18,9 @@ from confluent_kafka import Message as ConfluentMsg from fast_depends.dependencies import Depends - from faststream.broker.types import BrokerMiddleware + from faststream._internal.basic_types import AnyDict + from faststream._internal.types import BrokerMiddleware from faststream.confluent.schemas import TopicPartition - from faststream.types import AnyDict @overload diff --git a/faststream/confluent/subscriber/subscriber.py b/faststream/confluent/subscriber/subscriber.py index b706a075bb..281f222a12 100644 --- a/faststream/confluent/subscriber/subscriber.py +++ b/faststream/confluent/subscriber/subscriber.py @@ -4,7 +4,7 @@ Tuple, ) -from faststream.broker.types import MsgType +from faststream._internal.types import MsgType from faststream.confluent.subscriber.usecase import ( BatchSubscriber, DefaultSubscriber, diff --git a/faststream/confluent/subscriber/usecase.py b/faststream/confluent/subscriber/usecase.py index 3540be9bdf..84480c3018 100644 --- a/faststream/confluent/subscriber/usecase.py +++ b/faststream/confluent/subscriber/usecase.py @@ -16,25 +16,25 @@ from confluent_kafka import KafkaException, Message from typing_extensions import override -from faststream.broker.publisher.fake import FakePublisher -from faststream.broker.subscriber.usecase import SubscriberUsecase -from faststream.broker.types import MsgType -from faststream.broker.utils import process_msg +from faststream._internal.publisher.fake import FakePublisher +from faststream._internal.subscriber.usecase import SubscriberUsecase +from faststream._internal.subscriber.utils import process_msg +from faststream._internal.types import MsgType from faststream.confluent.parser import AsyncConfluentParser from faststream.confluent.schemas import TopicPartition if TYPE_CHECKING: from fast_depends.dependencies import Depends - from faststream.broker.message import StreamMessage - from faststream.broker.publisher.proto import ProducerProto - from faststream.broker.types import ( + from faststream._internal.basic_types import AnyDict, Decorator, LoggerProto + from faststream._internal.publisher.proto import ProducerProto + from faststream._internal.types import ( AsyncCallable, BrokerMiddleware, CustomCallable, ) from faststream.confluent.client import AsyncConfluentConsumer - from faststream.types import AnyDict, Decorator, LoggerProto + from faststream.message import StreamMessage class LogicSubscriber(ABC, SubscriberUsecase[MsgType]): diff --git a/faststream/confluent/testing.py b/faststream/confluent/testing.py index 9405eaf5d0..62cfe93354 100644 --- a/faststream/confluent/testing.py +++ b/faststream/confluent/testing.py @@ -5,8 +5,9 @@ import anyio from typing_extensions import override -from faststream.broker.message import encode_message, gen_cor_id -from faststream.broker.utils import resolve_custom_func +from faststream._internal.subscriber.utils import resolve_custom_func +from faststream._internal.testing.broker import TestBroker +from faststream._internal.utils.functions import timeout_scope from faststream.confluent.broker import KafkaBroker from faststream.confluent.parser import AsyncConfluentParser from faststream.confluent.publisher.producer import AsyncConfluentFastProducer @@ -14,13 +15,12 @@ from faststream.confluent.schemas import TopicPartition from faststream.confluent.subscriber.subscriber import SpecificationBatchSubscriber from faststream.exceptions import SubscriberNotFound -from faststream.testing.broker import TestBroker -from faststream.utils.functions import timeout_scope +from faststream.message import encode_message, gen_cor_id if TYPE_CHECKING: + from faststream._internal.basic_types import SendableMessage from faststream.confluent.publisher.publisher import SpecificationPublisher from faststream.confluent.subscriber.usecase import LogicSubscriber - from faststream.types import SendableMessage __all__ = ("TestKafkaBroker",) diff --git a/faststream/constants.py b/faststream/constants.py deleted file mode 100644 index d3f7c3e25d..0000000000 --- a/faststream/constants.py +++ /dev/null @@ -1,10 +0,0 @@ -from enum import Enum - -ContentType = str - - -class ContentTypes(str, Enum): - """A class to represent content types.""" - - text = "text/plain" - json = "application/json" diff --git a/faststream/exceptions.py b/faststream/exceptions.py index dfa62f5699..f7774ed818 100644 --- a/faststream/exceptions.py +++ b/faststream/exceptions.py @@ -1,3 +1,4 @@ +from pprint import pformat from typing import Any, Iterable @@ -110,6 +111,22 @@ class SubscriberNotFound(FastStreamException): """Raises as a service message or in tests.""" +class ContextError(FastStreamException, KeyError): + """Raises if context exception occurred.""" + + def __init__(self, context: Any, field: str) -> None: + self.context = context + self.field = field + + def __str__(self) -> str: + return "".join( + ( + f"\n Key `{self.field}` not found in the context\n ", + pformat(self.context), + ) + ) + + WRONG_PUBLISH_ARGS = SetupError( "You should use `reply_to` to send response to long-living queue " "and `rpc` to get response in sync mode." diff --git a/faststream/kafka/__init__.py b/faststream/kafka/__init__.py index dc5f5e3cf6..8d84e4b374 100644 --- a/faststream/kafka/__init__.py +++ b/faststream/kafka/__init__.py @@ -1,11 +1,11 @@ from aiokafka import TopicPartition +from faststream._internal.testing.app import TestApp from faststream.kafka.annotations import KafkaMessage from faststream.kafka.broker import KafkaBroker from faststream.kafka.response import KafkaResponse from faststream.kafka.router import KafkaPublisher, KafkaRoute, KafkaRouter from faststream.kafka.testing import TestKafkaBroker -from faststream.testing.app import TestApp __all__ = ( "KafkaBroker", diff --git a/faststream/kafka/annotations.py b/faststream/kafka/annotations.py index efca62b227..6f38b5f5cc 100644 --- a/faststream/kafka/annotations.py +++ b/faststream/kafka/annotations.py @@ -1,11 +1,12 @@ from aiokafka import AIOKafkaConsumer from typing_extensions import Annotated -from faststream.annotations import ContextRepo, Logger, NoCast +from faststream._internal.context import Context +from faststream.annotations import ContextRepo, Logger from faststream.kafka.broker import KafkaBroker as KB from faststream.kafka.message import KafkaMessage as KM from faststream.kafka.publisher.producer import AioKafkaFastProducer -from faststream.utils.context import Context +from faststream.params import NoCast __all__ = ( "Logger", diff --git a/faststream/kafka/broker/broker.py b/faststream/kafka/broker/broker.py index c9247d684b..156bae9964 100644 --- a/faststream/kafka/broker/broker.py +++ b/faststream/kafka/broker/broker.py @@ -22,15 +22,15 @@ from typing_extensions import Annotated, Doc, override from faststream.__about__ import SERVICE_NAME -from faststream.broker.message import gen_cor_id +from faststream._internal.constants import EMPTY +from faststream._internal.utils.data import filter_by_dict from faststream.exceptions import NOT_CONNECTED_YET from faststream.kafka.broker.logging import KafkaLoggingBroker from faststream.kafka.broker.registrator import KafkaRegistrator from faststream.kafka.publisher.producer import AioKafkaFastProducer from faststream.kafka.schemas.params import ConsumerConnectionParams from faststream.kafka.security import parse_security -from faststream.types import EMPTY -from faststream.utils.data import filter_by_dict +from faststream.message import gen_cor_id Partition = TypeVar("Partition") @@ -43,19 +43,19 @@ from fast_depends.dependencies import Depends from typing_extensions import TypedDict, Unpack - from faststream.broker.types import ( - BrokerMiddleware, - CustomCallable, - ) - from faststream.security import BaseSecurity - from faststream.specification.schema.tag import Tag, TagDict - from faststream.types import ( + from faststream._internal.basic_types import ( AnyDict, AsyncFunc, Decorator, LoggerProto, SendableMessage, ) + from faststream._internal.types import ( + BrokerMiddleware, + CustomCallable, + ) + from faststream.security import BaseSecurity + from faststream.specification.schema.tag import Tag, TagDict class KafkaInitKwargs(TypedDict, total=False): request_timeout_ms: Annotated[ diff --git a/faststream/kafka/broker/logging.py b/faststream/kafka/broker/logging.py index e7e534e98b..bb7fd2c6e7 100644 --- a/faststream/kafka/broker/logging.py +++ b/faststream/kafka/broker/logging.py @@ -1,14 +1,14 @@ import logging from typing import TYPE_CHECKING, Any, Callable, ClassVar, Optional, Tuple, Union -from faststream.broker.core.usecase import BrokerUsecase -from faststream.log.logging import get_broker_logger -from faststream.types import EMPTY +from faststream._internal.broker.broker import BrokerUsecase +from faststream._internal.constants import EMPTY +from faststream._internal.log.logging import get_broker_logger if TYPE_CHECKING: import aiokafka - from faststream.types import LoggerProto + from faststream._internal.basic_types import LoggerProto class KafkaLoggingBroker( diff --git a/faststream/kafka/broker/registrator.py b/faststream/kafka/broker/registrator.py index dba09de7eb..08bb18be47 100644 --- a/faststream/kafka/broker/registrator.py +++ b/faststream/kafka/broker/registrator.py @@ -15,10 +15,9 @@ from aiokafka import ConsumerRecord from aiokafka.coordinator.assignors.roundrobin import RoundRobinPartitionAssignor -from typing_extensions import Annotated, Doc, deprecated, override +from typing_extensions import Annotated, Doc, override -from faststream.broker.core.abc import ABCBroker -from faststream.broker.utils import default_filter +from faststream._internal.broker.abc_broker import ABCBroker from faststream.kafka.publisher.publisher import SpecificationPublisher from faststream.kafka.subscriber.factory import create_subscriber @@ -28,9 +27,8 @@ from aiokafka.coordinator.assignors.abstract import AbstractPartitionAssignor from fast_depends.dependencies import Depends - from faststream.broker.types import ( + from faststream._internal.types import ( CustomCallable, - Filter, PublisherMiddleware, SubscriberMiddleware, ) @@ -402,17 +400,6 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - "Filter[KafkaMessage]", - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, retry: Annotated[ bool, Doc("Whether to `nack` message at processing exception."), @@ -783,17 +770,6 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - "Filter[KafkaMessage]", - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, retry: Annotated[ bool, Doc("Whether to `nack` message at processing exception."), @@ -1164,17 +1140,6 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - "Filter[KafkaMessage]", - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, retry: Annotated[ bool, Doc("Whether to `nack` message at processing exception."), @@ -1548,17 +1513,6 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - "Filter[KafkaMessage]", - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, retry: Annotated[ bool, Doc("Whether to `nack` message at processing exception."), @@ -1640,7 +1594,6 @@ def subscriber( if batch: return cast("SpecificationBatchSubscriber", subscriber).add_call( - filter_=filter, parser_=parser or self._parser, decoder_=decoder or self._decoder, dependencies_=dependencies, @@ -1649,7 +1602,6 @@ def subscriber( else: return cast("SpecificationDefaultSubscriber", subscriber).add_call( - filter_=filter, parser_=parser or self._parser, decoder_=decoder or self._decoder, dependencies_=dependencies, diff --git a/faststream/kafka/fastapi/__init__.py b/faststream/kafka/fastapi/__init__.py index 629539ba98..07c82c6ccf 100644 --- a/faststream/kafka/fastapi/__init__.py +++ b/faststream/kafka/fastapi/__init__.py @@ -1,6 +1,6 @@ from typing_extensions import Annotated -from faststream.broker.fastapi.context import Context, ContextRepo, Logger +from faststream._internal.fastapi.context import Context, ContextRepo, Logger from faststream.kafka.broker import KafkaBroker as KB from faststream.kafka.fastapi.fastapi import KafkaRouter from faststream.kafka.message import KafkaMessage as KM diff --git a/faststream/kafka/fastapi/fastapi.py b/faststream/kafka/fastapi/fastapi.py index 15faa6a16a..d98ed0cc1c 100644 --- a/faststream/kafka/fastapi/fastapi.py +++ b/faststream/kafka/fastapi/fastapi.py @@ -29,10 +29,9 @@ from typing_extensions import Annotated, Doc, deprecated, override from faststream.__about__ import SERVICE_NAME -from faststream.broker.fastapi.router import StreamRouter -from faststream.broker.utils import default_filter +from faststream._internal.constants import EMPTY +from faststream._internal.fastapi.router import StreamRouter from faststream.kafka.broker.broker import KafkaBroker as KB -from faststream.types import EMPTY if TYPE_CHECKING: from asyncio import AbstractEventLoop @@ -45,10 +44,10 @@ from fastapi.types import IncEx from starlette.types import ASGIApp, Lifespan - from faststream.broker.types import ( + from faststream._internal.basic_types import AnyDict, LoggerProto + from faststream._internal.types import ( BrokerMiddleware, CustomCallable, - Filter, PublisherMiddleware, SubscriberMiddleware, ) @@ -63,7 +62,6 @@ ) from faststream.security import BaseSecurity from faststream.specification.schema.tag import Tag, TagDict - from faststream.types import AnyDict, LoggerProto Partition = TypeVar("Partition") @@ -950,17 +948,6 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - "Filter[KafkaMessage]", - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, retry: Annotated[ bool, Doc("Whether to `nack` message at processing exception."), @@ -1451,17 +1438,6 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - "Filter[KafkaMessage]", - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, retry: Annotated[ bool, Doc("Whether to `nack` message at processing exception."), @@ -1952,17 +1928,6 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - "Filter[KafkaMessage]", - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, retry: Annotated[ bool, Doc("Whether to `nack` message at processing exception."), @@ -2456,17 +2421,6 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - "Filter[KafkaMessage]", - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, retry: Annotated[ bool, Doc("Whether to `nack` message at processing exception."), @@ -2657,7 +2611,6 @@ def subscriber( parser=parser, decoder=decoder, middlewares=middlewares, - filter=filter, retry=retry, no_ack=no_ack, no_reply=no_reply, diff --git a/faststream/kafka/message.py b/faststream/kafka/message.py index d83a57bf6a..1bc750a77c 100644 --- a/faststream/kafka/message.py +++ b/faststream/kafka/message.py @@ -2,7 +2,7 @@ from aiokafka import TopicPartition as AIOKafkaTopicPartition -from faststream.broker.message import StreamMessage +from faststream.message import StreamMessage if TYPE_CHECKING: from aiokafka import ConsumerRecord diff --git a/faststream/kafka/opentelemetry/provider.py b/faststream/kafka/opentelemetry/provider.py index b90d82c9fd..9a2d3eec45 100644 --- a/faststream/kafka/opentelemetry/provider.py +++ b/faststream/kafka/opentelemetry/provider.py @@ -2,15 +2,15 @@ from opentelemetry.semconv.trace import SpanAttributes -from faststream.broker.types import MsgType +from faststream._internal.types import MsgType from faststream.opentelemetry import TelemetrySettingsProvider from faststream.opentelemetry.consts import MESSAGING_DESTINATION_PUBLISH_NAME if TYPE_CHECKING: from aiokafka import ConsumerRecord - from faststream.broker.message import StreamMessage - from faststream.types import AnyDict + from faststream._internal.basic_types import AnyDict + from faststream.message import StreamMessage class BaseKafkaTelemetrySettingsProvider(TelemetrySettingsProvider[MsgType]): diff --git a/faststream/kafka/parser.py b/faststream/kafka/parser.py index 92ad8c163f..c4ff44c0f2 100644 --- a/faststream/kafka/parser.py +++ b/faststream/kafka/parser.py @@ -1,17 +1,17 @@ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Type, cast -from faststream.broker.message import decode_message, gen_cor_id +from faststream._internal.context.repository import context from faststream.kafka.message import FAKE_CONSUMER, KafkaMessage -from faststream.utils.context.repository import context +from faststream.message import decode_message if TYPE_CHECKING: from re import Pattern from aiokafka import ConsumerRecord - from faststream.broker.message import StreamMessage + from faststream._internal.basic_types import DecodedMessage from faststream.kafka.subscriber.usecase import LogicSubscriber - from faststream.types import DecodedMessage + from faststream.message import StreamMessage class AioKafkaParser: @@ -39,7 +39,7 @@ async def parse_message( reply_to=headers.get("reply_to", ""), content_type=headers.get("content-type"), message_id=f"{message.offset}-{message.timestamp}", - correlation_id=headers.get("correlation_id", gen_cor_id()), + correlation_id=headers.get("correlation_id"), raw_message=message, path=self.get_path(message.topic), consumer=getattr(handler, "consumer", None) or FAKE_CONSUMER, @@ -86,7 +86,7 @@ async def parse_message( reply_to=headers.get("reply_to", ""), content_type=headers.get("content-type"), message_id=f"{first.offset}-{last.offset}-{first.timestamp}", - correlation_id=headers.get("correlation_id", gen_cor_id()), + correlation_id=headers.get("correlation_id"), raw_message=message, path=self.get_path(first.topic), consumer=getattr(handler, "consumer", None) or FAKE_CONSUMER, diff --git a/faststream/kafka/publisher/producer.py b/faststream/kafka/publisher/producer.py index 2d5d3c92ad..0b18adde67 100644 --- a/faststream/kafka/publisher/producer.py +++ b/faststream/kafka/publisher/producer.py @@ -2,18 +2,18 @@ from typing_extensions import override -from faststream.broker.message import encode_message -from faststream.broker.publisher.proto import ProducerProto -from faststream.broker.utils import resolve_custom_func +from faststream._internal.publisher.proto import ProducerProto +from faststream._internal.subscriber.utils import resolve_custom_func from faststream.exceptions import OperationForbiddenError from faststream.kafka.message import KafkaMessage from faststream.kafka.parser import AioKafkaParser +from faststream.message import encode_message if TYPE_CHECKING: from aiokafka import AIOKafkaProducer - from faststream.broker.types import CustomCallable - from faststream.types import SendableMessage + from faststream._internal.basic_types import SendableMessage + from faststream._internal.types import CustomCallable class AioKafkaFastProducer(ProducerProto): diff --git a/faststream/kafka/publisher/publisher.py b/faststream/kafka/publisher/publisher.py index f6ac82a709..e84ca8ba41 100644 --- a/faststream/kafka/publisher/publisher.py +++ b/faststream/kafka/publisher/publisher.py @@ -12,7 +12,7 @@ from typing_extensions import override -from faststream.broker.types import MsgType +from faststream._internal.types import MsgType from faststream.exceptions import SetupError from faststream.kafka.publisher.usecase import ( BatchPublisher, @@ -28,7 +28,7 @@ if TYPE_CHECKING: from aiokafka import ConsumerRecord - from faststream.broker.types import BrokerMiddleware, PublisherMiddleware + from faststream._internal.types import BrokerMiddleware, PublisherMiddleware class SpecificationPublisher(LogicPublisher[MsgType]): diff --git a/faststream/kafka/publisher/usecase.py b/faststream/kafka/publisher/usecase.py index 709aea898b..f78bee9955 100644 --- a/faststream/kafka/publisher/usecase.py +++ b/faststream/kafka/publisher/usecase.py @@ -17,17 +17,17 @@ from aiokafka import ConsumerRecord from typing_extensions import Annotated, Doc, override -from faststream.broker.message import gen_cor_id -from faststream.broker.publisher.usecase import PublisherUsecase -from faststream.broker.types import MsgType +from faststream._internal.publisher.usecase import PublisherUsecase +from faststream._internal.types import MsgType +from faststream._internal.utils.functions import return_input from faststream.exceptions import NOT_CONNECTED_YET -from faststream.utils.functions import return_input +from faststream.message import gen_cor_id if TYPE_CHECKING: - from faststream.broker.types import BrokerMiddleware, PublisherMiddleware + from faststream._internal.basic_types import AsyncFunc, SendableMessage + from faststream._internal.types import BrokerMiddleware, PublisherMiddleware from faststream.kafka.message import KafkaMessage from faststream.kafka.publisher.producer import AioKafkaFastProducer - from faststream.types import AsyncFunc, SendableMessage class LogicPublisher(PublisherUsecase[MsgType]): diff --git a/faststream/kafka/response.py b/faststream/kafka/response.py index da420aa286..353ac8251a 100644 --- a/faststream/kafka/response.py +++ b/faststream/kafka/response.py @@ -2,10 +2,10 @@ from typing_extensions import override -from faststream.broker.response import Response +from faststream.response import Response if TYPE_CHECKING: - from faststream.types import AnyDict, SendableMessage + from faststream._internal.basic_types import AnyDict, SendableMessage class KafkaResponse(Response): diff --git a/faststream/kafka/router.py b/faststream/kafka/router.py index cef54442c8..f06cd069b5 100644 --- a/faststream/kafka/router.py +++ b/faststream/kafka/router.py @@ -13,10 +13,13 @@ ) from aiokafka.coordinator.assignors.roundrobin import RoundRobinPartitionAssignor -from typing_extensions import Annotated, Doc, deprecated +from typing_extensions import Annotated, Doc -from faststream.broker.router import ArgsContainer, BrokerRouter, SubscriberRoute -from faststream.broker.utils import default_filter +from faststream._internal.broker.router import ( + ArgsContainer, + BrokerRouter, + SubscriberRoute, +) from faststream.kafka.broker.registrator import KafkaRegistrator if TYPE_CHECKING: @@ -25,15 +28,14 @@ from aiokafka.coordinator.assignors.abstract import AbstractPartitionAssignor from fast_depends.dependencies import Depends - from faststream.broker.types import ( + from faststream._internal.basic_types import SendableMessage + from faststream._internal.types import ( BrokerMiddleware, CustomCallable, - Filter, PublisherMiddleware, SubscriberMiddleware, ) from faststream.kafka.message import KafkaMessage - from faststream.types import SendableMessage class KafkaPublisher(ArgsContainer): @@ -484,17 +486,6 @@ def __init__( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - "Filter[KafkaMessage]", - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, retry: Annotated[ bool, Doc("Whether to `nack` message at processing exception."), @@ -561,7 +552,6 @@ def __init__( parser=parser, decoder=decoder, middlewares=middlewares, - filter=filter, no_reply=no_reply, # AsyncAPI args title=title, diff --git a/faststream/kafka/security.py b/faststream/kafka/security.py index 1f08878c1c..12860d191c 100644 --- a/faststream/kafka/security.py +++ b/faststream/kafka/security.py @@ -10,7 +10,7 @@ ) if TYPE_CHECKING: - from faststream.types import AnyDict + from faststream._internal.basic_types import AnyDict def parse_security(security: Optional[BaseSecurity]) -> "AnyDict": diff --git a/faststream/kafka/subscriber/factory.py b/faststream/kafka/subscriber/factory.py index a58843d52f..3f8515dd35 100644 --- a/faststream/kafka/subscriber/factory.py +++ b/faststream/kafka/subscriber/factory.py @@ -19,8 +19,8 @@ from aiokafka.abc import ConsumerRebalanceListener from fast_depends.dependencies import Depends - from faststream.broker.types import BrokerMiddleware - from faststream.types import AnyDict + from faststream._internal.basic_types import AnyDict + from faststream._internal.types import BrokerMiddleware @overload diff --git a/faststream/kafka/subscriber/subscriber.py b/faststream/kafka/subscriber/subscriber.py index 8931fe14c9..e173186d66 100644 --- a/faststream/kafka/subscriber/subscriber.py +++ b/faststream/kafka/subscriber/subscriber.py @@ -4,7 +4,7 @@ Tuple, ) -from faststream.broker.types import MsgType +from faststream._internal.types import MsgType from faststream.kafka.subscriber.usecase import ( BatchSubscriber, DefaultSubscriber, diff --git a/faststream/kafka/subscriber/usecase.py b/faststream/kafka/subscriber/usecase.py index 63c712b7fa..d8d4a47134 100644 --- a/faststream/kafka/subscriber/usecase.py +++ b/faststream/kafka/subscriber/usecase.py @@ -18,27 +18,27 @@ from aiokafka.errors import ConsumerStoppedError, KafkaError from typing_extensions import override -from faststream.broker.publisher.fake import FakePublisher -from faststream.broker.subscriber.usecase import SubscriberUsecase -from faststream.broker.types import ( +from faststream._internal.publisher.fake import FakePublisher +from faststream._internal.subscriber.usecase import SubscriberUsecase +from faststream._internal.subscriber.utils import process_msg +from faststream._internal.types import ( AsyncCallable, BrokerMiddleware, CustomCallable, MsgType, ) -from faststream.broker.utils import process_msg +from faststream._internal.utils.path import compile_path from faststream.kafka.message import KafkaAckableMessage, KafkaMessage from faststream.kafka.parser import AioKafkaBatchParser, AioKafkaParser -from faststream.utils.path import compile_path if TYPE_CHECKING: from aiokafka import AIOKafkaConsumer, ConsumerRecord from aiokafka.abc import ConsumerRebalanceListener from fast_depends.dependencies import Depends - from faststream.broker.message import StreamMessage - from faststream.broker.publisher.proto import ProducerProto - from faststream.types import AnyDict, Decorator, LoggerProto + from faststream._internal.basic_types import AnyDict, Decorator, LoggerProto + from faststream._internal.publisher.proto import ProducerProto + from faststream.message import StreamMessage class LogicSubscriber(SubscriberUsecase[MsgType]): diff --git a/faststream/kafka/testing.py b/faststream/kafka/testing.py index 881edc3269..5912e66d37 100755 --- a/faststream/kafka/testing.py +++ b/faststream/kafka/testing.py @@ -7,8 +7,9 @@ from aiokafka import ConsumerRecord from typing_extensions import override -from faststream.broker.message import encode_message, gen_cor_id -from faststream.broker.utils import resolve_custom_func +from faststream._internal.subscriber.utils import resolve_custom_func +from faststream._internal.testing.broker import TestBroker +from faststream._internal.utils.functions import timeout_scope from faststream.exceptions import SubscriberNotFound from faststream.kafka import TopicPartition from faststream.kafka.broker import KafkaBroker @@ -17,13 +18,12 @@ from faststream.kafka.publisher.producer import AioKafkaFastProducer from faststream.kafka.publisher.publisher import SpecificationBatchPublisher from faststream.kafka.subscriber.subscriber import SpecificationBatchSubscriber -from faststream.testing.broker import TestBroker -from faststream.utils.functions import timeout_scope +from faststream.message import encode_message, gen_cor_id if TYPE_CHECKING: + from faststream._internal.basic_types import SendableMessage from faststream.kafka.publisher.publisher import SpecificationPublisher from faststream.kafka.subscriber.usecase import LogicSubscriber - from faststream.types import SendableMessage __all__ = ("TestKafkaBroker",) diff --git a/faststream/log/__init__.py b/faststream/log/__init__.py deleted file mode 100644 index 0fc7042279..0000000000 --- a/faststream/log/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from faststream.log.logging import logger - -__all__ = ("logger",) diff --git a/faststream/message/__init__.py b/faststream/message/__init__.py new file mode 100644 index 0000000000..58eb791b89 --- /dev/null +++ b/faststream/message/__init__.py @@ -0,0 +1,10 @@ +from .message import AckStatus, StreamMessage +from .utils import decode_message, encode_message, gen_cor_id + +__all__ = ( + "StreamMessage", + "AckStatus", + "gen_cor_id", + "decode_message", + "encode_message", +) diff --git a/faststream/message/message.py b/faststream/message/message.py new file mode 100644 index 0000000000..592f51308e --- /dev/null +++ b/faststream/message/message.py @@ -0,0 +1,73 @@ +from enum import Enum +from typing import ( + TYPE_CHECKING, + Any, + Generic, + List, + Optional, + TypeVar, + Union, +) +from uuid import uuid4 + +if TYPE_CHECKING: + from faststream._internal.basic_types import AnyDict, DecodedMessage + +# prevent circular imports +MsgType = TypeVar("MsgType") + + +class AckStatus(str, Enum): + acked = "acked" + nacked = "nacked" + rejected = "rejected" + + +class StreamMessage(Generic[MsgType]): + """Generic class to represent a stream message.""" + + def __init__( + self, + raw_message: "MsgType", + body: Union[bytes, Any], + *, + headers: Optional["AnyDict"] = None, + reply_to: str = "", + batch_headers: Optional[List["AnyDict"]] = None, + path: Optional["AnyDict"] = None, + content_type: Optional[str] = None, + correlation_id: Optional[str] = None, + message_id: Optional[str] = None, + ) -> None: + self.raw_message = raw_message + self.body = body + self.reply_to = reply_to + self.content_type = content_type + + self.headers = headers or {} + self.batch_headers = batch_headers or [] + self.path = path or {} + self.correlation_id = correlation_id or str(uuid4()) + self.message_id = message_id or self.correlation_id + + # Setup later + self._decoded_body: Optional[DecodedMessage] = None + self.committed: Optional[AckStatus] = None + self.processed = False + + async def decode(self) -> Optional["DecodedMessage"]: + """Serialize the message by lazy decoder.""" + # TODO: make it lazy after `decoded_body` removed + return self._decoded_body + + async def ack(self) -> None: + if self.committed is None: + self.committed = AckStatus.acked + + async def nack(self) -> None: + if self.committed is None: + self.committed = AckStatus.nacked + + async def reject(self) -> None: + if self.committed is None: + self.committed = AckStatus.rejected diff --git a/faststream/message/utils.py b/faststream/message/utils.py new file mode 100644 index 0000000000..771ceac18b --- /dev/null +++ b/faststream/message/utils.py @@ -0,0 +1,78 @@ +import json +from contextlib import suppress +from typing import ( + TYPE_CHECKING, + Any, + Optional, + Sequence, + Tuple, + Union, + cast, +) +from uuid import uuid4 + +from faststream._internal._compat import dump_json, json_loads +from faststream._internal.constants import EMPTY, ContentTypes + +if TYPE_CHECKING: + from faststream._internal.basic_types import DecodedMessage, SendableMessage + + from .message import StreamMessage + + +def gen_cor_id() -> str: + """Generate random string to use as ID.""" + return str(uuid4()) + + +def decode_message(message: "StreamMessage[Any]") -> "DecodedMessage": + """Decodes a message.""" + body: Any = getattr(message, "body", message) + m: DecodedMessage = body + + if (content_type := getattr(message, "content_type", EMPTY)) is not EMPTY: + content_type = cast(Optional[str], content_type) + + if not content_type: + with suppress(json.JSONDecodeError, UnicodeDecodeError): + m = json_loads(body) + + elif ContentTypes.text.value in content_type: + m = body.decode() + + elif ContentTypes.json.value in content_type: + m = json_loads(body) + + else: + with suppress(json.JSONDecodeError, UnicodeDecodeError): + m = json_loads(body) + + return m + + +def encode_message( + msg: Union[Sequence["SendableMessage"], "SendableMessage"], +) -> Tuple[bytes, Optional[str]]: + """Encodes a message.""" + if msg is None: + return ( + b"", + None, + ) + + if isinstance(msg, bytes): + return ( + msg, + None, + ) + + if isinstance(msg, str): + return ( + msg.encode(), + ContentTypes.text.value, + ) + + return ( + dump_json(msg), + ContentTypes.json.value, + ) diff --git a/faststream/middlewares/__init__.py b/faststream/middlewares/__init__.py new file mode 100644 index 0000000000..0615c88194 --- /dev/null +++ b/faststream/middlewares/__init__.py @@ -0,0 +1,4 @@ +from faststream.middlewares.base import BaseMiddleware +from faststream.middlewares.exception import ExceptionMiddleware + +__all__ = ("BaseMiddleware", "ExceptionMiddleware") diff --git a/faststream/broker/middlewares/base.py b/faststream/middlewares/base.py similarity index 96% rename from faststream/broker/middlewares/base.py rename to faststream/middlewares/base.py index 5710c8ec1c..8d0a623abe 100644 --- a/faststream/broker/middlewares/base.py +++ b/faststream/middlewares/base.py @@ -5,8 +5,8 @@ if TYPE_CHECKING: from types import TracebackType - from faststream.broker.message import StreamMessage - from faststream.types import AsyncFunc, AsyncFuncAny + from faststream._internal.basic_types import AsyncFunc, AsyncFuncAny + from faststream.message import StreamMessage class BaseMiddleware: diff --git a/faststream/broker/middlewares/exception.py b/faststream/middlewares/exception.py similarity index 94% rename from faststream/broker/middlewares/exception.py rename to faststream/middlewares/exception.py index f0325a1788..291c65c470 100644 --- a/faststream/broker/middlewares/exception.py +++ b/faststream/middlewares/exception.py @@ -17,16 +17,17 @@ from typing_extensions import Literal, TypeAlias -from faststream.broker.middlewares.base import BaseMiddleware +from faststream._internal.context import context +from faststream._internal.utils import apply_types +from faststream._internal.utils.functions import sync_fake_context, to_async from faststream.exceptions import IgnoredException -from faststream.utils import apply_types, context -from faststream.utils.functions import sync_fake_context, to_async +from faststream.middlewares.base import BaseMiddleware if TYPE_CHECKING: from types import TracebackType - from faststream.broker.message import StreamMessage - from faststream.types import AsyncFuncAny + from faststream._internal.basic_types import AsyncFuncAny + from faststream.message import StreamMessage GeneralExceptionHandler: TypeAlias = Union[ diff --git a/faststream/broker/middlewares/logging.py b/faststream/middlewares/logging.py similarity index 90% rename from faststream/broker/middlewares/logging.py rename to faststream/middlewares/logging.py index 18c4c365e5..c0ab3c8479 100644 --- a/faststream/broker/middlewares/logging.py +++ b/faststream/middlewares/logging.py @@ -3,15 +3,16 @@ from typing_extensions import Self -from faststream.broker.middlewares.base import BaseMiddleware +from faststream._internal.context.repository import context from faststream.exceptions import IgnoredException -from faststream.utils.context.repository import context + +from .base import BaseMiddleware if TYPE_CHECKING: from types import TracebackType - from faststream.broker.message import StreamMessage - from faststream.types import LoggerProto + from faststream._internal.basic_types import LoggerProto + from faststream.message import StreamMessage class CriticalLogMiddleware(BaseMiddleware): diff --git a/faststream/nats/__init__.py b/faststream/nats/__init__.py index bae483a17e..abd0fe73ee 100644 --- a/faststream/nats/__init__.py +++ b/faststream/nats/__init__.py @@ -13,13 +13,13 @@ StreamSource, ) +from faststream._internal.testing.app import TestApp from faststream.nats.annotations import NatsMessage from faststream.nats.broker.broker import NatsBroker from faststream.nats.response import NatsResponse from faststream.nats.router import NatsPublisher, NatsRoute, NatsRouter from faststream.nats.schemas import JStream, KvWatch, ObjWatch, PullSub from faststream.nats.testing import TestNatsBroker -from faststream.testing.app import TestApp __all__ = ( "TestApp", diff --git a/faststream/nats/annotations.py b/faststream/nats/annotations.py index dabbcaa39a..f33f0eac78 100644 --- a/faststream/nats/annotations.py +++ b/faststream/nats/annotations.py @@ -3,13 +3,14 @@ from nats.js.object_store import ObjectStore as _ObjectStore from typing_extensions import Annotated -from faststream.annotations import ContextRepo, Logger, NoCast +from faststream._internal.context import Context +from faststream.annotations import ContextRepo, Logger from faststream.nats.broker import NatsBroker as _Broker from faststream.nats.message import NatsMessage as _Message from faststream.nats.publisher.producer import NatsFastProducer as _CoreProducer from faststream.nats.publisher.producer import NatsJSFastProducer as _JsProducer from faststream.nats.subscriber.usecase import OBJECT_STORAGE_CONTEXT_KEY -from faststream.utils.context import Context +from faststream.params import NoCast __all__ = ( "Logger", diff --git a/faststream/nats/broker/broker.py b/faststream/nats/broker/broker.py index 9df1319921..8279fea77e 100644 --- a/faststream/nats/broker/broker.py +++ b/faststream/nats/broker/broker.py @@ -30,14 +30,14 @@ from typing_extensions import Annotated, Doc, deprecated, override from faststream.__about__ import SERVICE_NAME -from faststream.broker.message import gen_cor_id +from faststream._internal.constants import EMPTY +from faststream.message import gen_cor_id from faststream.nats.broker.logging import NatsLoggingBroker from faststream.nats.broker.registrator import NatsRegistrator from faststream.nats.helpers import KVBucketDeclarer, OSBucketDeclarer from faststream.nats.publisher.producer import NatsFastProducer, NatsJSFastProducer from faststream.nats.security import parse_security from faststream.nats.subscriber.subscriber import SpecificationSubscriber -from faststream.types import EMPTY if TYPE_CHECKING: import ssl @@ -59,8 +59,15 @@ from nats.js.object_store import ObjectStore from typing_extensions import TypedDict, Unpack - from faststream.broker.publisher.proto import ProducerProto - from faststream.broker.types import ( + from faststream._internal.basic_types import ( + AnyDict, + DecodedMessage, + Decorator, + LoggerProto, + SendableMessage, + ) + from faststream._internal.publisher.proto import ProducerProto + from faststream._internal.types import ( BrokerMiddleware, CustomCallable, ) @@ -68,13 +75,6 @@ from faststream.nats.publisher.publisher import SpecificationPublisher from faststream.security import BaseSecurity from faststream.specification.schema.tag import Tag, TagDict - from faststream.types import ( - AnyDict, - DecodedMessage, - Decorator, - LoggerProto, - SendableMessage, - ) class NatsInitKwargs(TypedDict, total=False): """NatsBroker.connect() method type hints.""" diff --git a/faststream/nats/broker/logging.py b/faststream/nats/broker/logging.py index 5e2572ddcb..dd163a1c77 100644 --- a/faststream/nats/broker/logging.py +++ b/faststream/nats/broker/logging.py @@ -4,12 +4,12 @@ from nats.aio.client import Client from nats.aio.msg import Msg -from faststream.broker.core.usecase import BrokerUsecase -from faststream.log.logging import get_broker_logger -from faststream.types import EMPTY +from faststream._internal.broker.broker import BrokerUsecase +from faststream._internal.constants import EMPTY +from faststream._internal.log.logging import get_broker_logger if TYPE_CHECKING: - from faststream.types import LoggerProto + from faststream._internal.basic_types import LoggerProto class NatsLoggingBroker(BrokerUsecase[Msg, Client]): diff --git a/faststream/nats/broker/registrator.py b/faststream/nats/broker/registrator.py index 42d8c0ca88..8e5a3c99d3 100644 --- a/faststream/nats/broker/registrator.py +++ b/faststream/nats/broker/registrator.py @@ -1,10 +1,9 @@ from typing import TYPE_CHECKING, Any, Dict, Iterable, Optional, Union, cast from nats.js import api -from typing_extensions import Annotated, Doc, deprecated, override +from typing_extensions import Annotated, Doc, override -from faststream.broker.core.abc import ABCBroker -from faststream.broker.utils import default_filter +from faststream._internal.broker.abc_broker import ABCBroker from faststream.nats.helpers import StreamBuilder from faststream.nats.publisher.publisher import SpecificationPublisher from faststream.nats.schemas import JStream, KvWatch, ObjWatch, PullSub @@ -15,14 +14,13 @@ from fast_depends.dependencies import Depends from nats.aio.msg import Msg - from faststream.broker.types import ( + from faststream._internal.types import ( BrokerMiddleware, CustomCallable, - Filter, PublisherMiddleware, SubscriberMiddleware, ) - from faststream.nats.message import NatsBatchMessage, NatsMessage + from faststream.nats.message import NatsMessage class NatsRegistrator(ABCBroker["Msg"]): @@ -156,20 +154,6 @@ def subscriber( # type: ignore[override] Iterable["SubscriberMiddleware[NatsMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - Union[ - "Filter[NatsMessage]", - "Filter[NatsBatchMessage]", - ], - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, max_workers: Annotated[ int, Doc("Number of workers to process messages concurrently."), @@ -253,7 +237,6 @@ def subscriber( # type: ignore[override] stream.add_subject(subscriber.subject) return subscriber.add_call( - filter_=filter, parser_=parser or self._parser, decoder_=decoder or self._decoder, dependencies_=dependencies, diff --git a/faststream/nats/fastapi/__init__.py b/faststream/nats/fastapi/__init__.py index c1dc63c8a9..7ff134e5de 100644 --- a/faststream/nats/fastapi/__init__.py +++ b/faststream/nats/fastapi/__init__.py @@ -2,7 +2,7 @@ from nats.js.client import JetStreamContext from typing_extensions import Annotated -from faststream.broker.fastapi.context import Context, ContextRepo, Logger +from faststream._internal.fastapi.context import Context, ContextRepo, Logger from faststream.nats.broker import NatsBroker as NB from faststream.nats.fastapi.fastapi import NatsRouter from faststream.nats.message import NatsMessage as NM diff --git a/faststream/nats/fastapi/fastapi.py b/faststream/nats/fastapi/fastapi.py index 8a9e8cb7b3..276be0968a 100644 --- a/faststream/nats/fastapi/fastapi.py +++ b/faststream/nats/fastapi/fastapi.py @@ -33,12 +33,11 @@ from typing_extensions import Annotated, Doc, deprecated, override from faststream.__about__ import SERVICE_NAME -from faststream.broker.fastapi.router import StreamRouter -from faststream.broker.utils import default_filter +from faststream._internal.constants import EMPTY +from faststream._internal.fastapi.router import StreamRouter from faststream.nats.broker import NatsBroker from faststream.nats.publisher.publisher import SpecificationPublisher from faststream.nats.subscriber.subscriber import SpecificationSubscriber -from faststream.types import EMPTY if TYPE_CHECKING: import ssl @@ -57,18 +56,17 @@ from starlette.responses import Response from starlette.types import ASGIApp, Lifespan - from faststream.broker.types import ( + from faststream._internal.basic_types import AnyDict, LoggerProto + from faststream._internal.types import ( BrokerMiddleware, CustomCallable, - Filter, PublisherMiddleware, SubscriberMiddleware, ) - from faststream.nats.message import NatsBatchMessage, NatsMessage + from faststream.nats.message import NatsMessage from faststream.nats.schemas import JStream, KvWatch, ObjWatch, PullSub from faststream.security import BaseSecurity from faststream.specification.schema.tag import Tag, TagDict - from faststream.types import AnyDict, LoggerProto class NatsRouter(StreamRouter["Msg"]): @@ -691,20 +689,6 @@ def subscriber( # type: ignore[override] Iterable["SubscriberMiddleware[NatsMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - Union[ - "Filter[NatsMessage]", - "Filter[NatsBatchMessage]", - ], - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, max_workers: Annotated[ int, Doc("Number of workers to process messages concurrently."), @@ -887,7 +871,6 @@ def subscriber( # type: ignore[override] parser=parser, decoder=decoder, middlewares=middlewares, - filter=filter, max_workers=max_workers, retry=retry, no_ack=no_ack, diff --git a/faststream/nats/message.py b/faststream/nats/message.py index ee54ef2caa..69c5cc9ac1 100644 --- a/faststream/nats/message.py +++ b/faststream/nats/message.py @@ -4,7 +4,7 @@ from nats.js.api import ObjectInfo from nats.js.kv import KeyValue -from faststream.broker.message import StreamMessage +from faststream.message import StreamMessage class NatsMessage(StreamMessage[Msg]): diff --git a/faststream/nats/opentelemetry/provider.py b/faststream/nats/opentelemetry/provider.py index a77ff0a2b3..32c8a216d1 100644 --- a/faststream/nats/opentelemetry/provider.py +++ b/faststream/nats/opentelemetry/provider.py @@ -4,13 +4,13 @@ from opentelemetry.semconv.trace import SpanAttributes from faststream.__about__ import SERVICE_NAME -from faststream.broker.types import MsgType +from faststream._internal.types import MsgType from faststream.opentelemetry import TelemetrySettingsProvider from faststream.opentelemetry.consts import MESSAGING_DESTINATION_PUBLISH_NAME if TYPE_CHECKING: - from faststream.broker.message import StreamMessage - from faststream.types import AnyDict + from faststream._internal.basic_types import AnyDict + from faststream.message import StreamMessage class BaseNatsTelemetrySettingsProvider(TelemetrySettingsProvider[MsgType]): diff --git a/faststream/nats/parser.py b/faststream/nats/parser.py index c3a1c32928..e9820d8fad 100644 --- a/faststream/nats/parser.py +++ b/faststream/nats/parser.py @@ -1,6 +1,9 @@ from typing import TYPE_CHECKING, Any, Dict, List, Optional -from faststream.broker.message import StreamMessage, decode_message, gen_cor_id +from faststream.message import ( + StreamMessage, + decode_message, +) from faststream.nats.message import ( NatsBatchMessage, NatsKvMessage, @@ -14,7 +17,7 @@ from nats.js.api import ObjectInfo from nats.js.kv import KeyValue - from faststream.types import AnyDict, DecodedMessage + from faststream._internal.basic_types import AnyDict, DecodedMessage class NatsBaseParser: @@ -76,8 +79,8 @@ async def parse_message( reply_to=message.reply, headers=headers, content_type=headers.get("content-type", ""), - message_id=headers.get("message_id", gen_cor_id()), - correlation_id=headers.get("correlation_id", gen_cor_id()), + message_id=headers.get("message_id"), + correlation_id=headers.get("correlation_id"), ) @@ -101,9 +104,9 @@ async def parse_message( path=path or {}, reply_to=headers.get("reply_to", ""), # differ from core headers=headers, - content_type=headers.get("content-type", ""), - message_id=headers.get("message_id", gen_cor_id()), - correlation_id=headers.get("correlation_id", gen_cor_id()), + content_type=headers.get("content-type"), + message_id=headers.get("message_id"), + correlation_id=headers.get("correlation_id"), ) diff --git a/faststream/nats/publisher/producer.py b/faststream/nats/publisher/producer.py index eedb27932f..61f42aca91 100644 --- a/faststream/nats/publisher/producer.py +++ b/faststream/nats/publisher/producer.py @@ -5,23 +5,23 @@ import nats from typing_extensions import override -from faststream.broker.message import encode_message -from faststream.broker.publisher.proto import ProducerProto -from faststream.broker.utils import resolve_custom_func +from faststream._internal.publisher.proto import ProducerProto +from faststream._internal.subscriber.utils import resolve_custom_func +from faststream._internal.utils.functions import timeout_scope from faststream.exceptions import WRONG_PUBLISH_ARGS +from faststream.message import encode_message from faststream.nats.parser import NatsParser -from faststream.utils.functions import timeout_scope if TYPE_CHECKING: from nats.aio.client import Client from nats.aio.msg import Msg from nats.js import JetStreamContext - from faststream.broker.types import ( + from faststream._internal.basic_types import SendableMessage + from faststream._internal.types import ( AsyncCallable, CustomCallable, ) - from faststream.types import SendableMessage class NatsFastProducer(ProducerProto): diff --git a/faststream/nats/publisher/publisher.py b/faststream/nats/publisher/publisher.py index f86c12e142..2a16be477b 100644 --- a/faststream/nats/publisher/publisher.py +++ b/faststream/nats/publisher/publisher.py @@ -12,7 +12,7 @@ if TYPE_CHECKING: from nats.aio.msg import Msg - from faststream.broker.types import BrokerMiddleware, PublisherMiddleware + from faststream._internal.types import BrokerMiddleware, PublisherMiddleware from faststream.nats.schemas.js_stream import JStream diff --git a/faststream/nats/publisher/usecase.py b/faststream/nats/publisher/usecase.py index 83f9a7c0e4..b61b7d761b 100644 --- a/faststream/nats/publisher/usecase.py +++ b/faststream/nats/publisher/usecase.py @@ -15,17 +15,17 @@ from nats.aio.msg import Msg from typing_extensions import Annotated, Doc, override -from faststream.broker.message import gen_cor_id -from faststream.broker.publisher.usecase import PublisherUsecase +from faststream._internal.publisher.usecase import PublisherUsecase +from faststream._internal.utils.functions import return_input from faststream.exceptions import NOT_CONNECTED_YET -from faststream.utils.functions import return_input +from faststream.message import gen_cor_id if TYPE_CHECKING: - from faststream.broker.types import BrokerMiddleware, PublisherMiddleware + from faststream._internal.basic_types import AnyDict, AsyncFunc, SendableMessage + from faststream._internal.types import BrokerMiddleware, PublisherMiddleware from faststream.nats.message import NatsMessage from faststream.nats.publisher.producer import NatsFastProducer, NatsJSFastProducer from faststream.nats.schemas import JStream - from faststream.types import AnyDict, AsyncFunc, SendableMessage class LogicPublisher(PublisherUsecase[Msg]): diff --git a/faststream/nats/response.py b/faststream/nats/response.py index b15bc97277..6fd4e6466a 100644 --- a/faststream/nats/response.py +++ b/faststream/nats/response.py @@ -2,10 +2,10 @@ from typing_extensions import override -from faststream.broker.response import Response +from faststream.response import Response if TYPE_CHECKING: - from faststream.types import AnyDict, SendableMessage + from faststream._internal.basic_types import AnyDict, SendableMessage class NatsResponse(Response): diff --git a/faststream/nats/router.py b/faststream/nats/router.py index ace895ba59..45c8d9866a 100644 --- a/faststream/nats/router.py +++ b/faststream/nats/router.py @@ -10,26 +10,28 @@ ) from nats.js import api -from typing_extensions import Annotated, Doc, deprecated +from typing_extensions import Annotated, Doc -from faststream.broker.router import ArgsContainer, BrokerRouter, SubscriberRoute -from faststream.broker.utils import default_filter +from faststream._internal.broker.router import ( + ArgsContainer, + BrokerRouter, + SubscriberRoute, +) from faststream.nats.broker.registrator import NatsRegistrator if TYPE_CHECKING: from fast_depends.dependencies import Depends from nats.aio.msg import Msg - from faststream.broker.types import ( + from faststream._internal.basic_types import SendableMessage + from faststream._internal.types import ( BrokerMiddleware, CustomCallable, - Filter, PublisherMiddleware, SubscriberMiddleware, ) - from faststream.nats.message import NatsBatchMessage, NatsMessage + from faststream.nats.message import NatsMessage from faststream.nats.schemas import JStream, KvWatch, ObjWatch, PullSub - from faststream.types import SendableMessage class NatsPublisher(ArgsContainer): @@ -245,20 +247,6 @@ def __init__( Iterable["SubscriberMiddleware[NatsMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - Union[ - "Filter[NatsMessage]", - "Filter[NatsBatchMessage]", - ], - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, max_workers: Annotated[ int, Doc("Number of workers to process messages concurrently."), @@ -320,7 +308,6 @@ def __init__( parser=parser, decoder=decoder, middlewares=middlewares, - filter=filter, retry=retry, no_ack=no_ack, no_reply=no_reply, diff --git a/faststream/nats/schemas/js_stream.py b/faststream/nats/schemas/js_stream.py index 7a7450dd70..c155df5e0d 100644 --- a/faststream/nats/schemas/js_stream.py +++ b/faststream/nats/schemas/js_stream.py @@ -4,8 +4,8 @@ from nats.js.api import DiscardPolicy, StreamConfig from typing_extensions import Annotated, Doc -from faststream.broker.schemas import NameRequired -from faststream.utils.path import compile_path +from faststream._internal.proto import NameRequired +from faststream._internal.utils.path import compile_path if TYPE_CHECKING: from re import Pattern diff --git a/faststream/nats/schemas/kv_watch.py b/faststream/nats/schemas/kv_watch.py index d756f8d28d..24707a2fe6 100644 --- a/faststream/nats/schemas/kv_watch.py +++ b/faststream/nats/schemas/kv_watch.py @@ -1,6 +1,6 @@ from typing import Optional -from faststream.broker.schemas import NameRequired +from faststream._internal.proto import NameRequired class KvWatch(NameRequired): diff --git a/faststream/nats/security.py b/faststream/nats/security.py index c80931055b..4d1e855caf 100644 --- a/faststream/nats/security.py +++ b/faststream/nats/security.py @@ -6,7 +6,7 @@ ) if TYPE_CHECKING: - from faststream.types import AnyDict + from faststream._internal.basic_types import AnyDict def parse_security(security: Optional[BaseSecurity]) -> "AnyDict": diff --git a/faststream/nats/subscriber/factory.py b/faststream/nats/subscriber/factory.py index 51a7f84d8a..5395df4dbe 100644 --- a/faststream/nats/subscriber/factory.py +++ b/faststream/nats/subscriber/factory.py @@ -27,9 +27,9 @@ from fast_depends.dependencies import Depends from nats.js import api - from faststream.broker.types import BrokerMiddleware + from faststream._internal.basic_types import AnyDict + from faststream._internal.types import BrokerMiddleware from faststream.nats.schemas import JStream, KvWatch, ObjWatch, PullSub - from faststream.types import AnyDict def create_subscriber( diff --git a/faststream/nats/subscriber/usecase.py b/faststream/nats/subscriber/usecase.py index e7b3e0ce01..fc91ef8b88 100644 --- a/faststream/nats/subscriber/usecase.py +++ b/faststream/nats/subscriber/usecase.py @@ -24,10 +24,11 @@ from nats.js.api import ConsumerConfig, ObjectInfo from typing_extensions import Annotated, Doc, override -from faststream.broker.publisher.fake import FakePublisher -from faststream.broker.subscriber.usecase import SubscriberUsecase -from faststream.broker.types import MsgType -from faststream.broker.utils import process_msg +from faststream._internal.context.repository import context +from faststream._internal.publisher.fake import FakePublisher +from faststream._internal.subscriber.usecase import SubscriberUsecase +from faststream._internal.subscriber.utils import process_msg +from faststream._internal.types import MsgType from faststream.exceptions import NOT_CONNECTED_YET from faststream.nats.parser import ( BatchParser, @@ -41,7 +42,6 @@ UnsubscribeAdapter, Unsubscriptable, ) -from faststream.utils.context.repository import context if TYPE_CHECKING: from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream @@ -52,17 +52,22 @@ from nats.js.kv import KeyValue from nats.js.object_store import ObjectStore - from faststream.broker.message import StreamMessage - from faststream.broker.publisher.proto import ProducerProto - from faststream.broker.types import ( + from faststream._internal.basic_types import ( + AnyDict, + Decorator, + LoggerProto, + SendableMessage, + ) + from faststream._internal.publisher.proto import ProducerProto + from faststream._internal.types import ( AsyncCallable, BrokerMiddleware, CustomCallable, ) + from faststream.message import StreamMessage from faststream.nats.helpers import KVBucketDeclarer, OSBucketDeclarer from faststream.nats.message import NatsKvMessage, NatsMessage, NatsObjMessage from faststream.nats.schemas import JStream, KvWatch, ObjWatch, PullSub - from faststream.types import AnyDict, Decorator, LoggerProto, SendableMessage ConnectionType = TypeVar("ConnectionType") diff --git a/faststream/nats/testing.py b/faststream/nats/testing.py index eba94f67aa..6e3459af35 100644 --- a/faststream/nats/testing.py +++ b/faststream/nats/testing.py @@ -5,20 +5,20 @@ from nats.aio.msg import Msg from typing_extensions import override -from faststream.broker.message import encode_message, gen_cor_id -from faststream.broker.utils import resolve_custom_func +from faststream._internal.subscriber.utils import resolve_custom_func +from faststream._internal.testing.broker import TestBroker +from faststream._internal.utils.functions import timeout_scope from faststream.exceptions import WRONG_PUBLISH_ARGS, SubscriberNotFound +from faststream.message import encode_message, gen_cor_id from faststream.nats.broker import NatsBroker from faststream.nats.parser import NatsParser from faststream.nats.publisher.producer import NatsFastProducer from faststream.nats.schemas.js_stream import is_subject_match_wildcard -from faststream.testing.broker import TestBroker -from faststream.utils.functions import timeout_scope if TYPE_CHECKING: + from faststream._internal.basic_types import AnyDict, SendableMessage from faststream.nats.publisher.publisher import SpecificationPublisher from faststream.nats.subscriber.usecase import LogicSubscriber - from faststream.types import AnyDict, SendableMessage __all__ = ("TestNatsBroker",) diff --git a/faststream/opentelemetry/baggage.py b/faststream/opentelemetry/baggage.py index 420b0c9081..e03e9cb327 100644 --- a/faststream/opentelemetry/baggage.py +++ b/faststream/opentelemetry/baggage.py @@ -5,8 +5,8 @@ from typing_extensions import Self if TYPE_CHECKING: - from faststream.broker.message import StreamMessage - from faststream.types import AnyDict + from faststream._internal.basic_types import AnyDict + from faststream.message import StreamMessage _BAGGAGE_PROPAGATOR = W3CBaggagePropagator() @@ -15,7 +15,9 @@ class Baggage: __slots__ = ("_baggage", "_batch_baggage") def __init__( - self, payload: "AnyDict", batch_payload: Optional[List["AnyDict"]] = None + self, + payload: "AnyDict", + batch_payload: Optional[List["AnyDict"]] = None, ) -> None: self._baggage = dict(payload) self._batch_baggage = [dict(b) for b in batch_payload] if batch_payload else [] diff --git a/faststream/opentelemetry/middleware.py b/faststream/opentelemetry/middleware.py index 97cb7ddd14..95527118ff 100644 --- a/faststream/opentelemetry/middleware.py +++ b/faststream/opentelemetry/middleware.py @@ -30,8 +30,8 @@ from opentelemetry.trace import Tracer, TracerProvider from opentelemetry.util.types import Attributes - from faststream.broker.message import StreamMessage - from faststream.types import AnyDict, AsyncFunc, AsyncFuncAny + from faststream._internal.basic_types import AnyDict, AsyncFunc, AsyncFuncAny + from faststream.message import StreamMessage _BAGGAGE_PROPAGATOR = W3CBaggagePropagator() diff --git a/faststream/opentelemetry/provider.py b/faststream/opentelemetry/provider.py index 90232d45ab..304f1f332b 100644 --- a/faststream/opentelemetry/provider.py +++ b/faststream/opentelemetry/provider.py @@ -1,10 +1,10 @@ from typing import TYPE_CHECKING, Protocol -from faststream.broker.types import MsgType +from faststream._internal.types import MsgType if TYPE_CHECKING: - from faststream.broker.message import StreamMessage - from faststream.types import AnyDict + from faststream._internal.basic_types import AnyDict + from faststream.message import StreamMessage class TelemetrySettingsProvider(Protocol[MsgType]): diff --git a/faststream/params/__init__.py b/faststream/params/__init__.py new file mode 100644 index 0000000000..f771a71eef --- /dev/null +++ b/faststream/params/__init__.py @@ -0,0 +1,12 @@ +from fast_depends import Depends + +from .no_cast import NoCast +from .params import Context, Header, Path + +__all__ = ( + "NoCast", + "Context", + "Header", + "Path", + "Depends", +) diff --git a/faststream/utils/no_cast.py b/faststream/params/no_cast.py similarity index 60% rename from faststream/utils/no_cast.py rename to faststream/params/no_cast.py index 6a96fbd029..e030b40306 100644 --- a/faststream/utils/no_cast.py +++ b/faststream/params/no_cast.py @@ -1,11 +1,12 @@ -from typing import Any +from typing import Any, TypeVar from fast_depends.library import CustomField +from typing_extensions import Annotated -from faststream.types import AnyDict +from faststream._internal.basic_types import AnyDict -class NoCast(CustomField): +class NoCastField(CustomField): """A class that represents a custom field without casting. You can use it to annotate fields, that should not be casted. @@ -20,3 +21,8 @@ def __init__(self) -> None: def use(self, **kwargs: Any) -> AnyDict: return kwargs + + +_NoCastType = TypeVar("_NoCastType") + +NoCast = Annotated[_NoCastType, NoCastField()] diff --git a/faststream/utils/context/builders.py b/faststream/params/params.py similarity index 88% rename from faststream/utils/context/builders.py rename to faststream/params/params.py index 76e7499ba3..fd5dfd14ea 100644 --- a/faststream/utils/context/builders.py +++ b/faststream/params/params.py @@ -1,7 +1,7 @@ from typing import Any, Callable, Optional -from faststream.types import EMPTY -from faststream.utils.context.types import Context as Context_ +from faststream._internal.constants import EMPTY +from faststream._internal.context import Context as Context_ def Context( # noqa: N802 diff --git a/faststream/rabbit/__init__.py b/faststream/rabbit/__init__.py index cfc152d4e0..ab2152af76 100644 --- a/faststream/rabbit/__init__.py +++ b/faststream/rabbit/__init__.py @@ -1,3 +1,4 @@ +from faststream._internal.testing.app import TestApp from faststream.rabbit.annotations import RabbitMessage from faststream.rabbit.broker import RabbitBroker from faststream.rabbit.response import RabbitResponse @@ -6,10 +7,8 @@ ExchangeType, RabbitExchange, RabbitQueue, - ReplyConfig, ) from faststream.rabbit.testing import TestRabbitBroker -from faststream.testing.app import TestApp __all__ = ( "RabbitBroker", @@ -20,7 +19,6 @@ "RabbitPublisher", "RabbitResponse", "ExchangeType", - "ReplyConfig", "RabbitExchange", "RabbitQueue", # Annotations diff --git a/faststream/rabbit/annotations.py b/faststream/rabbit/annotations.py index f32654d2cc..e6800a5958 100644 --- a/faststream/rabbit/annotations.py +++ b/faststream/rabbit/annotations.py @@ -1,11 +1,12 @@ from aio_pika import RobustChannel, RobustConnection from typing_extensions import Annotated -from faststream.annotations import ContextRepo, Logger, NoCast +from faststream._internal.context import Context +from faststream.annotations import ContextRepo, Logger +from faststream.params import NoCast from faststream.rabbit.broker import RabbitBroker as RB from faststream.rabbit.message import RabbitMessage as RM from faststream.rabbit.publisher.producer import AioPikaFastProducer -from faststream.utils.context import Context __all__ = ( "Logger", diff --git a/faststream/rabbit/broker/broker.py b/faststream/rabbit/broker/broker.py index 2bd5fd9ab7..8004fe968d 100644 --- a/faststream/rabbit/broker/broker.py +++ b/faststream/rabbit/broker/broker.py @@ -16,8 +16,9 @@ from typing_extensions import Annotated, Doc, deprecated, override from faststream.__about__ import SERVICE_NAME -from faststream.broker.message import gen_cor_id +from faststream._internal.constants import EMPTY from faststream.exceptions import NOT_CONNECTED_YET +from faststream.message import gen_cor_id from faststream.rabbit.broker.logging import RabbitLoggingBroker from faststream.rabbit.broker.registrator import RabbitRegistrator from faststream.rabbit.helpers.declarer import RabbitDeclarer @@ -30,7 +31,6 @@ from faststream.rabbit.security import parse_security from faststream.rabbit.subscriber.subscriber import SpecificationSubscriber from faststream.rabbit.utils import build_url -from faststream.types import EMPTY if TYPE_CHECKING: from ssl import SSLContext @@ -48,7 +48,8 @@ from pamqp.common import FieldTable from yarl import URL - from faststream.broker.types import ( + from faststream._internal.basic_types import AnyDict, Decorator, LoggerProto + from faststream._internal.types import ( BrokerMiddleware, CustomCallable, ) @@ -56,7 +57,6 @@ from faststream.rabbit.types import AioPikaSendableMessage from faststream.security import BaseSecurity from faststream.specification.schema.tag import Tag, TagDict - from faststream.types import AnyDict, Decorator, LoggerProto class RabbitBroker( diff --git a/faststream/rabbit/broker/logging.py b/faststream/rabbit/broker/logging.py index 738254b36e..cf104338a7 100644 --- a/faststream/rabbit/broker/logging.py +++ b/faststream/rabbit/broker/logging.py @@ -3,12 +3,12 @@ from aio_pika import IncomingMessage, RobustConnection -from faststream.broker.core.usecase import BrokerUsecase -from faststream.log.logging import get_broker_logger -from faststream.types import EMPTY +from faststream._internal.broker.broker import BrokerUsecase +from faststream._internal.constants import EMPTY +from faststream._internal.log.logging import get_broker_logger if TYPE_CHECKING: - from faststream.types import LoggerProto + from faststream._internal.basic_types import LoggerProto class RabbitLoggingBroker(BrokerUsecase[IncomingMessage, RobustConnection]): diff --git a/faststream/rabbit/broker/registrator.py b/faststream/rabbit/broker/registrator.py index 4be99d8caf..8564aa0846 100644 --- a/faststream/rabbit/broker/registrator.py +++ b/faststream/rabbit/broker/registrator.py @@ -1,9 +1,8 @@ from typing import TYPE_CHECKING, Any, Dict, Iterable, Optional, Union, cast -from typing_extensions import Annotated, Doc, deprecated, override +from typing_extensions import Annotated, Doc, override -from faststream.broker.core.abc import ABCBroker -from faststream.broker.utils import default_filter +from faststream._internal.broker.abc_broker import ABCBroker from faststream.rabbit.publisher.publisher import SpecificationPublisher from faststream.rabbit.publisher.usecase import PublishKwargs from faststream.rabbit.schemas import ( @@ -18,15 +17,13 @@ from aio_pika.abc import DateType, HeadersType, TimeoutType from fast_depends.dependencies import Depends - from faststream.broker.types import ( + from faststream._internal.basic_types import AnyDict + from faststream._internal.types import ( CustomCallable, - Filter, PublisherMiddleware, SubscriberMiddleware, ) from faststream.rabbit.message import RabbitMessage - from faststream.rabbit.schemas.reply import ReplyConfig - from faststream.types import AnyDict class RabbitRegistrator(ABCBroker["IncomingMessage"]): @@ -58,15 +55,6 @@ def subscriber( # type: ignore[override] Optional["AnyDict"], Doc("Extra consumer arguments to use in `queue.consume(...)` method."), ] = None, - reply_config: Annotated[ - Optional["ReplyConfig"], - Doc("Extra options to use at replies publishing."), - deprecated( - "Deprecated in **FastStream 0.5.16**. " - "Please, use `RabbitResponse` object as a handler return instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = None, # broker arguments dependencies: Annotated[ Iterable["Depends"], @@ -84,17 +72,6 @@ def subscriber( # type: ignore[override] Iterable["SubscriberMiddleware[RabbitMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - "Filter[RabbitMessage]", - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, retry: Annotated[ Union[bool, int], Doc("Whether to `nack` message at processing exception."), @@ -133,7 +110,6 @@ def subscriber( # type: ignore[override] queue=RabbitQueue.validate(queue), exchange=RabbitExchange.validate(exchange), consume_args=consume_args, - reply_config=reply_config, # subscriber args no_ack=no_ack, no_reply=no_reply, @@ -149,7 +125,6 @@ def subscriber( # type: ignore[override] ) return subscriber.add_call( - filter_=filter, parser_=parser or self._parser, decoder_=decoder or self._decoder, dependencies_=dependencies, diff --git a/faststream/rabbit/fastapi/__init__.py b/faststream/rabbit/fastapi/__init__.py index 06f1226e58..dcbc649abc 100644 --- a/faststream/rabbit/fastapi/__init__.py +++ b/faststream/rabbit/fastapi/__init__.py @@ -1,6 +1,6 @@ from typing_extensions import Annotated -from faststream.broker.fastapi.context import Context, ContextRepo, Logger +from faststream._internal.fastapi.context import Context, ContextRepo, Logger from faststream.rabbit.broker import RabbitBroker as RB from faststream.rabbit.fastapi.router import RabbitRouter from faststream.rabbit.message import RabbitMessage as RM diff --git a/faststream/rabbit/fastapi/router.py b/faststream/rabbit/fastapi/router.py index 03a1a76eb5..85e63a14c4 100644 --- a/faststream/rabbit/fastapi/router.py +++ b/faststream/rabbit/fastapi/router.py @@ -21,8 +21,8 @@ from typing_extensions import Annotated, Doc, deprecated, override from faststream.__about__ import SERVICE_NAME -from faststream.broker.fastapi.router import StreamRouter -from faststream.broker.utils import default_filter +from faststream._internal.constants import EMPTY +from faststream._internal.fastapi.router import StreamRouter from faststream.rabbit.broker.broker import RabbitBroker as RB from faststream.rabbit.publisher.publisher import SpecificationPublisher from faststream.rabbit.schemas import ( @@ -30,7 +30,6 @@ RabbitQueue, ) from faststream.rabbit.subscriber.subscriber import SpecificationSubscriber -from faststream.types import EMPTY if TYPE_CHECKING: from enum import Enum @@ -44,18 +43,16 @@ from starlette.types import ASGIApp, Lifespan from yarl import URL - from faststream.broker.types import ( + from faststream._internal.basic_types import AnyDict, LoggerProto + from faststream._internal.types import ( BrokerMiddleware, CustomCallable, - Filter, PublisherMiddleware, SubscriberMiddleware, ) from faststream.rabbit.message import RabbitMessage - from faststream.rabbit.schemas.reply import ReplyConfig from faststream.security import BaseSecurity from faststream.specification.schema.tag import Tag, TagDict - from faststream.types import AnyDict, LoggerProto class RabbitRouter(StreamRouter["IncomingMessage"]): @@ -498,15 +495,6 @@ def subscriber( # type: ignore[override] Optional["AnyDict"], Doc("Extra consumer arguments to use in `queue.consume(...)` method."), ] = None, - reply_config: Annotated[ - Optional["ReplyConfig"], - Doc("Extra options to use at replies publishing."), - deprecated( - "Deprecated in **FastStream 0.5.16**. " - "Please, use `RabbitResponse` object as a handler return instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = None, # broker arguments dependencies: Annotated[ Iterable["params.Depends"], @@ -526,17 +514,6 @@ def subscriber( # type: ignore[override] Iterable["SubscriberMiddleware[RabbitMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - "Filter[RabbitMessage]", - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, retry: Annotated[ Union[bool, int], Doc("Whether to `nack` message at processing exception."), @@ -697,12 +674,10 @@ def subscriber( # type: ignore[override] queue=queue, exchange=exchange, consume_args=consume_args, - reply_config=reply_config, dependencies=dependencies, parser=parser, decoder=decoder, middlewares=middlewares, - filter=filter, retry=retry, no_ack=no_ack, no_reply=no_reply, diff --git a/faststream/rabbit/message.py b/faststream/rabbit/message.py index 4287cf2fd7..7b91fdd72f 100644 --- a/faststream/rabbit/message.py +++ b/faststream/rabbit/message.py @@ -1,6 +1,6 @@ from aio_pika import IncomingMessage -from faststream.broker.message import StreamMessage +from faststream.message import StreamMessage class RabbitMessage(StreamMessage[IncomingMessage]): diff --git a/faststream/rabbit/opentelemetry/provider.py b/faststream/rabbit/opentelemetry/provider.py index 6971810ff2..15febc0480 100644 --- a/faststream/rabbit/opentelemetry/provider.py +++ b/faststream/rabbit/opentelemetry/provider.py @@ -8,9 +8,9 @@ if TYPE_CHECKING: from aio_pika import IncomingMessage - from faststream.broker.message import StreamMessage + from faststream._internal.basic_types import AnyDict + from faststream.message import StreamMessage from faststream.rabbit.schemas.exchange import RabbitExchange - from faststream.types import AnyDict class RabbitTelemetrySettingsProvider(TelemetrySettingsProvider["IncomingMessage"]): diff --git a/faststream/rabbit/parser.py b/faststream/rabbit/parser.py index 8fe02dc4b3..f9970c80a7 100644 --- a/faststream/rabbit/parser.py +++ b/faststream/rabbit/parser.py @@ -3,7 +3,7 @@ from aio_pika import Message from aio_pika.abc import DeliveryMode -from faststream.broker.message import ( +from faststream.message import ( StreamMessage, decode_message, encode_message, @@ -17,8 +17,8 @@ from aio_pika import IncomingMessage from aio_pika.abc import DateType, HeadersType + from faststream._internal.basic_types import DecodedMessage from faststream.rabbit.types import AioPikaSendableMessage - from faststream.types import DecodedMessage class AioPikaParser: diff --git a/faststream/rabbit/publisher/producer.py b/faststream/rabbit/publisher/producer.py index ea83ba0672..1614d0c0b2 100644 --- a/faststream/rabbit/publisher/producer.py +++ b/faststream/rabbit/publisher/producer.py @@ -11,12 +11,12 @@ import anyio from typing_extensions import override -from faststream.broker.publisher.proto import ProducerProto -from faststream.broker.utils import resolve_custom_func +from faststream._internal.publisher.proto import ProducerProto +from faststream._internal.subscriber.utils import resolve_custom_func +from faststream._internal.utils.functions import fake_context, timeout_scope from faststream.exceptions import WRONG_PUBLISH_ARGS from faststream.rabbit.parser import AioPikaParser from faststream.rabbit.schemas import RABBIT_REPLY, RabbitExchange -from faststream.utils.functions import fake_context, timeout_scope if TYPE_CHECKING: from types import TracebackType @@ -26,13 +26,13 @@ from aio_pika.abc import AbstractIncomingMessage, DateType, HeadersType, TimeoutType from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream - from faststream.broker.types import ( + from faststream._internal.basic_types import SendableMessage + from faststream._internal.types import ( AsyncCallable, CustomCallable, ) from faststream.rabbit.helpers.declarer import RabbitDeclarer from faststream.rabbit.types import AioPikaSendableMessage - from faststream.types import SendableMessage class AioPikaFastProducer(ProducerProto): diff --git a/faststream/rabbit/publisher/publisher.py b/faststream/rabbit/publisher/publisher.py index f61d069fde..f3967eb769 100644 --- a/faststream/rabbit/publisher/publisher.py +++ b/faststream/rabbit/publisher/publisher.py @@ -17,7 +17,7 @@ if TYPE_CHECKING: from aio_pika import IncomingMessage - from faststream.broker.types import BrokerMiddleware, PublisherMiddleware + from faststream._internal.types import BrokerMiddleware, PublisherMiddleware from faststream.rabbit.schemas import RabbitExchange, RabbitQueue diff --git a/faststream/rabbit/publisher/usecase.py b/faststream/rabbit/publisher/usecase.py index c3306c78d2..4b537fef79 100644 --- a/faststream/rabbit/publisher/usecase.py +++ b/faststream/rabbit/publisher/usecase.py @@ -15,22 +15,22 @@ from aio_pika import IncomingMessage from typing_extensions import Annotated, Doc, TypedDict, Unpack, deprecated, override -from faststream.broker.message import gen_cor_id -from faststream.broker.publisher.usecase import PublisherUsecase +from faststream._internal.publisher.usecase import PublisherUsecase +from faststream._internal.utils.functions import return_input from faststream.exceptions import NOT_CONNECTED_YET +from faststream.message import gen_cor_id from faststream.rabbit.schemas import BaseRMQInformation, RabbitQueue from faststream.rabbit.subscriber.usecase import LogicSubscriber -from faststream.utils.functions import return_input if TYPE_CHECKING: from aio_pika.abc import DateType, HeadersType, TimeoutType - from faststream.broker.types import BrokerMiddleware, PublisherMiddleware + from faststream._internal.basic_types import AnyDict, AsyncFunc + from faststream._internal.types import BrokerMiddleware, PublisherMiddleware from faststream.rabbit.message import RabbitMessage from faststream.rabbit.publisher.producer import AioPikaFastProducer from faststream.rabbit.schemas.exchange import RabbitExchange from faststream.rabbit.types import AioPikaSendableMessage - from faststream.types import AnyDict, AsyncFunc # should be public to use in imports diff --git a/faststream/rabbit/response.py b/faststream/rabbit/response.py index c145f295dd..e75aab7979 100644 --- a/faststream/rabbit/response.py +++ b/faststream/rabbit/response.py @@ -2,13 +2,13 @@ from typing_extensions import override -from faststream.broker.response import Response +from faststream.response import Response if TYPE_CHECKING: from aio_pika.abc import DateType, TimeoutType + from faststream._internal.basic_types import AnyDict from faststream.rabbit.types import AioPikaSendableMessage - from faststream.types import AnyDict class RabbitResponse(Response): diff --git a/faststream/rabbit/router.py b/faststream/rabbit/router.py index 7e1986c8c6..a2de4128f2 100644 --- a/faststream/rabbit/router.py +++ b/faststream/rabbit/router.py @@ -1,9 +1,12 @@ from typing import TYPE_CHECKING, Any, Awaitable, Callable, Iterable, Optional, Union -from typing_extensions import Annotated, Doc, deprecated +from typing_extensions import Annotated, Doc -from faststream.broker.router import ArgsContainer, BrokerRouter, SubscriberRoute -from faststream.broker.utils import default_filter +from faststream._internal.broker.router import ( + ArgsContainer, + BrokerRouter, + SubscriberRoute, +) from faststream.rabbit.broker.registrator import RabbitRegistrator if TYPE_CHECKING: @@ -12,10 +15,10 @@ from broker.types import PublisherMiddleware from fast_depends.dependencies import Depends - from faststream.broker.types import ( + from faststream._internal.basic_types import AnyDict + from faststream._internal.types import ( BrokerMiddleware, CustomCallable, - Filter, SubscriberMiddleware, ) from faststream.rabbit.message import RabbitMessage @@ -23,9 +26,7 @@ RabbitExchange, RabbitQueue, ) - from faststream.rabbit.schemas.reply import ReplyConfig from faststream.rabbit.types import AioPikaSendableMessage - from faststream.types import AnyDict class RabbitPublisher(ArgsContainer): @@ -210,15 +211,6 @@ def __init__( Optional["AnyDict"], Doc("Extra consumer arguments to use in `queue.consume(...)` method."), ] = None, - reply_config: Annotated[ - Optional["ReplyConfig"], - Doc("Extra options to use at replies publishing."), - deprecated( - "Deprecated in **FastStream 0.5.16**. " - "Please, use `RabbitResponse` object as a handler return instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = None, # broker arguments dependencies: Annotated[ Iterable["Depends"], @@ -236,17 +228,6 @@ def __init__( Iterable["SubscriberMiddleware[RabbitMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - "Filter[RabbitMessage]", - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, retry: Annotated[ Union[bool, int], Doc("Whether to `nack` message at processing exception."), @@ -284,12 +265,10 @@ def __init__( queue=queue, exchange=exchange, consume_args=consume_args, - reply_config=reply_config, dependencies=dependencies, parser=parser, decoder=decoder, middlewares=middlewares, - filter=filter, retry=retry, no_ack=no_ack, no_reply=no_reply, diff --git a/faststream/rabbit/schemas/__init__.py b/faststream/rabbit/schemas/__init__.py index ddfb3635cc..02e423031d 100644 --- a/faststream/rabbit/schemas/__init__.py +++ b/faststream/rabbit/schemas/__init__.py @@ -2,13 +2,11 @@ from faststream.rabbit.schemas.exchange import RabbitExchange from faststream.rabbit.schemas.proto import BaseRMQInformation from faststream.rabbit.schemas.queue import RabbitQueue -from faststream.rabbit.schemas.reply import ReplyConfig __all__ = ( "ExchangeType", "RabbitQueue", "RabbitExchange", - "ReplyConfig", "RABBIT_REPLY", "BaseRMQInformation", ) diff --git a/faststream/rabbit/schemas/exchange.py b/faststream/rabbit/schemas/exchange.py index a9dfae79a1..414cba87f9 100644 --- a/faststream/rabbit/schemas/exchange.py +++ b/faststream/rabbit/schemas/exchange.py @@ -3,9 +3,9 @@ from typing_extensions import Annotated, Doc, override -from faststream.broker.schemas import NameRequired +from faststream._internal.basic_types import AnyDict +from faststream._internal.proto import NameRequired from faststream.rabbit.schemas.constants import ExchangeType -from faststream.types import AnyDict if TYPE_CHECKING: from aio_pika.abc import TimeoutType diff --git a/faststream/rabbit/schemas/queue.py b/faststream/rabbit/schemas/queue.py index a9bccf013d..231be101e3 100644 --- a/faststream/rabbit/schemas/queue.py +++ b/faststream/rabbit/schemas/queue.py @@ -3,13 +3,13 @@ from typing_extensions import Annotated, Doc -from faststream.broker.schemas import NameRequired -from faststream.utils.path import compile_path +from faststream._internal.proto import NameRequired +from faststream._internal.utils.path import compile_path if TYPE_CHECKING: from aio_pika.abc import TimeoutType - from faststream.types import AnyDict + from faststream._internal.basic_types import AnyDict class RabbitQueue(NameRequired): diff --git a/faststream/rabbit/schemas/reply.py b/faststream/rabbit/schemas/reply.py deleted file mode 100644 index 0391d4bd8c..0000000000 --- a/faststream/rabbit/schemas/reply.py +++ /dev/null @@ -1,46 +0,0 @@ -from typing import Dict - -from typing_extensions import Annotated, Doc - - -class ReplyConfig: - """Class to store a config for subscribers' replies.""" - - __slots__ = ( - "mandatory", - "immediate", - "persist", - ) - - def __init__( - self, - mandatory: Annotated[ - bool, - Doc( - "Client waits for confirmation that the message is placed to some queue. " - "RabbitMQ returns message to client if there is no suitable queue." - ), - ] = True, - immediate: Annotated[ - bool, - Doc( - "Client expects that there is consumer ready to take the message to work. " - "RabbitMQ returns message to client if there is no suitable consumer." - ), - ] = False, - persist: Annotated[ - bool, - Doc("Restore the message on RabbitMQ reboot."), - ] = False, - ) -> None: - self.mandatory = mandatory - self.immediate = immediate - self.persist = persist - - def to_dict(self) -> Dict[str, bool]: - """Convert object to options dict.""" - return { - "mandatory": self.mandatory, - "immediate": self.immediate, - "persist": self.persist, - } diff --git a/faststream/rabbit/security.py b/faststream/rabbit/security.py index eb887076d6..6878272818 100644 --- a/faststream/rabbit/security.py +++ b/faststream/rabbit/security.py @@ -6,7 +6,7 @@ ) if TYPE_CHECKING: - from faststream.types import AnyDict + from faststream._internal.basic_types import AnyDict def parse_security(security: Optional[BaseSecurity]) -> "AnyDict": diff --git a/faststream/rabbit/subscriber/factory.py b/faststream/rabbit/subscriber/factory.py index 39830f4d2d..6652dd41c0 100644 --- a/faststream/rabbit/subscriber/factory.py +++ b/faststream/rabbit/subscriber/factory.py @@ -1,4 +1,3 @@ -import warnings from typing import TYPE_CHECKING, Iterable, Optional, Union from faststream.rabbit.subscriber.subscriber import SpecificationSubscriber @@ -7,9 +6,9 @@ from aio_pika import IncomingMessage from fast_depends.dependencies import Depends - from faststream.broker.types import BrokerMiddleware - from faststream.rabbit.schemas import RabbitExchange, RabbitQueue, ReplyConfig - from faststream.types import AnyDict + from faststream._internal.basic_types import AnyDict + from faststream._internal.types import BrokerMiddleware + from faststream.rabbit.schemas import RabbitExchange, RabbitQueue def create_subscriber( @@ -17,7 +16,6 @@ def create_subscriber( queue: "RabbitQueue", exchange: "RabbitExchange", consume_args: Optional["AnyDict"], - reply_config: Optional["ReplyConfig"], # Subscriber args no_ack: bool, no_reply: bool, @@ -29,22 +27,10 @@ def create_subscriber( description_: Optional[str], include_in_schema: bool, ) -> SpecificationSubscriber: - if reply_config: # pragma: no cover - warnings.warn( - ( - "\n`reply_config` was deprecated in **FastStream 0.5.16**." - "\nPlease, use `RabbitResponse` object as a handler return instead." - "\nArgument will be removed in **FastStream 0.6.0**." - ), - DeprecationWarning, - stacklevel=2, - ) - return SpecificationSubscriber( queue=queue, exchange=exchange, consume_args=consume_args, - reply_config=reply_config, no_ack=no_ack, no_reply=no_reply, retry=retry, diff --git a/faststream/rabbit/subscriber/usecase.py b/faststream/rabbit/subscriber/usecase.py index 5ed53edf24..0fb1c1cfbb 100644 --- a/faststream/rabbit/subscriber/usecase.py +++ b/faststream/rabbit/subscriber/usecase.py @@ -12,11 +12,10 @@ import anyio from typing_extensions import override -from faststream.broker.publisher.fake import FakePublisher -from faststream.broker.subscriber.usecase import SubscriberUsecase -from faststream.broker.utils import process_msg +from faststream._internal.publisher.fake import FakePublisher +from faststream._internal.subscriber.usecase import SubscriberUsecase +from faststream._internal.subscriber.utils import process_msg from faststream.exceptions import SetupError -from faststream.rabbit.helpers.declarer import RabbitDeclarer from faststream.rabbit.parser import AioPikaParser from faststream.rabbit.schemas import BaseRMQInformation @@ -24,17 +23,16 @@ from aio_pika import IncomingMessage, RobustQueue from fast_depends.dependencies import Depends - from faststream.broker.message import StreamMessage - from faststream.broker.types import BrokerMiddleware, CustomCallable + from faststream._internal.basic_types import AnyDict, Decorator, LoggerProto + from faststream._internal.types import BrokerMiddleware, CustomCallable + from faststream.message import StreamMessage from faststream.rabbit.helpers.declarer import RabbitDeclarer from faststream.rabbit.message import RabbitMessage from faststream.rabbit.publisher.producer import AioPikaFastProducer from faststream.rabbit.schemas import ( RabbitExchange, RabbitQueue, - ReplyConfig, ) - from faststream.types import AnyDict, Decorator, LoggerProto class LogicSubscriber( @@ -56,7 +54,6 @@ def __init__( queue: "RabbitQueue", exchange: "RabbitExchange", consume_args: Optional["AnyDict"], - reply_config: Optional["ReplyConfig"], # Subscriber args no_ack: bool, no_reply: bool, @@ -86,7 +83,6 @@ def __init__( ) self.consume_args = consume_args or {} - self.reply_config = reply_config.to_dict() if reply_config else {} self._consumer_tag = None self._queue_obj = None @@ -224,7 +220,6 @@ def _make_response_publisher( FakePublisher( self._producer.publish, publish_kwargs={ - **self.reply_config, "routing_key": message.reply_to, "app_id": self.app_id, }, diff --git a/faststream/rabbit/testing.py b/faststream/rabbit/testing.py index afc6ace2d7..12c5136b9f 100644 --- a/faststream/rabbit/testing.py +++ b/faststream/rabbit/testing.py @@ -10,9 +10,11 @@ from pamqp.header import ContentHeader from typing_extensions import override -from faststream.broker.message import gen_cor_id -from faststream.broker.utils import resolve_custom_func +from faststream._internal.subscriber.utils import resolve_custom_func +from faststream._internal.testing.broker import TestBroker +from faststream._internal.utils.functions import timeout_scope from faststream.exceptions import WRONG_PUBLISH_ARGS, SubscriberNotFound +from faststream.message import gen_cor_id from faststream.rabbit.broker.broker import RabbitBroker from faststream.rabbit.parser import AioPikaParser from faststream.rabbit.publisher.producer import AioPikaFastProducer @@ -22,8 +24,6 @@ RabbitExchange, RabbitQueue, ) -from faststream.testing.broker import TestBroker -from faststream.utils.functions import timeout_scope if TYPE_CHECKING: from aio_pika.abc import DateType, HeadersType, TimeoutType diff --git a/faststream/rabbit/types.py b/faststream/rabbit/types.py index fb5bca3e3c..127100d59a 100644 --- a/faststream/rabbit/types.py +++ b/faststream/rabbit/types.py @@ -3,6 +3,6 @@ import aio_pika from typing_extensions import TypeAlias -from faststream.types import SendableMessage +from faststream._internal.basic_types import SendableMessage AioPikaSendableMessage: TypeAlias = Union[aio_pika.Message, SendableMessage] diff --git a/faststream/redis/__init__.py b/faststream/redis/__init__.py index 7624747bf8..dafc1744bd 100644 --- a/faststream/redis/__init__.py +++ b/faststream/redis/__init__.py @@ -1,10 +1,10 @@ +from faststream._internal.testing.app import TestApp from faststream.redis.annotations import Redis, RedisMessage from faststream.redis.broker.broker import RedisBroker from faststream.redis.response import RedisResponse from faststream.redis.router import RedisPublisher, RedisRoute, RedisRouter from faststream.redis.schemas import ListSub, PubSub, StreamSub from faststream.redis.testing import TestRedisBroker -from faststream.testing.app import TestApp __all__ = ( "Redis", diff --git a/faststream/redis/annotations.py b/faststream/redis/annotations.py index 2e9741ef70..a34f106e62 100644 --- a/faststream/redis/annotations.py +++ b/faststream/redis/annotations.py @@ -1,10 +1,11 @@ from redis.asyncio.client import Redis as RedisClient from typing_extensions import Annotated -from faststream.annotations import ContextRepo, Logger, NoCast +from faststream._internal.context import Context +from faststream.annotations import ContextRepo, Logger +from faststream.params import NoCast from faststream.redis.broker.broker import RedisBroker as RB from faststream.redis.message import UnifyRedisMessage -from faststream.utils.context import Context __all__ = ( "Logger", diff --git a/faststream/redis/broker/broker.py b/faststream/redis/broker/broker.py index d1644fde7e..b65a02008f 100644 --- a/faststream/redis/broker/broker.py +++ b/faststream/redis/broker/broker.py @@ -26,13 +26,13 @@ from typing_extensions import Annotated, Doc, TypeAlias, deprecated, override from faststream.__about__ import __version__ -from faststream.broker.message import gen_cor_id +from faststream._internal.constants import EMPTY from faststream.exceptions import NOT_CONNECTED_YET +from faststream.message import gen_cor_id from faststream.redis.broker.logging import RedisLoggingBroker from faststream.redis.broker.registrator import RedisRegistrator from faststream.redis.publisher.producer import RedisFastProducer from faststream.redis.security import parse_security -from faststream.types import EMPTY if TYPE_CHECKING: from types import TracebackType @@ -41,14 +41,7 @@ from redis.asyncio.connection import BaseParser from typing_extensions import TypedDict, Unpack - from faststream.broker.types import ( - BrokerMiddleware, - CustomCallable, - ) - from faststream.redis.message import BaseMessage, RedisMessage - from faststream.security import BaseSecurity - from faststream.specification.schema.tag import Tag, TagDict - from faststream.types import ( + from faststream._internal.basic_types import ( AnyDict, AsyncFunc, DecodedMessage, @@ -56,6 +49,13 @@ LoggerProto, SendableMessage, ) + from faststream._internal.types import ( + BrokerMiddleware, + CustomCallable, + ) + from faststream.redis.message import BaseMessage, RedisMessage + from faststream.security import BaseSecurity + from faststream.specification.schema.tag import Tag, TagDict class RedisInitKwargs(TypedDict, total=False): host: Optional[str] diff --git a/faststream/redis/broker/logging.py b/faststream/redis/broker/logging.py index b4d94af615..468da8162e 100644 --- a/faststream/redis/broker/logging.py +++ b/faststream/redis/broker/logging.py @@ -1,15 +1,15 @@ import logging from typing import TYPE_CHECKING, Any, ClassVar, Optional -from faststream.broker.core.usecase import BrokerUsecase -from faststream.log.logging import get_broker_logger +from faststream._internal.broker.broker import BrokerUsecase +from faststream._internal.constants import EMPTY +from faststream._internal.log.logging import get_broker_logger from faststream.redis.message import UnifyRedisDict -from faststream.types import EMPTY if TYPE_CHECKING: from redis.asyncio.client import Redis # noqa: F401 - from faststream.types import LoggerProto + from faststream._internal.basic_types import LoggerProto class RedisLoggingBroker(BrokerUsecase[UnifyRedisDict, "Redis[bytes]"]): diff --git a/faststream/redis/broker/registrator.py b/faststream/redis/broker/registrator.py index 227d316fab..0d822da7bb 100644 --- a/faststream/redis/broker/registrator.py +++ b/faststream/redis/broker/registrator.py @@ -1,9 +1,8 @@ from typing import TYPE_CHECKING, Any, Dict, Iterable, Optional, Union, cast -from typing_extensions import Annotated, Doc, deprecated, override +from typing_extensions import Annotated, Doc, override -from faststream.broker.core.abc import ABCBroker -from faststream.broker.utils import default_filter +from faststream._internal.broker.abc_broker import ABCBroker from faststream.redis.message import UnifyRedisDict from faststream.redis.publisher.publisher import SpecificationPublisher from faststream.redis.subscriber.factory import SubsciberType, create_subscriber @@ -12,16 +11,15 @@ if TYPE_CHECKING: from fast_depends.dependencies import Depends - from faststream.broker.types import ( + from faststream._internal.basic_types import AnyDict + from faststream._internal.types import ( CustomCallable, - Filter, PublisherMiddleware, SubscriberMiddleware, ) from faststream.redis.message import UnifyRedisMessage from faststream.redis.publisher.publisher import PublisherType from faststream.redis.schemas import ListSub, PubSub, StreamSub - from faststream.types import AnyDict class RedisRegistrator(ABCBroker[UnifyRedisDict]): @@ -65,17 +63,6 @@ def subscriber( # type: ignore[override] Iterable["SubscriberMiddleware[UnifyRedisMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - "Filter[UnifyRedisMessage]", - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, retry: Annotated[ bool, Doc("Whether to `nack` message at processing exception."), @@ -129,7 +116,6 @@ def subscriber( # type: ignore[override] ) return subscriber.add_call( - filter_=filter, parser_=parser or self._parser, decoder_=decoder or self._decoder, dependencies_=dependencies, diff --git a/faststream/redis/fastapi/__init__.py b/faststream/redis/fastapi/__init__.py index e1f7993047..86cb87a12b 100644 --- a/faststream/redis/fastapi/__init__.py +++ b/faststream/redis/fastapi/__init__.py @@ -1,7 +1,7 @@ from redis.asyncio.client import Redis as RedisClient from typing_extensions import Annotated -from faststream.broker.fastapi.context import Context, ContextRepo, Logger +from faststream._internal.fastapi.context import Context, ContextRepo, Logger from faststream.redis.broker.broker import RedisBroker as RB from faststream.redis.fastapi.fastapi import RedisRouter from faststream.redis.message import BaseMessage as RM # noqa: N814 diff --git a/faststream/redis/fastapi/fastapi.py b/faststream/redis/fastapi/fastapi.py index ebd7d323f5..2c50440075 100644 --- a/faststream/redis/fastapi/fastapi.py +++ b/faststream/redis/fastapi/fastapi.py @@ -27,14 +27,13 @@ from typing_extensions import Annotated, Doc, deprecated, override from faststream.__about__ import SERVICE_NAME -from faststream.broker.fastapi.router import StreamRouter -from faststream.broker.utils import default_filter +from faststream._internal.constants import EMPTY +from faststream._internal.fastapi.router import StreamRouter from faststream.redis.broker.broker import RedisBroker as RB from faststream.redis.message import UnifyRedisDict from faststream.redis.publisher.publisher import SpecificationPublisher from faststream.redis.schemas import ListSub, PubSub, StreamSub from faststream.redis.subscriber.subscriber import SpecificationSubscriber -from faststream.types import EMPTY if TYPE_CHECKING: from enum import Enum @@ -45,17 +44,16 @@ from starlette.responses import Response from starlette.types import ASGIApp, Lifespan - from faststream.broker.types import ( + from faststream._internal.basic_types import AnyDict, LoggerProto + from faststream._internal.types import ( BrokerMiddleware, CustomCallable, - Filter, PublisherMiddleware, SubscriberMiddleware, ) from faststream.redis.message import UnifyRedisMessage from faststream.security import BaseSecurity from faststream.specification.schema.tag import Tag, TagDict - from faststream.types import AnyDict, LoggerProto class RedisRouter(StreamRouter[UnifyRedisDict]): @@ -467,17 +465,6 @@ def subscriber( # type: ignore[override] Iterable["SubscriberMiddleware[UnifyRedisMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - "Filter[UnifyRedisMessage]", - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, retry: Annotated[ bool, Doc("Whether to `nack` message at processing exception."), @@ -642,7 +629,6 @@ def subscriber( # type: ignore[override] parser=parser, decoder=decoder, middlewares=middlewares, - filter=filter, retry=retry, no_ack=no_ack, no_reply=no_reply, diff --git a/faststream/redis/message.py b/faststream/redis/message.py index 8bce4005c8..68d11d7f90 100644 --- a/faststream/redis/message.py +++ b/faststream/redis/message.py @@ -10,12 +10,12 @@ from typing_extensions import NotRequired, TypeAlias, TypedDict, override -from faststream.broker.message import StreamMessage as BrokerStreamMessage +from faststream.message import StreamMessage as BrokerStreamMessage if TYPE_CHECKING: from redis.asyncio import Redis - from faststream.types import DecodedMessage + from faststream._internal.basic_types import DecodedMessage BaseMessage: TypeAlias = Union[ diff --git a/faststream/redis/opentelemetry/provider.py b/faststream/redis/opentelemetry/provider.py index a809db603d..043a6efbe5 100644 --- a/faststream/redis/opentelemetry/provider.py +++ b/faststream/redis/opentelemetry/provider.py @@ -6,8 +6,8 @@ from faststream.opentelemetry.consts import MESSAGING_DESTINATION_PUBLISH_NAME if TYPE_CHECKING: - from faststream.broker.message import StreamMessage - from faststream.types import AnyDict + from faststream._internal.basic_types import AnyDict + from faststream.message import StreamMessage class RedisTelemetrySettingsProvider(TelemetrySettingsProvider["AnyDict"]): diff --git a/faststream/redis/parser.py b/faststream/redis/parser.py index d42297af77..b529b70648 100644 --- a/faststream/redis/parser.py +++ b/faststream/redis/parser.py @@ -11,13 +11,14 @@ Union, ) -from faststream._compat import dump_json, json_loads -from faststream.broker.message import ( +from faststream._internal._compat import dump_json, json_loads +from faststream._internal.basic_types import AnyDict, DecodedMessage, SendableMessage +from faststream._internal.constants import ContentTypes +from faststream.message import ( decode_message, encode_message, gen_cor_id, ) -from faststream.constants import ContentTypes from faststream.redis.message import ( RedisBatchListMessage, RedisBatchStreamMessage, @@ -26,12 +27,11 @@ RedisStreamMessage, bDATA_KEY, ) -from faststream.types import AnyDict, DecodedMessage, SendableMessage if TYPE_CHECKING: from re import Pattern - from faststream.broker.message import StreamMessage + from faststream.message import StreamMessage MsgType = TypeVar("MsgType", bound=Mapping[str, Any]) diff --git a/faststream/redis/publisher/producer.py b/faststream/redis/publisher/producer.py index 3dc44271e0..afcb416aa6 100644 --- a/faststream/redis/publisher/producer.py +++ b/faststream/redis/publisher/producer.py @@ -3,23 +3,23 @@ import anyio from typing_extensions import override -from faststream.broker.publisher.proto import ProducerProto -from faststream.broker.utils import resolve_custom_func +from faststream._internal.publisher.proto import ProducerProto +from faststream._internal.subscriber.utils import resolve_custom_func +from faststream._internal.utils.functions import timeout_scope +from faststream._internal.utils.nuid import NUID from faststream.exceptions import WRONG_PUBLISH_ARGS, SetupError from faststream.redis.message import DATA_KEY from faststream.redis.parser import RawMessage, RedisPubSubParser from faststream.redis.schemas import INCORRECT_SETUP_MSG -from faststream.utils.functions import timeout_scope -from faststream.utils.nuid import NUID if TYPE_CHECKING: from redis.asyncio.client import PubSub, Redis - from faststream.broker.types import ( + from faststream._internal.basic_types import AnyDict, SendableMessage + from faststream._internal.types import ( AsyncCallable, CustomCallable, ) - from faststream.types import AnyDict, SendableMessage class RedisFastProducer(ProducerProto): diff --git a/faststream/redis/publisher/publisher.py b/faststream/redis/publisher/publisher.py index 759308872e..ac66d37c41 100644 --- a/faststream/redis/publisher/publisher.py +++ b/faststream/redis/publisher/publisher.py @@ -19,9 +19,9 @@ from faststream.specification.schema.operation import Operation if TYPE_CHECKING: - from faststream.broker.types import BrokerMiddleware, PublisherMiddleware + from faststream._internal.basic_types import AnyDict + from faststream._internal.types import BrokerMiddleware, PublisherMiddleware from faststream.redis.message import UnifyRedisDict - from faststream.types import AnyDict PublisherType: TypeAlias = Union[ "AsyncAPIChannelPublisher", diff --git a/faststream/redis/publisher/usecase.py b/faststream/redis/publisher/usecase.py index cc9a523439..5f7e57a475 100644 --- a/faststream/redis/publisher/usecase.py +++ b/faststream/redis/publisher/usecase.py @@ -7,18 +7,18 @@ from typing_extensions import Annotated, Doc, deprecated, override -from faststream.broker.message import gen_cor_id -from faststream.broker.publisher.usecase import PublisherUsecase +from faststream._internal.publisher.usecase import PublisherUsecase +from faststream._internal.utils.functions import return_input from faststream.exceptions import NOT_CONNECTED_YET +from faststream.message import gen_cor_id from faststream.redis.message import UnifyRedisDict from faststream.redis.schemas import ListSub, PubSub, StreamSub -from faststream.utils.functions import return_input if TYPE_CHECKING: - from faststream.broker.types import BrokerMiddleware, PublisherMiddleware + from faststream._internal.basic_types import AnyDict, AsyncFunc, SendableMessage + from faststream._internal.types import BrokerMiddleware, PublisherMiddleware from faststream.redis.message import RedisMessage from faststream.redis.publisher.producer import RedisFastProducer - from faststream.types import AnyDict, AsyncFunc, SendableMessage class LogicPublisher(PublisherUsecase[UnifyRedisDict]): diff --git a/faststream/redis/response.py b/faststream/redis/response.py index 9656fbc7b3..2896fd48b8 100644 --- a/faststream/redis/response.py +++ b/faststream/redis/response.py @@ -2,10 +2,10 @@ from typing_extensions import override -from faststream.broker.response import Response +from faststream.response import Response if TYPE_CHECKING: - from faststream.types import AnyDict, SendableMessage + from faststream._internal.basic_types import AnyDict, SendableMessage class RedisResponse(Response): diff --git a/faststream/redis/router.py b/faststream/redis/router.py index 38964c2c59..bf1035d7f6 100644 --- a/faststream/redis/router.py +++ b/faststream/redis/router.py @@ -1,25 +1,27 @@ from typing import TYPE_CHECKING, Any, Awaitable, Callable, Iterable, Optional, Union -from typing_extensions import Annotated, Doc, deprecated +from typing_extensions import Annotated, Doc -from faststream.broker.router import ArgsContainer, BrokerRouter, SubscriberRoute -from faststream.broker.utils import default_filter +from faststream._internal.broker.router import ( + ArgsContainer, + BrokerRouter, + SubscriberRoute, +) from faststream.redis.broker.registrator import RedisRegistrator from faststream.redis.message import BaseMessage if TYPE_CHECKING: from fast_depends.dependencies import Depends - from faststream.broker.types import ( + from faststream._internal.basic_types import AnyDict, SendableMessage + from faststream._internal.types import ( BrokerMiddleware, CustomCallable, - Filter, PublisherMiddleware, SubscriberMiddleware, ) from faststream.redis.message import UnifyRedisMessage from faststream.redis.schemas import ListSub, PubSub, StreamSub - from faststream.types import AnyDict, SendableMessage class RedisPublisher(ArgsContainer): @@ -144,17 +146,6 @@ def __init__( Iterable["SubscriberMiddleware[UnifyRedisMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - filter: Annotated[ - "Filter[UnifyRedisMessage]", - Doc( - "Overload subscriber to consume various messages from the same source." - ), - deprecated( - "Deprecated in **FastStream 0.5.0**. " - "Please, create `subscriber` object and use it explicitly instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = default_filter, retry: Annotated[ bool, Doc("Whether to `nack` message at processing exception."), @@ -196,7 +187,6 @@ def __init__( parser=parser, decoder=decoder, middlewares=middlewares, - filter=filter, retry=retry, no_ack=no_ack, no_reply=no_reply, diff --git a/faststream/redis/schemas/list_sub.py b/faststream/redis/schemas/list_sub.py index 544db9e86e..53660bb546 100644 --- a/faststream/redis/schemas/list_sub.py +++ b/faststream/redis/schemas/list_sub.py @@ -1,7 +1,7 @@ from functools import cached_property from typing import Optional -from faststream.broker.schemas import NameRequired +from faststream._internal.proto import NameRequired class ListSub(NameRequired): diff --git a/faststream/redis/schemas/pub_sub.py b/faststream/redis/schemas/pub_sub.py index 5277cc1213..4ec950256b 100644 --- a/faststream/redis/schemas/pub_sub.py +++ b/faststream/redis/schemas/pub_sub.py @@ -1,5 +1,5 @@ -from faststream.broker.schemas import NameRequired -from faststream.utils.path import compile_path +from faststream._internal.proto import NameRequired +from faststream._internal.utils.path import compile_path class PubSub(NameRequired): diff --git a/faststream/redis/schemas/stream_sub.py b/faststream/redis/schemas/stream_sub.py index 7ab768cb28..cbc4cd8504 100644 --- a/faststream/redis/schemas/stream_sub.py +++ b/faststream/redis/schemas/stream_sub.py @@ -1,7 +1,7 @@ import warnings from typing import Optional -from faststream.broker.schemas import NameRequired +from faststream._internal.proto import NameRequired from faststream.exceptions import SetupError diff --git a/faststream/redis/security.py b/faststream/redis/security.py index 08db65778d..8fea384ecc 100644 --- a/faststream/redis/security.py +++ b/faststream/redis/security.py @@ -5,7 +5,7 @@ from faststream.security import BaseSecurity, SASLPlaintext if TYPE_CHECKING: - from faststream.types import AnyDict + from faststream._internal.basic_types import AnyDict def parse_security(security: Optional[BaseSecurity]) -> "AnyDict": diff --git a/faststream/redis/subscriber/factory.py b/faststream/redis/subscriber/factory.py index 7f387ab058..d1097e41ce 100644 --- a/faststream/redis/subscriber/factory.py +++ b/faststream/redis/subscriber/factory.py @@ -16,7 +16,7 @@ if TYPE_CHECKING: from fast_depends.dependencies import Depends - from faststream.broker.types import BrokerMiddleware + from faststream._internal.types import BrokerMiddleware from faststream.redis.message import UnifyRedisDict SubsciberType: TypeAlias = Union[ diff --git a/faststream/redis/subscriber/usecase.py b/faststream/redis/subscriber/usecase.py index a67095e986..6ef23b05f8 100644 --- a/faststream/redis/subscriber/usecase.py +++ b/faststream/redis/subscriber/usecase.py @@ -22,9 +22,9 @@ from redis.exceptions import ResponseError from typing_extensions import TypeAlias, override -from faststream.broker.publisher.fake import FakePublisher -from faststream.broker.subscriber.usecase import SubscriberUsecase -from faststream.broker.utils import process_msg +from faststream._internal.publisher.fake import FakePublisher +from faststream._internal.subscriber.usecase import SubscriberUsecase +from faststream._internal.subscriber.utils import process_msg from faststream.redis.message import ( BatchListMessage, BatchStreamMessage, @@ -48,14 +48,14 @@ if TYPE_CHECKING: from fast_depends.dependencies import Depends - from faststream.broker.message import StreamMessage as BrokerStreamMessage - from faststream.broker.publisher.proto import ProducerProto - from faststream.broker.types import ( + from faststream._internal.basic_types import AnyDict, Decorator, LoggerProto + from faststream._internal.publisher.proto import ProducerProto + from faststream._internal.types import ( AsyncCallable, BrokerMiddleware, CustomCallable, ) - from faststream.types import AnyDict, Decorator, LoggerProto + from faststream.message import StreamMessage as BrokerStreamMessage TopicName: TypeAlias = bytes diff --git a/faststream/redis/testing.py b/faststream/redis/testing.py index 5ef5e1c360..8a7c1f0d05 100644 --- a/faststream/redis/testing.py +++ b/faststream/redis/testing.py @@ -15,9 +15,11 @@ import anyio from typing_extensions import TypedDict, override -from faststream.broker.message import gen_cor_id -from faststream.broker.utils import resolve_custom_func +from faststream._internal.subscriber.utils import resolve_custom_func +from faststream._internal.testing.broker import TestBroker +from faststream._internal.utils.functions import timeout_scope from faststream.exceptions import WRONG_PUBLISH_ARGS, SetupError, SubscriberNotFound +from faststream.message import gen_cor_id from faststream.redis.broker.broker import RedisBroker from faststream.redis.message import ( BatchListMessage, @@ -36,12 +38,10 @@ _ListHandlerMixin, _StreamHandlerMixin, ) -from faststream.testing.broker import TestBroker -from faststream.utils.functions import timeout_scope if TYPE_CHECKING: + from faststream._internal.basic_types import AnyDict, SendableMessage from faststream.redis.publisher.publisher import SpecificationPublisher - from faststream.types import AnyDict, SendableMessage __all__ = ("TestRedisBroker",) diff --git a/faststream/response/__init__.py b/faststream/response/__init__.py new file mode 100644 index 0000000000..686ec1dc50 --- /dev/null +++ b/faststream/response/__init__.py @@ -0,0 +1,7 @@ +from .response import Response +from .utils import ensure_response + +__all__ = ( + "Response", + "ensure_response", +) diff --git a/faststream/broker/response.py b/faststream/response/response.py similarity index 74% rename from faststream/broker/response.py rename to faststream/response/response.py index fb08993251..7cfed34628 100644 --- a/faststream/broker/response.py +++ b/faststream/response/response.py @@ -1,13 +1,13 @@ -from typing import TYPE_CHECKING, Any, Optional, Union +from typing import TYPE_CHECKING, Any, Optional if TYPE_CHECKING: - from faststream.types import AnyDict + from faststream._internal.basic_types import AnyDict class Response: def __init__( self, - body: "Any", + body: Any, *, headers: Optional["AnyDict"] = None, correlation_id: Optional[str] = None, @@ -34,10 +34,3 @@ def as_publish_kwargs(self) -> "AnyDict": "correlation_id": self.correlation_id, } return publish_options - - -def ensure_response(response: Union["Response", "Any"]) -> "Response": - if isinstance(response, Response): - return response - - return Response(response) diff --git a/faststream/response/utils.py b/faststream/response/utils.py new file mode 100644 index 0000000000..c29f366a5d --- /dev/null +++ b/faststream/response/utils.py @@ -0,0 +1,10 @@ +from typing import Any, Union + +from .response import Response + + +def ensure_response(response: Union[Response, Any]) -> Response: + if isinstance(response, Response): + return response + + return Response(response) diff --git a/faststream/security.py b/faststream/security.py index 4bcd4eba99..e4b05b7ac9 100644 --- a/faststream/security.py +++ b/faststream/security.py @@ -3,7 +3,7 @@ if TYPE_CHECKING: from ssl import SSLContext - from faststream.types import AnyDict + from faststream._internal.basic_types import AnyDict class BaseSecurity: diff --git a/faststream/specification/asyncapi/base/schema/info.py b/faststream/specification/asyncapi/base/schema/info.py index 6472de4334..c808a49d06 100644 --- a/faststream/specification/asyncapi/base/schema/info.py +++ b/faststream/specification/asyncapi/base/schema/info.py @@ -1,6 +1,6 @@ from pydantic import BaseModel -from faststream._compat import ( +from faststream._internal._compat import ( PYDANTIC_V2, ) diff --git a/faststream/specification/asyncapi/base/schema/schema.py b/faststream/specification/asyncapi/base/schema/schema.py index 49e8c90fd1..ed8b51c075 100644 --- a/faststream/specification/asyncapi/base/schema/schema.py +++ b/faststream/specification/asyncapi/base/schema/schema.py @@ -2,7 +2,7 @@ from pydantic import BaseModel -from faststream._compat import model_to_json, model_to_jsonable +from faststream._internal._compat import model_to_json, model_to_jsonable from faststream.specification.asyncapi.base.schema.info import BaseInfo diff --git a/faststream/specification/asyncapi/message.py b/faststream/specification/asyncapi/message.py index 08b5a38e1c..26d7d8d3eb 100644 --- a/faststream/specification/asyncapi/message.py +++ b/faststream/specification/asyncapi/message.py @@ -3,8 +3,13 @@ from pydantic import BaseModel, create_model -from faststream._compat import DEF_KEY, PYDANTIC_V2, get_model_fields, model_schema -from faststream.types import AnyDict +from faststream._internal._compat import ( + DEF_KEY, + PYDANTIC_V2, + get_model_fields, + model_schema, +) +from faststream._internal.basic_types import AnyDict if TYPE_CHECKING: from fast_depends.core import CallModel diff --git a/faststream/specification/asyncapi/site.py b/faststream/specification/asyncapi/site.py index 278b059e3a..92608c3615 100644 --- a/faststream/specification/asyncapi/site.py +++ b/faststream/specification/asyncapi/site.py @@ -3,8 +3,8 @@ from typing import TYPE_CHECKING, Any, Dict from urllib.parse import parse_qs, urlparse -from faststream._compat import json_dumps -from faststream.log import logger +from faststream._internal._compat import json_dumps +from faststream._internal.log import logger if TYPE_CHECKING: from faststream.specification.asyncapi.base.schema import BaseSchema diff --git a/faststream/specification/asyncapi/utils.py b/faststream/specification/asyncapi/utils.py index 4edddae6ad..516adb15c2 100644 --- a/faststream/specification/asyncapi/utils.py +++ b/faststream/specification/asyncapi/utils.py @@ -1,7 +1,7 @@ from typing import TYPE_CHECKING, List, Tuple if TYPE_CHECKING: - from faststream.types import AnyDict + from faststream._internal.basic_types import AnyDict def to_camelcase(*names: str) -> str: diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index c3e36294eb..886aa715f4 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -1,7 +1,8 @@ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union -from faststream._compat import DEF_KEY -from faststream.constants import ContentTypes +from faststream._internal._compat import DEF_KEY +from faststream._internal.basic_types import AnyDict +from faststream._internal.constants import ContentTypes from faststream.specification.asyncapi.v2_6_0.schema import ( Channel, Components, @@ -18,11 +19,10 @@ ) from faststream.specification.asyncapi.v2_6_0.schema.message import Message from faststream.specification.proto import Application -from faststream.types import AnyDict if TYPE_CHECKING: - from faststream.broker.core.usecase import BrokerUsecase - from faststream.broker.types import ConnectionType, MsgType + from faststream._internal.broker.broker import BrokerUsecase + from faststream._internal.types import ConnectionType, MsgType def get_app_schema(app: Application) -> Schema: diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation.py index 016eb825d9..005cc92cf7 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation.py @@ -8,8 +8,8 @@ from pydantic import BaseModel from typing_extensions import Self +from faststream._internal.basic_types import AnyDict from faststream.specification import schema as spec -from faststream.types import AnyDict class OperationBinding(BaseModel): diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel.py index 533fd0e1a3..e19da52a5e 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel.py @@ -3,7 +3,7 @@ from pydantic import BaseModel from typing_extensions import Self -from faststream._compat import PYDANTIC_V2 +from faststream._internal._compat import PYDANTIC_V2 from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( amqp as amqp_bindings, diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation.py index 1b827809de..46864ab289 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation.py @@ -3,7 +3,7 @@ from pydantic import BaseModel from typing_extensions import Self -from faststream._compat import PYDANTIC_V2 +from faststream._internal._compat import PYDANTIC_V2 from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( amqp as amqp_bindings, diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation.py index 7911763747..b38a2f89dd 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation.py @@ -8,8 +8,8 @@ from pydantic import BaseModel from typing_extensions import Self +from faststream._internal.basic_types import AnyDict from faststream.specification import schema as spec -from faststream.types import AnyDict class OperationBinding(BaseModel): diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation.py index a6a28678bd..39a4c94b99 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation.py @@ -8,8 +8,8 @@ from pydantic import BaseModel from typing_extensions import Self +from faststream._internal.basic_types import AnyDict from faststream.specification import schema as spec -from faststream.types import AnyDict class OperationBinding(BaseModel): diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs.py index 52cc73cf3d..5eed3c9984 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs.py @@ -8,8 +8,8 @@ from pydantic import BaseModel from typing_extensions import Self +from faststream._internal.basic_types import AnyDict from faststream.specification import schema as spec -from faststream.types import AnyDict class ChannelBinding(BaseModel): diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel.py index dcb78f727d..631e9c7bb4 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel.py @@ -6,8 +6,8 @@ from pydantic import BaseModel from typing_extensions import Self +from faststream._internal.basic_types import AnyDict from faststream.specification import schema as spec -from faststream.types import AnyDict class ChannelBinding(BaseModel): diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation.py index ee55d78cdd..4ea0ece20a 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation.py @@ -8,8 +8,8 @@ from pydantic import BaseModel from typing_extensions import Self +from faststream._internal.basic_types import AnyDict from faststream.specification import schema as spec -from faststream.types import AnyDict class OperationBinding(BaseModel): diff --git a/faststream/specification/asyncapi/v2_6_0/schema/channels.py b/faststream/specification/asyncapi/v2_6_0/schema/channels.py index b9aee43ca9..72af50eb97 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/channels.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/channels.py @@ -3,7 +3,7 @@ from pydantic import BaseModel from typing_extensions import Self -from faststream._compat import PYDANTIC_V2 +from faststream._internal._compat import PYDANTIC_V2 from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( ChannelBinding, diff --git a/faststream/specification/asyncapi/v2_6_0/schema/components.py b/faststream/specification/asyncapi/v2_6_0/schema/components.py index ea8840e16b..884c5b86ba 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/components.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/components.py @@ -5,11 +5,11 @@ from pydantic import BaseModel -from faststream._compat import ( +from faststream._internal._compat import ( PYDANTIC_V2, ) +from faststream._internal.basic_types import AnyDict from faststream.specification.asyncapi.v2_6_0.schema.message import Message -from faststream.types import AnyDict class Components(BaseModel): diff --git a/faststream/specification/asyncapi/v2_6_0/schema/contact.py b/faststream/specification/asyncapi/v2_6_0/schema/contact.py index b5ad2df8a5..8a3b23c417 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/contact.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/contact.py @@ -11,16 +11,16 @@ from pydantic import AnyHttpUrl, BaseModel from typing_extensions import Self -from faststream._compat import ( +from faststream._internal._compat import ( PYDANTIC_V2, CoreSchema, GetJsonSchemaHandler, JsonSchemaValue, with_info_plain_validator_function, ) -from faststream.log import logger +from faststream._internal.basic_types import AnyDict +from faststream._internal.log import logger from faststream.specification import schema as spec -from faststream.types import AnyDict try: import email_validator diff --git a/faststream/specification/asyncapi/v2_6_0/schema/docs.py b/faststream/specification/asyncapi/v2_6_0/schema/docs.py index 3b0d56d5fe..34b2e3ed8d 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/docs.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/docs.py @@ -3,9 +3,9 @@ from pydantic import AnyHttpUrl, BaseModel from typing_extensions import Self -from faststream._compat import PYDANTIC_V2 +from faststream._internal._compat import PYDANTIC_V2 +from faststream._internal.basic_types import AnyDict from faststream.specification import schema as spec -from faststream.types import AnyDict class ExternalDocs(BaseModel): diff --git a/faststream/specification/asyncapi/v2_6_0/schema/info.py b/faststream/specification/asyncapi/v2_6_0/schema/info.py index f9030fa05f..2afa9a08cd 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/info.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/info.py @@ -5,10 +5,10 @@ from pydantic import AnyHttpUrl +from faststream._internal.basic_types import AnyDict from faststream.specification.asyncapi.base.schema import BaseInfo from faststream.specification.asyncapi.v2_6_0.schema.contact import Contact from faststream.specification.asyncapi.v2_6_0.schema.license import License -from faststream.types import AnyDict class Info(BaseInfo): diff --git a/faststream/specification/asyncapi/v2_6_0/schema/license.py b/faststream/specification/asyncapi/v2_6_0/schema/license.py index d81e1530a1..761511789a 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/license.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/license.py @@ -7,11 +7,11 @@ from pydantic import AnyHttpUrl, BaseModel from typing_extensions import Self -from faststream._compat import ( +from faststream._internal._compat import ( PYDANTIC_V2, ) +from faststream._internal.basic_types import AnyDict from faststream.specification import schema as spec -from faststream.types import AnyDict class License(BaseModel): diff --git a/faststream/specification/asyncapi/v2_6_0/schema/message.py b/faststream/specification/asyncapi/v2_6_0/schema/message.py index fbf991bc8a..576773bd28 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/message.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/message.py @@ -3,13 +3,13 @@ import typing_extensions from pydantic import BaseModel -from faststream._compat import PYDANTIC_V2 +from faststream._internal._compat import PYDANTIC_V2 +from faststream._internal.basic_types import AnyDict from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag from faststream.specification.asyncapi.v2_6_0.schema.tag import ( from_spec as tag_from_spec, ) -from faststream.types import AnyDict class CorrelationId(BaseModel): diff --git a/faststream/specification/asyncapi/v2_6_0/schema/operations.py b/faststream/specification/asyncapi/v2_6_0/schema/operations.py index f84f8fdb8f..c6ba7e93cf 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/operations.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/operations.py @@ -3,7 +3,8 @@ from pydantic import BaseModel from typing_extensions import Self -from faststream._compat import PYDANTIC_V2 +from faststream._internal._compat import PYDANTIC_V2 +from faststream._internal.basic_types import AnyDict from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.schema.bindings import OperationBinding from faststream.specification.asyncapi.v2_6_0.schema.bindings.main import ( @@ -20,7 +21,6 @@ from faststream.specification.asyncapi.v2_6_0.schema.utils import ( Reference, ) -from faststream.types import AnyDict class Operation(BaseModel): diff --git a/faststream/specification/asyncapi/v2_6_0/schema/schema.py b/faststream/specification/asyncapi/v2_6_0/schema/schema.py index f2e691f5bb..81b29d06a2 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/schema.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/schema.py @@ -1,5 +1,6 @@ from typing import Dict, List, Literal, Optional, Union +from faststream._internal.basic_types import AnyDict from faststream.specification.asyncapi.base.schema import BaseSchema from faststream.specification.asyncapi.v2_6_0.schema.channels import Channel from faststream.specification.asyncapi.v2_6_0.schema.components import Components @@ -7,7 +8,6 @@ from faststream.specification.asyncapi.v2_6_0.schema.info import Info from faststream.specification.asyncapi.v2_6_0.schema.servers import Server from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag -from faststream.types import AnyDict class Schema(BaseSchema): diff --git a/faststream/specification/asyncapi/v2_6_0/schema/servers.py b/faststream/specification/asyncapi/v2_6_0/schema/servers.py index 318e2a40c9..9220c893b7 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/servers.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/servers.py @@ -2,10 +2,10 @@ from pydantic import BaseModel -from faststream._compat import PYDANTIC_V2 +from faststream._internal._compat import PYDANTIC_V2 +from faststream._internal.basic_types import AnyDict from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag from faststream.specification.asyncapi.v2_6_0.schema.utils import Reference -from faststream.types import AnyDict SecurityRequirement = List[Dict[str, List[str]]] diff --git a/faststream/specification/asyncapi/v2_6_0/schema/tag.py b/faststream/specification/asyncapi/v2_6_0/schema/tag.py index b8688f8162..1e1b0d4696 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/tag.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/tag.py @@ -3,7 +3,8 @@ import typing_extensions from pydantic import BaseModel -from faststream._compat import PYDANTIC_V2 +from faststream._internal._compat import PYDANTIC_V2 +from faststream._internal.basic_types import AnyDict from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.schema.docs import ( ExternalDocs, @@ -11,7 +12,6 @@ from faststream.specification.asyncapi.v2_6_0.schema.docs import ( from_spec as docs_from_spec, ) -from faststream.types import AnyDict class Tag(BaseModel): diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index 37028b82a1..c4fac01933 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -1,8 +1,9 @@ from typing import TYPE_CHECKING, Dict, List, Optional, Union from urllib.parse import urlparse -from faststream._compat import DEF_KEY -from faststream.constants import ContentTypes +from faststream._internal._compat import DEF_KEY +from faststream._internal.basic_types import AnyDict +from faststream._internal.constants import ContentTypes from faststream.specification.asyncapi.v2_6_0.generate import move_pydantic_refs from faststream.specification.asyncapi.v2_6_0.schema import ( Reference, @@ -27,11 +28,10 @@ Action, ) from faststream.specification.proto import Application -from faststream.types import AnyDict if TYPE_CHECKING: - from faststream.broker.core.usecase import BrokerUsecase - from faststream.broker.types import ConnectionType, MsgType + from faststream._internal.broker.broker import BrokerUsecase + from faststream._internal.types import ConnectionType, MsgType def get_app_schema(app: Application) -> Schema: diff --git a/faststream/specification/asyncapi/v3_0_0/schema/channels.py b/faststream/specification/asyncapi/v3_0_0/schema/channels.py index aaa6b657d7..75021725ba 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/channels.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/channels.py @@ -3,7 +3,7 @@ from pydantic import BaseModel from typing_extensions import Self -from faststream._compat import PYDANTIC_V2 +from faststream._internal._compat import PYDANTIC_V2 from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.schema.bindings import ChannelBinding from faststream.specification.asyncapi.v2_6_0.schema.bindings.main import ( diff --git a/faststream/specification/asyncapi/v3_0_0/schema/components.py b/faststream/specification/asyncapi/v3_0_0/schema/components.py index 57d0e1b03f..342dddfd4f 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/components.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/components.py @@ -2,9 +2,9 @@ from pydantic import BaseModel -from faststream._compat import PYDANTIC_V2 +from faststream._internal._compat import PYDANTIC_V2 +from faststream._internal.basic_types import AnyDict from faststream.specification.asyncapi.v2_6_0.schema.message import Message -from faststream.types import AnyDict class Components(BaseModel): diff --git a/faststream/specification/asyncapi/v3_0_0/schema/info.py b/faststream/specification/asyncapi/v3_0_0/schema/info.py index 45bb3e5372..23759f5b89 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/info.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/info.py @@ -6,6 +6,9 @@ from pydantic import AnyHttpUrl +from faststream._internal.basic_types import ( + AnyDict, +) from faststream.specification.asyncapi.base.schema import BaseInfo from faststream.specification.asyncapi.v2_6_0.schema import ( Contact, @@ -13,9 +16,6 @@ License, Tag, ) -from faststream.types import ( - AnyDict, -) class Info(BaseInfo): diff --git a/faststream/specification/asyncapi/v3_0_0/schema/operations.py b/faststream/specification/asyncapi/v3_0_0/schema/operations.py index a0e89cbb3b..ef06352522 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/operations.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/operations.py @@ -4,7 +4,8 @@ from pydantic import BaseModel from typing_extensions import Self -from faststream._compat import PYDANTIC_V2 +from faststream._internal._compat import PYDANTIC_V2 +from faststream._internal.basic_types import AnyDict from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.schema.bindings import OperationBinding from faststream.specification.asyncapi.v2_6_0.schema.bindings.main import ( @@ -15,7 +16,6 @@ Reference, ) from faststream.specification.asyncapi.v3_0_0.schema.channels import Channel -from faststream.types import AnyDict class Action(str, Enum): diff --git a/faststream/specification/asyncapi/v3_0_0/schema/servers.py b/faststream/specification/asyncapi/v3_0_0/schema/servers.py index d8edab9180..6d49226452 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/servers.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/servers.py @@ -2,10 +2,10 @@ from pydantic import BaseModel -from faststream._compat import PYDANTIC_V2 +from faststream._internal._compat import PYDANTIC_V2 +from faststream._internal.basic_types import AnyDict from faststream.specification.asyncapi.v2_6_0.schema import ServerVariable, Tag from faststream.specification.asyncapi.v2_6_0.schema.utils import Reference -from faststream.types import AnyDict SecurityRequirement = List[Dict[str, List[str]]] diff --git a/faststream/specification/proto.py b/faststream/specification/proto.py index 13702cae37..de9514573b 100644 --- a/faststream/specification/proto.py +++ b/faststream/specification/proto.py @@ -6,15 +6,15 @@ from faststream.specification.schema.channel import Channel if TYPE_CHECKING: - from faststream.broker.core.usecase import BrokerUsecase + from faststream._internal.basic_types import ( + AnyDict, + AnyHttpUrl, + ) + from faststream._internal.broker.broker import BrokerUsecase from faststream.specification.schema.contact import Contact, ContactDict from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict from faststream.specification.schema.license import License, LicenseDict from faststream.specification.schema.tag import Tag - from faststream.types import ( - AnyDict, - AnyHttpUrl, - ) class Application(Protocol): diff --git a/faststream/specification/schema/components.py b/faststream/specification/schema/components.py index e7755c2748..bcce7129bb 100644 --- a/faststream/specification/schema/components.py +++ b/faststream/specification/schema/components.py @@ -6,7 +6,7 @@ from pydantic import BaseModel -from faststream._compat import ( +from faststream._internal._compat import ( PYDANTIC_V2, ) from faststream.specification.schema.message import Message diff --git a/faststream/specification/schema/contact.py b/faststream/specification/schema/contact.py index dec0c5d5cc..e51f5286d5 100644 --- a/faststream/specification/schema/contact.py +++ b/faststream/specification/schema/contact.py @@ -9,14 +9,14 @@ from pydantic import AnyHttpUrl, BaseModel from typing_extensions import Required, TypedDict -from faststream._compat import ( +from faststream._internal._compat import ( PYDANTIC_V2, CoreSchema, GetJsonSchemaHandler, JsonSchemaValue, with_info_plain_validator_function, ) -from faststream.log import logger +from faststream._internal.log import logger try: import email_validator diff --git a/faststream/specification/schema/license.py b/faststream/specification/schema/license.py index 7bf7c20042..bc88795f6f 100644 --- a/faststream/specification/schema/license.py +++ b/faststream/specification/schema/license.py @@ -5,7 +5,7 @@ from pydantic import AnyHttpUrl, BaseModel from typing_extensions import Required, TypedDict -from faststream._compat import ( +from faststream._internal._compat import ( PYDANTIC_V2, ) diff --git a/faststream/specification/schema/schema.py b/faststream/specification/schema/schema.py index f3dafed01b..6b2f5d4942 100644 --- a/faststream/specification/schema/schema.py +++ b/faststream/specification/schema/schema.py @@ -2,7 +2,7 @@ from pydantic import BaseModel -from faststream._compat import model_to_json, model_to_jsonable +from faststream._internal._compat import model_to_json, model_to_jsonable from faststream.specification.asyncapi.base.schema import BaseInfo diff --git a/faststream/specification/schema/security.py b/faststream/specification/schema/security.py index a157dc5cf5..ccb621a4dd 100644 --- a/faststream/specification/schema/security.py +++ b/faststream/specification/schema/security.py @@ -2,7 +2,7 @@ from pydantic import AnyHttpUrl, BaseModel, Field -from faststream._compat import PYDANTIC_V2 +from faststream._internal._compat import PYDANTIC_V2 class OauthFlowObj(BaseModel): diff --git a/faststream/specification/schema/servers.py b/faststream/specification/schema/servers.py index 92e87f1ec3..619a5fc3c6 100644 --- a/faststream/specification/schema/servers.py +++ b/faststream/specification/schema/servers.py @@ -2,7 +2,7 @@ from pydantic import BaseModel -from faststream._compat import PYDANTIC_V2 +from faststream._internal._compat import PYDANTIC_V2 from faststream.specification.schema.tag import Tag SecurityRequirement = List[Dict[str, List[str]]] diff --git a/faststream/testing/__init__.py b/faststream/testing/__init__.py deleted file mode 100644 index f1a3c33c12..0000000000 --- a/faststream/testing/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from faststream.testing.app import TestApp - -__all__ = ("TestApp",) diff --git a/faststream/utils/__init__.py b/faststream/utils/__init__.py deleted file mode 100644 index 049e708b4d..0000000000 --- a/faststream/utils/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -from fast_depends import Depends -from fast_depends import inject as apply_types - -from faststream.utils.context import Context, ContextRepo, Header, Path, context -from faststream.utils.no_cast import NoCast - -__all__ = ( - "apply_types", - "context", - "Context", - "Header", - "Path", - "ContextRepo", - "Depends", - "NoCast", -) diff --git a/faststream/utils/classes.py b/faststream/utils/classes.py deleted file mode 100644 index 1bf053cbce..0000000000 --- a/faststream/utils/classes.py +++ /dev/null @@ -1,40 +0,0 @@ -from typing import Any, ClassVar, Optional - -from typing_extensions import Self - - -class Singleton: - """A class to implement the Singleton design pattern. - - Attributes: - _instance : the single instance of the class - - Methods: - __new__ : creates a new instance of the class if it doesn't exist, otherwise returns the existing instance - _drop : sets the instance to None, allowing a new instance to be created - """ - - _instance: ClassVar[Optional[Self]] = None - - def __new__(cls, *args: Any, **kwargs: Any) -> Self: - """Create a singleton instance of a class. - - Args: - *args: Variable length argument list - **kwargs: Arbitrary keyword arguments - - Returns: - The singleton instance of the class - """ - if cls._instance is None: - cls._instance = super().__new__(cls) - return cls._instance - - @classmethod - def _drop(cls) -> None: - """Drop the instance of a class. - - Returns: - None - """ - cls._instance = None diff --git a/faststream/utils/context/__init__.py b/faststream/utils/context/__init__.py deleted file mode 100644 index 0c4609c499..0000000000 --- a/faststream/utils/context/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -from faststream.utils.context.builders import Context, Header, Path -from faststream.utils.context.repository import ContextRepo, context - -__all__ = ( - "Context", - "context", - "ContextRepo", - "Header", - "Path", -) diff --git a/faststream/utils/data.py b/faststream/utils/data.py deleted file mode 100644 index cf00f649ef..0000000000 --- a/faststream/utils/data.py +++ /dev/null @@ -1,21 +0,0 @@ -from typing import Type, TypeVar - -from faststream.types import AnyDict - -TypedDictCls = TypeVar("TypedDictCls") - - -def filter_by_dict(typed_dict: Type[TypedDictCls], data: AnyDict) -> TypedDictCls: - """Filter a dictionary based on a typed dictionary. - - Args: - typed_dict: The typed dictionary to filter by. - data: The dictionary to filter. - - Returns: - A new instance of the typed dictionary with only the keys present in the data dictionary. - """ - annotations = typed_dict.__annotations__ - return typed_dict( # type: ignore - {k: v for k, v in data.items() if k in annotations} - ) diff --git a/pyproject.toml b/pyproject.toml index e92057e7c9..7919811427 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -269,9 +269,15 @@ convention = "google" extend-immutable-calls = [ "faststream.Depends", "faststream.Context", - "faststream.broker.fastapi.context.Context", "faststream.Header", "faststream.Path", + "faststream.NoCast", + "faststream.params.Depends", + "faststream.params.Context", + "faststream.params.Header", + "faststream.params.Path", + "faststream.params.NoCast", + "faststream._internal.fastapi.context.Context", "faststream.utils.Header", "faststream.utils.Path", "faststream.utils.Depends", diff --git a/tests/a_docs/confluent/basic/test_cmd_run.py b/tests/a_docs/confluent/basic/test_cmd_run.py index 46a63b4257..419e2ad76a 100644 --- a/tests/a_docs/confluent/basic/test_cmd_run.py +++ b/tests/a_docs/confluent/basic/test_cmd_run.py @@ -4,8 +4,8 @@ import pytest from typer.testing import CliRunner +from faststream._internal.cli.main import cli from faststream.app import FastStream -from faststream.cli.main import cli @pytest.fixture diff --git a/tests/a_docs/kafka/basic/test_cmd_run.py b/tests/a_docs/kafka/basic/test_cmd_run.py index 0d7609faf6..71e59013fb 100644 --- a/tests/a_docs/kafka/basic/test_cmd_run.py +++ b/tests/a_docs/kafka/basic/test_cmd_run.py @@ -4,8 +4,8 @@ import pytest from typer.testing import CliRunner +from faststream._internal.cli.main import cli from faststream.app import FastStream -from faststream.cli.main import cli @pytest.mark.kafka diff --git a/tests/asyncapi/base/v2_6_0/arguments.py b/tests/asyncapi/base/v2_6_0/arguments.py index 26d1b1e187..2b62e99907 100644 --- a/tests/asyncapi/base/v2_6_0/arguments.py +++ b/tests/asyncapi/base/v2_6_0/arguments.py @@ -9,8 +9,8 @@ from typing_extensions import Annotated, Literal from faststream import Context, FastStream -from faststream._compat import PYDANTIC_V2 -from faststream.broker.core.usecase import BrokerUsecase +from faststream._internal._compat import PYDANTIC_V2 +from faststream._internal.broker.broker import BrokerUsecase from faststream.specification.asyncapi.generate import get_app_schema from tests.marks import pydantic_v2 @@ -547,36 +547,6 @@ async def handle(user: Model): ... }, }, schema["components"] - def test_with_filter(self): - class User(pydantic.BaseModel): - name: str = "" - id: int - - broker = self.broker_class() - - sub = broker.subscriber("test/one") - - @sub( - filter=lambda m: m.content_type == "application/json", - ) - async def handle(id: int): ... - - @sub - async def handle_default(msg): ... - - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() - - name, message = next(iter(schema["components"]["messages"].items())) - - assert name == IsStr(regex=r"test.one[\w:]*:Handle:Message"), name - - assert len(message["payload"]["oneOf"]) == 2 - - payload = schema["components"]["schemas"] - - assert "Handle:Message:Payload" in list(payload.keys()) - assert "HandleDefault:Message:Payload" in list(payload.keys()) - class ArgumentsTestcase(FastAPICompatible): dependency_builder = staticmethod(Depends) @@ -646,3 +616,37 @@ async def handle(id: int, user: Optional[str] = None, message=Context()): ... "type": "object", } ) + + def test_with_filter(self): + # TODO: move it to FastAPICompatible with FastAPI refactore + class User(pydantic.BaseModel): + name: str = "" + id: int + + broker = self.broker_class() + + sub = broker.subscriber("test") + + @sub( + filter=lambda m: m.content_type == "application/json", + ) + async def handle(id: int): ... + + @sub + async def handle_default(msg): ... + + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + + assert ( + len( + next(iter(schema["components"]["messages"].values()))["payload"][ + "oneOf" + ] + ) + == 2 + ) + + payload = schema["components"]["schemas"] + + assert "Handle:Message:Payload" in list(payload.keys()) + assert "HandleDefault:Message:Payload" in list(payload.keys()) diff --git a/tests/asyncapi/base/v2_6_0/fastapi.py b/tests/asyncapi/base/v2_6_0/fastapi.py index 2b9415268c..9cae10870d 100644 --- a/tests/asyncapi/base/v2_6_0/fastapi.py +++ b/tests/asyncapi/base/v2_6_0/fastapi.py @@ -5,9 +5,9 @@ from fastapi import FastAPI from fastapi.testclient import TestClient -from faststream.broker.core.usecase import BrokerUsecase -from faststream.broker.fastapi.router import StreamRouter -from faststream.broker.types import MsgType +from faststream._internal.broker.broker import BrokerUsecase +from faststream._internal.fastapi.router import StreamRouter +from faststream._internal.types import MsgType from faststream.specification.asyncapi.generate import get_app_schema diff --git a/tests/asyncapi/base/v2_6_0/naming.py b/tests/asyncapi/base/v2_6_0/naming.py index 4713dcdd79..bf8fd6c623 100644 --- a/tests/asyncapi/base/v2_6_0/naming.py +++ b/tests/asyncapi/base/v2_6_0/naming.py @@ -4,7 +4,7 @@ from pydantic import create_model from faststream import FastStream -from faststream.broker.core.usecase import BrokerUsecase +from faststream._internal.broker.broker import BrokerUsecase from faststream.specification.asyncapi.generate import get_app_schema diff --git a/tests/asyncapi/base/v2_6_0/publisher.py b/tests/asyncapi/base/v2_6_0/publisher.py index 86abe51361..3983996aea 100644 --- a/tests/asyncapi/base/v2_6_0/publisher.py +++ b/tests/asyncapi/base/v2_6_0/publisher.py @@ -3,7 +3,7 @@ import pydantic from faststream import FastStream -from faststream.broker.core.usecase import BrokerUsecase +from faststream._internal.broker.broker import BrokerUsecase from faststream.specification.asyncapi.generate import get_app_schema diff --git a/tests/asyncapi/base/v2_6_0/router.py b/tests/asyncapi/base/v2_6_0/router.py index 112e6e6d40..dbb391baa6 100644 --- a/tests/asyncapi/base/v2_6_0/router.py +++ b/tests/asyncapi/base/v2_6_0/router.py @@ -3,8 +3,12 @@ from dirty_equals import IsStr from faststream import FastStream -from faststream.broker.core.usecase import BrokerUsecase -from faststream.broker.router import ArgsContainer, BrokerRouter, SubscriberRoute +from faststream._internal.broker.broker import BrokerUsecase +from faststream._internal.broker.router import ( + ArgsContainer, + BrokerRouter, + SubscriberRoute, +) from faststream.specification.asyncapi.generate import get_app_schema diff --git a/tests/asyncapi/base/v3_0_0/arguments.py b/tests/asyncapi/base/v3_0_0/arguments.py index fb9708bbc0..57ff9b4ce1 100644 --- a/tests/asyncapi/base/v3_0_0/arguments.py +++ b/tests/asyncapi/base/v3_0_0/arguments.py @@ -9,9 +9,9 @@ from typing_extensions import Annotated, Literal from faststream import Context, FastStream -from faststream._compat import PYDANTIC_V2 -from faststream.broker.core.usecase import BrokerUsecase -from faststream.broker.fastapi import StreamRouter +from faststream._internal._compat import PYDANTIC_V2 +from faststream._internal.broker.broker import BrokerUsecase +from faststream._internal.fastapi import StreamRouter from faststream.specification.asyncapi.generate import get_app_schema from tests.marks import pydantic_v2 @@ -404,13 +404,14 @@ class User(pydantic.BaseModel): broker = self.broker_factory() - @broker.subscriber( # pragma: no branch - "test", + sub = broker.subscriber("test") + + @sub( # pragma: no branch filter=lambda m: m.content_type == "application/json", ) async def handle(id: int): ... - @broker.subscriber("test") + @sub async def handle_default(msg): ... schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() diff --git a/tests/asyncapi/base/v3_0_0/fastapi.py b/tests/asyncapi/base/v3_0_0/fastapi.py index 5a1a9d1432..f1d4a1bafa 100644 --- a/tests/asyncapi/base/v3_0_0/fastapi.py +++ b/tests/asyncapi/base/v3_0_0/fastapi.py @@ -5,9 +5,9 @@ from fastapi import FastAPI from fastapi.testclient import TestClient -from faststream.broker.core.usecase import BrokerUsecase -from faststream.broker.fastapi.router import StreamRouter -from faststream.broker.types import MsgType +from faststream._internal.broker.broker import BrokerUsecase +from faststream._internal.fastapi.router import StreamRouter +from faststream._internal.types import MsgType from faststream.specification.asyncapi.generate import get_app_schema diff --git a/tests/asyncapi/base/v3_0_0/naming.py b/tests/asyncapi/base/v3_0_0/naming.py index 790b5ddfba..0759aa6894 100644 --- a/tests/asyncapi/base/v3_0_0/naming.py +++ b/tests/asyncapi/base/v3_0_0/naming.py @@ -4,7 +4,7 @@ from pydantic import create_model from faststream import FastStream -from faststream.broker.core.usecase import BrokerUsecase +from faststream._internal.broker.broker import BrokerUsecase from faststream.specification.asyncapi.generate import get_app_schema diff --git a/tests/asyncapi/base/v3_0_0/publisher.py b/tests/asyncapi/base/v3_0_0/publisher.py index 8120827358..908fb5232b 100644 --- a/tests/asyncapi/base/v3_0_0/publisher.py +++ b/tests/asyncapi/base/v3_0_0/publisher.py @@ -3,8 +3,8 @@ import pydantic from faststream import FastStream -from faststream.broker.core.usecase import BrokerUsecase -from faststream.broker.fastapi import StreamRouter +from faststream._internal.broker.broker import BrokerUsecase +from faststream._internal.fastapi import StreamRouter from faststream.specification.asyncapi.generate import get_app_schema diff --git a/tests/asyncapi/base/v3_0_0/router.py b/tests/asyncapi/base/v3_0_0/router.py index 255079dfa5..e7446dd1ef 100644 --- a/tests/asyncapi/base/v3_0_0/router.py +++ b/tests/asyncapi/base/v3_0_0/router.py @@ -3,8 +3,12 @@ from dirty_equals import IsStr from faststream import FastStream -from faststream.broker.core.usecase import BrokerUsecase -from faststream.broker.router import ArgsContainer, BrokerRouter, SubscriberRoute +from faststream._internal.broker.broker import BrokerUsecase +from faststream._internal.broker.router import ( + ArgsContainer, + BrokerRouter, + SubscriberRoute, +) from faststream.specification.asyncapi.generate import get_app_schema diff --git a/tests/brokers/base/connection.py b/tests/brokers/base/connection.py index 1614b6151b..8bd9319a59 100644 --- a/tests/brokers/base/connection.py +++ b/tests/brokers/base/connection.py @@ -2,7 +2,7 @@ import pytest -from faststream.broker.core.usecase import BrokerUsecase +from faststream._internal.broker.broker import BrokerUsecase class BrokerConnectionTestcase: diff --git a/tests/brokers/base/consume.py b/tests/brokers/base/consume.py index 0e7b07b698..9c01be73b7 100644 --- a/tests/brokers/base/consume.py +++ b/tests/brokers/base/consume.py @@ -8,7 +8,7 @@ from pydantic import BaseModel from faststream import Context, Depends -from faststream.broker.core.usecase import BrokerUsecase +from faststream._internal.broker.broker import BrokerUsecase from faststream.exceptions import StopConsume from .basic import BaseTestcaseConfig diff --git a/tests/brokers/base/fastapi.py b/tests/brokers/base/fastapi.py index f20dd61866..75292309b1 100644 --- a/tests/brokers/base/fastapi.py +++ b/tests/brokers/base/fastapi.py @@ -9,11 +9,11 @@ from fastapi.testclient import TestClient from faststream import context -from faststream.broker.core.usecase import BrokerUsecase -from faststream.broker.fastapi.context import Context -from faststream.broker.fastapi.router import StreamRouter -from faststream.broker.router import BrokerRouter -from faststream.types import AnyCallable +from faststream._internal.basic_types import AnyCallable +from faststream._internal.broker.broker import BrokerUsecase +from faststream._internal.broker.router import BrokerRouter +from faststream._internal.fastapi.context import Context +from faststream._internal.fastapi.router import StreamRouter from .basic import BaseTestcaseConfig @@ -218,13 +218,12 @@ async def hello(): with TestClient(app) as client: assert client.app_state["broker"] is router.broker - r = await router.broker.publish( + r = await router.broker.request( "hi", queue, - rpc=True, - rpc_timeout=0.5, + timeout=0.5, ) - assert r == "hi", r + assert await r.decode() == "hi", r async def test_base_without_state(self, queue: str): router = self.router_class(setup_state=False) @@ -241,13 +240,12 @@ async def hello(): with TestClient(app) as client: assert not client.app_state.get("broker") - r = await router.broker.publish( + r = await router.broker.request( "hi", queue, - rpc=True, - rpc_timeout=0.5, + timeout=0.5, ) - assert r == "hi" + assert await r.decode() == "hi", r async def test_invalid(self, queue: str): router = self.router_class() @@ -276,14 +274,13 @@ async def hello(w=Header()): return w async with self.broker_test(router.broker): - r = await router.broker.publish( + r = await router.broker.request( "", queue, headers={"w": "hi"}, - rpc=True, - rpc_timeout=0.5, + timeout=0.5, ) - assert r == "hi" + assert await r.decode() == "hi", r async def test_depends(self, mock: Mock, queue: str): router = self.router_class() @@ -299,13 +296,12 @@ async def hello(a, w=Depends(dep)): return w async with self.broker_test(router.broker): - r = await router.broker.publish( + r = await router.broker.request( {"a": "hi"}, queue, - rpc=True, - rpc_timeout=0.5, + timeout=0.5, ) - assert r == "hi" + assert await r.decode() == "hi", r mock.assert_called_once_with("hi") @@ -326,13 +322,12 @@ async def hello(a, w=Depends(dep)): return w async with self.broker_test(router.broker): - r = await router.broker.publish( + r = await router.broker.request( {"a": "hi"}, queue, - rpc=True, - rpc_timeout=0.5, + timeout=0.5, ) - assert r == "hi" + assert await r.decode() == "hi", r mock.start.assert_called_once() mock.close.assert_called_once() @@ -350,8 +345,8 @@ async def hello(a): return a async with self.broker_test(router.broker): - r = await router.broker.publish("hi", queue, rpc=True, rpc_timeout=0.5) - assert r == "hi" + r = await router.broker.request("hi", queue, timeout=0.5) + assert await r.decode() == "hi", r mock.assert_called_once() @@ -371,13 +366,12 @@ async def hello(a): return a async with self.broker_test(router.broker): - r = await router.broker.publish( + r = await router.broker.request( "hi", queue, - rpc=True, - rpc_timeout=0.5, + timeout=0.5, ) - assert r == "hi" + assert await r.decode() == "hi", r mock.assert_called_once() @@ -486,21 +480,19 @@ async def hello_router2(): with TestClient(app) as client: assert client.app_state["broker"] is router.broker - r = await router.broker.publish( + r = await router.broker.request( "hi", queue, - rpc=True, - rpc_timeout=0.5, + timeout=0.5, ) - assert r == "hi" + assert await r.decode() == "hi", r - r = await router.broker.publish( + r = await router.broker.request( "hi", queue + "1", - rpc=True, - rpc_timeout=0.5, + timeout=0.5, ) - assert r == "hi" + assert await r.decode() == "hi", r async def test_dependency_overrides(self, mock: Mock, queue: str): router = self.router_class() @@ -526,13 +518,12 @@ async def hello_router2(dep=Depends(dep1)): with TestClient(app) as client: assert client.app_state["broker"] is router.broker - r = await router.broker.publish( + r = await router.broker.request( "hi", queue, - rpc=True, - rpc_timeout=0.5, + timeout=0.5, ) - assert r == "hi" + assert await r.decode() == "hi", r mock.assert_called_once() assert not mock.not_call.called diff --git a/tests/brokers/base/middlewares.py b/tests/brokers/base/middlewares.py index 07560708ef..1f33d372ea 100644 --- a/tests/brokers/base/middlewares.py +++ b/tests/brokers/base/middlewares.py @@ -5,10 +5,10 @@ import pytest from faststream import Context -from faststream.broker.core.usecase import BrokerUsecase -from faststream.broker.middlewares import BaseMiddleware, ExceptionMiddleware +from faststream._internal.basic_types import DecodedMessage +from faststream._internal.broker.broker import BrokerUsecase from faststream.exceptions import SkipMessage -from faststream.types import DecodedMessage +from faststream.middlewares import BaseMiddleware, ExceptionMiddleware from .basic import BaseTestcaseConfig diff --git a/tests/brokers/base/parser.py b/tests/brokers/base/parser.py index c4a47683c3..cdb833c40b 100644 --- a/tests/brokers/base/parser.py +++ b/tests/brokers/base/parser.py @@ -4,7 +4,7 @@ import pytest -from faststream.broker.core.usecase import BrokerUsecase +from faststream._internal.broker.broker import BrokerUsecase from .basic import BaseTestcaseConfig @@ -178,11 +178,10 @@ async def test_local_parser_no_share_between_handlers( ): broker = self.broker_class() - args, kwargs = self.get_subscriber_params( - queue, filter=lambda m: m.content_type == "application/json" - ) + args, kwargs = self.get_subscriber_params(queue) + sub = broker.subscriber(*args, **kwargs) - @broker.subscriber(*args, **kwargs) + @sub(filter=lambda m: m.content_type == "application/json") async def handle(m): event.set() @@ -193,9 +192,7 @@ async def custom_parser(msg, original): mock(msg.body) return msg - args2, kwargs2 = self.get_subscriber_params(queue, parser=custom_parser) - - @broker.subscriber(*args2, **kwargs2) + @sub(parser=custom_parser) async def handle2(m): event2.set() diff --git a/tests/brokers/base/publish.py b/tests/brokers/base/publish.py index c94b9ca6bb..8e10e8f5d0 100644 --- a/tests/brokers/base/publish.py +++ b/tests/brokers/base/publish.py @@ -10,8 +10,8 @@ from pydantic import BaseModel from faststream import BaseMiddleware, Context, Response -from faststream._compat import dump_json, model_to_json -from faststream.broker.core.usecase import BrokerUsecase +from faststream._internal._compat import dump_json, model_to_json +from faststream._internal.broker.broker import BrokerUsecase from .basic import BaseTestcaseConfig diff --git a/tests/brokers/base/router.py b/tests/brokers/base/router.py index 02d60cd578..abd80e5da7 100644 --- a/tests/brokers/base/router.py +++ b/tests/brokers/base/router.py @@ -5,9 +5,13 @@ import pytest from faststream import BaseMiddleware, Depends -from faststream.broker.core.usecase import BrokerUsecase -from faststream.broker.router import ArgsContainer, BrokerRouter, SubscriberRoute -from faststream.types import AnyCallable +from faststream._internal.basic_types import AnyCallable +from faststream._internal.broker.broker import BrokerUsecase +from faststream._internal.broker.router import ( + ArgsContainer, + BrokerRouter, + SubscriberRoute, +) from tests.brokers.base.middlewares import LocalMiddlewareTestcase from tests.brokers.base.parser import LocalCustomParserTestcase diff --git a/tests/brokers/base/rpc.py b/tests/brokers/base/rpc.py deleted file mode 100644 index dcdd8e85e0..0000000000 --- a/tests/brokers/base/rpc.py +++ /dev/null @@ -1,131 +0,0 @@ -import asyncio -from abc import abstractstaticmethod -from typing import Any -from unittest.mock import MagicMock - -import anyio -import pytest - -from faststream.broker.core.usecase import BrokerUsecase -from faststream.utils.functions import timeout_scope - -from .basic import BaseTestcaseConfig - - -class BrokerRPCTestcase(BaseTestcaseConfig): - @abstractstaticmethod - def get_broker(self, apply_types: bool = False) -> BrokerUsecase[Any, Any]: - raise NotImplementedError - - def patch_broker(self, broker: BrokerUsecase[Any, Any]) -> BrokerUsecase[Any, Any]: - return broker - - @pytest.mark.asyncio - async def test_rpc(self, queue: str): - rpc_broker = self.get_broker() - - args, kwargs = self.get_subscriber_params(queue) - - @rpc_broker.subscriber(*args, **kwargs) - async def m(m): - return "Hi!" - - async with self.patch_broker(rpc_broker) as br: - await br.start() - r = await br.publish("hello", queue, rpc_timeout=3, rpc=True) - - assert r == "Hi!" - - @pytest.mark.asyncio - async def test_rpc_timeout_raises(self, queue: str): - rpc_broker = self.get_broker() - - args, kwargs = self.get_subscriber_params(queue) - - @rpc_broker.subscriber(*args, **kwargs) - async def m(m): # pragma: no cover - await anyio.sleep(1) - - async with self.patch_broker(rpc_broker) as br: - await br.start() - - with pytest.raises(TimeoutError): # pragma: no branch - await br.publish( - "hello", - queue, - rpc=True, - rpc_timeout=0, - raise_timeout=True, - ) - - @pytest.mark.asyncio - async def test_rpc_timeout_none(self, queue: str): - rpc_broker = self.get_broker() - - args, kwargs = self.get_subscriber_params(queue) - - @rpc_broker.subscriber(*args, **kwargs) - async def m(m): # pragma: no cover - await anyio.sleep(1) - - async with self.patch_broker(rpc_broker) as br: - await br.start() - - r = await br.publish( - "hello", - queue, - rpc=True, - rpc_timeout=0, - ) - - assert r is None - - @pytest.mark.asyncio - async def test_rpc_with_reply( - self, - queue: str, - mock: MagicMock, - event: asyncio.Event, - ): - rpc_broker = self.get_broker() - - reply_queue = queue + "1" - - args, kwargs = self.get_subscriber_params(reply_queue) - - @rpc_broker.subscriber(*args, **kwargs) - async def response_hanler(m: str): - mock(m) - event.set() - - args2, kwargs2 = self.get_subscriber_params(queue) - - @rpc_broker.subscriber(*args2, **kwargs2) - async def m(m): - return "1" - - async with self.patch_broker(rpc_broker) as br: - await br.start() - - await br.publish("hello", queue, reply_to=reply_queue) - - with timeout_scope(3, True): - await event.wait() - - mock.assert_called_with("1") - - -class ReplyAndConsumeForbidden: - @pytest.mark.asyncio - async def test_rpc_with_reply_and_callback(self): - rpc_broker = self.get_broker() - - async with rpc_broker: - with pytest.raises(ValueError): # noqa: PT011 - await rpc_broker.publish( - "hello", - "some", - reply_to="some", - rpc=True, - rpc_timeout=0, - ) diff --git a/tests/brokers/base/testclient.py b/tests/brokers/base/testclient.py index 4cc45da756..df4697338a 100644 --- a/tests/brokers/base/testclient.py +++ b/tests/brokers/base/testclient.py @@ -5,17 +5,16 @@ import anyio import pytest -from faststream.testing.broker import TestBroker -from faststream.types import AnyCallable +from faststream._internal.basic_types import AnyCallable +from faststream._internal.testing.broker import TestBroker from tests.brokers.base.consume import BrokerConsumeTestcase from tests.brokers.base.publish import BrokerPublishTestcase -from tests.brokers.base.rpc import BrokerRPCTestcase class BrokerTestclientTestcase( BrokerPublishTestcase, BrokerConsumeTestcase, - BrokerRPCTestcase, + # RequestsTestcase, ): build_message: AnyCallable test_class: TestBroker diff --git a/tests/brokers/confluent/test_logger.py b/tests/brokers/confluent/test_logger.py index 3c2e3a132a..1f91070402 100644 --- a/tests/brokers/confluent/test_logger.py +++ b/tests/brokers/confluent/test_logger.py @@ -4,7 +4,7 @@ import pytest -from faststream.broker.core.usecase import BrokerUsecase +from faststream._internal.broker.broker import BrokerUsecase from faststream.confluent import KafkaBroker from .basic import ConfluentTestcaseConfig diff --git a/tests/brokers/nats/test_fastapi.py b/tests/brokers/nats/test_fastapi.py index 518fdcd637..3c7f5f205b 100644 --- a/tests/brokers/nats/test_fastapi.py +++ b/tests/brokers/nats/test_fastapi.py @@ -117,10 +117,9 @@ async def hello(name): return name async with self.broker_test(router.broker): - r = await router.broker.publish( + r = await router.broker.request( "hi", f"{queue}.john", - rpc=True, - rpc_timeout=0.5, + timeout=0.5, ) - assert r == "john" + assert await r.decode() == "john" diff --git a/tests/brokers/nats/test_publish.py b/tests/brokers/nats/test_publish.py index 1fb8b799d6..e8af505124 100644 --- a/tests/brokers/nats/test_publish.py +++ b/tests/brokers/nats/test_publish.py @@ -70,8 +70,8 @@ async def handle(): await br.start() response = await asyncio.wait_for( - br.publish("", queue, rpc=True), + br.request("", queue), timeout=3, ) - assert response == "Hi!", response + assert await response.decode() == "Hi!", response diff --git a/tests/brokers/nats/test_router.py b/tests/brokers/nats/test_router.py index d882fd881f..e178eed079 100644 --- a/tests/brokers/nats/test_router.py +++ b/tests/brokers/nats/test_router.py @@ -33,11 +33,7 @@ async def h( await pub_broker.start() - await pub_broker.publish( - "", - "in.john.2", - rpc=True, - ) + await pub_broker.request("", "in.john.2") assert event.is_set() mock.assert_called_once_with(name="john", id=2) @@ -64,11 +60,7 @@ async def h( await pub_broker.start() - await pub_broker.publish( - "", - "test.in.john.2", - rpc=True, - ) + await pub_broker.request("", "test.in.john.2") assert event.is_set() mock.assert_called_once_with(name="john", id=2) @@ -94,11 +86,7 @@ async def h( await pub_broker.start() - await pub_broker.publish( - "", - "in.john.2", - rpc=True, - ) + await pub_broker.request("", "in.john.2") assert event.is_set() mock.assert_called_once_with(name="john", id=2) diff --git a/tests/brokers/nats/test_rpc.py b/tests/brokers/nats/test_rpc.py deleted file mode 100644 index d863008fb4..0000000000 --- a/tests/brokers/nats/test_rpc.py +++ /dev/null @@ -1,26 +0,0 @@ -import pytest - -from faststream.nats import JStream, NatsBroker -from tests.brokers.base.rpc import BrokerRPCTestcase, ReplyAndConsumeForbidden - - -@pytest.mark.nats -class TestRPC(BrokerRPCTestcase, ReplyAndConsumeForbidden): - def get_broker(self, apply_types: bool = False) -> NatsBroker: - return NatsBroker(apply_types=apply_types) - - @pytest.mark.asyncio - async def test_rpc_js(self, queue: str, stream: JStream): - rpc_broker = self.get_broker() - - @rpc_broker.subscriber(queue, stream=stream) - async def m(m): # pragma: no cover - return "1" - - async with rpc_broker: - await rpc_broker.start() - - r = await rpc_broker.publish( - "hello", queue, rpc_timeout=3, stream=stream.name, rpc=True - ) - assert r == "1" diff --git a/tests/brokers/nats/test_test_client.py b/tests/brokers/nats/test_test_client.py index b8f7f8d5b2..28c8526c25 100644 --- a/tests/brokers/nats/test_test_client.py +++ b/tests/brokers/nats/test_test_client.py @@ -3,7 +3,6 @@ import pytest from faststream import BaseMiddleware -from faststream.exceptions import SetupError from faststream.nats import ConsumerConfig, JStream, NatsBroker, PullSub, TestNatsBroker from faststream.nats.testing import FakeProducer from tests.brokers.base.testclient import BrokerTestclientTestcase @@ -50,17 +49,6 @@ async def m(msg): ... await br.publish("Hi!", queue, stream="test") assert not m.mock.called - @pytest.mark.asyncio - async def test_rpc_conflicts_reply(self, queue): - async with TestNatsBroker(NatsBroker()) as br: - with pytest.raises(SetupError): - await br.publish( - "", - queue, - rpc=True, - reply_to="response", - ) - @pytest.mark.nats async def test_with_real_testclient( self, diff --git a/tests/brokers/rabbit/core/test_depends.py b/tests/brokers/rabbit/core/test_depends.py index 7b4f0e72bd..21f498d268 100644 --- a/tests/brokers/rabbit/core/test_depends.py +++ b/tests/brokers/rabbit/core/test_depends.py @@ -1,9 +1,9 @@ import aio_pika import pytest +from faststream import Depends from faststream.rabbit import RabbitBroker from faststream.rabbit.annotations import RabbitMessage -from faststream.utils import Depends @pytest.mark.asyncio @@ -35,7 +35,7 @@ async def h( await full_broker.start() - await full_broker.publish(queue=queue, rpc=True) + await full_broker.request(queue=queue) assert check_message is True @@ -61,8 +61,8 @@ async def consumer2(message: RabbitMessage): await full_broker.start() - await full_broker.publish(queue="test_different_consume_1", rpc=True) - await full_broker.publish(queue="test_different_consume_2", rpc=True) + await full_broker.request(queue="test_different_consume_1") + await full_broker.request(queue="test_different_consume_2") assert isinstance(message1.raw_message, aio_pika.IncomingMessage) assert isinstance(message2.raw_message, aio_pika.IncomingMessage) diff --git a/tests/brokers/rabbit/test_fastapi.py b/tests/brokers/rabbit/test_fastapi.py index 18fff70dc6..0dd0fcef52 100644 --- a/tests/brokers/rabbit/test_fastapi.py +++ b/tests/brokers/rabbit/test_fastapi.py @@ -77,11 +77,10 @@ async def hello(name): return name async with self.broker_test(router.broker): - r = await router.broker.publish( + r = await router.broker.request( "hi", "in.john", "test", - rpc=True, - rpc_timeout=0.5, + timeout=0.5, ) - assert r == "john" + assert await r.decode() == "john" diff --git a/tests/brokers/rabbit/test_publish.py b/tests/brokers/rabbit/test_publish.py index f747bb6b29..1e68f8ac1e 100644 --- a/tests/brokers/rabbit/test_publish.py +++ b/tests/brokers/rabbit/test_publish.py @@ -4,7 +4,7 @@ import pytest from faststream import Context -from faststream.rabbit import RabbitBroker, RabbitResponse, ReplyConfig +from faststream.rabbit import RabbitBroker, RabbitResponse from faststream.rabbit.publisher.producer import AioPikaFastProducer from tests.brokers.base.publish import BrokerPublishTestcase from tests.tools import spy_decorator @@ -31,11 +31,9 @@ async def reply_handler(m): event.set() mock(m) - with pytest.warns(DeprecationWarning): - - @pub_broker.subscriber(queue, reply_config=ReplyConfig(persist=True)) - async def handler(m): - return m + @pub_broker.subscriber(queue) + async def handler(m): + return RabbitResponse(m, persist=True) async with self.patch_broker(pub_broker) as br: with patch.object( @@ -121,8 +119,8 @@ async def handle(): await br.start() response = await asyncio.wait_for( - br.publish("", queue, rpc=True), + br.request("", queue), timeout=3, ) - assert response == "Hi!", response + assert await response.decode() == "Hi!", response diff --git a/tests/brokers/rabbit/test_router.py b/tests/brokers/rabbit/test_router.py index 6cbd2557a4..2d58bab9e9 100644 --- a/tests/brokers/rabbit/test_router.py +++ b/tests/brokers/rabbit/test_router.py @@ -51,11 +51,10 @@ async def h( await pub_broker.start() - await pub_broker.publish( + await pub_broker.request( "", "in.john.2", queue + "1", - rpc=True, ) assert event.is_set() @@ -97,11 +96,10 @@ async def h( await pub_broker.start() - await pub_broker.publish( + await pub_broker.request( "", "in.john.2", queue + "1", - rpc=True, ) assert event.is_set() diff --git a/tests/brokers/rabbit/test_rpc.py b/tests/brokers/rabbit/test_rpc.py deleted file mode 100644 index 68e6d12812..0000000000 --- a/tests/brokers/rabbit/test_rpc.py +++ /dev/null @@ -1,10 +0,0 @@ -import pytest - -from faststream.rabbit import RabbitBroker -from tests.brokers.base.rpc import BrokerRPCTestcase, ReplyAndConsumeForbidden - - -@pytest.mark.rabbit -class TestRPC(BrokerRPCTestcase, ReplyAndConsumeForbidden): - def get_broker(self, apply_types: bool = False) -> RabbitBroker: - return RabbitBroker(apply_types=apply_types) diff --git a/tests/brokers/rabbit/test_test_client.py b/tests/brokers/rabbit/test_test_client.py index 1d92edf2fa..c2970a4107 100644 --- a/tests/brokers/rabbit/test_test_client.py +++ b/tests/brokers/rabbit/test_test_client.py @@ -3,7 +3,7 @@ import pytest from faststream import BaseMiddleware -from faststream.exceptions import SetupError +from faststream.exceptions import SubscriberNotFound from faststream.rabbit import ( ExchangeType, RabbitBroker, @@ -29,18 +29,6 @@ def patch_broker(self, broker: RabbitBroker) -> RabbitBroker: def get_fake_producer_class(self) -> type: return FakeProducer - async def test_rpc_conflicts_reply(self, queue): - broker = self.get_broker() - - async with TestRabbitBroker(broker) as br: - with pytest.raises(SetupError): - await br.publish( - "", - queue, - rpc=True, - reply_to="response", - ) - @pytest.mark.rabbit async def test_with_real_testclient( self, @@ -92,9 +80,14 @@ async def handler2(m): async with TestRabbitBroker(broker) as br: await br.start() - assert await br.publish("", queue, rpc=True) == 1 - assert await br.publish("", queue + "1", exchange="test", rpc=True) == 2 - assert None is await br.publish("", exchange="test2", rpc=True) + + assert await (await br.request("", queue)).decode() == 1 + assert ( + await (await br.request("", queue + "1", exchange="test")).decode() == 2 + ) + + with pytest.raises(SubscriberNotFound): + await br.request("", exchange="test2") async def test_fanout( self, @@ -110,9 +103,10 @@ async def handler(m): mock() async with TestRabbitBroker(broker) as br: - await br.publish("", exchange=exch, rpc=True) + await br.request("", exchange=exch) - assert None is await br.publish("", exchange="test2", rpc=True) + with pytest.raises(SubscriberNotFound): + await br.request("", exchange="test2") assert mock.call_count == 1 @@ -192,11 +186,16 @@ async def handler3(msg): async with TestRabbitBroker(broker) as br: assert ( - await br.publish(exchange=exch, rpc=True, headers={"key": 2, "key2": 2}) + await ( + await br.request(exchange=exch, headers={"key": 2, "key2": 2}) + ).decode() == 2 ) - assert await br.publish(exchange=exch, rpc=True, headers={"key": 2}) == 1 - assert await br.publish(exchange=exch, rpc=True, headers={}) == 3 + assert ( + await (await br.request(exchange=exch, headers={"key": 2})).decode() + == 1 + ) + assert await (await br.request(exchange=exch, headers={})).decode() == 3 async def test_consume_manual_ack( self, diff --git a/tests/brokers/redis/test_fastapi.py b/tests/brokers/redis/test_fastapi.py index 56ef879e7c..9993419d5f 100644 --- a/tests/brokers/redis/test_fastapi.py +++ b/tests/brokers/redis/test_fastapi.py @@ -199,10 +199,9 @@ async def hello(name): return name async with self.broker_test(router.broker): - r = await router.broker.publish( + r = await router.broker.request( "hi", f"{queue}.john", - rpc=True, - rpc_timeout=0.5, + timeout=0.5, ) - assert r == "john" + assert await r.decode() == "john" diff --git a/tests/brokers/redis/test_publish.py b/tests/brokers/redis/test_publish.py index 7e4430ea93..ebb348892e 100644 --- a/tests/brokers/redis/test_publish.py +++ b/tests/brokers/redis/test_publish.py @@ -200,8 +200,8 @@ async def handle(): await br.start() response = await asyncio.wait_for( - br.publish("", queue, rpc=True), + br.request("", queue), timeout=3, ) - assert response == "Hi!", response + assert await response.decode() == "Hi!", response diff --git a/tests/brokers/redis/test_router.py b/tests/brokers/redis/test_router.py index 33eda512c9..7ef36317c4 100644 --- a/tests/brokers/redis/test_router.py +++ b/tests/brokers/redis/test_router.py @@ -39,11 +39,7 @@ async def h( await pub_broker.start() - await pub_broker.publish( - "", - "in.john.2", - rpc=True, - ) + await pub_broker.request("", "in.john.2") assert event.is_set() mock.assert_called_once_with(name="john", id=2) @@ -70,11 +66,7 @@ async def h( await pub_broker.start() - await pub_broker.publish( - "", - "test.in.john.2", - rpc=True, - ) + await pub_broker.request("", "test.in.john.2") assert event.is_set() mock.assert_called_once_with(name="john", id=2) @@ -100,11 +92,7 @@ async def h( await pub_broker.start() - await pub_broker.publish( - "", - "in.john.2", - rpc=True, - ) + await pub_broker.request("", "in.john.2") assert event.is_set() mock.assert_called_once_with(name="john", id=2) diff --git a/tests/brokers/redis/test_rpc.py b/tests/brokers/redis/test_rpc.py deleted file mode 100644 index 6895c7c998..0000000000 --- a/tests/brokers/redis/test_rpc.py +++ /dev/null @@ -1,25 +0,0 @@ -import pytest - -from faststream.redis import RedisBroker -from tests.brokers.base.rpc import BrokerRPCTestcase, ReplyAndConsumeForbidden - - -@pytest.mark.redis -class TestRPC(BrokerRPCTestcase, ReplyAndConsumeForbidden): - def get_broker(self, apply_types: bool = False): - return RedisBroker(apply_types=apply_types) - - @pytest.mark.asyncio - async def test_list_rpc(self, queue: str): - rpc_broker = self.get_broker() - - @rpc_broker.subscriber(list=queue) - async def m(m): # pragma: no cover - return "1" - - async with self.patch_broker(rpc_broker) as br: - await br.start() - - r = await br.publish("hello", list=queue, rpc_timeout=3, rpc=True) - - assert r == "1" diff --git a/tests/brokers/redis/test_test_client.py b/tests/brokers/redis/test_test_client.py index 1203c9448a..a4c803fa3f 100644 --- a/tests/brokers/redis/test_test_client.py +++ b/tests/brokers/redis/test_test_client.py @@ -3,7 +3,6 @@ import pytest from faststream import BaseMiddleware -from faststream.exceptions import SetupError from faststream.redis import ListSub, RedisBroker, StreamSub, TestRedisBroker from faststream.redis.testing import FakeProducer from tests.brokers.base.testclient import BrokerTestclientTestcase @@ -22,16 +21,6 @@ def patch_broker(self, broker: RedisBroker) -> TestRedisBroker: def get_fake_producer_class(self) -> type: return FakeProducer - async def test_rpc_conflicts_reply(self, queue): - async with TestRedisBroker(RedisBroker()) as br: - with pytest.raises(SetupError): - await br.publish( - "", - queue, - rpc=True, - reply_to="response", - ) - @pytest.mark.redis async def test_with_real_testclient( self, @@ -110,7 +99,7 @@ async def handler(msg): return msg async with self.patch_broker(broker) as br: - assert await br.publish(1, "test.name.useless", rpc=True) == 1 + assert await (await br.request(1, "test.name.useless")).decode() == 1 handler.mock.assert_called_once_with(1) async def test_list( @@ -124,7 +113,7 @@ async def handler(msg): return msg async with self.patch_broker(broker) as br: - assert await br.publish(1, list=queue, rpc=True) == 1 + assert await (await br.request(1, list=queue)).decode() == 1 handler.mock.assert_called_once_with(1) async def test_batch_pub_by_default_pub( @@ -185,7 +174,7 @@ async def handler(msg): return msg async with self.patch_broker(broker) as br: - assert await br.publish(1, stream=queue, rpc=True) == 1 + assert await (await br.request(1, stream=queue)).decode() == 1 handler.mock.assert_called_once_with(1) async def test_stream_batch_pub_by_default_pub( diff --git a/tests/brokers/test_pushback.py b/tests/brokers/test_pushback.py index 9f18aa038b..79ac9dae9f 100644 --- a/tests/brokers/test_pushback.py +++ b/tests/brokers/test_pushback.py @@ -2,7 +2,7 @@ import pytest -from faststream.broker.acknowledgement_watcher import ( +from faststream._internal.subscriber.acknowledgement_watcher import ( CounterWatcher, EndlessWatcher, WatcherContext, diff --git a/tests/brokers/test_response.py b/tests/brokers/test_response.py index 785e0a21cf..15c76c4972 100644 --- a/tests/brokers/test_response.py +++ b/tests/brokers/test_response.py @@ -1,4 +1,4 @@ -from faststream.broker.response import Response, ensure_response +from faststream.response import Response, ensure_response def test_raw_data(): diff --git a/tests/cli/rabbit/test_app.py b/tests/cli/rabbit/test_app.py index 4765ffac9a..104b515c0e 100644 --- a/tests/cli/rabbit/test_app.py +++ b/tests/cli/rabbit/test_app.py @@ -8,8 +8,8 @@ import pytest from faststream import FastStream, TestApp -from faststream._compat import IS_WINDOWS -from faststream.log import logger +from faststream._internal._compat import IS_WINDOWS +from faststream._internal.log import logger def test_init(app: FastStream, broker): diff --git a/tests/cli/rabbit/test_logs.py b/tests/cli/rabbit/test_logs.py index 79e140da99..92bf5beb67 100644 --- a/tests/cli/rabbit/test_logs.py +++ b/tests/cli/rabbit/test_logs.py @@ -3,7 +3,7 @@ import pytest from faststream import FastStream -from faststream.cli.utils.logs import LogLevels, get_log_level, set_log_level +from faststream._internal.cli.utils.logs import LogLevels, get_log_level, set_log_level from faststream.rabbit import RabbitBroker diff --git a/tests/cli/supervisors/test_base_reloader.py b/tests/cli/supervisors/test_base_reloader.py index ebc29e1d4e..bb11b1b42a 100644 --- a/tests/cli/supervisors/test_base_reloader.py +++ b/tests/cli/supervisors/test_base_reloader.py @@ -2,7 +2,7 @@ import pytest -from faststream.cli.supervisors.basereload import BaseReload +from faststream._internal.cli.supervisors.basereload import BaseReload class PatchedBaseReload(BaseReload): diff --git a/tests/cli/supervisors/test_multiprocess.py b/tests/cli/supervisors/test_multiprocess.py index d50ce7995d..d12a5db195 100644 --- a/tests/cli/supervisors/test_multiprocess.py +++ b/tests/cli/supervisors/test_multiprocess.py @@ -4,7 +4,7 @@ import pytest -from faststream.cli.supervisors.multiprocess import Multiprocess +from faststream._internal.cli.supervisors.multiprocess import Multiprocess def exit(parent_id): # pragma: no cover diff --git a/tests/cli/supervisors/test_watchfiles.py b/tests/cli/supervisors/test_watchfiles.py index 511ccac0a2..11f59fb052 100644 --- a/tests/cli/supervisors/test_watchfiles.py +++ b/tests/cli/supervisors/test_watchfiles.py @@ -7,7 +7,7 @@ import pytest -from faststream.cli.supervisors.watchfiles import WatchReloader +from faststream._internal.cli.supervisors.watchfiles import WatchReloader DIR = Path(__file__).resolve().parent diff --git a/tests/cli/test_asyncapi_docs.py b/tests/cli/test_asyncapi_docs.py index 5c80bfdaac..42b24a2c08 100644 --- a/tests/cli/test_asyncapi_docs.py +++ b/tests/cli/test_asyncapi_docs.py @@ -13,7 +13,7 @@ gen_asyncapi_json_cmd, gen_asyncapi_yaml_cmd, ) -from faststream.cli.main import cli +from faststream._internal.cli.main import cli from tests.marks import require_aiokafka GEN_JSON_CMD = gen_asyncapi_json_cmd.split(" ")[1:-1] diff --git a/tests/cli/test_publish.py b/tests/cli/test_publish.py index 7e2aa367ea..06f58308f3 100644 --- a/tests/cli/test_publish.py +++ b/tests/cli/test_publish.py @@ -3,7 +3,7 @@ from dirty_equals import IsPartialDict from faststream import FastStream -from faststream.cli.main import cli as faststream_app +from faststream._internal.cli.main import cli as faststream_app from tests.marks import ( require_aiokafka, require_aiopika, @@ -30,7 +30,7 @@ def test_publish_command_with_redis_options(runner): mock_app = get_mock_app(RedisBroker, RedisFastProducer) with patch( - "faststream.cli.main.import_from_string", + "faststream._internal.cli.main.import_from_string", return_value=(None, mock_app), ): result = runner.invoke( @@ -72,7 +72,10 @@ def test_publish_command_with_confluent_options(runner): mock_app = get_mock_app(ConfluentBroker, AsyncConfluentFastProducer) - with patch("faststream.cli.main.import_from_string", return_value=(None, mock_app)): + with patch( + "faststream._internal.cli.main.import_from_string", + return_value=(None, mock_app), + ): result = runner.invoke( faststream_app, [ @@ -102,7 +105,10 @@ def test_publish_command_with_kafka_options(runner): mock_app = get_mock_app(KafkaBroker, AioKafkaFastProducer) - with patch("faststream.cli.main.import_from_string", return_value=(None, mock_app)): + with patch( + "faststream._internal.cli.main.import_from_string", + return_value=(None, mock_app), + ): result = runner.invoke( faststream_app, [ @@ -132,7 +138,10 @@ def test_publish_command_with_nats_options(runner): mock_app = get_mock_app(NatsBroker, NatsFastProducer) - with patch("faststream.cli.main.import_from_string", return_value=(None, mock_app)): + with patch( + "faststream._internal.cli.main.import_from_string", + return_value=(None, mock_app), + ): result = runner.invoke( faststream_app, [ @@ -166,7 +175,10 @@ def test_publish_command_with_rabbit_options(runner): mock_app = get_mock_app(RabbitBroker, AioPikaFastProducer) - with patch("faststream.cli.main.import_from_string", return_value=(None, mock_app)): + with patch( + "faststream._internal.cli.main.import_from_string", + return_value=(None, mock_app), + ): result = runner.invoke( faststream_app, [ diff --git a/tests/cli/test_version.py b/tests/cli/test_version.py index 98fbfd5c23..c606b03abc 100644 --- a/tests/cli/test_version.py +++ b/tests/cli/test_version.py @@ -1,6 +1,6 @@ import platform -from faststream.cli.main import cli +from faststream._internal.cli.main import cli def test_version(runner, version): diff --git a/tests/cli/utils/test_imports.py b/tests/cli/utils/test_imports.py index f97e26c0ff..ebac2be5b5 100644 --- a/tests/cli/utils/test_imports.py +++ b/tests/cli/utils/test_imports.py @@ -3,8 +3,12 @@ import pytest from typer import BadParameter +from faststream._internal.cli.utils.imports import ( + get_app_path, + import_from_string, + import_object, +) from faststream.app import FastStream -from faststream.cli.utils.imports import get_app_path, import_from_string, import_object from tests.marks import require_aiokafka, require_aiopika, require_nats diff --git a/tests/cli/utils/test_parser.py b/tests/cli/utils/test_parser.py index 91ace3770e..449249307c 100644 --- a/tests/cli/utils/test_parser.py +++ b/tests/cli/utils/test_parser.py @@ -2,7 +2,7 @@ import pytest -from faststream.cli.utils.parser import parse_cli_args +from faststream._internal.cli.utils.parser import parse_cli_args APPLICATION = "module:app" diff --git a/tests/conftest.py b/tests/conftest.py index e6b227941e..43c39a2cde 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -6,7 +6,7 @@ from typer.testing import CliRunner from faststream.__about__ import __version__ -from faststream.utils import context as global_context +from faststream._internal.context import context as global_context @pytest.hookimpl(tryfirst=True) diff --git a/tests/log/test_formatter.py b/tests/log/test_formatter.py index e8f21a9e52..24d38a11d0 100644 --- a/tests/log/test_formatter.py +++ b/tests/log/test_formatter.py @@ -1,6 +1,6 @@ import logging -from faststream.log.formatter import ColourizedFormatter +from faststream._internal.log.formatter import ColourizedFormatter def test_formatter(): diff --git a/tests/marks.py b/tests/marks.py index 07bde035b0..ad698dac45 100644 --- a/tests/marks.py +++ b/tests/marks.py @@ -2,7 +2,7 @@ import pytest -from faststream._compat import PYDANTIC_V2 +from faststream._internal._compat import PYDANTIC_V2 python39 = pytest.mark.skipif( sys.version_info < (3, 9), diff --git a/tests/mypy/kafka.py b/tests/mypy/kafka.py index eeeef066ed..043639ddb2 100644 --- a/tests/mypy/kafka.py +++ b/tests/mypy/kafka.py @@ -2,9 +2,9 @@ from aiokafka import ConsumerRecord +from faststream._internal.basic_types import DecodedMessage from faststream.kafka import KafkaBroker, KafkaMessage, KafkaRoute, KafkaRouter from faststream.kafka.fastapi import KafkaRouter as FastAPIRouter -from faststream.types import DecodedMessage def sync_decoder(msg: KafkaMessage) -> DecodedMessage: diff --git a/tests/mypy/nats.py b/tests/mypy/nats.py index 955458eada..7330ca4b1f 100644 --- a/tests/mypy/nats.py +++ b/tests/mypy/nats.py @@ -2,9 +2,9 @@ from nats.aio.msg import Msg +from faststream._internal.basic_types import DecodedMessage from faststream.nats import NatsBroker, NatsMessage, NatsRoute, NatsRouter from faststream.nats.fastapi import NatsRouter as FastAPIRouter -from faststream.types import DecodedMessage def sync_decoder(msg: NatsMessage) -> DecodedMessage: diff --git a/tests/mypy/rabbit.py b/tests/mypy/rabbit.py index 064f6faad7..6c79509136 100644 --- a/tests/mypy/rabbit.py +++ b/tests/mypy/rabbit.py @@ -2,9 +2,9 @@ from aio_pika import IncomingMessage +from faststream._internal.basic_types import DecodedMessage from faststream.rabbit import RabbitBroker, RabbitMessage, RabbitRoute, RabbitRouter from faststream.rabbit.fastapi import RabbitRouter as FastAPIRouter -from faststream.types import DecodedMessage def sync_decoder(msg: RabbitMessage) -> DecodedMessage: diff --git a/tests/mypy/redis.py b/tests/mypy/redis.py index 58a3da36cd..3ee2088f89 100644 --- a/tests/mypy/redis.py +++ b/tests/mypy/redis.py @@ -1,12 +1,12 @@ from typing import Awaitable, Callable +from faststream._internal.basic_types import DecodedMessage from faststream.redis import RedisBroker as Broker from faststream.redis import RedisMessage as Message from faststream.redis import RedisRoute as Route from faststream.redis import RedisRouter as StreamRouter from faststream.redis.fastapi import RedisRouter as FastAPIRouter from faststream.redis.message import RedisMessage as Msg -from faststream.types import DecodedMessage def sync_decoder(msg: Message) -> DecodedMessage: diff --git a/tests/opentelemetry/basic.py b/tests/opentelemetry/basic.py index 0c5be63a1c..2207f7b0dc 100644 --- a/tests/opentelemetry/basic.py +++ b/tests/opentelemetry/basic.py @@ -14,7 +14,7 @@ from opentelemetry.semconv.trace import SpanAttributes as SpanAttr from opentelemetry.trace import SpanKind, get_current_span -from faststream.broker.core.usecase import BrokerUsecase +from faststream._internal.broker.broker import BrokerUsecase from faststream.opentelemetry import Baggage, CurrentBaggage, CurrentSpan from faststream.opentelemetry.consts import ( ERROR_TYPE, diff --git a/tests/utils/context/test_alias.py b/tests/utils/context/test_alias.py index 55590cea2f..309700e1b8 100644 --- a/tests/utils/context/test_alias.py +++ b/tests/utils/context/test_alias.py @@ -3,7 +3,8 @@ import pytest from typing_extensions import Annotated -from faststream.utils import Context, ContextRepo, apply_types +from faststream import Context, ContextRepo +from faststream._internal.utils import apply_types @pytest.mark.asyncio diff --git a/tests/utils/context/test_depends.py b/tests/utils/context/test_depends.py index b2c92434a9..5d90533665 100644 --- a/tests/utils/context/test_depends.py +++ b/tests/utils/context/test_depends.py @@ -1,7 +1,8 @@ import pytest from typing_extensions import Annotated -from faststream.utils import Depends, apply_types +from faststream import Depends +from faststream._internal.utils import apply_types def sync_dep(key): diff --git a/tests/utils/context/test_headers.py b/tests/utils/context/test_headers.py index fa6c716db9..cb4934f4cc 100644 --- a/tests/utils/context/test_headers.py +++ b/tests/utils/context/test_headers.py @@ -22,15 +22,16 @@ async def h( async with TestNatsBroker(broker) as br: assert ( - await br.publish( - "", - "in", - headers={ - "name": "john", - "id": "1", - }, - rpc=True, - rpc_timeout=1.0, - ) + await ( + await br.request( + "", + "in", + headers={ + "name": "john", + "id": "1", + }, + timeout=1.0, + ) + ).decode() == 1 ) diff --git a/tests/utils/context/test_main.py b/tests/utils/context/test_main.py index 2a7ca6d093..6f9b889452 100644 --- a/tests/utils/context/test_main.py +++ b/tests/utils/context/test_main.py @@ -1,7 +1,8 @@ import pytest from pydantic import ValidationError -from faststream.utils import Context, ContextRepo, apply_types +from faststream import Context, ContextRepo +from faststream._internal.utils import apply_types def test_context_getattr(context: ContextRepo): diff --git a/tests/utils/context/test_path.py b/tests/utils/context/test_path.py index 5cfc8caf99..ab4f5695ab 100644 --- a/tests/utils/context/test_path.py +++ b/tests/utils/context/test_path.py @@ -25,12 +25,13 @@ async def h( async with TestKafkaBroker(broker) as br: assert ( - await br.publish( - "", - "in.john.1", - rpc=True, - rpc_timeout=1.0, - ) + await ( + await br.request( + "", + "in.john.1", + timeout=1.0, + ) + ).decode() == 1 ) @@ -53,12 +54,13 @@ async def h( async with TestNatsBroker(broker) as br: assert ( - await br.publish( - "", - "in.john.1", - rpc=True, - rpc_timeout=1.0, - ) + await ( + await br.request( + "", + "in.john.1", + timeout=1.0, + ) + ).decode() == 1 ) @@ -119,12 +121,13 @@ async def h( async with TestNatsBroker(broker) as br: assert ( - await br.publish( - "", - "in.john.1", - rpc=True, - rpc_timeout=1.0, - ) + await ( + await br.request( + "", + "in.john.1", + timeout=1.0, + ) + ).decode() == 1 ) @@ -147,12 +150,13 @@ async def h( async with TestRedisBroker(broker) as br: assert ( - await br.publish( - "", - "in.john.1", - rpc=True, - rpc_timeout=1.0, - ) + await ( + await br.request( + "", + "in.john.1", + timeout=1.0, + ) + ).decode() == 1 ) @@ -190,12 +194,13 @@ async def h( async with TestRabbitBroker(broker) as br: assert ( - await br.publish( - "", - "in.john.1", - "test", - rpc=True, - rpc_timeout=1.0, - ) + await ( + await br.request( + "", + "in.john.1", + "test", + timeout=1.0, + ) + ).decode() == 1 ) diff --git a/tests/utils/test_ast.py b/tests/utils/test_ast.py index 6417425c90..6f226c4acc 100644 --- a/tests/utils/test_ast.py +++ b/tests/utils/test_ast.py @@ -1,6 +1,6 @@ import pytest -from faststream.utils.ast import is_contains_context_name +from faststream._internal.testing.ast import is_contains_context_name class Context: diff --git a/tests/utils/test_classes.py b/tests/utils/test_classes.py deleted file mode 100644 index 65d1a3bc8a..0000000000 --- a/tests/utils/test_classes.py +++ /dev/null @@ -1,11 +0,0 @@ -from faststream.utils.classes import Singleton - - -def test_singleton(): - assert Singleton() is Singleton() - - -def test_drop(): - s1 = Singleton() - s1._drop() - assert Singleton() is not s1 diff --git a/tests/utils/test_functions.py b/tests/utils/test_functions.py index 5b3cf8a57e..e6f11a1611 100644 --- a/tests/utils/test_functions.py +++ b/tests/utils/test_functions.py @@ -1,6 +1,6 @@ import pytest -from faststream.utils.functions import call_or_await +from faststream._internal.utils.functions import call_or_await def sync_func(a): diff --git a/tests/utils/test_handler_lock.py b/tests/utils/test_handler_lock.py index 814b606f46..4b784d2ad9 100644 --- a/tests/utils/test_handler_lock.py +++ b/tests/utils/test_handler_lock.py @@ -4,7 +4,7 @@ import pytest from anyio.abc import TaskStatus -from faststream.broker.utils import MultiLock +from faststream._internal.subscriber.utils import MultiLock @pytest.mark.asyncio diff --git a/tests/utils/type_cast/test_base.py b/tests/utils/type_cast/test_base.py index 150e0e68db..a92e960a24 100644 --- a/tests/utils/type_cast/test_base.py +++ b/tests/utils/type_cast/test_base.py @@ -2,7 +2,7 @@ import pytest -from faststream.utils import apply_types +from faststream._internal.utils import apply_types @apply_types diff --git a/tests/utils/type_cast/test_model.py b/tests/utils/type_cast/test_model.py index 2cb57dca04..d69503b349 100644 --- a/tests/utils/type_cast/test_model.py +++ b/tests/utils/type_cast/test_model.py @@ -3,7 +3,7 @@ import pytest from pydantic import BaseModel -from faststream.utils import apply_types +from faststream._internal.utils import apply_types class Base(BaseModel): From 6b638c738500d4499ad9f8779cfbdcd0b58acb17 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Fri, 13 Sep 2024 18:55:02 +0300 Subject: [PATCH 152/245] lint: add ruff TID check --- faststream/_internal/broker/abc_broker.py | 6 +----- faststream/_internal/broker/logging_mixin.py | 2 +- faststream/_internal/broker/router.py | 3 ++- pyproject.toml | 1 + tests/opentelemetry/confluent/test_confluent.py | 3 +-- tests/opentelemetry/kafka/test_kafka.py | 3 +-- tests/opentelemetry/nats/test_nats.py | 3 +-- tests/opentelemetry/rabbit/test_rabbit.py | 3 +-- tests/opentelemetry/redis/test_redis.py | 3 +-- 9 files changed, 10 insertions(+), 17 deletions(-) diff --git a/faststream/_internal/broker/abc_broker.py b/faststream/_internal/broker/abc_broker.py index e3998c75d5..9e9f268038 100644 --- a/faststream/_internal/broker/abc_broker.py +++ b/faststream/_internal/broker/abc_broker.py @@ -8,11 +8,7 @@ Optional, ) -from ..types import ( - BrokerMiddleware, - CustomCallable, - MsgType, -) +from faststream._internal.types import BrokerMiddleware, CustomCallable, MsgType if TYPE_CHECKING: from fast_depends.dependencies import Depends diff --git a/faststream/_internal/broker/logging_mixin.py b/faststream/_internal/broker/logging_mixin.py index 43ab11a4e1..3b8f401465 100644 --- a/faststream/_internal/broker/logging_mixin.py +++ b/faststream/_internal/broker/logging_mixin.py @@ -5,8 +5,8 @@ from typing_extensions import Annotated, Doc from faststream._internal.constants import EMPTY +from faststream._internal.types import MsgType -from ..types import MsgType from .abc_broker import ABCBroker if TYPE_CHECKING: diff --git a/faststream/_internal/broker/router.py b/faststream/_internal/broker/router.py index 12d0eb3b76..0661ac4bd6 100644 --- a/faststream/_internal/broker/router.py +++ b/faststream/_internal/broker/router.py @@ -6,11 +6,12 @@ Optional, ) -from ..types import ( +from faststream._internal.types import ( BrokerMiddleware, CustomCallable, MsgType, ) + from .abc_broker import ABCBroker if TYPE_CHECKING: diff --git a/pyproject.toml b/pyproject.toml index 7919811427..9086bf09fd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -213,6 +213,7 @@ select = [ "PT", # flake8-pytest-style https://docs.astral.sh/ruff/rules/#flake8-pytest-style-pt "PTH", # flake8-use-pathlib https://docs.astral.sh/ruff/rules/#flake8-use-pathlib-pth "TCH", # flake8-type-checking https://docs.astral.sh/ruff/rules/#flake8-type-checking-tch + "TID", # flake8-tidy-imports https://docs.astral.sh/ruff/rules/#flake8-tidy-imports-tid "RUF", # Ruff-specific rules https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf "PERF", # Perflint https://docs.astral.sh/ruff/rules/#perflint-perf "UP", # pyupgrade https://docs.astral.sh/ruff/rules/#pyupgrade-up diff --git a/tests/opentelemetry/confluent/test_confluent.py b/tests/opentelemetry/confluent/test_confluent.py index 9eb52d9742..af914ebc9d 100644 --- a/tests/opentelemetry/confluent/test_confluent.py +++ b/tests/opentelemetry/confluent/test_confluent.py @@ -17,8 +17,7 @@ from faststream.opentelemetry.consts import MESSAGING_DESTINATION_PUBLISH_NAME from faststream.opentelemetry.middleware import MessageAction as Action from tests.brokers.confluent.basic import ConfluentTestcaseConfig - -from ..basic import LocalTelemetryTestcase +from tests.opentelemetry.basic import LocalTelemetryTestcase @pytest.mark.confluent diff --git a/tests/opentelemetry/kafka/test_kafka.py b/tests/opentelemetry/kafka/test_kafka.py index 0967069ade..a4f83748c4 100644 --- a/tests/opentelemetry/kafka/test_kafka.py +++ b/tests/opentelemetry/kafka/test_kafka.py @@ -18,8 +18,7 @@ from faststream.opentelemetry.middleware import MessageAction as Action from tests.brokers.kafka.test_consume import TestConsume from tests.brokers.kafka.test_publish import TestPublish - -from ..basic import LocalTelemetryTestcase +from tests.opentelemetry.basic import LocalTelemetryTestcase @pytest.mark.kafka diff --git a/tests/opentelemetry/nats/test_nats.py b/tests/opentelemetry/nats/test_nats.py index d1262c7e6a..88dc22d49c 100644 --- a/tests/opentelemetry/nats/test_nats.py +++ b/tests/opentelemetry/nats/test_nats.py @@ -12,8 +12,7 @@ from faststream.nats.opentelemetry import NatsTelemetryMiddleware from tests.brokers.nats.test_consume import TestConsume from tests.brokers.nats.test_publish import TestPublish - -from ..basic import LocalTelemetryTestcase +from tests.opentelemetry.basic import LocalTelemetryTestcase @pytest.fixture diff --git a/tests/opentelemetry/rabbit/test_rabbit.py b/tests/opentelemetry/rabbit/test_rabbit.py index 59d77c3b70..2a779cdd4b 100644 --- a/tests/opentelemetry/rabbit/test_rabbit.py +++ b/tests/opentelemetry/rabbit/test_rabbit.py @@ -12,8 +12,7 @@ from faststream.rabbit.opentelemetry import RabbitTelemetryMiddleware from tests.brokers.rabbit.test_consume import TestConsume from tests.brokers.rabbit.test_publish import TestPublish - -from ..basic import LocalTelemetryTestcase +from tests.opentelemetry.basic import LocalTelemetryTestcase @pytest.fixture diff --git a/tests/opentelemetry/redis/test_redis.py b/tests/opentelemetry/redis/test_redis.py index 9729b0a27f..8d8366ba10 100644 --- a/tests/opentelemetry/redis/test_redis.py +++ b/tests/opentelemetry/redis/test_redis.py @@ -17,8 +17,7 @@ TestConsumeStream, ) from tests.brokers.redis.test_publish import TestPublish - -from ..basic import LocalTelemetryTestcase +from tests.opentelemetry.basic import LocalTelemetryTestcase @pytest.mark.redis From 485c1135af15eff33c02f43b8fe32e7ded39e6ca Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Fri, 13 Sep 2024 19:05:13 +0300 Subject: [PATCH 153/245] tests: use request instead of rpc publish everywhere --- pyproject.toml | 2 +- tests/a_docs/getting_started/lifespan/test_ml.py | 10 +++++----- .../a_docs/getting_started/lifespan/test_ml_context.py | 10 +++++----- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9086bf09fd..23c74b0d19 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -213,7 +213,7 @@ select = [ "PT", # flake8-pytest-style https://docs.astral.sh/ruff/rules/#flake8-pytest-style-pt "PTH", # flake8-use-pathlib https://docs.astral.sh/ruff/rules/#flake8-use-pathlib-pth "TCH", # flake8-type-checking https://docs.astral.sh/ruff/rules/#flake8-type-checking-tch - "TID", # flake8-tidy-imports https://docs.astral.sh/ruff/rules/#flake8-tidy-imports-tid + "TID", # flake8-tidy-imports https://docs.astral.sh/ruff/rules/#flake8-tidy-imports-tidb "RUF", # Ruff-specific rules https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf "PERF", # Perflint https://docs.astral.sh/ruff/rules/#perflint-perf "UP", # pyupgrade https://docs.astral.sh/ruff/rules/#pyupgrade-up diff --git a/tests/a_docs/getting_started/lifespan/test_ml.py b/tests/a_docs/getting_started/lifespan/test_ml.py index 0060f0719a..5c1d77f946 100644 --- a/tests/a_docs/getting_started/lifespan/test_ml.py +++ b/tests/a_docs/getting_started/lifespan/test_ml.py @@ -17,7 +17,7 @@ async def test_rabbit_ml_lifespan(): from faststream.rabbit import TestRabbitBroker async with TestRabbitBroker(broker), TestApp(app): - assert await broker.publish(1.0, "test", rpc=True) == {"result": 42.0} + assert await(await broker.request(1.0, "test")).decode() == {"result": 42.0} predict.mock.assert_called_once_with(1.0) @@ -29,7 +29,7 @@ async def test_kafka_ml_lifespan(): from faststream.kafka import TestKafkaBroker async with TestKafkaBroker(broker), TestApp(app): - assert await broker.publish(1.0, "test", rpc=True) == {"result": 42.0} + assert await(await broker.request(1.0, "test")).decode() == {"result": 42.0} predict.mock.assert_called_once_with(1.0) @@ -41,7 +41,7 @@ async def test_confluent_ml_lifespan(): from faststream.confluent import TestKafkaBroker as TestConfluentKafkaBroker async with TestConfluentKafkaBroker(broker), TestApp(app): - assert await broker.publish(1.0, "test", rpc=True) == {"result": 42.0} + assert await(await broker.request(1.0, "test")).decode() == {"result": 42.0} predict.mock.assert_called_once_with(1.0) @@ -53,7 +53,7 @@ async def test_nats_ml_lifespan(): from faststream.nats import TestNatsBroker async with TestNatsBroker(broker), TestApp(app): - assert await broker.publish(1.0, "test", rpc=True) == {"result": 42.0} + assert await(await broker.request(1.0, "test")).decode() == {"result": 42.0} predict.mock.assert_called_once_with(1.0) @@ -65,6 +65,6 @@ async def test_redis_ml_lifespan(): from faststream.redis import TestRedisBroker async with TestRedisBroker(broker), TestApp(app): - assert await broker.publish(1.0, "test", rpc=True) == {"result": 42.0} + assert await(await broker.request(1.0, "test")).decode() == {"result": 42.0} predict.mock.assert_called_once_with(1.0) diff --git a/tests/a_docs/getting_started/lifespan/test_ml_context.py b/tests/a_docs/getting_started/lifespan/test_ml_context.py index e239e831a9..dce871230d 100644 --- a/tests/a_docs/getting_started/lifespan/test_ml_context.py +++ b/tests/a_docs/getting_started/lifespan/test_ml_context.py @@ -21,7 +21,7 @@ async def test_rabbit_ml_lifespan(): from faststream.rabbit import TestRabbitBroker async with TestRabbitBroker(broker), TestApp(app): - assert await broker.publish(1.0, "test", rpc=True) == {"result": 42.0} + assert await(await broker.request(1.0, "test")).decode() == {"result": 42.0} predict.mock.assert_called_once_with(1.0) @@ -37,7 +37,7 @@ async def test_kafka_ml_lifespan(): from faststream.kafka import TestKafkaBroker async with TestKafkaBroker(broker), TestApp(app): - assert await broker.publish(1.0, "test", rpc=True) == {"result": 42.0} + assert await(await broker.request(1.0, "test")).decode() == {"result": 42.0} predict.mock.assert_called_once_with(1.0) @@ -53,7 +53,7 @@ async def test_confluent_ml_lifespan(): from faststream.confluent import TestKafkaBroker as TestConfluentKafkaBroker async with TestConfluentKafkaBroker(broker), TestApp(app): - assert await broker.publish(1.0, "test", rpc=True) == {"result": 42.0} + assert await(await broker.request(1.0, "test")).decode() == {"result": 42.0} predict.mock.assert_called_once_with(1.0) @@ -69,7 +69,7 @@ async def test_nats_ml_lifespan(): from faststream.nats import TestNatsBroker async with TestNatsBroker(broker), TestApp(app): - assert await broker.publish(1.0, "test", rpc=True) == {"result": 42.0} + assert await(await broker.request(1.0, "test")).decode() == {"result": 42.0} predict.mock.assert_called_once_with(1.0) @@ -85,6 +85,6 @@ async def test_redis_ml_lifespan(): from faststream.redis import TestRedisBroker async with TestRedisBroker(broker), TestApp(app): - assert await broker.publish(1.0, "test", rpc=True) == {"result": 42.0} + assert await(await broker.request(1.0, "test")).decode() == {"result": 42.0} predict.mock.assert_called_once_with(1.0) From 35fa776a1ebfeeb18a2f3f88fb5f0e6186c01d39 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Fri, 13 Sep 2024 19:36:26 +0300 Subject: [PATCH 154/245] refactor: remove NATS publish rpc --- faststream/nats/broker/broker.py | 36 +---------- faststream/nats/publisher/producer.py | 60 +------------------ faststream/nats/publisher/usecase.py | 11 ---- faststream/nats/testing.py | 15 +---- .../getting_started/lifespan/test_ml.py | 10 ++-- .../lifespan/test_ml_context.py | 10 ++-- 6 files changed, 14 insertions(+), 128 deletions(-) diff --git a/faststream/nats/broker/broker.py b/faststream/nats/broker/broker.py index 8279fea77e..20496ab38d 100644 --- a/faststream/nats/broker/broker.py +++ b/faststream/nats/broker/broker.py @@ -27,7 +27,7 @@ ) from nats.errors import Error from nats.js.errors import BadRequestError -from typing_extensions import Annotated, Doc, deprecated, override +from typing_extensions import Annotated, Doc, override from faststream.__about__ import SERVICE_NAME from faststream._internal.constants import EMPTY @@ -712,37 +712,6 @@ async def publish( # type: ignore[override] Optional[float], Doc("Timeout to send message to NATS."), ] = None, - *, - rpc: Annotated[ - bool, - Doc("Whether to wait for reply in blocking mode."), - deprecated( - "Deprecated in **FastStream 0.5.17**. " - "Please, use `request` method instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = False, - rpc_timeout: Annotated[ - Optional[float], - Doc("RPC reply waiting time."), - deprecated( - "Deprecated in **FastStream 0.5.17**. " - "Please, use `request` method with `timeout` instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = 30.0, - raise_timeout: Annotated[ - bool, - Doc( - "Whetever to raise `TimeoutError` or return `None` at **rpc_timeout**. " - "RPC request returns `None` at timeout by default." - ), - deprecated( - "Deprecated in **FastStream 0.5.17**. " - "`request` always raises TimeoutError instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = False, ) -> Optional["DecodedMessage"]: """Publish message directly. @@ -755,9 +724,6 @@ async def publish( # type: ignore[override] "subject": subject, "headers": headers, "reply_to": reply_to, - "rpc": rpc, - "rpc_timeout": rpc_timeout, - "raise_timeout": raise_timeout, } producer: Optional[ProducerProto] diff --git a/faststream/nats/publisher/producer.py b/faststream/nats/publisher/producer.py index 61f42aca91..f489938e9e 100644 --- a/faststream/nats/publisher/producer.py +++ b/faststream/nats/publisher/producer.py @@ -7,8 +7,6 @@ from faststream._internal.publisher.proto import ProducerProto from faststream._internal.subscriber.utils import resolve_custom_func -from faststream._internal.utils.functions import timeout_scope -from faststream.exceptions import WRONG_PUBLISH_ARGS from faststream.message import encode_message from faststream.nats.parser import NatsParser @@ -52,9 +50,6 @@ async def publish( # type: ignore[override] correlation_id: str, headers: Optional[Dict[str, str]] = None, reply_to: str = "", - rpc: bool = False, - rpc_timeout: Optional[float] = 30.0, - raise_timeout: bool = False, **kwargs: Any, # suprress stream option ) -> Optional[Any]: payload, content_type = encode_message(message) @@ -65,39 +60,13 @@ async def publish( # type: ignore[override] **(headers or {}), } - client = self._connection - - if rpc: - if reply_to: - raise WRONG_PUBLISH_ARGS - - reply_to = client.new_inbox() - - future: asyncio.Future[Msg] = asyncio.Future() - sub = await client.subscribe(reply_to, future=future, max_msgs=1) - await sub.unsubscribe(limit=1) - - await client.publish( + await self._connection.publish( subject=subject, payload=payload, reply=reply_to, headers=headers_to_send, ) - if rpc: - msg: Any = None - with timeout_scope(rpc_timeout, raise_timeout): - msg = await future - - if msg: # pragma: no branch - if msg.headers: # pragma: no cover # noqa: SIM102 - if ( - msg.headers.get(nats.js.api.Header.STATUS) - == nats.aio.client.NO_RESPONDERS_STATUS - ): - raise nats.errors.NoRespondersError - return await self._decoder(await self._parser(msg)) - return None @override @@ -156,9 +125,6 @@ async def publish( # type: ignore[override] reply_to: str = "", stream: Optional[str] = None, timeout: Optional[float] = None, - rpc: bool = False, - rpc_timeout: Optional[float] = 30.0, - raise_timeout: bool = False, ) -> Optional[Any]: payload, content_type = encode_message(message) @@ -168,16 +134,6 @@ async def publish( # type: ignore[override] **(headers or {}), } - if rpc: - if reply_to: - raise WRONG_PUBLISH_ARGS - reply_to = self._connection._nc.new_inbox() - future: asyncio.Future[Msg] = asyncio.Future() - sub = await self._connection._nc.subscribe( - reply_to, future=future, max_msgs=1 - ) - await sub.unsubscribe(limit=1) - if reply_to: headers_to_send.update({"reply_to": reply_to}) @@ -189,20 +145,6 @@ async def publish( # type: ignore[override] timeout=timeout, ) - if rpc: - msg: Any = None - with timeout_scope(rpc_timeout, raise_timeout): - msg = await future - - if msg: # pragma: no branch - if msg.headers: # pragma: no cover # noqa: SIM102 - if ( - msg.headers.get(nats.js.api.Header.STATUS) - == nats.aio.client.NO_RESPONDERS_STATUS - ): - raise nats.errors.NoRespondersError - return await self._decoder(await self._parser(msg)) - return None @override diff --git a/faststream/nats/publisher/usecase.py b/faststream/nats/publisher/usecase.py index b61b7d761b..8515ebac96 100644 --- a/faststream/nats/publisher/usecase.py +++ b/faststream/nats/publisher/usecase.py @@ -81,9 +81,6 @@ async def publish( correlation_id: Optional[str] = None, stream: Optional[str] = None, timeout: Optional[float] = None, - rpc: bool = False, - rpc_timeout: Optional[float] = 30.0, - raise_timeout: bool = False, # publisher specific _extra_middlewares: Iterable["PublisherMiddleware"] = (), ) -> Optional[Any]: @@ -103,10 +100,6 @@ async def publish( stream (str, optional): This option validates that the target subject is in presented stream (default is `None`). Can be omitted without any effect. timeout (float, optional): Timeout to send message to NATS in seconds (default is `None`). - rpc (bool): Whether to wait for reply in blocking mode (default is `False`). - rpc_timeout (float, optional): RPC reply waiting time (default is `30.0`). - raise_timeout (bool): Whetever to raise `TimeoutError` or return `None` at **rpc_timeout** (default is `False`). - RPC request returns `None` at timeout by default. _extra_middlewares (:obj:`Iterable` of :obj:`PublisherMiddleware`): Extra middlewares to wrap publishing process (default is `()`). """ @@ -117,10 +110,6 @@ async def publish( "headers": headers or self.headers, "reply_to": reply_to or self.reply_to, "correlation_id": correlation_id or gen_cor_id(), - # specific args - "rpc": rpc, - "rpc_timeout": rpc_timeout, - "raise_timeout": raise_timeout, } if stream := stream or getattr(self.stream, "name", None): diff --git a/faststream/nats/testing.py b/faststream/nats/testing.py index 6e3459af35..ff51e4ed1b 100644 --- a/faststream/nats/testing.py +++ b/faststream/nats/testing.py @@ -7,8 +7,7 @@ from faststream._internal.subscriber.utils import resolve_custom_func from faststream._internal.testing.broker import TestBroker -from faststream._internal.utils.functions import timeout_scope -from faststream.exceptions import WRONG_PUBLISH_ARGS, SubscriberNotFound +from faststream.exceptions import SubscriberNotFound from faststream.message import encode_message, gen_cor_id from faststream.nats.broker import NatsBroker from faststream.nats.parser import NatsParser @@ -78,14 +77,7 @@ async def publish( # type: ignore[override] # NatsJSFastProducer compatibility timeout: Optional[float] = None, stream: Optional[str] = None, - *, - rpc: bool = False, - rpc_timeout: Optional[float] = None, - raise_timeout: bool = False, ) -> Any: - if rpc and reply_to: - raise WRONG_PUBLISH_ARGS - incoming = build_message( message=message, subject=subject, @@ -103,10 +95,7 @@ async def publish( # type: ignore[override] else: msg = incoming - with timeout_scope(rpc_timeout, raise_timeout): - response = await self._execute_handler(msg, subject, handler) - if rpc: - return await self._decoder(await self._parser(response)) + await self._execute_handler(msg, subject, handler) return None diff --git a/tests/a_docs/getting_started/lifespan/test_ml.py b/tests/a_docs/getting_started/lifespan/test_ml.py index 5c1d77f946..70aa060f4b 100644 --- a/tests/a_docs/getting_started/lifespan/test_ml.py +++ b/tests/a_docs/getting_started/lifespan/test_ml.py @@ -17,7 +17,7 @@ async def test_rabbit_ml_lifespan(): from faststream.rabbit import TestRabbitBroker async with TestRabbitBroker(broker), TestApp(app): - assert await(await broker.request(1.0, "test")).decode() == {"result": 42.0} + assert await (await broker.request(1.0, "test")).decode() == {"result": 42.0} predict.mock.assert_called_once_with(1.0) @@ -29,7 +29,7 @@ async def test_kafka_ml_lifespan(): from faststream.kafka import TestKafkaBroker async with TestKafkaBroker(broker), TestApp(app): - assert await(await broker.request(1.0, "test")).decode() == {"result": 42.0} + assert await (await broker.request(1.0, "test")).decode() == {"result": 42.0} predict.mock.assert_called_once_with(1.0) @@ -41,7 +41,7 @@ async def test_confluent_ml_lifespan(): from faststream.confluent import TestKafkaBroker as TestConfluentKafkaBroker async with TestConfluentKafkaBroker(broker), TestApp(app): - assert await(await broker.request(1.0, "test")).decode() == {"result": 42.0} + assert await (await broker.request(1.0, "test")).decode() == {"result": 42.0} predict.mock.assert_called_once_with(1.0) @@ -53,7 +53,7 @@ async def test_nats_ml_lifespan(): from faststream.nats import TestNatsBroker async with TestNatsBroker(broker), TestApp(app): - assert await(await broker.request(1.0, "test")).decode() == {"result": 42.0} + assert await (await broker.request(1.0, "test")).decode() == {"result": 42.0} predict.mock.assert_called_once_with(1.0) @@ -65,6 +65,6 @@ async def test_redis_ml_lifespan(): from faststream.redis import TestRedisBroker async with TestRedisBroker(broker), TestApp(app): - assert await(await broker.request(1.0, "test")).decode() == {"result": 42.0} + assert await (await broker.request(1.0, "test")).decode() == {"result": 42.0} predict.mock.assert_called_once_with(1.0) diff --git a/tests/a_docs/getting_started/lifespan/test_ml_context.py b/tests/a_docs/getting_started/lifespan/test_ml_context.py index dce871230d..6ab4e9da25 100644 --- a/tests/a_docs/getting_started/lifespan/test_ml_context.py +++ b/tests/a_docs/getting_started/lifespan/test_ml_context.py @@ -21,7 +21,7 @@ async def test_rabbit_ml_lifespan(): from faststream.rabbit import TestRabbitBroker async with TestRabbitBroker(broker), TestApp(app): - assert await(await broker.request(1.0, "test")).decode() == {"result": 42.0} + assert await (await broker.request(1.0, "test")).decode() == {"result": 42.0} predict.mock.assert_called_once_with(1.0) @@ -37,7 +37,7 @@ async def test_kafka_ml_lifespan(): from faststream.kafka import TestKafkaBroker async with TestKafkaBroker(broker), TestApp(app): - assert await(await broker.request(1.0, "test")).decode() == {"result": 42.0} + assert await (await broker.request(1.0, "test")).decode() == {"result": 42.0} predict.mock.assert_called_once_with(1.0) @@ -53,7 +53,7 @@ async def test_confluent_ml_lifespan(): from faststream.confluent import TestKafkaBroker as TestConfluentKafkaBroker async with TestConfluentKafkaBroker(broker), TestApp(app): - assert await(await broker.request(1.0, "test")).decode() == {"result": 42.0} + assert await (await broker.request(1.0, "test")).decode() == {"result": 42.0} predict.mock.assert_called_once_with(1.0) @@ -69,7 +69,7 @@ async def test_nats_ml_lifespan(): from faststream.nats import TestNatsBroker async with TestNatsBroker(broker), TestApp(app): - assert await(await broker.request(1.0, "test")).decode() == {"result": 42.0} + assert await (await broker.request(1.0, "test")).decode() == {"result": 42.0} predict.mock.assert_called_once_with(1.0) @@ -85,6 +85,6 @@ async def test_redis_ml_lifespan(): from faststream.redis import TestRedisBroker async with TestRedisBroker(broker), TestApp(app): - assert await(await broker.request(1.0, "test")).decode() == {"result": 42.0} + assert await (await broker.request(1.0, "test")).decode() == {"result": 42.0} predict.mock.assert_called_once_with(1.0) From fba8e91de351523b554cb8f1c3ca5299a8c5aaa8 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Fri, 13 Sep 2024 20:38:02 +0300 Subject: [PATCH 155/245] tests: polish requests tests --- tests/brokers/base/testclient.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/tests/brokers/base/testclient.py b/tests/brokers/base/testclient.py index df4697338a..1262b45e2c 100644 --- a/tests/brokers/base/testclient.py +++ b/tests/brokers/base/testclient.py @@ -7,15 +7,12 @@ from faststream._internal.basic_types import AnyCallable from faststream._internal.testing.broker import TestBroker -from tests.brokers.base.consume import BrokerConsumeTestcase -from tests.brokers.base.publish import BrokerPublishTestcase +from .consume import BrokerConsumeTestcase +from .publish import BrokerPublishTestcase -class BrokerTestclientTestcase( - BrokerPublishTestcase, - BrokerConsumeTestcase, - # RequestsTestcase, -): + +class BrokerTestclientTestcase(BrokerPublishTestcase, BrokerConsumeTestcase): build_message: AnyCallable test_class: TestBroker From 1662627f850fb99e9675d88413e847abb715c9fb Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Fri, 13 Sep 2024 20:47:23 +0300 Subject: [PATCH 156/245] refactor: remove RMQ publish rpc --- faststream/nats/broker/broker.py | 3 +- faststream/nats/publisher/producer.py | 2 +- faststream/nats/publisher/usecase.py | 2 +- faststream/nats/testing.py | 2 +- faststream/rabbit/broker/broker.py | 38 +----------- faststream/rabbit/publisher/producer.py | 82 +++++++------------------ faststream/rabbit/publisher/usecase.py | 39 +----------- faststream/rabbit/testing.py | 14 +---- 8 files changed, 35 insertions(+), 147 deletions(-) diff --git a/faststream/nats/broker/broker.py b/faststream/nats/broker/broker.py index 20496ab38d..f07a278d6c 100644 --- a/faststream/nats/broker/broker.py +++ b/faststream/nats/broker/broker.py @@ -61,7 +61,6 @@ from faststream._internal.basic_types import ( AnyDict, - DecodedMessage, Decorator, LoggerProto, SendableMessage, @@ -712,7 +711,7 @@ async def publish( # type: ignore[override] Optional[float], Doc("Timeout to send message to NATS."), ] = None, - ) -> Optional["DecodedMessage"]: + ) -> None: """Publish message directly. This method allows you to publish message in not AsyncAPI-documented way. You can use it in another frameworks diff --git a/faststream/nats/publisher/producer.py b/faststream/nats/publisher/producer.py index f489938e9e..f4859d1f6e 100644 --- a/faststream/nats/publisher/producer.py +++ b/faststream/nats/publisher/producer.py @@ -51,7 +51,7 @@ async def publish( # type: ignore[override] headers: Optional[Dict[str, str]] = None, reply_to: str = "", **kwargs: Any, # suprress stream option - ) -> Optional[Any]: + ) -> None: payload, content_type = encode_message(message) headers_to_send = { diff --git a/faststream/nats/publisher/usecase.py b/faststream/nats/publisher/usecase.py index 8515ebac96..fe0420047c 100644 --- a/faststream/nats/publisher/usecase.py +++ b/faststream/nats/publisher/usecase.py @@ -83,7 +83,7 @@ async def publish( timeout: Optional[float] = None, # publisher specific _extra_middlewares: Iterable["PublisherMiddleware"] = (), - ) -> Optional[Any]: + ) -> None: """Publish message directly. Args: diff --git a/faststream/nats/testing.py b/faststream/nats/testing.py index ff51e4ed1b..3ca3dfb67d 100644 --- a/faststream/nats/testing.py +++ b/faststream/nats/testing.py @@ -77,7 +77,7 @@ async def publish( # type: ignore[override] # NatsJSFastProducer compatibility timeout: Optional[float] = None, stream: Optional[str] = None, - ) -> Any: + ) -> None: incoming = build_message( message=message, subject=subject, diff --git a/faststream/rabbit/broker/broker.py b/faststream/rabbit/broker/broker.py index 8004fe968d..18b23f6a53 100644 --- a/faststream/rabbit/broker/broker.py +++ b/faststream/rabbit/broker/broker.py @@ -13,7 +13,7 @@ import anyio from aio_pika import connect_robust -from typing_extensions import Annotated, Doc, deprecated, override +from typing_extensions import Annotated, Doc, override from faststream.__about__ import SERVICE_NAME from faststream._internal.constants import EMPTY @@ -36,6 +36,7 @@ from ssl import SSLContext from types import TracebackType + import aiormq from aio_pika import ( IncomingMessage, RobustChannel, @@ -570,36 +571,6 @@ async def publish( # type: ignore[override] "Reply message routing key to send with (always sending to default exchange)." ), ] = None, - rpc: Annotated[ - bool, - Doc("Whether to wait for reply in blocking mode."), - deprecated( - "Deprecated in **FastStream 0.5.17**. " - "Please, use `request` method instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = False, - rpc_timeout: Annotated[ - Optional[float], - Doc("RPC reply waiting time."), - deprecated( - "Deprecated in **FastStream 0.5.17**. " - "Please, use `request` method with `timeout` instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = 30.0, - raise_timeout: Annotated[ - bool, - Doc( - "Whetever to raise `TimeoutError` or return `None` at **rpc_timeout**. " - "RPC request returns `None` at timeout by default." - ), - deprecated( - "Deprecated in **FastStream 0.5.17**. " - "`request` always raises TimeoutError instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = False, # message args correlation_id: Annotated[ Optional[str], @@ -648,7 +619,7 @@ async def publish( # type: ignore[override] Optional[int], Doc("The message priority (0 by default)."), ] = None, - ) -> Optional[Any]: + ) -> Optional["aiormq.abc.ConfirmationFrameType"]: """Publish message directly. This method allows you to publish message in not AsyncAPI-documented way. You can use it in another frameworks @@ -680,9 +651,6 @@ async def publish( # type: ignore[override] user_id=user_id, timeout=timeout, priority=priority, - rpc=rpc, - rpc_timeout=rpc_timeout, - raise_timeout=raise_timeout, ) @override diff --git a/faststream/rabbit/publisher/producer.py b/faststream/rabbit/publisher/producer.py index 1614d0c0b2..64e0421116 100644 --- a/faststream/rabbit/publisher/producer.py +++ b/faststream/rabbit/publisher/producer.py @@ -1,7 +1,5 @@ from typing import ( TYPE_CHECKING, - Any, - AsyncContextManager, Optional, Type, Union, @@ -13,8 +11,6 @@ from faststream._internal.publisher.proto import ProducerProto from faststream._internal.subscriber.utils import resolve_custom_func -from faststream._internal.utils.functions import fake_context, timeout_scope -from faststream.exceptions import WRONG_PUBLISH_ARGS from faststream.rabbit.parser import AioPikaParser from faststream.rabbit.schemas import RABBIT_REPLY, RabbitExchange @@ -26,7 +22,6 @@ from aio_pika.abc import AbstractIncomingMessage, DateType, HeadersType, TimeoutType from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream - from faststream._internal.basic_types import SendableMessage from faststream._internal.types import ( AsyncCallable, CustomCallable, @@ -67,9 +62,6 @@ async def publish( # type: ignore[override] mandatory: bool = True, immediate: bool = False, timeout: "TimeoutType" = None, - rpc: bool = False, - rpc_timeout: Optional[float] = 30.0, - raise_timeout: bool = False, persist: bool = False, reply_to: Optional[str] = None, headers: Optional["HeadersType"] = None, @@ -82,57 +74,29 @@ async def publish( # type: ignore[override] message_type: Optional[str] = None, user_id: Optional[str] = None, app_id: Optional[str] = None, - ) -> Optional[Any]: + ) -> Optional["aiormq.abc.ConfirmationFrameType"]: """Publish a message to a RabbitMQ queue.""" - context: AsyncContextManager[ - Optional[MemoryObjectReceiveStream[IncomingMessage]] - ] - if rpc: - if reply_to is not None: - raise WRONG_PUBLISH_ARGS - - context = _RPCCallback( - self._rpc_lock, - await self.declarer.declare_queue(RABBIT_REPLY), - ) - else: - context = fake_context() - - async with context as response_queue: - r = await self._publish( - message=message, - exchange=exchange, - routing_key=routing_key, - mandatory=mandatory, - immediate=immediate, - timeout=timeout, - persist=persist, - reply_to=reply_to if response_queue is None else RABBIT_REPLY.name, - headers=headers, - content_type=content_type, - content_encoding=content_encoding, - priority=priority, - correlation_id=correlation_id, - expiration=expiration, - message_id=message_id, - timestamp=timestamp, - message_type=message_type, - user_id=user_id, - app_id=app_id, - ) - - if response_queue is None: - return r - - else: - msg: Optional[IncomingMessage] = None - with timeout_scope(rpc_timeout, raise_timeout): - msg = await response_queue.receive() - - if msg: # pragma: no branch - return await self._decoder(await self._parser(msg)) - - return None + return await self._publish( + message=message, + exchange=exchange, + routing_key=routing_key, + mandatory=mandatory, + immediate=immediate, + timeout=timeout, + persist=persist, + reply_to=reply_to, + headers=headers, + content_type=content_type, + content_encoding=content_encoding, + priority=priority, + correlation_id=correlation_id, + expiration=expiration, + message_id=message_id, + timestamp=timestamp, + message_type=message_type, + user_id=user_id, + app_id=app_id, + ) @override async def request( # type: ignore[override] @@ -208,7 +172,7 @@ async def _publish( message_type: Optional[str], user_id: Optional[str], app_id: Optional[str], - ) -> Union["aiormq.abc.ConfirmationFrameType", "SendableMessage"]: + ) -> Optional["aiormq.abc.ConfirmationFrameType"]: """Publish a message to a RabbitMQ exchange.""" message = AioPikaParser.encode_message( message=message, diff --git a/faststream/rabbit/publisher/usecase.py b/faststream/rabbit/publisher/usecase.py index 4b537fef79..9a9521b6dc 100644 --- a/faststream/rabbit/publisher/usecase.py +++ b/faststream/rabbit/publisher/usecase.py @@ -13,7 +13,7 @@ ) from aio_pika import IncomingMessage -from typing_extensions import Annotated, Doc, TypedDict, Unpack, deprecated, override +from typing_extensions import Annotated, Doc, TypedDict, Unpack, override from faststream._internal.publisher.usecase import PublisherUsecase from faststream._internal.utils.functions import return_input @@ -23,6 +23,7 @@ from faststream.rabbit.subscriber.usecase import LogicSubscriber if TYPE_CHECKING: + import aiormq from aio_pika.abc import DateType, HeadersType, TimeoutType from faststream._internal.basic_types import AnyDict, AsyncFunc @@ -216,44 +217,13 @@ async def publish( # type: ignore[override] Optional["DateType"], Doc("Message publish timestamp. Generated automatically if not presented."), ] = None, - # rpc args - rpc: Annotated[ - bool, - Doc("Whether to wait for reply in blocking mode."), - deprecated( - "Deprecated in **FastStream 0.5.17**. " - "Please, use `request` method instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = False, - rpc_timeout: Annotated[ - Optional[float], - Doc("RPC reply waiting time."), - deprecated( - "Deprecated in **FastStream 0.5.17**. " - "Please, use `request` method with `timeout` instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = 30.0, - raise_timeout: Annotated[ - bool, - Doc( - "Whetever to raise `TimeoutError` or return `None` at **rpc_timeout**. " - "RPC request returns `None` at timeout by default." - ), - deprecated( - "Deprecated in **FastStream 0.5.17**. " - "`request` always raises TimeoutError instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = False, # publisher specific _extra_middlewares: Annotated[ Iterable["PublisherMiddleware"], Doc("Extra middlewares to wrap publishing process."), ] = (), **publish_kwargs: "Unpack[PublishKwargs]", - ) -> Optional[Any]: + ) -> Optional["aiormq.abc.ConfirmationFrameType"]: assert self._producer, NOT_CONNECTED_YET # nosec B101 kwargs: AnyDict = { @@ -266,9 +236,6 @@ async def publish( # type: ignore[override] "message_id": message_id, "timestamp": timestamp, # specific args - "rpc": rpc, - "rpc_timeout": rpc_timeout, - "raise_timeout": raise_timeout, "reply_to": self.reply_to, **self.message_kwargs, **publish_kwargs, diff --git a/faststream/rabbit/testing.py b/faststream/rabbit/testing.py index 12c5136b9f..edef7c9fdc 100644 --- a/faststream/rabbit/testing.py +++ b/faststream/rabbit/testing.py @@ -12,8 +12,7 @@ from faststream._internal.subscriber.utils import resolve_custom_func from faststream._internal.testing.broker import TestBroker -from faststream._internal.utils.functions import timeout_scope -from faststream.exceptions import WRONG_PUBLISH_ARGS, SubscriberNotFound +from faststream.exceptions import SubscriberNotFound from faststream.message import gen_cor_id from faststream.rabbit.broker.broker import RabbitBroker from faststream.rabbit.parser import AioPikaParser @@ -200,9 +199,6 @@ async def publish( # type: ignore[override] mandatory: bool = True, immediate: bool = False, timeout: "TimeoutType" = None, - rpc: bool = False, - rpc_timeout: Optional[float] = 30.0, - raise_timeout: bool = False, persist: bool = False, reply_to: Optional[str] = None, headers: Optional["HeadersType"] = None, @@ -219,9 +215,6 @@ async def publish( # type: ignore[override] """Publish a message to a RabbitMQ queue or exchange.""" exch = RabbitExchange.validate(exchange) - if rpc and reply_to: - raise WRONG_PUBLISH_ARGS - incoming = build_message( message=message, exchange=exch, @@ -245,10 +238,7 @@ async def publish( # type: ignore[override] if _is_handler_suitable( handler, incoming.routing_key, incoming.headers, exch ): - with timeout_scope(rpc_timeout, raise_timeout): - response = await self._execute_handler(incoming, handler) - if rpc: - return await self._decoder(await self._parser(response)) + await self._execute_handler(incoming, handler) return None From f551c21bc805ba16afb7dd506ff8b81e700c47f3 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Fri, 13 Sep 2024 22:37:48 +0300 Subject: [PATCH 157/245] refactor: remove Redis publish rpc --- faststream/rabbit/testing.py | 2 +- faststream/redis/broker/broker.py | 38 +------- faststream/redis/publisher/producer.py | 49 +---------- faststream/redis/publisher/usecase.py | 115 +------------------------ faststream/redis/testing.py | 16 +--- 5 files changed, 14 insertions(+), 206 deletions(-) diff --git a/faststream/rabbit/testing.py b/faststream/rabbit/testing.py index edef7c9fdc..75026edaac 100644 --- a/faststream/rabbit/testing.py +++ b/faststream/rabbit/testing.py @@ -211,7 +211,7 @@ async def publish( # type: ignore[override] message_type: Optional[str] = None, user_id: Optional[str] = None, app_id: Optional[str] = None, - ) -> Optional[Any]: + ) -> None: """Publish a message to a RabbitMQ queue or exchange.""" exch = RabbitExchange.validate(exchange) diff --git a/faststream/redis/broker/broker.py b/faststream/redis/broker/broker.py index b65a02008f..82e6423b14 100644 --- a/faststream/redis/broker/broker.py +++ b/faststream/redis/broker/broker.py @@ -23,7 +23,7 @@ parse_url, ) from redis.exceptions import ConnectionError -from typing_extensions import Annotated, Doc, TypeAlias, deprecated, override +from typing_extensions import Annotated, Doc, TypeAlias, override from faststream.__about__ import __version__ from faststream._internal.constants import EMPTY @@ -44,7 +44,6 @@ from faststream._internal.basic_types import ( AnyDict, AsyncFunc, - DecodedMessage, Decorator, LoggerProto, SendableMessage, @@ -405,37 +404,7 @@ async def publish( # type: ignore[override] "Remove eldest message if maxlen exceeded." ), ] = None, - rpc: Annotated[ - bool, - Doc("Whether to wait for reply in blocking mode."), - deprecated( - "Deprecated in **FastStream 0.5.17**. " - "Please, use `request` method instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = False, - rpc_timeout: Annotated[ - Optional[float], - Doc("RPC reply waiting time."), - deprecated( - "Deprecated in **FastStream 0.5.17**. " - "Please, use `request` method with `timeout` instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = 30.0, - raise_timeout: Annotated[ - bool, - Doc( - "Whetever to raise `TimeoutError` or return `None` at **rpc_timeout**. " - "RPC request returns `None` at timeout by default." - ), - deprecated( - "Deprecated in **FastStream 0.5.17**. " - "`request` always raises TimeoutError instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = False, - ) -> Optional["DecodedMessage"]: + ) -> None: """Publish message directly. This method allows you to publish message in not AsyncAPI-documented way. You can use it in another frameworks @@ -453,9 +422,6 @@ async def publish( # type: ignore[override] maxlen=maxlen, reply_to=reply_to, headers=headers, - rpc=rpc, - rpc_timeout=rpc_timeout, - raise_timeout=raise_timeout, ) @override diff --git a/faststream/redis/publisher/producer.py b/faststream/redis/publisher/producer.py index afcb416aa6..189347a7c4 100644 --- a/faststream/redis/publisher/producer.py +++ b/faststream/redis/publisher/producer.py @@ -5,15 +5,14 @@ from faststream._internal.publisher.proto import ProducerProto from faststream._internal.subscriber.utils import resolve_custom_func -from faststream._internal.utils.functions import timeout_scope from faststream._internal.utils.nuid import NUID -from faststream.exceptions import WRONG_PUBLISH_ARGS, SetupError +from faststream.exceptions import SetupError from faststream.redis.message import DATA_KEY from faststream.redis.parser import RawMessage, RedisPubSubParser from faststream.redis.schemas import INCORRECT_SETUP_MSG if TYPE_CHECKING: - from redis.asyncio.client import PubSub, Redis + from redis.asyncio.client import Redis from faststream._internal.basic_types import AnyDict, SendableMessage from faststream._internal.types import ( @@ -59,23 +58,10 @@ async def publish( # type: ignore[override] maxlen: Optional[int] = None, headers: Optional["AnyDict"] = None, reply_to: str = "", - rpc: bool = False, - rpc_timeout: Optional[float] = 30.0, - raise_timeout: bool = False, - ) -> Optional[Any]: + ) -> None: if not any((channel, list, stream)): raise SetupError(INCORRECT_SETUP_MSG) - psub: Optional[PubSub] = None - if rpc: - if reply_to: - raise WRONG_PUBLISH_ARGS - nuid = NUID() - rpc_nuid = str(nuid.next(), "utf-8") - reply_to = rpc_nuid - psub = self._connection.pubsub() - await psub.subscribe(reply_to) - msg = RawMessage.encode( message=message, reply_to=reply_to, @@ -96,34 +82,7 @@ async def publish( # type: ignore[override] else: raise AssertionError("unreachable") - if psub is None: - return None - - else: - m = None - with timeout_scope(rpc_timeout, raise_timeout): - # skip subscribe message - await psub.get_message( - ignore_subscribe_messages=True, - timeout=rpc_timeout or 0.0, - ) - - # get real response - m = await psub.get_message( - ignore_subscribe_messages=True, - timeout=rpc_timeout or 0.0, - ) - - await psub.unsubscribe() - await psub.aclose() # type: ignore[attr-defined] - - if m is None: - if raise_timeout: - raise TimeoutError() - else: - return None - else: - return await self._decoder(await self._parser(m)) + return None @override async def request( # type: ignore[override] diff --git a/faststream/redis/publisher/usecase.py b/faststream/redis/publisher/usecase.py index 5f7e57a475..5dcd6785f5 100644 --- a/faststream/redis/publisher/usecase.py +++ b/faststream/redis/publisher/usecase.py @@ -5,7 +5,7 @@ from itertools import chain from typing import TYPE_CHECKING, Any, Awaitable, Callable, Iterable, Optional -from typing_extensions import Annotated, Doc, deprecated, override +from typing_extensions import Annotated, Doc, override from faststream._internal.publisher.usecase import PublisherUsecase from faststream._internal.utils.functions import return_input @@ -131,45 +131,13 @@ async def publish( "**correlation_id** is a useful option to trace messages." ), ] = None, - *, - # rpc args - rpc: Annotated[ - bool, - Doc("Whether to wait for reply in blocking mode."), - deprecated( - "Deprecated in **FastStream 0.5.17**. " - "Please, use `request` method instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = False, - rpc_timeout: Annotated[ - Optional[float], - Doc("RPC reply waiting time."), - deprecated( - "Deprecated in **FastStream 0.5.17**. " - "Please, use `request` method with `timeout` instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = 30.0, - raise_timeout: Annotated[ - bool, - Doc( - "Whetever to raise `TimeoutError` or return `None` at **rpc_timeout**. " - "RPC request returns `None` at timeout by default." - ), - deprecated( - "Deprecated in **FastStream 0.5.17**. " - "`request` always raises TimeoutError instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = False, # publisher specific _extra_middlewares: Annotated[ Iterable["PublisherMiddleware"], Doc("Extra middlewares to wrap publishing process."), ] = (), **kwargs: Any, # option to suppress maxlen - ) -> Optional[Any]: + ) -> None: assert self._producer, NOT_CONNECTED_YET # nosec B101 channel_sub = PubSub.validate(channel or self.channel) @@ -195,10 +163,6 @@ async def publish( reply_to=reply_to, headers=headers, correlation_id=correlation_id, - # RPC args - rpc=rpc, - rpc_timeout=rpc_timeout, - raise_timeout=raise_timeout, ) @override @@ -344,45 +308,13 @@ async def publish( "**correlation_id** is a useful option to trace messages." ), ] = None, - *, - # rpc args - rpc: Annotated[ - bool, - Doc("Whether to wait for reply in blocking mode."), - deprecated( - "Deprecated in **FastStream 0.5.17**. " - "Please, use `request` method instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = False, - rpc_timeout: Annotated[ - Optional[float], - Doc("RPC reply waiting time."), - deprecated( - "Deprecated in **FastStream 0.5.17**. " - "Please, use `request` method with `timeout` instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = 30.0, - raise_timeout: Annotated[ - bool, - Doc( - "Whetever to raise `TimeoutError` or return `None` at **rpc_timeout**. " - "RPC request returns `None` at timeout by default." - ), - deprecated( - "Deprecated in **FastStream 0.5.17**. " - "`request` always raises TimeoutError instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = False, # publisher specific _extra_middlewares: Annotated[ Iterable["PublisherMiddleware"], Doc("Extra middlewares to wrap publishing process."), ] = (), **kwargs: Any, # option to suppress maxlen - ) -> Any: + ) -> None: assert self._producer, NOT_CONNECTED_YET # nosec B101 list_sub = ListSub.validate(list or self.list) @@ -407,10 +339,6 @@ async def publish( reply_to=reply_to, headers=headers or self.headers, correlation_id=correlation_id, - # RPC args - rpc=rpc, - rpc_timeout=rpc_timeout, - raise_timeout=raise_timeout, ) @override @@ -617,43 +545,12 @@ async def publish( "Remove eldest message if maxlen exceeded." ), ] = None, - # rpc args - rpc: Annotated[ - bool, - Doc("Whether to wait for reply in blocking mode."), - deprecated( - "Deprecated in **FastStream 0.5.17**. " - "Please, use `request` method instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = False, - rpc_timeout: Annotated[ - Optional[float], - Doc("RPC reply waiting time."), - deprecated( - "Deprecated in **FastStream 0.5.17**. " - "Please, use `request` method with `timeout` instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = 30.0, - raise_timeout: Annotated[ - bool, - Doc( - "Whetever to raise `TimeoutError` or return `None` at **rpc_timeout**. " - "RPC request returns `None` at timeout by default." - ), - deprecated( - "Deprecated in **FastStream 0.5.17**. " - "`request` always raises TimeoutError instead. " - "Argument will be removed in **FastStream 0.6.0**." - ), - ] = False, # publisher specific _extra_middlewares: Annotated[ Iterable["PublisherMiddleware"], Doc("Extra middlewares to wrap publishing process."), ] = (), - ) -> Optional[Any]: + ) -> None: assert self._producer, NOT_CONNECTED_YET # nosec B101 stream_sub = StreamSub.validate(stream or self.stream) @@ -681,10 +578,6 @@ async def publish( reply_to=reply_to, headers=headers, correlation_id=correlation_id, - # RPC args - rpc=rpc, - rpc_timeout=rpc_timeout, - raise_timeout=raise_timeout, ) @override diff --git a/faststream/redis/testing.py b/faststream/redis/testing.py index 8a7c1f0d05..c729305229 100644 --- a/faststream/redis/testing.py +++ b/faststream/redis/testing.py @@ -17,8 +17,7 @@ from faststream._internal.subscriber.utils import resolve_custom_func from faststream._internal.testing.broker import TestBroker -from faststream._internal.utils.functions import timeout_scope -from faststream.exceptions import WRONG_PUBLISH_ARGS, SetupError, SubscriberNotFound +from faststream.exceptions import SetupError, SubscriberNotFound from faststream.message import gen_cor_id from faststream.redis.broker.broker import RedisBroker from faststream.redis.message import ( @@ -121,13 +120,7 @@ async def publish( headers: Optional["AnyDict"] = None, reply_to: str = "", correlation_id: Optional[str] = None, - rpc: bool = False, - rpc_timeout: Optional[float] = 30.0, - raise_timeout: bool = False, - ) -> Optional[Any]: - if rpc and reply_to: - raise WRONG_PUBLISH_ARGS - + ) -> None: correlation_id = correlation_id or gen_cor_id() body = build_message( @@ -149,10 +142,7 @@ async def publish( handler, # type: ignore[arg-type] ) - with timeout_scope(rpc_timeout, raise_timeout): - response_msg = await self._execute_handler(msg, handler) - if rpc: - return await self._decoder(await self._parser(response_msg)) + await self._execute_handler(msg, handler) return None From 999665036285722b8e8563e73d159828c33f9c06 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Fri, 13 Sep 2024 22:42:29 +0300 Subject: [PATCH 158/245] refactor: remove Kafka & Confluent publish rpc --- faststream/confluent/testing.py | 19 ++----------------- faststream/kafka/testing.py | 19 ++----------------- 2 files changed, 4 insertions(+), 34 deletions(-) diff --git a/faststream/confluent/testing.py b/faststream/confluent/testing.py index 62cfe93354..13be8c316c 100644 --- a/faststream/confluent/testing.py +++ b/faststream/confluent/testing.py @@ -7,7 +7,6 @@ from faststream._internal.subscriber.utils import resolve_custom_func from faststream._internal.testing.broker import TestBroker -from faststream._internal.utils.functions import timeout_scope from faststream.confluent.broker import KafkaBroker from faststream.confluent.parser import AsyncConfluentParser from faststream.confluent.publisher.producer import AsyncConfluentFastProducer @@ -102,10 +101,7 @@ async def publish( # type: ignore[override] *, no_confirm: bool = False, reply_to: str = "", - rpc: bool = False, - rpc_timeout: Optional[float] = None, - raise_timeout: bool = False, - ) -> Optional[Any]: + ) -> None: """Publish a message to the Kafka broker.""" incoming = build_message( message=message, @@ -118,8 +114,6 @@ async def publish( # type: ignore[override] reply_to=reply_to, ) - return_value = None - for handler in self.broker._subscribers.values(): # pragma: no branch if _is_handler_matches(handler, topic, partition): msg_to_send = ( @@ -128,16 +122,7 @@ async def publish( # type: ignore[override] else incoming ) - with timeout_scope(rpc_timeout, raise_timeout): - response_msg = await self._execute_handler( - msg_to_send, topic, handler - ) - if rpc: - return_value = return_value or await self._decoder( - await self._parser(response_msg) - ) - - return return_value + await self._execute_handler(msg_to_send, topic, handler) async def publish_batch( self, diff --git a/faststream/kafka/testing.py b/faststream/kafka/testing.py index 5912e66d37..bc87c5d2ed 100755 --- a/faststream/kafka/testing.py +++ b/faststream/kafka/testing.py @@ -9,7 +9,6 @@ from faststream._internal.subscriber.utils import resolve_custom_func from faststream._internal.testing.broker import TestBroker -from faststream._internal.utils.functions import timeout_scope from faststream.exceptions import SubscriberNotFound from faststream.kafka import TopicPartition from faststream.kafka.broker import KafkaBroker @@ -102,11 +101,8 @@ async def publish( # type: ignore[override] correlation_id: Optional[str] = None, *, reply_to: str = "", - rpc: bool = False, - rpc_timeout: Optional[float] = None, - raise_timeout: bool = False, no_confirm: bool = False, - ) -> Optional[Any]: + ) -> None: """Publish a message to the Kafka broker.""" incoming = build_message( message=message, @@ -119,8 +115,6 @@ async def publish( # type: ignore[override] reply_to=reply_to, ) - return_value = None - for handler in self.broker._subscribers.values(): # pragma: no branch if _is_handler_matches(handler, topic, partition): msg_to_send = ( @@ -129,16 +123,7 @@ async def publish( # type: ignore[override] else incoming ) - with timeout_scope(rpc_timeout, raise_timeout): - response_msg = await self._execute_handler( - msg_to_send, topic, handler - ) - if rpc: - return_value = return_value or await self._decoder( - await self._parser(response_msg) - ) - - return return_value + await self._execute_handler(msg_to_send, topic, handler) @override async def request( # type: ignore[override] From 0d90ebad26b06376a6d8ddbdb558839165ce092b Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Fri, 13 Sep 2024 21:17:23 +0300 Subject: [PATCH 159/245] Refactor AsyncAPI 2.6.0 generation / handling + fix wrong message title --- faststream/specification/asyncapi/utils.py | 4 ++++ .../specification/asyncapi/v2_6_0/generate.py | 17 +++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/faststream/specification/asyncapi/utils.py b/faststream/specification/asyncapi/utils.py index 516adb15c2..56c545168d 100644 --- a/faststream/specification/asyncapi/utils.py +++ b/faststream/specification/asyncapi/utils.py @@ -45,3 +45,7 @@ def resolve_payloads( payload = {} return payload + + +def clear_json_key(key: str) -> str: + return key.replace("/", ".") diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index 886aa715f4..00b84aeb23 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -3,6 +3,7 @@ from faststream._internal._compat import DEF_KEY from faststream._internal.basic_types import AnyDict from faststream._internal.constants import ContentTypes +from faststream.specification.asyncapi.utils import clear_json_key from faststream.specification.asyncapi.v2_6_0.schema import ( Channel, Components, @@ -142,13 +143,13 @@ def get_broker_channels( for h in broker._subscribers.values(): schema = h.schema() channels.update( - {key: channel_from_spec(channel) for key, channel in schema.items()} + {clear_json_key(key): channel_from_spec(channel) for key, channel in schema.items()} ) for p in broker._publishers.values(): schema = p.schema() channels.update( - {key: channel_from_spec(channel) for key, channel in schema.items()} + {clear_json_key(key): channel_from_spec(channel) for key, channel in schema.items()} ) return channels @@ -173,7 +174,7 @@ def _resolve_msg_payloads( one_of = m.payload.get("oneOf") if isinstance(one_of, dict): for p_title, p in one_of.items(): - p_title = p_title.replace("/", ".") + p_title = clear_json_key(p_title) payloads.update(p.pop(DEF_KEY, {})) if p_title not in payloads: payloads[p_title] = p @@ -184,7 +185,7 @@ def _resolve_msg_payloads( for p in one_of: p_value = next(iter(p.values())) p_title = p_value.split("/")[-1] - p_title = p_title.replace("/", ".") + p_title = clear_json_key(p_title) if p_title not in payloads: payloads[p_title] = p one_of_list.append(Reference(**{"$ref": f"#/components/schemas/{p_title}"})) @@ -192,7 +193,7 @@ def _resolve_msg_payloads( if not one_of_list: payloads.update(m.payload.pop(DEF_KEY, {})) p_title = m.payload.get("title", f"{channel_name}Payload") - p_title = p_title.replace("/", ".") + p_title = clear_json_key(p_title) if p_title not in payloads: payloads[p_title] = m.payload m.payload = {"$ref": f"#/components/schemas/{p_title}"} @@ -201,9 +202,9 @@ def _resolve_msg_payloads( m.payload["oneOf"] = one_of_list assert m.title # nosec B101 - m.title = m.title.replace("/", ".") - messages[m.title] = m - return Reference(**{"$ref": f"#/components/messages/{m.title}"}) + message_title = clear_json_key(m.title) + messages[message_title] = m + return Reference(**{"$ref": f"#/components/messages/{message_title}"}) def move_pydantic_refs( From 1999eb8eddc7d6b35e8fff38fa109dd67a2c08ae Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 14 Sep 2024 11:37:56 +0300 Subject: [PATCH 160/245] AsyncAPI 3.0.0 generation / char in titles support --- faststream/specification/asyncapi/utils.py | 2 +- .../specification/asyncapi/v2_6_0/generate.py | 14 +++++++------- .../specification/asyncapi/v3_0_0/generate.py | 19 ++++++++++++++----- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/faststream/specification/asyncapi/utils.py b/faststream/specification/asyncapi/utils.py index 56c545168d..1ffffec138 100644 --- a/faststream/specification/asyncapi/utils.py +++ b/faststream/specification/asyncapi/utils.py @@ -47,5 +47,5 @@ def resolve_payloads( return payload -def clear_json_key(key: str) -> str: +def clear_key(key: str) -> str: return key.replace("/", ".") diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index 00b84aeb23..405efba399 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -3,7 +3,7 @@ from faststream._internal._compat import DEF_KEY from faststream._internal.basic_types import AnyDict from faststream._internal.constants import ContentTypes -from faststream.specification.asyncapi.utils import clear_json_key +from faststream.specification.asyncapi.utils import clear_key from faststream.specification.asyncapi.v2_6_0.schema import ( Channel, Components, @@ -143,13 +143,13 @@ def get_broker_channels( for h in broker._subscribers.values(): schema = h.schema() channels.update( - {clear_json_key(key): channel_from_spec(channel) for key, channel in schema.items()} + {clear_key(key): channel_from_spec(channel) for key, channel in schema.items()} ) for p in broker._publishers.values(): schema = p.schema() channels.update( - {clear_json_key(key): channel_from_spec(channel) for key, channel in schema.items()} + {clear_key(key): channel_from_spec(channel) for key, channel in schema.items()} ) return channels @@ -174,7 +174,7 @@ def _resolve_msg_payloads( one_of = m.payload.get("oneOf") if isinstance(one_of, dict): for p_title, p in one_of.items(): - p_title = clear_json_key(p_title) + p_title = clear_key(p_title) payloads.update(p.pop(DEF_KEY, {})) if p_title not in payloads: payloads[p_title] = p @@ -185,7 +185,7 @@ def _resolve_msg_payloads( for p in one_of: p_value = next(iter(p.values())) p_title = p_value.split("/")[-1] - p_title = clear_json_key(p_title) + p_title = clear_key(p_title) if p_title not in payloads: payloads[p_title] = p one_of_list.append(Reference(**{"$ref": f"#/components/schemas/{p_title}"})) @@ -193,7 +193,7 @@ def _resolve_msg_payloads( if not one_of_list: payloads.update(m.payload.pop(DEF_KEY, {})) p_title = m.payload.get("title", f"{channel_name}Payload") - p_title = clear_json_key(p_title) + p_title = clear_key(p_title) if p_title not in payloads: payloads[p_title] = m.payload m.payload = {"$ref": f"#/components/schemas/{p_title}"} @@ -202,7 +202,7 @@ def _resolve_msg_payloads( m.payload["oneOf"] = one_of_list assert m.title # nosec B101 - message_title = clear_json_key(m.title) + message_title = clear_key(m.title) messages[message_title] = m return Reference(**{"$ref": f"#/components/messages/{message_title}"}) diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index c4fac01933..97ca91c561 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -4,6 +4,7 @@ from faststream._internal._compat import DEF_KEY from faststream._internal.basic_types import AnyDict from faststream._internal.constants import ContentTypes +from faststream.specification.asyncapi.utils import clear_key from faststream.specification.asyncapi.v2_6_0.generate import move_pydantic_refs from faststream.specification.asyncapi.v2_6_0.schema import ( Reference, @@ -143,6 +144,8 @@ def get_broker_operations( for h in broker._subscribers.values(): for channel_name, specs_channel in h.schema().items(): + channel_name = clear_key(channel_name) + if specs_channel.subscribe is not None: operations[f"{channel_name}Subscribe"] = operation_from_spec( specs_channel.subscribe, Action.RECEIVE, channel_name @@ -150,6 +153,8 @@ def get_broker_operations( for p in broker._publishers.values(): for channel_name, specs_channel in p.schema().items(): + channel_name = clear_key(channel_name) + if specs_channel.publish is not None: operations[f"{channel_name}"] = operation_from_spec( specs_channel.publish, Action.SEND, channel_name @@ -174,7 +179,7 @@ def get_broker_channels( *left, right = message.title.split(":") message.title = ":".join(left) + f":Subscribe{right}" - channels_schema_v3_0[channel_name] = channel_from_spec( + channels_schema_v3_0[clear_key(channel_name)] = channel_from_spec( specs_channel, message, channel_name, @@ -187,7 +192,7 @@ def get_broker_channels( channels_schema_v3_0 = {} for channel_name, specs_channel in pub.schema().items(): if specs_channel.publish: - channels_schema_v3_0[channel_name] = channel_from_spec( + channels_schema_v3_0[clear_key(channel_name)] = channel_from_spec( specs_channel, specs_channel.publish.message, channel_name, @@ -210,6 +215,9 @@ def _resolve_msg_payloads( m.payload = move_pydantic_refs(m.payload, DEF_KEY) + message_name = clear_key(message_name) + channel_name = clear_key(channel_name) + if DEF_KEY in m.payload: payloads.update(m.payload.pop(DEF_KEY)) @@ -218,13 +226,13 @@ def _resolve_msg_payloads( one_of_list = [] processed_payloads: Dict[str, AnyDict] = {} for name, payload in one_of.items(): - processed_payloads[name] = payload + processed_payloads[clear_key(name)] = payload one_of_list.append(Reference(**{"$ref": f"#/components/schemas/{name}"})) payloads.update(processed_payloads) m.payload["oneOf"] = one_of_list assert m.title - messages[m.title] = m + messages[clear_key(m.title)] = m return Reference( **{"$ref": f"#/components/messages/{channel_name}:{message_name}"} ) @@ -232,10 +240,11 @@ def _resolve_msg_payloads( else: 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) payloads[payload_name] = m.payload m.payload = {"$ref": f"#/components/schemas/{payload_name}"} assert m.title - messages[m.title] = m + messages[clear_key(m.title)] = m return Reference( **{"$ref": f"#/components/messages/{channel_name}:{message_name}"} ) From 92f7f746cb5724a8239ec6f46f8b229d99738a30 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 14 Sep 2024 12:05:38 +0300 Subject: [PATCH 161/245] AsyncAPI generation / handling tests --- tests/asyncapi/base/v2_6_0/arguments.py | 14 ++++++++++++++ tests/asyncapi/base/v3_0_0/arguments.py | 18 ++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/tests/asyncapi/base/v2_6_0/arguments.py b/tests/asyncapi/base/v2_6_0/arguments.py index 2b62e99907..5096b3e693 100644 --- a/tests/asyncapi/base/v2_6_0/arguments.py +++ b/tests/asyncapi/base/v2_6_0/arguments.py @@ -35,6 +35,20 @@ async def handle(msg): ... assert key == "custom_name" assert schema["channels"][key]["description"] == "test description" + def test_slash_in_title(self): + broker = self.broker_class() + + @broker.subscriber("test", title="/") + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + + assert tuple(schema["channels"].keys())[0] == "." + assert tuple(schema["components"]["messages"].keys())[0] == ".:Message" + assert schema["components"]["messages"][".:Message"]["title"] == "/:Message" + assert tuple(schema["components"]["schemas"].keys())[0] == ".:Message:Payload" + assert schema["components"]["schemas"][".:Message:Payload"]["title"] == "/:Message:Payload" + def test_docstring_description(self): broker = self.broker_class() diff --git a/tests/asyncapi/base/v3_0_0/arguments.py b/tests/asyncapi/base/v3_0_0/arguments.py index 57ff9b4ce1..0842223318 100644 --- a/tests/asyncapi/base/v3_0_0/arguments.py +++ b/tests/asyncapi/base/v3_0_0/arguments.py @@ -36,6 +36,24 @@ async def handle(msg): ... assert key == "custom_name" assert schema["channels"][key]["description"] == "test description" + def test_slash_in_title(self): + broker = self.broker_factory() + + @broker.subscriber("test", title="/") + async def handle(msg): ... + + schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + + assert tuple(schema["channels"].keys())[0] == "." + assert schema["channels"]["."]["address"] == "/" + + assert tuple(schema["operations"].keys())[0] == ".Subscribe" + + assert tuple(schema["components"]["messages"].keys())[0] == ".:SubscribeMessage" + assert schema["components"]["messages"][".:SubscribeMessage"]["title"] == "/:SubscribeMessage" + assert tuple(schema["components"]["schemas"].keys())[0] == ".:Message:Payload" + assert schema["components"]["schemas"][".:Message:Payload"]["title"] == "/:Message:Payload" + def test_docstring_description(self): broker = self.broker_factory() From c6e5bad56df5359d3686e83796814a1183afeab8 Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov Date: Sat, 14 Sep 2024 12:08:54 +0300 Subject: [PATCH 162/245] New tests refactoring --- tests/asyncapi/base/v2_6_0/arguments.py | 8 +++++--- tests/asyncapi/base/v3_0_0/arguments.py | 9 +++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/tests/asyncapi/base/v2_6_0/arguments.py b/tests/asyncapi/base/v2_6_0/arguments.py index 5096b3e693..74c81466f9 100644 --- a/tests/asyncapi/base/v2_6_0/arguments.py +++ b/tests/asyncapi/base/v2_6_0/arguments.py @@ -43,10 +43,12 @@ async def handle(msg): ... schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() - assert tuple(schema["channels"].keys())[0] == "." - assert tuple(schema["components"]["messages"].keys())[0] == ".:Message" + assert next(iter(schema["channels"].keys())) == "." + + assert next(iter(schema["components"]["messages"].keys())) == ".:Message" assert schema["components"]["messages"][".:Message"]["title"] == "/:Message" - assert tuple(schema["components"]["schemas"].keys())[0] == ".:Message:Payload" + + assert next(iter(schema["components"]["schemas"].keys())) == ".:Message:Payload" assert schema["components"]["schemas"][".:Message:Payload"]["title"] == "/:Message:Payload" def test_docstring_description(self): diff --git a/tests/asyncapi/base/v3_0_0/arguments.py b/tests/asyncapi/base/v3_0_0/arguments.py index 0842223318..1a9fbd24c3 100644 --- a/tests/asyncapi/base/v3_0_0/arguments.py +++ b/tests/asyncapi/base/v3_0_0/arguments.py @@ -44,14 +44,15 @@ async def handle(msg): ... schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() - assert tuple(schema["channels"].keys())[0] == "." + assert next(iter(schema["channels"].keys())) == "." assert schema["channels"]["."]["address"] == "/" - assert tuple(schema["operations"].keys())[0] == ".Subscribe" + assert next(iter(schema["operations"].keys())) == ".Subscribe" - assert tuple(schema["components"]["messages"].keys())[0] == ".:SubscribeMessage" + assert next(iter(schema["components"]["messages"].keys())) == ".:SubscribeMessage" assert schema["components"]["messages"][".:SubscribeMessage"]["title"] == "/:SubscribeMessage" - assert tuple(schema["components"]["schemas"].keys())[0] == ".:Message:Payload" + + assert next(iter(schema["components"]["schemas"].keys())) == ".:Message:Payload" assert schema["components"]["schemas"][".:Message:Payload"]["title"] == "/:Message:Payload" def test_docstring_description(self): From d7c6a758c8637a1d33fa962703bbbebd528b68e7 Mon Sep 17 00:00:00 2001 From: KrySeyt Date: Sat, 14 Sep 2024 09:17:48 +0000 Subject: [PATCH 163/245] docs: generate API References --- docs/docs/SUMMARY.md | 236 ++++-------------- .../acknowledgement_watcher/CounterWatcher.md | 11 - .../acknowledgement_watcher/EndlessWatcher.md | 11 - .../acknowledgement_watcher/OneTryWatcher.md | 11 - .../acknowledgement_watcher/WatcherContext.md | 11 - .../acknowledgement_watcher/get_watcher.md | 11 - .../get_dependant/get_fastapi_dependant.md | 11 - .../get_fastapi_native_dependant.md | 11 - .../broker/fastapi/route/StreamMessage.md | 11 - .../build_faststream_to_fastapi_parser.md | 11 - .../fastapi/route/make_fastapi_execution.md | 11 - .../wrap_callable_to_fastapi_compatible.md | 11 - .../broker/fastapi/router/StreamRouter.md | 11 - .../broker/message/decode_message.md | 11 - .../broker/message/encode_message.md | 11 - .../broker/middlewares/BaseMiddleware.md | 11 - .../broker/middlewares/base/BaseMiddleware.md | 11 - .../exception/BaseExceptionMiddleware.md | 11 - .../exception/ExceptionMiddleware.md | 11 - .../middlewares/exception/ignore_handler.md | 11 - .../logging/CriticalLogMiddleware.md | 11 - .../broker/publisher/fake/FakePublisher.md | 11 - .../publisher/proto/BasePublisherProto.md | 11 - .../broker/publisher/proto/ProducerProto.md | 11 - .../broker/publisher/proto/PublisherProto.md | 11 - .../publisher/usecase/PublisherUsecase.md | 11 - .../broker/response/ensure_response.md | 11 - .../faststream/broker/router/ArgsContainer.md | 11 - .../faststream/broker/router/BrokerRouter.md | 11 - .../broker/router/SubscriberRoute.md | 11 - .../faststream/broker/schemas/NameRequired.md | 11 - .../subscriber/call_item/HandlerItem.md | 11 - .../subscriber/proto/SubscriberProto.md | 11 - .../subscriber/usecase/SubscriberUsecase.md | 11 - .../broker/types/PublisherMiddleware.md | 11 - .../faststream/broker/utils/default_filter.md | 11 - .../broker/utils/get_watcher_context.md | 11 - .../faststream/broker/utils/process_msg.md | 11 - .../broker/utils/resolve_custom_func.md | 11 - .../broker/wrapper/call/HandlerCallWrapper.md | 11 - .../broker/wrapper/proto/WrapperProto.md | 11 - .../faststream/cli/main/publish_message.md | 11 - .../faststream/cli/main/version_callback.md | 11 - .../cli/supervisors/basereload/BaseReload.md | 11 - .../supervisors/multiprocess/Multiprocess.md | 11 - .../cli/supervisors/utils/get_subprocess.md | 11 - .../cli/supervisors/utils/set_exit.md | 11 - .../supervisors/utils/subprocess_started.md | 11 - .../supervisors/watchfiles/ExtendedFilter.md | 11 - .../supervisors/watchfiles/WatchReloader.md | 11 - .../cli/utils/imports/get_app_path.md | 11 - .../cli/utils/imports/import_from_string.md | 11 - .../cli/utils/imports/import_object.md | 11 - .../cli/utils/imports/try_import_app.md | 11 - .../faststream/cli/utils/logs/LogLevels.md | 11 - .../cli/utils/logs/get_log_level.md | 11 - .../cli/utils/logs/set_log_level.md | 11 - .../cli/utils/parser/parse_cli_args.md | 11 - .../cli/utils/parser/remove_prefix.md | 11 - .../en/api/faststream/confluent/TestApp.md | 2 +- .../faststream/confluent/fastapi/Context.md | 2 +- .../api/faststream/constants/ContentTypes.md | 11 - .../serve.md => exceptions/ContextError.md} | 2 +- docs/docs/en/api/faststream/kafka/TestApp.md | 2 +- .../api/faststream/kafka/fastapi/Context.md | 2 +- .../log/formatter/ColourizedFormatter.md | 11 - .../log/formatter/expand_log_field.md | 11 - .../faststream/log/logging/ExtendedFilter.md | 11 - .../log/logging/get_broker_logger.md | 11 - .../faststream/log/logging/set_logger_fmt.md | 11 - .../main/main.md => message/AckStatus.md} | 2 +- .../app/gen.md => message/StreamMessage.md} | 2 +- .../decode_message.md} | 2 +- .../encode_message.md} | 2 +- .../main/publish.md => message/gen_cor_id.md} | 2 +- .../message/AckStatus.md} | 2 +- .../message/StreamMessage.md | 2 +- .../utils/decode_message.md} | 2 +- .../utils/encode_message.md} | 2 +- .../utils/gen_cor_id.md} | 2 +- .../BaseMiddleware.md} | 2 +- .../middlewares/ExceptionMiddleware.md | 11 + .../middlewares/base/BaseMiddleware.md | 11 + .../exception/BaseExceptionMiddleware.md} | 2 +- .../exception}/ExceptionMiddleware.md | 2 +- .../exception/ignore_handler.md} | 2 +- .../logging/CriticalLogMiddleware.md | 11 + docs/docs/en/api/faststream/nats/TestApp.md | 2 +- .../en/api/faststream/nats/fastapi/Context.md | 2 +- .../faststream/{utils => params}/Context.md | 2 +- .../faststream/{utils => params}/Depends.md | 0 .../faststream/{utils => params}/Header.md | 2 +- .../api/faststream/{utils => params}/Path.md | 2 +- .../no_cast/NoCastField.md} | 2 +- .../context => params/params}/Context.md | 2 +- .../context => params/params}/Header.md | 2 +- .../{utils/context => params/params}/Path.md | 2 +- .../en/api/faststream/rabbit/ReplyConfig.md | 11 - docs/docs/en/api/faststream/rabbit/TestApp.md | 2 +- .../api/faststream/rabbit/fastapi/Context.md | 2 +- .../faststream/rabbit/schemas/ReplyConfig.md | 11 - .../rabbit/schemas/reply/ReplyConfig.md | 11 - docs/docs/en/api/faststream/redis/TestApp.md | 2 +- .../api/faststream/redis/fastapi/Context.md | 2 +- .../{cli/main/run.md => response/Response.md} | 2 +- .../ensure_response.md} | 2 +- .../faststream/response/response/Response.md | 11 + .../utils/ensure_response.md} | 2 +- .../asyncapi/utils/clear_key.md} | 2 +- .../docs/en/api/faststream/testing/TestApp.md | 11 - .../en/api/faststream/testing/app/TestApp.md | 11 - .../faststream/testing/broker/TestBroker.md | 11 - .../testing/broker/patch_broker_calls.md | 11 - .../en/api/faststream/types/LoggerProto.md | 11 - .../api/faststream/types/StandardDataclass.md | 11 - .../en/api/faststream/utils/ContextRepo.md | 11 - docs/docs/en/api/faststream/utils/NoCast.md | 11 - .../en/api/faststream/utils/apply_types.md | 11 - .../api/faststream/utils/ast/find_ast_node.md | 11 - .../faststream/utils/ast/find_withitems.md | 11 - .../utils/ast/get_withitem_calls.md | 11 - .../utils/ast/is_contains_context_name.md | 11 - .../api/faststream/utils/classes/Singleton.md | 11 - .../faststream/utils/context/ContextRepo.md | 11 - .../utils/context/builders/Context.md | 11 - .../utils/context/builders/Header.md | 11 - .../faststream/utils/context/builders/Path.md | 11 - .../utils/context/repository/ContextRepo.md | 11 - .../faststream/utils/context/types/Context.md | 11 - .../context/types/resolve_context_by_name.md | 11 - .../faststream/utils/data/filter_by_dict.md | 11 - .../utils/functions/call_or_await.md | 11 - .../utils/functions/drop_response_type.md | 11 - .../utils/functions/fake_context.md | 11 - .../utils/functions/return_input.md | 11 - .../utils/functions/sync_fake_context.md | 11 - .../utils/functions/timeout_scope.md | 11 - .../faststream/utils/functions/to_async.md | 11 - .../en/api/faststream/utils/no_cast/NoCast.md | 11 - .../docs/en/api/faststream/utils/nuid/NUID.md | 11 - .../api/faststream/utils/path/compile_path.md | 11 - 141 files changed, 123 insertions(+), 1318 deletions(-) delete mode 100644 docs/docs/en/api/faststream/broker/acknowledgement_watcher/CounterWatcher.md delete mode 100644 docs/docs/en/api/faststream/broker/acknowledgement_watcher/EndlessWatcher.md delete mode 100644 docs/docs/en/api/faststream/broker/acknowledgement_watcher/OneTryWatcher.md delete mode 100644 docs/docs/en/api/faststream/broker/acknowledgement_watcher/WatcherContext.md delete mode 100644 docs/docs/en/api/faststream/broker/acknowledgement_watcher/get_watcher.md delete mode 100644 docs/docs/en/api/faststream/broker/fastapi/get_dependant/get_fastapi_dependant.md delete mode 100644 docs/docs/en/api/faststream/broker/fastapi/get_dependant/get_fastapi_native_dependant.md delete mode 100644 docs/docs/en/api/faststream/broker/fastapi/route/StreamMessage.md delete mode 100644 docs/docs/en/api/faststream/broker/fastapi/route/build_faststream_to_fastapi_parser.md delete mode 100644 docs/docs/en/api/faststream/broker/fastapi/route/make_fastapi_execution.md delete mode 100644 docs/docs/en/api/faststream/broker/fastapi/route/wrap_callable_to_fastapi_compatible.md delete mode 100644 docs/docs/en/api/faststream/broker/fastapi/router/StreamRouter.md delete mode 100644 docs/docs/en/api/faststream/broker/message/decode_message.md delete mode 100644 docs/docs/en/api/faststream/broker/message/encode_message.md delete mode 100644 docs/docs/en/api/faststream/broker/middlewares/BaseMiddleware.md delete mode 100644 docs/docs/en/api/faststream/broker/middlewares/base/BaseMiddleware.md delete mode 100644 docs/docs/en/api/faststream/broker/middlewares/exception/BaseExceptionMiddleware.md delete mode 100644 docs/docs/en/api/faststream/broker/middlewares/exception/ExceptionMiddleware.md delete mode 100644 docs/docs/en/api/faststream/broker/middlewares/exception/ignore_handler.md delete mode 100644 docs/docs/en/api/faststream/broker/middlewares/logging/CriticalLogMiddleware.md delete mode 100644 docs/docs/en/api/faststream/broker/publisher/fake/FakePublisher.md delete mode 100644 docs/docs/en/api/faststream/broker/publisher/proto/BasePublisherProto.md delete mode 100644 docs/docs/en/api/faststream/broker/publisher/proto/ProducerProto.md delete mode 100644 docs/docs/en/api/faststream/broker/publisher/proto/PublisherProto.md delete mode 100644 docs/docs/en/api/faststream/broker/publisher/usecase/PublisherUsecase.md delete mode 100644 docs/docs/en/api/faststream/broker/response/ensure_response.md delete mode 100644 docs/docs/en/api/faststream/broker/router/ArgsContainer.md delete mode 100644 docs/docs/en/api/faststream/broker/router/BrokerRouter.md delete mode 100644 docs/docs/en/api/faststream/broker/router/SubscriberRoute.md delete mode 100644 docs/docs/en/api/faststream/broker/schemas/NameRequired.md delete mode 100644 docs/docs/en/api/faststream/broker/subscriber/call_item/HandlerItem.md delete mode 100644 docs/docs/en/api/faststream/broker/subscriber/proto/SubscriberProto.md delete mode 100644 docs/docs/en/api/faststream/broker/subscriber/usecase/SubscriberUsecase.md delete mode 100644 docs/docs/en/api/faststream/broker/types/PublisherMiddleware.md delete mode 100644 docs/docs/en/api/faststream/broker/utils/default_filter.md delete mode 100644 docs/docs/en/api/faststream/broker/utils/get_watcher_context.md delete mode 100644 docs/docs/en/api/faststream/broker/utils/process_msg.md delete mode 100644 docs/docs/en/api/faststream/broker/utils/resolve_custom_func.md delete mode 100644 docs/docs/en/api/faststream/broker/wrapper/call/HandlerCallWrapper.md delete mode 100644 docs/docs/en/api/faststream/broker/wrapper/proto/WrapperProto.md delete mode 100644 docs/docs/en/api/faststream/cli/main/publish_message.md delete mode 100644 docs/docs/en/api/faststream/cli/main/version_callback.md delete mode 100644 docs/docs/en/api/faststream/cli/supervisors/basereload/BaseReload.md delete mode 100644 docs/docs/en/api/faststream/cli/supervisors/multiprocess/Multiprocess.md delete mode 100644 docs/docs/en/api/faststream/cli/supervisors/utils/get_subprocess.md delete mode 100644 docs/docs/en/api/faststream/cli/supervisors/utils/set_exit.md delete mode 100644 docs/docs/en/api/faststream/cli/supervisors/utils/subprocess_started.md delete mode 100644 docs/docs/en/api/faststream/cli/supervisors/watchfiles/ExtendedFilter.md delete mode 100644 docs/docs/en/api/faststream/cli/supervisors/watchfiles/WatchReloader.md delete mode 100644 docs/docs/en/api/faststream/cli/utils/imports/get_app_path.md delete mode 100644 docs/docs/en/api/faststream/cli/utils/imports/import_from_string.md delete mode 100644 docs/docs/en/api/faststream/cli/utils/imports/import_object.md delete mode 100644 docs/docs/en/api/faststream/cli/utils/imports/try_import_app.md delete mode 100644 docs/docs/en/api/faststream/cli/utils/logs/LogLevels.md delete mode 100644 docs/docs/en/api/faststream/cli/utils/logs/get_log_level.md delete mode 100644 docs/docs/en/api/faststream/cli/utils/logs/set_log_level.md delete mode 100644 docs/docs/en/api/faststream/cli/utils/parser/parse_cli_args.md delete mode 100644 docs/docs/en/api/faststream/cli/utils/parser/remove_prefix.md delete mode 100644 docs/docs/en/api/faststream/constants/ContentTypes.md rename docs/docs/en/api/faststream/{cli/docs/app/serve.md => exceptions/ContextError.md} (73%) delete mode 100644 docs/docs/en/api/faststream/log/formatter/ColourizedFormatter.md delete mode 100644 docs/docs/en/api/faststream/log/formatter/expand_log_field.md delete mode 100644 docs/docs/en/api/faststream/log/logging/ExtendedFilter.md delete mode 100644 docs/docs/en/api/faststream/log/logging/get_broker_logger.md delete mode 100644 docs/docs/en/api/faststream/log/logging/set_logger_fmt.md rename docs/docs/en/api/faststream/{cli/main/main.md => message/AckStatus.md} (76%) rename docs/docs/en/api/faststream/{cli/docs/app/gen.md => message/StreamMessage.md} (74%) rename docs/docs/en/api/faststream/{broker/proto/SetupAble.md => message/decode_message.md} (74%) rename docs/docs/en/api/faststream/{broker/utils/MultiLock.md => message/encode_message.md} (74%) rename docs/docs/en/api/faststream/{cli/main/publish.md => message/gen_cor_id.md} (76%) rename docs/docs/en/api/faststream/{broker/message/gen_cor_id.md => message/message/AckStatus.md} (72%) rename docs/docs/en/api/faststream/{broker => message}/message/StreamMessage.md (70%) rename docs/docs/en/api/faststream/{broker/fastapi/StreamRouter.md => message/utils/decode_message.md} (71%) rename docs/docs/en/api/faststream/{broker/fastapi/StreamMessage.md => message/utils/encode_message.md} (71%) rename docs/docs/en/api/faststream/{broker/response/Response.md => message/utils/gen_cor_id.md} (73%) rename docs/docs/en/api/faststream/{broker/proto/EndpointProto.md => middlewares/BaseMiddleware.md} (72%) create mode 100644 docs/docs/en/api/faststream/middlewares/ExceptionMiddleware.md create mode 100644 docs/docs/en/api/faststream/middlewares/base/BaseMiddleware.md rename docs/docs/en/api/faststream/{broker/acknowledgement_watcher/BaseWatcher.md => middlewares/exception/BaseExceptionMiddleware.md} (64%) rename docs/docs/en/api/faststream/{broker/middlewares => middlewares/exception}/ExceptionMiddleware.md (65%) rename docs/docs/en/api/faststream/{broker/core/usecase/BrokerUsecase.md => middlewares/exception/ignore_handler.md} (67%) create mode 100644 docs/docs/en/api/faststream/middlewares/logging/CriticalLogMiddleware.md rename docs/docs/en/api/faststream/{utils => params}/Context.md (78%) rename docs/docs/en/api/faststream/{utils => params}/Depends.md (100%) rename docs/docs/en/api/faststream/{utils => params}/Header.md (79%) rename docs/docs/en/api/faststream/{utils => params}/Path.md (80%) rename docs/docs/en/api/faststream/{broker/core/abc/ABCBroker.md => params/no_cast/NoCastField.md} (72%) rename docs/docs/en/api/faststream/{utils/context => params/params}/Context.md (74%) rename docs/docs/en/api/faststream/{utils/context => params/params}/Header.md (75%) rename docs/docs/en/api/faststream/{utils/context => params/params}/Path.md (76%) delete mode 100644 docs/docs/en/api/faststream/rabbit/ReplyConfig.md delete mode 100644 docs/docs/en/api/faststream/rabbit/schemas/ReplyConfig.md delete mode 100644 docs/docs/en/api/faststream/rabbit/schemas/reply/ReplyConfig.md rename docs/docs/en/api/faststream/{cli/main/run.md => response/Response.md} (76%) rename docs/docs/en/api/faststream/{broker/message/AckStatus.md => response/ensure_response.md} (73%) create mode 100644 docs/docs/en/api/faststream/response/response/Response.md rename docs/docs/en/api/faststream/{broker/fastapi/context/Context.md => response/utils/ensure_response.md} (70%) rename docs/docs/en/api/faststream/{broker/core/logging/LoggingBroker.md => specification/asyncapi/utils/clear_key.md} (67%) delete mode 100644 docs/docs/en/api/faststream/testing/TestApp.md delete mode 100644 docs/docs/en/api/faststream/testing/app/TestApp.md delete mode 100644 docs/docs/en/api/faststream/testing/broker/TestBroker.md delete mode 100644 docs/docs/en/api/faststream/testing/broker/patch_broker_calls.md delete mode 100644 docs/docs/en/api/faststream/types/LoggerProto.md delete mode 100644 docs/docs/en/api/faststream/types/StandardDataclass.md delete mode 100644 docs/docs/en/api/faststream/utils/ContextRepo.md delete mode 100644 docs/docs/en/api/faststream/utils/NoCast.md delete mode 100644 docs/docs/en/api/faststream/utils/apply_types.md delete mode 100644 docs/docs/en/api/faststream/utils/ast/find_ast_node.md delete mode 100644 docs/docs/en/api/faststream/utils/ast/find_withitems.md delete mode 100644 docs/docs/en/api/faststream/utils/ast/get_withitem_calls.md delete mode 100644 docs/docs/en/api/faststream/utils/ast/is_contains_context_name.md delete mode 100644 docs/docs/en/api/faststream/utils/classes/Singleton.md delete mode 100644 docs/docs/en/api/faststream/utils/context/ContextRepo.md delete mode 100644 docs/docs/en/api/faststream/utils/context/builders/Context.md delete mode 100644 docs/docs/en/api/faststream/utils/context/builders/Header.md delete mode 100644 docs/docs/en/api/faststream/utils/context/builders/Path.md delete mode 100644 docs/docs/en/api/faststream/utils/context/repository/ContextRepo.md delete mode 100644 docs/docs/en/api/faststream/utils/context/types/Context.md delete mode 100644 docs/docs/en/api/faststream/utils/context/types/resolve_context_by_name.md delete mode 100644 docs/docs/en/api/faststream/utils/data/filter_by_dict.md delete mode 100644 docs/docs/en/api/faststream/utils/functions/call_or_await.md delete mode 100644 docs/docs/en/api/faststream/utils/functions/drop_response_type.md delete mode 100644 docs/docs/en/api/faststream/utils/functions/fake_context.md delete mode 100644 docs/docs/en/api/faststream/utils/functions/return_input.md delete mode 100644 docs/docs/en/api/faststream/utils/functions/sync_fake_context.md delete mode 100644 docs/docs/en/api/faststream/utils/functions/timeout_scope.md delete mode 100644 docs/docs/en/api/faststream/utils/functions/to_async.md delete mode 100644 docs/docs/en/api/faststream/utils/no_cast/NoCast.md delete mode 100644 docs/docs/en/api/faststream/utils/nuid/NUID.md delete mode 100644 docs/docs/en/api/faststream/utils/path/compile_path.md diff --git a/docs/docs/SUMMARY.md b/docs/docs/SUMMARY.md index d4808275d0..5739aad3e6 100644 --- a/docs/docs/SUMMARY.md +++ b/docs/docs/SUMMARY.md @@ -186,7 +186,6 @@ search: - [RabbitResponse](public_api/faststream/rabbit/RabbitResponse.md) - [RabbitRoute](public_api/faststream/rabbit/RabbitRoute.md) - [RabbitRouter](public_api/faststream/rabbit/RabbitRouter.md) - - [ReplyConfig](public_api/faststream/rabbit/ReplyConfig.md) - [TestApp](public_api/faststream/rabbit/TestApp.md) - [TestRabbitBroker](public_api/faststream/rabbit/TestRabbitBroker.md) - redis @@ -232,130 +231,6 @@ search: - [AsgiResponse](api/faststream/asgi/response/AsgiResponse.md) - websocket - [WebSocketClose](api/faststream/asgi/websocket/WebSocketClose.md) - - broker - - acknowledgement_watcher - - [BaseWatcher](api/faststream/broker/acknowledgement_watcher/BaseWatcher.md) - - [CounterWatcher](api/faststream/broker/acknowledgement_watcher/CounterWatcher.md) - - [EndlessWatcher](api/faststream/broker/acknowledgement_watcher/EndlessWatcher.md) - - [OneTryWatcher](api/faststream/broker/acknowledgement_watcher/OneTryWatcher.md) - - [WatcherContext](api/faststream/broker/acknowledgement_watcher/WatcherContext.md) - - [get_watcher](api/faststream/broker/acknowledgement_watcher/get_watcher.md) - - core - - abc - - [ABCBroker](api/faststream/broker/core/abc/ABCBroker.md) - - logging - - [LoggingBroker](api/faststream/broker/core/logging/LoggingBroker.md) - - usecase - - [BrokerUsecase](api/faststream/broker/core/usecase/BrokerUsecase.md) - - fastapi - - [StreamMessage](api/faststream/broker/fastapi/StreamMessage.md) - - [StreamRouter](api/faststream/broker/fastapi/StreamRouter.md) - - context - - [Context](api/faststream/broker/fastapi/context/Context.md) - - get_dependant - - [get_fastapi_dependant](api/faststream/broker/fastapi/get_dependant/get_fastapi_dependant.md) - - [get_fastapi_native_dependant](api/faststream/broker/fastapi/get_dependant/get_fastapi_native_dependant.md) - - route - - [StreamMessage](api/faststream/broker/fastapi/route/StreamMessage.md) - - [build_faststream_to_fastapi_parser](api/faststream/broker/fastapi/route/build_faststream_to_fastapi_parser.md) - - [make_fastapi_execution](api/faststream/broker/fastapi/route/make_fastapi_execution.md) - - [wrap_callable_to_fastapi_compatible](api/faststream/broker/fastapi/route/wrap_callable_to_fastapi_compatible.md) - - router - - [StreamRouter](api/faststream/broker/fastapi/router/StreamRouter.md) - - message - - [AckStatus](api/faststream/broker/message/AckStatus.md) - - [StreamMessage](api/faststream/broker/message/StreamMessage.md) - - [decode_message](api/faststream/broker/message/decode_message.md) - - [encode_message](api/faststream/broker/message/encode_message.md) - - [gen_cor_id](api/faststream/broker/message/gen_cor_id.md) - - middlewares - - [BaseMiddleware](api/faststream/broker/middlewares/BaseMiddleware.md) - - [ExceptionMiddleware](api/faststream/broker/middlewares/ExceptionMiddleware.md) - - base - - [BaseMiddleware](api/faststream/broker/middlewares/base/BaseMiddleware.md) - - exception - - [BaseExceptionMiddleware](api/faststream/broker/middlewares/exception/BaseExceptionMiddleware.md) - - [ExceptionMiddleware](api/faststream/broker/middlewares/exception/ExceptionMiddleware.md) - - [ignore_handler](api/faststream/broker/middlewares/exception/ignore_handler.md) - - logging - - [CriticalLogMiddleware](api/faststream/broker/middlewares/logging/CriticalLogMiddleware.md) - - proto - - [EndpointProto](api/faststream/broker/proto/EndpointProto.md) - - [SetupAble](api/faststream/broker/proto/SetupAble.md) - - publisher - - fake - - [FakePublisher](api/faststream/broker/publisher/fake/FakePublisher.md) - - proto - - [BasePublisherProto](api/faststream/broker/publisher/proto/BasePublisherProto.md) - - [ProducerProto](api/faststream/broker/publisher/proto/ProducerProto.md) - - [PublisherProto](api/faststream/broker/publisher/proto/PublisherProto.md) - - usecase - - [PublisherUsecase](api/faststream/broker/publisher/usecase/PublisherUsecase.md) - - response - - [Response](api/faststream/broker/response/Response.md) - - [ensure_response](api/faststream/broker/response/ensure_response.md) - - router - - [ArgsContainer](api/faststream/broker/router/ArgsContainer.md) - - [BrokerRouter](api/faststream/broker/router/BrokerRouter.md) - - [SubscriberRoute](api/faststream/broker/router/SubscriberRoute.md) - - schemas - - [NameRequired](api/faststream/broker/schemas/NameRequired.md) - - subscriber - - call_item - - [HandlerItem](api/faststream/broker/subscriber/call_item/HandlerItem.md) - - proto - - [SubscriberProto](api/faststream/broker/subscriber/proto/SubscriberProto.md) - - usecase - - [SubscriberUsecase](api/faststream/broker/subscriber/usecase/SubscriberUsecase.md) - - types - - [PublisherMiddleware](api/faststream/broker/types/PublisherMiddleware.md) - - utils - - [MultiLock](api/faststream/broker/utils/MultiLock.md) - - [default_filter](api/faststream/broker/utils/default_filter.md) - - [get_watcher_context](api/faststream/broker/utils/get_watcher_context.md) - - [process_msg](api/faststream/broker/utils/process_msg.md) - - [resolve_custom_func](api/faststream/broker/utils/resolve_custom_func.md) - - wrapper - - call - - [HandlerCallWrapper](api/faststream/broker/wrapper/call/HandlerCallWrapper.md) - - proto - - [WrapperProto](api/faststream/broker/wrapper/proto/WrapperProto.md) - - cli - - docs - - app - - [gen](api/faststream/cli/docs/app/gen.md) - - [serve](api/faststream/cli/docs/app/serve.md) - - main - - [main](api/faststream/cli/main/main.md) - - [publish](api/faststream/cli/main/publish.md) - - [publish_message](api/faststream/cli/main/publish_message.md) - - [run](api/faststream/cli/main/run.md) - - [version_callback](api/faststream/cli/main/version_callback.md) - - supervisors - - basereload - - [BaseReload](api/faststream/cli/supervisors/basereload/BaseReload.md) - - multiprocess - - [Multiprocess](api/faststream/cli/supervisors/multiprocess/Multiprocess.md) - - utils - - [get_subprocess](api/faststream/cli/supervisors/utils/get_subprocess.md) - - [set_exit](api/faststream/cli/supervisors/utils/set_exit.md) - - [subprocess_started](api/faststream/cli/supervisors/utils/subprocess_started.md) - - watchfiles - - [ExtendedFilter](api/faststream/cli/supervisors/watchfiles/ExtendedFilter.md) - - [WatchReloader](api/faststream/cli/supervisors/watchfiles/WatchReloader.md) - - utils - - imports - - [get_app_path](api/faststream/cli/utils/imports/get_app_path.md) - - [import_from_string](api/faststream/cli/utils/imports/import_from_string.md) - - [import_object](api/faststream/cli/utils/imports/import_object.md) - - [try_import_app](api/faststream/cli/utils/imports/try_import_app.md) - - logs - - [LogLevels](api/faststream/cli/utils/logs/LogLevels.md) - - [get_log_level](api/faststream/cli/utils/logs/get_log_level.md) - - [set_log_level](api/faststream/cli/utils/logs/set_log_level.md) - - parser - - [parse_cli_args](api/faststream/cli/utils/parser/parse_cli_args.md) - - [remove_prefix](api/faststream/cli/utils/parser/remove_prefix.md) - confluent - [KafkaBroker](api/faststream/confluent/KafkaBroker.md) - [KafkaPublisher](api/faststream/confluent/KafkaPublisher.md) @@ -454,10 +329,9 @@ search: - [MockConfluentMessage](api/faststream/confluent/testing/MockConfluentMessage.md) - [TestKafkaBroker](api/faststream/confluent/testing/TestKafkaBroker.md) - [build_message](api/faststream/confluent/testing/build_message.md) - - constants - - [ContentTypes](api/faststream/constants/ContentTypes.md) - exceptions - [AckMessage](api/faststream/exceptions/AckMessage.md) + - [ContextError](api/faststream/exceptions/ContextError.md) - [FastStreamException](api/faststream/exceptions/FastStreamException.md) - [HandlerException](api/faststream/exceptions/HandlerException.md) - [IgnoredException](api/faststream/exceptions/IgnoredException.md) @@ -546,14 +420,30 @@ search: - [FakeProducer](api/faststream/kafka/testing/FakeProducer.md) - [TestKafkaBroker](api/faststream/kafka/testing/TestKafkaBroker.md) - [build_message](api/faststream/kafka/testing/build_message.md) - - log - - formatter - - [ColourizedFormatter](api/faststream/log/formatter/ColourizedFormatter.md) - - [expand_log_field](api/faststream/log/formatter/expand_log_field.md) + - message + - [AckStatus](api/faststream/message/AckStatus.md) + - [StreamMessage](api/faststream/message/StreamMessage.md) + - [decode_message](api/faststream/message/decode_message.md) + - [encode_message](api/faststream/message/encode_message.md) + - [gen_cor_id](api/faststream/message/gen_cor_id.md) + - message + - [AckStatus](api/faststream/message/message/AckStatus.md) + - [StreamMessage](api/faststream/message/message/StreamMessage.md) + - utils + - [decode_message](api/faststream/message/utils/decode_message.md) + - [encode_message](api/faststream/message/utils/encode_message.md) + - [gen_cor_id](api/faststream/message/utils/gen_cor_id.md) + - middlewares + - [BaseMiddleware](api/faststream/middlewares/BaseMiddleware.md) + - [ExceptionMiddleware](api/faststream/middlewares/ExceptionMiddleware.md) + - base + - [BaseMiddleware](api/faststream/middlewares/base/BaseMiddleware.md) + - exception + - [BaseExceptionMiddleware](api/faststream/middlewares/exception/BaseExceptionMiddleware.md) + - [ExceptionMiddleware](api/faststream/middlewares/exception/ExceptionMiddleware.md) + - [ignore_handler](api/faststream/middlewares/exception/ignore_handler.md) - logging - - [ExtendedFilter](api/faststream/log/logging/ExtendedFilter.md) - - [get_broker_logger](api/faststream/log/logging/get_broker_logger.md) - - [set_logger_fmt](api/faststream/log/logging/set_logger_fmt.md) + - [CriticalLogMiddleware](api/faststream/middlewares/logging/CriticalLogMiddleware.md) - nats - [AckPolicy](api/faststream/nats/AckPolicy.md) - [ConsumerConfig](api/faststream/nats/ConsumerConfig.md) @@ -700,6 +590,17 @@ search: - [TelemetryMiddleware](api/faststream/opentelemetry/middleware/TelemetryMiddleware.md) - provider - [TelemetrySettingsProvider](api/faststream/opentelemetry/provider/TelemetrySettingsProvider.md) + - params + - [Context](api/faststream/params/Context.md) + - [Depends](api/faststream/params/Depends.md) + - [Header](api/faststream/params/Header.md) + - [Path](api/faststream/params/Path.md) + - no_cast + - [NoCastField](api/faststream/params/no_cast/NoCastField.md) + - params + - [Context](api/faststream/params/params/Context.md) + - [Header](api/faststream/params/params/Header.md) + - [Path](api/faststream/params/params/Path.md) - rabbit - [ExchangeType](api/faststream/rabbit/ExchangeType.md) - [RabbitBroker](api/faststream/rabbit/RabbitBroker.md) @@ -709,7 +610,6 @@ search: - [RabbitResponse](api/faststream/rabbit/RabbitResponse.md) - [RabbitRoute](api/faststream/rabbit/RabbitRoute.md) - [RabbitRouter](api/faststream/rabbit/RabbitRouter.md) - - [ReplyConfig](api/faststream/rabbit/ReplyConfig.md) - [TestApp](api/faststream/rabbit/TestApp.md) - [TestRabbitBroker](api/faststream/rabbit/TestRabbitBroker.md) - broker @@ -758,7 +658,6 @@ search: - [ExchangeType](api/faststream/rabbit/schemas/ExchangeType.md) - [RabbitExchange](api/faststream/rabbit/schemas/RabbitExchange.md) - [RabbitQueue](api/faststream/rabbit/schemas/RabbitQueue.md) - - [ReplyConfig](api/faststream/rabbit/schemas/ReplyConfig.md) - constants - [ExchangeType](api/faststream/rabbit/schemas/constants/ExchangeType.md) - exchange @@ -767,8 +666,6 @@ search: - [BaseRMQInformation](api/faststream/rabbit/schemas/proto/BaseRMQInformation.md) - queue - [RabbitQueue](api/faststream/rabbit/schemas/queue/RabbitQueue.md) - - reply - - [ReplyConfig](api/faststream/rabbit/schemas/reply/ReplyConfig.md) - security - [parse_security](api/faststream/rabbit/security/parse_security.md) - subscriber @@ -900,6 +797,13 @@ search: - [TestRedisBroker](api/faststream/redis/testing/TestRedisBroker.md) - [Visitor](api/faststream/redis/testing/Visitor.md) - [build_message](api/faststream/redis/testing/build_message.md) + - response + - [Response](api/faststream/response/Response.md) + - [ensure_response](api/faststream/response/ensure_response.md) + - response + - [Response](api/faststream/response/response/Response.md) + - utils + - [ensure_response](api/faststream/response/utils/ensure_response.md) - security - [BaseSecurity](api/faststream/security/BaseSecurity.md) - [SASLGSSAPI](api/faststream/security/SASLGSSAPI.md) @@ -929,6 +833,7 @@ search: - [get_asyncapi_html](api/faststream/specification/asyncapi/site/get_asyncapi_html.md) - [serve_app](api/faststream/specification/asyncapi/site/serve_app.md) - utils + - [clear_key](api/faststream/specification/asyncapi/utils/clear_key.md) - [resolve_payloads](api/faststream/specification/asyncapi/utils/resolve_payloads.md) - [to_camelcase](api/faststream/specification/asyncapi/utils/to_camelcase.md) - v2_6_0 @@ -1159,61 +1064,6 @@ search: - tag - [Tag](api/faststream/specification/schema/tag/Tag.md) - [TagDict](api/faststream/specification/schema/tag/TagDict.md) - - testing - - [TestApp](api/faststream/testing/TestApp.md) - - app - - [TestApp](api/faststream/testing/app/TestApp.md) - - broker - - [TestBroker](api/faststream/testing/broker/TestBroker.md) - - [patch_broker_calls](api/faststream/testing/broker/patch_broker_calls.md) - - types - - [LoggerProto](api/faststream/types/LoggerProto.md) - - [StandardDataclass](api/faststream/types/StandardDataclass.md) - - utils - - [Context](api/faststream/utils/Context.md) - - [ContextRepo](api/faststream/utils/ContextRepo.md) - - [Depends](api/faststream/utils/Depends.md) - - [Header](api/faststream/utils/Header.md) - - [NoCast](api/faststream/utils/NoCast.md) - - [Path](api/faststream/utils/Path.md) - - [apply_types](api/faststream/utils/apply_types.md) - - ast - - [find_ast_node](api/faststream/utils/ast/find_ast_node.md) - - [find_withitems](api/faststream/utils/ast/find_withitems.md) - - [get_withitem_calls](api/faststream/utils/ast/get_withitem_calls.md) - - [is_contains_context_name](api/faststream/utils/ast/is_contains_context_name.md) - - classes - - [Singleton](api/faststream/utils/classes/Singleton.md) - - context - - [Context](api/faststream/utils/context/Context.md) - - [ContextRepo](api/faststream/utils/context/ContextRepo.md) - - [Header](api/faststream/utils/context/Header.md) - - [Path](api/faststream/utils/context/Path.md) - - builders - - [Context](api/faststream/utils/context/builders/Context.md) - - [Header](api/faststream/utils/context/builders/Header.md) - - [Path](api/faststream/utils/context/builders/Path.md) - - repository - - [ContextRepo](api/faststream/utils/context/repository/ContextRepo.md) - - types - - [Context](api/faststream/utils/context/types/Context.md) - - [resolve_context_by_name](api/faststream/utils/context/types/resolve_context_by_name.md) - - data - - [filter_by_dict](api/faststream/utils/data/filter_by_dict.md) - - functions - - [call_or_await](api/faststream/utils/functions/call_or_await.md) - - [drop_response_type](api/faststream/utils/functions/drop_response_type.md) - - [fake_context](api/faststream/utils/functions/fake_context.md) - - [return_input](api/faststream/utils/functions/return_input.md) - - [sync_fake_context](api/faststream/utils/functions/sync_fake_context.md) - - [timeout_scope](api/faststream/utils/functions/timeout_scope.md) - - [to_async](api/faststream/utils/functions/to_async.md) - - no_cast - - [NoCast](api/faststream/utils/no_cast/NoCast.md) - - nuid - - [NUID](api/faststream/utils/nuid/NUID.md) - - path - - [compile_path](api/faststream/utils/path/compile_path.md) - Contributing - [Development](getting-started/contributing/CONTRIBUTING.md) - [Documentation](getting-started/contributing/docs.md) diff --git a/docs/docs/en/api/faststream/broker/acknowledgement_watcher/CounterWatcher.md b/docs/docs/en/api/faststream/broker/acknowledgement_watcher/CounterWatcher.md deleted file mode 100644 index e299f4c442..0000000000 --- a/docs/docs/en/api/faststream/broker/acknowledgement_watcher/CounterWatcher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.acknowledgement_watcher.CounterWatcher diff --git a/docs/docs/en/api/faststream/broker/acknowledgement_watcher/EndlessWatcher.md b/docs/docs/en/api/faststream/broker/acknowledgement_watcher/EndlessWatcher.md deleted file mode 100644 index b3aac70921..0000000000 --- a/docs/docs/en/api/faststream/broker/acknowledgement_watcher/EndlessWatcher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.acknowledgement_watcher.EndlessWatcher diff --git a/docs/docs/en/api/faststream/broker/acknowledgement_watcher/OneTryWatcher.md b/docs/docs/en/api/faststream/broker/acknowledgement_watcher/OneTryWatcher.md deleted file mode 100644 index 4baa0bdd9c..0000000000 --- a/docs/docs/en/api/faststream/broker/acknowledgement_watcher/OneTryWatcher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.acknowledgement_watcher.OneTryWatcher diff --git a/docs/docs/en/api/faststream/broker/acknowledgement_watcher/WatcherContext.md b/docs/docs/en/api/faststream/broker/acknowledgement_watcher/WatcherContext.md deleted file mode 100644 index ee1ef8643b..0000000000 --- a/docs/docs/en/api/faststream/broker/acknowledgement_watcher/WatcherContext.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.acknowledgement_watcher.WatcherContext diff --git a/docs/docs/en/api/faststream/broker/acknowledgement_watcher/get_watcher.md b/docs/docs/en/api/faststream/broker/acknowledgement_watcher/get_watcher.md deleted file mode 100644 index 9f6869bcf5..0000000000 --- a/docs/docs/en/api/faststream/broker/acknowledgement_watcher/get_watcher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.acknowledgement_watcher.get_watcher diff --git a/docs/docs/en/api/faststream/broker/fastapi/get_dependant/get_fastapi_dependant.md b/docs/docs/en/api/faststream/broker/fastapi/get_dependant/get_fastapi_dependant.md deleted file mode 100644 index 1f5d3d1e77..0000000000 --- a/docs/docs/en/api/faststream/broker/fastapi/get_dependant/get_fastapi_dependant.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.fastapi.get_dependant.get_fastapi_dependant diff --git a/docs/docs/en/api/faststream/broker/fastapi/get_dependant/get_fastapi_native_dependant.md b/docs/docs/en/api/faststream/broker/fastapi/get_dependant/get_fastapi_native_dependant.md deleted file mode 100644 index f3d6a05e39..0000000000 --- a/docs/docs/en/api/faststream/broker/fastapi/get_dependant/get_fastapi_native_dependant.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.fastapi.get_dependant.get_fastapi_native_dependant diff --git a/docs/docs/en/api/faststream/broker/fastapi/route/StreamMessage.md b/docs/docs/en/api/faststream/broker/fastapi/route/StreamMessage.md deleted file mode 100644 index 0fbed89be9..0000000000 --- a/docs/docs/en/api/faststream/broker/fastapi/route/StreamMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.fastapi.route.StreamMessage diff --git a/docs/docs/en/api/faststream/broker/fastapi/route/build_faststream_to_fastapi_parser.md b/docs/docs/en/api/faststream/broker/fastapi/route/build_faststream_to_fastapi_parser.md deleted file mode 100644 index dc05bb190e..0000000000 --- a/docs/docs/en/api/faststream/broker/fastapi/route/build_faststream_to_fastapi_parser.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.fastapi.route.build_faststream_to_fastapi_parser diff --git a/docs/docs/en/api/faststream/broker/fastapi/route/make_fastapi_execution.md b/docs/docs/en/api/faststream/broker/fastapi/route/make_fastapi_execution.md deleted file mode 100644 index f9a0fdd712..0000000000 --- a/docs/docs/en/api/faststream/broker/fastapi/route/make_fastapi_execution.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.fastapi.route.make_fastapi_execution diff --git a/docs/docs/en/api/faststream/broker/fastapi/route/wrap_callable_to_fastapi_compatible.md b/docs/docs/en/api/faststream/broker/fastapi/route/wrap_callable_to_fastapi_compatible.md deleted file mode 100644 index ab7081c711..0000000000 --- a/docs/docs/en/api/faststream/broker/fastapi/route/wrap_callable_to_fastapi_compatible.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.fastapi.route.wrap_callable_to_fastapi_compatible diff --git a/docs/docs/en/api/faststream/broker/fastapi/router/StreamRouter.md b/docs/docs/en/api/faststream/broker/fastapi/router/StreamRouter.md deleted file mode 100644 index d1f017acc6..0000000000 --- a/docs/docs/en/api/faststream/broker/fastapi/router/StreamRouter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.fastapi.router.StreamRouter diff --git a/docs/docs/en/api/faststream/broker/message/decode_message.md b/docs/docs/en/api/faststream/broker/message/decode_message.md deleted file mode 100644 index a5904b1458..0000000000 --- a/docs/docs/en/api/faststream/broker/message/decode_message.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.message.decode_message diff --git a/docs/docs/en/api/faststream/broker/message/encode_message.md b/docs/docs/en/api/faststream/broker/message/encode_message.md deleted file mode 100644 index ed34f0ceb1..0000000000 --- a/docs/docs/en/api/faststream/broker/message/encode_message.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.message.encode_message diff --git a/docs/docs/en/api/faststream/broker/middlewares/BaseMiddleware.md b/docs/docs/en/api/faststream/broker/middlewares/BaseMiddleware.md deleted file mode 100644 index d81c2fbf20..0000000000 --- a/docs/docs/en/api/faststream/broker/middlewares/BaseMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.middlewares.BaseMiddleware diff --git a/docs/docs/en/api/faststream/broker/middlewares/base/BaseMiddleware.md b/docs/docs/en/api/faststream/broker/middlewares/base/BaseMiddleware.md deleted file mode 100644 index 8502288249..0000000000 --- a/docs/docs/en/api/faststream/broker/middlewares/base/BaseMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.middlewares.base.BaseMiddleware diff --git a/docs/docs/en/api/faststream/broker/middlewares/exception/BaseExceptionMiddleware.md b/docs/docs/en/api/faststream/broker/middlewares/exception/BaseExceptionMiddleware.md deleted file mode 100644 index 7ab0a414d0..0000000000 --- a/docs/docs/en/api/faststream/broker/middlewares/exception/BaseExceptionMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.middlewares.exception.BaseExceptionMiddleware diff --git a/docs/docs/en/api/faststream/broker/middlewares/exception/ExceptionMiddleware.md b/docs/docs/en/api/faststream/broker/middlewares/exception/ExceptionMiddleware.md deleted file mode 100644 index 0abf119ab3..0000000000 --- a/docs/docs/en/api/faststream/broker/middlewares/exception/ExceptionMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.middlewares.exception.ExceptionMiddleware diff --git a/docs/docs/en/api/faststream/broker/middlewares/exception/ignore_handler.md b/docs/docs/en/api/faststream/broker/middlewares/exception/ignore_handler.md deleted file mode 100644 index 425561dcba..0000000000 --- a/docs/docs/en/api/faststream/broker/middlewares/exception/ignore_handler.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.middlewares.exception.ignore_handler diff --git a/docs/docs/en/api/faststream/broker/middlewares/logging/CriticalLogMiddleware.md b/docs/docs/en/api/faststream/broker/middlewares/logging/CriticalLogMiddleware.md deleted file mode 100644 index 829368d699..0000000000 --- a/docs/docs/en/api/faststream/broker/middlewares/logging/CriticalLogMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.middlewares.logging.CriticalLogMiddleware diff --git a/docs/docs/en/api/faststream/broker/publisher/fake/FakePublisher.md b/docs/docs/en/api/faststream/broker/publisher/fake/FakePublisher.md deleted file mode 100644 index 67b2c04f5c..0000000000 --- a/docs/docs/en/api/faststream/broker/publisher/fake/FakePublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.publisher.fake.FakePublisher diff --git a/docs/docs/en/api/faststream/broker/publisher/proto/BasePublisherProto.md b/docs/docs/en/api/faststream/broker/publisher/proto/BasePublisherProto.md deleted file mode 100644 index ed0944fa14..0000000000 --- a/docs/docs/en/api/faststream/broker/publisher/proto/BasePublisherProto.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.publisher.proto.BasePublisherProto diff --git a/docs/docs/en/api/faststream/broker/publisher/proto/ProducerProto.md b/docs/docs/en/api/faststream/broker/publisher/proto/ProducerProto.md deleted file mode 100644 index 8cf65d4e00..0000000000 --- a/docs/docs/en/api/faststream/broker/publisher/proto/ProducerProto.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.publisher.proto.ProducerProto diff --git a/docs/docs/en/api/faststream/broker/publisher/proto/PublisherProto.md b/docs/docs/en/api/faststream/broker/publisher/proto/PublisherProto.md deleted file mode 100644 index f86760bba6..0000000000 --- a/docs/docs/en/api/faststream/broker/publisher/proto/PublisherProto.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.publisher.proto.PublisherProto diff --git a/docs/docs/en/api/faststream/broker/publisher/usecase/PublisherUsecase.md b/docs/docs/en/api/faststream/broker/publisher/usecase/PublisherUsecase.md deleted file mode 100644 index f1de9539fe..0000000000 --- a/docs/docs/en/api/faststream/broker/publisher/usecase/PublisherUsecase.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.publisher.usecase.PublisherUsecase diff --git a/docs/docs/en/api/faststream/broker/response/ensure_response.md b/docs/docs/en/api/faststream/broker/response/ensure_response.md deleted file mode 100644 index b4a98bd4a4..0000000000 --- a/docs/docs/en/api/faststream/broker/response/ensure_response.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.response.ensure_response diff --git a/docs/docs/en/api/faststream/broker/router/ArgsContainer.md b/docs/docs/en/api/faststream/broker/router/ArgsContainer.md deleted file mode 100644 index bd82308c79..0000000000 --- a/docs/docs/en/api/faststream/broker/router/ArgsContainer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.router.ArgsContainer diff --git a/docs/docs/en/api/faststream/broker/router/BrokerRouter.md b/docs/docs/en/api/faststream/broker/router/BrokerRouter.md deleted file mode 100644 index d6bb82fdd2..0000000000 --- a/docs/docs/en/api/faststream/broker/router/BrokerRouter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.router.BrokerRouter diff --git a/docs/docs/en/api/faststream/broker/router/SubscriberRoute.md b/docs/docs/en/api/faststream/broker/router/SubscriberRoute.md deleted file mode 100644 index 18c3a547ec..0000000000 --- a/docs/docs/en/api/faststream/broker/router/SubscriberRoute.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.router.SubscriberRoute diff --git a/docs/docs/en/api/faststream/broker/schemas/NameRequired.md b/docs/docs/en/api/faststream/broker/schemas/NameRequired.md deleted file mode 100644 index 398f70b421..0000000000 --- a/docs/docs/en/api/faststream/broker/schemas/NameRequired.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.schemas.NameRequired diff --git a/docs/docs/en/api/faststream/broker/subscriber/call_item/HandlerItem.md b/docs/docs/en/api/faststream/broker/subscriber/call_item/HandlerItem.md deleted file mode 100644 index e2f635512c..0000000000 --- a/docs/docs/en/api/faststream/broker/subscriber/call_item/HandlerItem.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.subscriber.call_item.HandlerItem diff --git a/docs/docs/en/api/faststream/broker/subscriber/proto/SubscriberProto.md b/docs/docs/en/api/faststream/broker/subscriber/proto/SubscriberProto.md deleted file mode 100644 index fd887d41b9..0000000000 --- a/docs/docs/en/api/faststream/broker/subscriber/proto/SubscriberProto.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.subscriber.proto.SubscriberProto diff --git a/docs/docs/en/api/faststream/broker/subscriber/usecase/SubscriberUsecase.md b/docs/docs/en/api/faststream/broker/subscriber/usecase/SubscriberUsecase.md deleted file mode 100644 index f7e9448277..0000000000 --- a/docs/docs/en/api/faststream/broker/subscriber/usecase/SubscriberUsecase.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.subscriber.usecase.SubscriberUsecase diff --git a/docs/docs/en/api/faststream/broker/types/PublisherMiddleware.md b/docs/docs/en/api/faststream/broker/types/PublisherMiddleware.md deleted file mode 100644 index 2c43d2efcb..0000000000 --- a/docs/docs/en/api/faststream/broker/types/PublisherMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.types.PublisherMiddleware diff --git a/docs/docs/en/api/faststream/broker/utils/default_filter.md b/docs/docs/en/api/faststream/broker/utils/default_filter.md deleted file mode 100644 index 3fe25fa14a..0000000000 --- a/docs/docs/en/api/faststream/broker/utils/default_filter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.utils.default_filter diff --git a/docs/docs/en/api/faststream/broker/utils/get_watcher_context.md b/docs/docs/en/api/faststream/broker/utils/get_watcher_context.md deleted file mode 100644 index 883599c043..0000000000 --- a/docs/docs/en/api/faststream/broker/utils/get_watcher_context.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.utils.get_watcher_context diff --git a/docs/docs/en/api/faststream/broker/utils/process_msg.md b/docs/docs/en/api/faststream/broker/utils/process_msg.md deleted file mode 100644 index e7ce8aaf99..0000000000 --- a/docs/docs/en/api/faststream/broker/utils/process_msg.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.utils.process_msg diff --git a/docs/docs/en/api/faststream/broker/utils/resolve_custom_func.md b/docs/docs/en/api/faststream/broker/utils/resolve_custom_func.md deleted file mode 100644 index f72ed3c059..0000000000 --- a/docs/docs/en/api/faststream/broker/utils/resolve_custom_func.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.utils.resolve_custom_func diff --git a/docs/docs/en/api/faststream/broker/wrapper/call/HandlerCallWrapper.md b/docs/docs/en/api/faststream/broker/wrapper/call/HandlerCallWrapper.md deleted file mode 100644 index 4c25733797..0000000000 --- a/docs/docs/en/api/faststream/broker/wrapper/call/HandlerCallWrapper.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.wrapper.call.HandlerCallWrapper diff --git a/docs/docs/en/api/faststream/broker/wrapper/proto/WrapperProto.md b/docs/docs/en/api/faststream/broker/wrapper/proto/WrapperProto.md deleted file mode 100644 index 87ffdf815b..0000000000 --- a/docs/docs/en/api/faststream/broker/wrapper/proto/WrapperProto.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.broker.wrapper.proto.WrapperProto diff --git a/docs/docs/en/api/faststream/cli/main/publish_message.md b/docs/docs/en/api/faststream/cli/main/publish_message.md deleted file mode 100644 index a8bb7b8efa..0000000000 --- a/docs/docs/en/api/faststream/cli/main/publish_message.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.cli.main.publish_message diff --git a/docs/docs/en/api/faststream/cli/main/version_callback.md b/docs/docs/en/api/faststream/cli/main/version_callback.md deleted file mode 100644 index a5467ffeb7..0000000000 --- a/docs/docs/en/api/faststream/cli/main/version_callback.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.cli.main.version_callback diff --git a/docs/docs/en/api/faststream/cli/supervisors/basereload/BaseReload.md b/docs/docs/en/api/faststream/cli/supervisors/basereload/BaseReload.md deleted file mode 100644 index b378b2922a..0000000000 --- a/docs/docs/en/api/faststream/cli/supervisors/basereload/BaseReload.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.cli.supervisors.basereload.BaseReload diff --git a/docs/docs/en/api/faststream/cli/supervisors/multiprocess/Multiprocess.md b/docs/docs/en/api/faststream/cli/supervisors/multiprocess/Multiprocess.md deleted file mode 100644 index 4cdd6d30e3..0000000000 --- a/docs/docs/en/api/faststream/cli/supervisors/multiprocess/Multiprocess.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.cli.supervisors.multiprocess.Multiprocess diff --git a/docs/docs/en/api/faststream/cli/supervisors/utils/get_subprocess.md b/docs/docs/en/api/faststream/cli/supervisors/utils/get_subprocess.md deleted file mode 100644 index 1488078e45..0000000000 --- a/docs/docs/en/api/faststream/cli/supervisors/utils/get_subprocess.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.cli.supervisors.utils.get_subprocess diff --git a/docs/docs/en/api/faststream/cli/supervisors/utils/set_exit.md b/docs/docs/en/api/faststream/cli/supervisors/utils/set_exit.md deleted file mode 100644 index e739d79409..0000000000 --- a/docs/docs/en/api/faststream/cli/supervisors/utils/set_exit.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.cli.supervisors.utils.set_exit diff --git a/docs/docs/en/api/faststream/cli/supervisors/utils/subprocess_started.md b/docs/docs/en/api/faststream/cli/supervisors/utils/subprocess_started.md deleted file mode 100644 index 8840390ca8..0000000000 --- a/docs/docs/en/api/faststream/cli/supervisors/utils/subprocess_started.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.cli.supervisors.utils.subprocess_started diff --git a/docs/docs/en/api/faststream/cli/supervisors/watchfiles/ExtendedFilter.md b/docs/docs/en/api/faststream/cli/supervisors/watchfiles/ExtendedFilter.md deleted file mode 100644 index 095c3cc2f0..0000000000 --- a/docs/docs/en/api/faststream/cli/supervisors/watchfiles/ExtendedFilter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.cli.supervisors.watchfiles.ExtendedFilter diff --git a/docs/docs/en/api/faststream/cli/supervisors/watchfiles/WatchReloader.md b/docs/docs/en/api/faststream/cli/supervisors/watchfiles/WatchReloader.md deleted file mode 100644 index b86533f1e8..0000000000 --- a/docs/docs/en/api/faststream/cli/supervisors/watchfiles/WatchReloader.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.cli.supervisors.watchfiles.WatchReloader diff --git a/docs/docs/en/api/faststream/cli/utils/imports/get_app_path.md b/docs/docs/en/api/faststream/cli/utils/imports/get_app_path.md deleted file mode 100644 index be8fcfef0c..0000000000 --- a/docs/docs/en/api/faststream/cli/utils/imports/get_app_path.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.cli.utils.imports.get_app_path diff --git a/docs/docs/en/api/faststream/cli/utils/imports/import_from_string.md b/docs/docs/en/api/faststream/cli/utils/imports/import_from_string.md deleted file mode 100644 index 731203ac54..0000000000 --- a/docs/docs/en/api/faststream/cli/utils/imports/import_from_string.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.cli.utils.imports.import_from_string diff --git a/docs/docs/en/api/faststream/cli/utils/imports/import_object.md b/docs/docs/en/api/faststream/cli/utils/imports/import_object.md deleted file mode 100644 index e26a3e280c..0000000000 --- a/docs/docs/en/api/faststream/cli/utils/imports/import_object.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.cli.utils.imports.import_object diff --git a/docs/docs/en/api/faststream/cli/utils/imports/try_import_app.md b/docs/docs/en/api/faststream/cli/utils/imports/try_import_app.md deleted file mode 100644 index 0c6df90c86..0000000000 --- a/docs/docs/en/api/faststream/cli/utils/imports/try_import_app.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.cli.utils.imports.try_import_app diff --git a/docs/docs/en/api/faststream/cli/utils/logs/LogLevels.md b/docs/docs/en/api/faststream/cli/utils/logs/LogLevels.md deleted file mode 100644 index f82e3bbb6f..0000000000 --- a/docs/docs/en/api/faststream/cli/utils/logs/LogLevels.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.cli.utils.logs.LogLevels diff --git a/docs/docs/en/api/faststream/cli/utils/logs/get_log_level.md b/docs/docs/en/api/faststream/cli/utils/logs/get_log_level.md deleted file mode 100644 index f5e4fcaea0..0000000000 --- a/docs/docs/en/api/faststream/cli/utils/logs/get_log_level.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.cli.utils.logs.get_log_level diff --git a/docs/docs/en/api/faststream/cli/utils/logs/set_log_level.md b/docs/docs/en/api/faststream/cli/utils/logs/set_log_level.md deleted file mode 100644 index 6db13adbb9..0000000000 --- a/docs/docs/en/api/faststream/cli/utils/logs/set_log_level.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.cli.utils.logs.set_log_level diff --git a/docs/docs/en/api/faststream/cli/utils/parser/parse_cli_args.md b/docs/docs/en/api/faststream/cli/utils/parser/parse_cli_args.md deleted file mode 100644 index 9c6f03d066..0000000000 --- a/docs/docs/en/api/faststream/cli/utils/parser/parse_cli_args.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.cli.utils.parser.parse_cli_args diff --git a/docs/docs/en/api/faststream/cli/utils/parser/remove_prefix.md b/docs/docs/en/api/faststream/cli/utils/parser/remove_prefix.md deleted file mode 100644 index 587db3677f..0000000000 --- a/docs/docs/en/api/faststream/cli/utils/parser/remove_prefix.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.cli.utils.parser.remove_prefix diff --git a/docs/docs/en/api/faststream/confluent/TestApp.md b/docs/docs/en/api/faststream/confluent/TestApp.md index 2468f3755c..ad101303af 100644 --- a/docs/docs/en/api/faststream/confluent/TestApp.md +++ b/docs/docs/en/api/faststream/confluent/TestApp.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.testing.app.TestApp +::: faststream._internal.testing.app.TestApp diff --git a/docs/docs/en/api/faststream/confluent/fastapi/Context.md b/docs/docs/en/api/faststream/confluent/fastapi/Context.md index f4240bb0da..99bf141f5c 100644 --- a/docs/docs/en/api/faststream/confluent/fastapi/Context.md +++ b/docs/docs/en/api/faststream/confluent/fastapi/Context.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.broker.fastapi.context.Context +::: faststream._internal.fastapi.context.Context diff --git a/docs/docs/en/api/faststream/constants/ContentTypes.md b/docs/docs/en/api/faststream/constants/ContentTypes.md deleted file mode 100644 index 28d62bdcd7..0000000000 --- a/docs/docs/en/api/faststream/constants/ContentTypes.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.constants.ContentTypes diff --git a/docs/docs/en/api/faststream/cli/docs/app/serve.md b/docs/docs/en/api/faststream/exceptions/ContextError.md similarity index 73% rename from docs/docs/en/api/faststream/cli/docs/app/serve.md rename to docs/docs/en/api/faststream/exceptions/ContextError.md index 3d9ec139d9..73b4fcdd21 100644 --- a/docs/docs/en/api/faststream/cli/docs/app/serve.md +++ b/docs/docs/en/api/faststream/exceptions/ContextError.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.cli.docs.app.serve +::: faststream.exceptions.ContextError diff --git a/docs/docs/en/api/faststream/kafka/TestApp.md b/docs/docs/en/api/faststream/kafka/TestApp.md index 2468f3755c..ad101303af 100644 --- a/docs/docs/en/api/faststream/kafka/TestApp.md +++ b/docs/docs/en/api/faststream/kafka/TestApp.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.testing.app.TestApp +::: faststream._internal.testing.app.TestApp diff --git a/docs/docs/en/api/faststream/kafka/fastapi/Context.md b/docs/docs/en/api/faststream/kafka/fastapi/Context.md index f4240bb0da..99bf141f5c 100644 --- a/docs/docs/en/api/faststream/kafka/fastapi/Context.md +++ b/docs/docs/en/api/faststream/kafka/fastapi/Context.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.broker.fastapi.context.Context +::: faststream._internal.fastapi.context.Context diff --git a/docs/docs/en/api/faststream/log/formatter/ColourizedFormatter.md b/docs/docs/en/api/faststream/log/formatter/ColourizedFormatter.md deleted file mode 100644 index 6e1aec157c..0000000000 --- a/docs/docs/en/api/faststream/log/formatter/ColourizedFormatter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.log.formatter.ColourizedFormatter diff --git a/docs/docs/en/api/faststream/log/formatter/expand_log_field.md b/docs/docs/en/api/faststream/log/formatter/expand_log_field.md deleted file mode 100644 index ce943209af..0000000000 --- a/docs/docs/en/api/faststream/log/formatter/expand_log_field.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.log.formatter.expand_log_field diff --git a/docs/docs/en/api/faststream/log/logging/ExtendedFilter.md b/docs/docs/en/api/faststream/log/logging/ExtendedFilter.md deleted file mode 100644 index bd8f017947..0000000000 --- a/docs/docs/en/api/faststream/log/logging/ExtendedFilter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.log.logging.ExtendedFilter diff --git a/docs/docs/en/api/faststream/log/logging/get_broker_logger.md b/docs/docs/en/api/faststream/log/logging/get_broker_logger.md deleted file mode 100644 index e3433fc8dd..0000000000 --- a/docs/docs/en/api/faststream/log/logging/get_broker_logger.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.log.logging.get_broker_logger diff --git a/docs/docs/en/api/faststream/log/logging/set_logger_fmt.md b/docs/docs/en/api/faststream/log/logging/set_logger_fmt.md deleted file mode 100644 index a4af3d137f..0000000000 --- a/docs/docs/en/api/faststream/log/logging/set_logger_fmt.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.log.logging.set_logger_fmt diff --git a/docs/docs/en/api/faststream/cli/main/main.md b/docs/docs/en/api/faststream/message/AckStatus.md similarity index 76% rename from docs/docs/en/api/faststream/cli/main/main.md rename to docs/docs/en/api/faststream/message/AckStatus.md index c15cba484c..b8d3d6c6c8 100644 --- a/docs/docs/en/api/faststream/cli/main/main.md +++ b/docs/docs/en/api/faststream/message/AckStatus.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.cli.main.main +::: faststream.message.AckStatus diff --git a/docs/docs/en/api/faststream/cli/docs/app/gen.md b/docs/docs/en/api/faststream/message/StreamMessage.md similarity index 74% rename from docs/docs/en/api/faststream/cli/docs/app/gen.md rename to docs/docs/en/api/faststream/message/StreamMessage.md index 72af7d6688..5f072b2410 100644 --- a/docs/docs/en/api/faststream/cli/docs/app/gen.md +++ b/docs/docs/en/api/faststream/message/StreamMessage.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.cli.docs.app.gen +::: faststream.message.StreamMessage diff --git a/docs/docs/en/api/faststream/broker/proto/SetupAble.md b/docs/docs/en/api/faststream/message/decode_message.md similarity index 74% rename from docs/docs/en/api/faststream/broker/proto/SetupAble.md rename to docs/docs/en/api/faststream/message/decode_message.md index a4b487318e..c0dce11670 100644 --- a/docs/docs/en/api/faststream/broker/proto/SetupAble.md +++ b/docs/docs/en/api/faststream/message/decode_message.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.broker.proto.SetupAble +::: faststream.message.decode_message diff --git a/docs/docs/en/api/faststream/broker/utils/MultiLock.md b/docs/docs/en/api/faststream/message/encode_message.md similarity index 74% rename from docs/docs/en/api/faststream/broker/utils/MultiLock.md rename to docs/docs/en/api/faststream/message/encode_message.md index 5f4bc6d5cb..7d33d8d904 100644 --- a/docs/docs/en/api/faststream/broker/utils/MultiLock.md +++ b/docs/docs/en/api/faststream/message/encode_message.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.broker.utils.MultiLock +::: faststream.message.encode_message diff --git a/docs/docs/en/api/faststream/cli/main/publish.md b/docs/docs/en/api/faststream/message/gen_cor_id.md similarity index 76% rename from docs/docs/en/api/faststream/cli/main/publish.md rename to docs/docs/en/api/faststream/message/gen_cor_id.md index 84b490cde8..0abdf298b9 100644 --- a/docs/docs/en/api/faststream/cli/main/publish.md +++ b/docs/docs/en/api/faststream/message/gen_cor_id.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.cli.main.publish +::: faststream.message.gen_cor_id diff --git a/docs/docs/en/api/faststream/broker/message/gen_cor_id.md b/docs/docs/en/api/faststream/message/message/AckStatus.md similarity index 72% rename from docs/docs/en/api/faststream/broker/message/gen_cor_id.md rename to docs/docs/en/api/faststream/message/message/AckStatus.md index 5e4c2a4622..80940a8ba7 100644 --- a/docs/docs/en/api/faststream/broker/message/gen_cor_id.md +++ b/docs/docs/en/api/faststream/message/message/AckStatus.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.broker.message.gen_cor_id +::: faststream.message.message.AckStatus diff --git a/docs/docs/en/api/faststream/broker/message/StreamMessage.md b/docs/docs/en/api/faststream/message/message/StreamMessage.md similarity index 70% rename from docs/docs/en/api/faststream/broker/message/StreamMessage.md rename to docs/docs/en/api/faststream/message/message/StreamMessage.md index 800059b91d..a41232b74c 100644 --- a/docs/docs/en/api/faststream/broker/message/StreamMessage.md +++ b/docs/docs/en/api/faststream/message/message/StreamMessage.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.broker.message.StreamMessage +::: faststream.message.message.StreamMessage diff --git a/docs/docs/en/api/faststream/broker/fastapi/StreamRouter.md b/docs/docs/en/api/faststream/message/utils/decode_message.md similarity index 71% rename from docs/docs/en/api/faststream/broker/fastapi/StreamRouter.md rename to docs/docs/en/api/faststream/message/utils/decode_message.md index 32a8e8743d..b2ec48dac0 100644 --- a/docs/docs/en/api/faststream/broker/fastapi/StreamRouter.md +++ b/docs/docs/en/api/faststream/message/utils/decode_message.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.broker.fastapi.StreamRouter +::: faststream.message.utils.decode_message diff --git a/docs/docs/en/api/faststream/broker/fastapi/StreamMessage.md b/docs/docs/en/api/faststream/message/utils/encode_message.md similarity index 71% rename from docs/docs/en/api/faststream/broker/fastapi/StreamMessage.md rename to docs/docs/en/api/faststream/message/utils/encode_message.md index 2124b279ea..7401e07da5 100644 --- a/docs/docs/en/api/faststream/broker/fastapi/StreamMessage.md +++ b/docs/docs/en/api/faststream/message/utils/encode_message.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.broker.fastapi.StreamMessage +::: faststream.message.utils.encode_message diff --git a/docs/docs/en/api/faststream/broker/response/Response.md b/docs/docs/en/api/faststream/message/utils/gen_cor_id.md similarity index 73% rename from docs/docs/en/api/faststream/broker/response/Response.md rename to docs/docs/en/api/faststream/message/utils/gen_cor_id.md index 1163381d7b..74b49c30d2 100644 --- a/docs/docs/en/api/faststream/broker/response/Response.md +++ b/docs/docs/en/api/faststream/message/utils/gen_cor_id.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.broker.response.Response +::: faststream.message.utils.gen_cor_id diff --git a/docs/docs/en/api/faststream/broker/proto/EndpointProto.md b/docs/docs/en/api/faststream/middlewares/BaseMiddleware.md similarity index 72% rename from docs/docs/en/api/faststream/broker/proto/EndpointProto.md rename to docs/docs/en/api/faststream/middlewares/BaseMiddleware.md index 5a3b095952..30f98187a1 100644 --- a/docs/docs/en/api/faststream/broker/proto/EndpointProto.md +++ b/docs/docs/en/api/faststream/middlewares/BaseMiddleware.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.broker.proto.EndpointProto +::: faststream.middlewares.BaseMiddleware diff --git a/docs/docs/en/api/faststream/middlewares/ExceptionMiddleware.md b/docs/docs/en/api/faststream/middlewares/ExceptionMiddleware.md new file mode 100644 index 0000000000..c1d21850c8 --- /dev/null +++ b/docs/docs/en/api/faststream/middlewares/ExceptionMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.middlewares.ExceptionMiddleware diff --git a/docs/docs/en/api/faststream/middlewares/base/BaseMiddleware.md b/docs/docs/en/api/faststream/middlewares/base/BaseMiddleware.md new file mode 100644 index 0000000000..d3319e7441 --- /dev/null +++ b/docs/docs/en/api/faststream/middlewares/base/BaseMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.middlewares.base.BaseMiddleware diff --git a/docs/docs/en/api/faststream/broker/acknowledgement_watcher/BaseWatcher.md b/docs/docs/en/api/faststream/middlewares/exception/BaseExceptionMiddleware.md similarity index 64% rename from docs/docs/en/api/faststream/broker/acknowledgement_watcher/BaseWatcher.md rename to docs/docs/en/api/faststream/middlewares/exception/BaseExceptionMiddleware.md index d0c27d17d9..54f8031f0a 100644 --- a/docs/docs/en/api/faststream/broker/acknowledgement_watcher/BaseWatcher.md +++ b/docs/docs/en/api/faststream/middlewares/exception/BaseExceptionMiddleware.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.broker.acknowledgement_watcher.BaseWatcher +::: faststream.middlewares.exception.BaseExceptionMiddleware diff --git a/docs/docs/en/api/faststream/broker/middlewares/ExceptionMiddleware.md b/docs/docs/en/api/faststream/middlewares/exception/ExceptionMiddleware.md similarity index 65% rename from docs/docs/en/api/faststream/broker/middlewares/ExceptionMiddleware.md rename to docs/docs/en/api/faststream/middlewares/exception/ExceptionMiddleware.md index 1fa11b80fc..da1693a722 100644 --- a/docs/docs/en/api/faststream/broker/middlewares/ExceptionMiddleware.md +++ b/docs/docs/en/api/faststream/middlewares/exception/ExceptionMiddleware.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.broker.middlewares.ExceptionMiddleware +::: faststream.middlewares.exception.ExceptionMiddleware diff --git a/docs/docs/en/api/faststream/broker/core/usecase/BrokerUsecase.md b/docs/docs/en/api/faststream/middlewares/exception/ignore_handler.md similarity index 67% rename from docs/docs/en/api/faststream/broker/core/usecase/BrokerUsecase.md rename to docs/docs/en/api/faststream/middlewares/exception/ignore_handler.md index 0e791c5c38..1eea49ddbe 100644 --- a/docs/docs/en/api/faststream/broker/core/usecase/BrokerUsecase.md +++ b/docs/docs/en/api/faststream/middlewares/exception/ignore_handler.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.broker.core.usecase.BrokerUsecase +::: faststream.middlewares.exception.ignore_handler diff --git a/docs/docs/en/api/faststream/middlewares/logging/CriticalLogMiddleware.md b/docs/docs/en/api/faststream/middlewares/logging/CriticalLogMiddleware.md new file mode 100644 index 0000000000..58be3830e6 --- /dev/null +++ b/docs/docs/en/api/faststream/middlewares/logging/CriticalLogMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.middlewares.logging.CriticalLogMiddleware diff --git a/docs/docs/en/api/faststream/nats/TestApp.md b/docs/docs/en/api/faststream/nats/TestApp.md index 2468f3755c..ad101303af 100644 --- a/docs/docs/en/api/faststream/nats/TestApp.md +++ b/docs/docs/en/api/faststream/nats/TestApp.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.testing.app.TestApp +::: faststream._internal.testing.app.TestApp diff --git a/docs/docs/en/api/faststream/nats/fastapi/Context.md b/docs/docs/en/api/faststream/nats/fastapi/Context.md index f4240bb0da..99bf141f5c 100644 --- a/docs/docs/en/api/faststream/nats/fastapi/Context.md +++ b/docs/docs/en/api/faststream/nats/fastapi/Context.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.broker.fastapi.context.Context +::: faststream._internal.fastapi.context.Context diff --git a/docs/docs/en/api/faststream/utils/Context.md b/docs/docs/en/api/faststream/params/Context.md similarity index 78% rename from docs/docs/en/api/faststream/utils/Context.md rename to docs/docs/en/api/faststream/params/Context.md index 3e4f9f17c5..8eb7fc249a 100644 --- a/docs/docs/en/api/faststream/utils/Context.md +++ b/docs/docs/en/api/faststream/params/Context.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.utils.Context +::: faststream.params.Context diff --git a/docs/docs/en/api/faststream/utils/Depends.md b/docs/docs/en/api/faststream/params/Depends.md similarity index 100% rename from docs/docs/en/api/faststream/utils/Depends.md rename to docs/docs/en/api/faststream/params/Depends.md diff --git a/docs/docs/en/api/faststream/utils/Header.md b/docs/docs/en/api/faststream/params/Header.md similarity index 79% rename from docs/docs/en/api/faststream/utils/Header.md rename to docs/docs/en/api/faststream/params/Header.md index 10e6ccaec7..f3dd71365c 100644 --- a/docs/docs/en/api/faststream/utils/Header.md +++ b/docs/docs/en/api/faststream/params/Header.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.utils.Header +::: faststream.params.Header diff --git a/docs/docs/en/api/faststream/utils/Path.md b/docs/docs/en/api/faststream/params/Path.md similarity index 80% rename from docs/docs/en/api/faststream/utils/Path.md rename to docs/docs/en/api/faststream/params/Path.md index b311930841..ad04fdff6e 100644 --- a/docs/docs/en/api/faststream/utils/Path.md +++ b/docs/docs/en/api/faststream/params/Path.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.utils.Path +::: faststream.params.Path diff --git a/docs/docs/en/api/faststream/broker/core/abc/ABCBroker.md b/docs/docs/en/api/faststream/params/no_cast/NoCastField.md similarity index 72% rename from docs/docs/en/api/faststream/broker/core/abc/ABCBroker.md rename to docs/docs/en/api/faststream/params/no_cast/NoCastField.md index 88b39efd40..56821cae8a 100644 --- a/docs/docs/en/api/faststream/broker/core/abc/ABCBroker.md +++ b/docs/docs/en/api/faststream/params/no_cast/NoCastField.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.broker.core.abc.ABCBroker +::: faststream.params.no_cast.NoCastField diff --git a/docs/docs/en/api/faststream/utils/context/Context.md b/docs/docs/en/api/faststream/params/params/Context.md similarity index 74% rename from docs/docs/en/api/faststream/utils/context/Context.md rename to docs/docs/en/api/faststream/params/params/Context.md index 5669863fee..4c3ec6b4dd 100644 --- a/docs/docs/en/api/faststream/utils/context/Context.md +++ b/docs/docs/en/api/faststream/params/params/Context.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.utils.context.Context +::: faststream.params.params.Context diff --git a/docs/docs/en/api/faststream/utils/context/Header.md b/docs/docs/en/api/faststream/params/params/Header.md similarity index 75% rename from docs/docs/en/api/faststream/utils/context/Header.md rename to docs/docs/en/api/faststream/params/params/Header.md index 7e10284ec1..6b15bd1ec1 100644 --- a/docs/docs/en/api/faststream/utils/context/Header.md +++ b/docs/docs/en/api/faststream/params/params/Header.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.utils.context.Header +::: faststream.params.params.Header diff --git a/docs/docs/en/api/faststream/utils/context/Path.md b/docs/docs/en/api/faststream/params/params/Path.md similarity index 76% rename from docs/docs/en/api/faststream/utils/context/Path.md rename to docs/docs/en/api/faststream/params/params/Path.md index 92c2ef36fe..0903f40023 100644 --- a/docs/docs/en/api/faststream/utils/context/Path.md +++ b/docs/docs/en/api/faststream/params/params/Path.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.utils.context.Path +::: faststream.params.params.Path diff --git a/docs/docs/en/api/faststream/rabbit/ReplyConfig.md b/docs/docs/en/api/faststream/rabbit/ReplyConfig.md deleted file mode 100644 index 013bd2f986..0000000000 --- a/docs/docs/en/api/faststream/rabbit/ReplyConfig.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.ReplyConfig diff --git a/docs/docs/en/api/faststream/rabbit/TestApp.md b/docs/docs/en/api/faststream/rabbit/TestApp.md index 2468f3755c..ad101303af 100644 --- a/docs/docs/en/api/faststream/rabbit/TestApp.md +++ b/docs/docs/en/api/faststream/rabbit/TestApp.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.testing.app.TestApp +::: faststream._internal.testing.app.TestApp diff --git a/docs/docs/en/api/faststream/rabbit/fastapi/Context.md b/docs/docs/en/api/faststream/rabbit/fastapi/Context.md index f4240bb0da..99bf141f5c 100644 --- a/docs/docs/en/api/faststream/rabbit/fastapi/Context.md +++ b/docs/docs/en/api/faststream/rabbit/fastapi/Context.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.broker.fastapi.context.Context +::: faststream._internal.fastapi.context.Context diff --git a/docs/docs/en/api/faststream/rabbit/schemas/ReplyConfig.md b/docs/docs/en/api/faststream/rabbit/schemas/ReplyConfig.md deleted file mode 100644 index 239c4f9d6e..0000000000 --- a/docs/docs/en/api/faststream/rabbit/schemas/ReplyConfig.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.schemas.ReplyConfig diff --git a/docs/docs/en/api/faststream/rabbit/schemas/reply/ReplyConfig.md b/docs/docs/en/api/faststream/rabbit/schemas/reply/ReplyConfig.md deleted file mode 100644 index 1aeb941ff5..0000000000 --- a/docs/docs/en/api/faststream/rabbit/schemas/reply/ReplyConfig.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.schemas.reply.ReplyConfig diff --git a/docs/docs/en/api/faststream/redis/TestApp.md b/docs/docs/en/api/faststream/redis/TestApp.md index 2468f3755c..ad101303af 100644 --- a/docs/docs/en/api/faststream/redis/TestApp.md +++ b/docs/docs/en/api/faststream/redis/TestApp.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.testing.app.TestApp +::: faststream._internal.testing.app.TestApp diff --git a/docs/docs/en/api/faststream/redis/fastapi/Context.md b/docs/docs/en/api/faststream/redis/fastapi/Context.md index f4240bb0da..99bf141f5c 100644 --- a/docs/docs/en/api/faststream/redis/fastapi/Context.md +++ b/docs/docs/en/api/faststream/redis/fastapi/Context.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.broker.fastapi.context.Context +::: faststream._internal.fastapi.context.Context diff --git a/docs/docs/en/api/faststream/cli/main/run.md b/docs/docs/en/api/faststream/response/Response.md similarity index 76% rename from docs/docs/en/api/faststream/cli/main/run.md rename to docs/docs/en/api/faststream/response/Response.md index 6a01af3d26..e96fe35896 100644 --- a/docs/docs/en/api/faststream/cli/main/run.md +++ b/docs/docs/en/api/faststream/response/Response.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.cli.main.run +::: faststream.response.Response diff --git a/docs/docs/en/api/faststream/broker/message/AckStatus.md b/docs/docs/en/api/faststream/response/ensure_response.md similarity index 73% rename from docs/docs/en/api/faststream/broker/message/AckStatus.md rename to docs/docs/en/api/faststream/response/ensure_response.md index 412a61de84..e55d638acf 100644 --- a/docs/docs/en/api/faststream/broker/message/AckStatus.md +++ b/docs/docs/en/api/faststream/response/ensure_response.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.broker.message.AckStatus +::: faststream.response.ensure_response diff --git a/docs/docs/en/api/faststream/response/response/Response.md b/docs/docs/en/api/faststream/response/response/Response.md new file mode 100644 index 0000000000..01a68bb486 --- /dev/null +++ b/docs/docs/en/api/faststream/response/response/Response.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.response.response.Response diff --git a/docs/docs/en/api/faststream/broker/fastapi/context/Context.md b/docs/docs/en/api/faststream/response/utils/ensure_response.md similarity index 70% rename from docs/docs/en/api/faststream/broker/fastapi/context/Context.md rename to docs/docs/en/api/faststream/response/utils/ensure_response.md index f4240bb0da..327b9ce951 100644 --- a/docs/docs/en/api/faststream/broker/fastapi/context/Context.md +++ b/docs/docs/en/api/faststream/response/utils/ensure_response.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.broker.fastapi.context.Context +::: faststream.response.utils.ensure_response diff --git a/docs/docs/en/api/faststream/broker/core/logging/LoggingBroker.md b/docs/docs/en/api/faststream/specification/asyncapi/utils/clear_key.md similarity index 67% rename from docs/docs/en/api/faststream/broker/core/logging/LoggingBroker.md rename to docs/docs/en/api/faststream/specification/asyncapi/utils/clear_key.md index b10dd8bc3f..cf6103d19a 100644 --- a/docs/docs/en/api/faststream/broker/core/logging/LoggingBroker.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/utils/clear_key.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.broker.core.logging.LoggingBroker +::: faststream.specification.asyncapi.utils.clear_key diff --git a/docs/docs/en/api/faststream/testing/TestApp.md b/docs/docs/en/api/faststream/testing/TestApp.md deleted file mode 100644 index 3d8f650f0f..0000000000 --- a/docs/docs/en/api/faststream/testing/TestApp.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.testing.TestApp diff --git a/docs/docs/en/api/faststream/testing/app/TestApp.md b/docs/docs/en/api/faststream/testing/app/TestApp.md deleted file mode 100644 index 2468f3755c..0000000000 --- a/docs/docs/en/api/faststream/testing/app/TestApp.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.testing.app.TestApp diff --git a/docs/docs/en/api/faststream/testing/broker/TestBroker.md b/docs/docs/en/api/faststream/testing/broker/TestBroker.md deleted file mode 100644 index 48e34a6ca3..0000000000 --- a/docs/docs/en/api/faststream/testing/broker/TestBroker.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.testing.broker.TestBroker diff --git a/docs/docs/en/api/faststream/testing/broker/patch_broker_calls.md b/docs/docs/en/api/faststream/testing/broker/patch_broker_calls.md deleted file mode 100644 index 12a6431765..0000000000 --- a/docs/docs/en/api/faststream/testing/broker/patch_broker_calls.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.testing.broker.patch_broker_calls diff --git a/docs/docs/en/api/faststream/types/LoggerProto.md b/docs/docs/en/api/faststream/types/LoggerProto.md deleted file mode 100644 index 064320bf42..0000000000 --- a/docs/docs/en/api/faststream/types/LoggerProto.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.types.LoggerProto diff --git a/docs/docs/en/api/faststream/types/StandardDataclass.md b/docs/docs/en/api/faststream/types/StandardDataclass.md deleted file mode 100644 index 5140818794..0000000000 --- a/docs/docs/en/api/faststream/types/StandardDataclass.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.types.StandardDataclass diff --git a/docs/docs/en/api/faststream/utils/ContextRepo.md b/docs/docs/en/api/faststream/utils/ContextRepo.md deleted file mode 100644 index dd18ad81e4..0000000000 --- a/docs/docs/en/api/faststream/utils/ContextRepo.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.utils.ContextRepo diff --git a/docs/docs/en/api/faststream/utils/NoCast.md b/docs/docs/en/api/faststream/utils/NoCast.md deleted file mode 100644 index 606a31e563..0000000000 --- a/docs/docs/en/api/faststream/utils/NoCast.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.utils.NoCast diff --git a/docs/docs/en/api/faststream/utils/apply_types.md b/docs/docs/en/api/faststream/utils/apply_types.md deleted file mode 100644 index 9dc4603bd2..0000000000 --- a/docs/docs/en/api/faststream/utils/apply_types.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: fast_depends.use.inject diff --git a/docs/docs/en/api/faststream/utils/ast/find_ast_node.md b/docs/docs/en/api/faststream/utils/ast/find_ast_node.md deleted file mode 100644 index 228e6f058c..0000000000 --- a/docs/docs/en/api/faststream/utils/ast/find_ast_node.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.utils.ast.find_ast_node diff --git a/docs/docs/en/api/faststream/utils/ast/find_withitems.md b/docs/docs/en/api/faststream/utils/ast/find_withitems.md deleted file mode 100644 index 123acd71e4..0000000000 --- a/docs/docs/en/api/faststream/utils/ast/find_withitems.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.utils.ast.find_withitems diff --git a/docs/docs/en/api/faststream/utils/ast/get_withitem_calls.md b/docs/docs/en/api/faststream/utils/ast/get_withitem_calls.md deleted file mode 100644 index c9d68c1ed2..0000000000 --- a/docs/docs/en/api/faststream/utils/ast/get_withitem_calls.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.utils.ast.get_withitem_calls diff --git a/docs/docs/en/api/faststream/utils/ast/is_contains_context_name.md b/docs/docs/en/api/faststream/utils/ast/is_contains_context_name.md deleted file mode 100644 index 61cf140ea6..0000000000 --- a/docs/docs/en/api/faststream/utils/ast/is_contains_context_name.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.utils.ast.is_contains_context_name diff --git a/docs/docs/en/api/faststream/utils/classes/Singleton.md b/docs/docs/en/api/faststream/utils/classes/Singleton.md deleted file mode 100644 index c9751ee2bd..0000000000 --- a/docs/docs/en/api/faststream/utils/classes/Singleton.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.utils.classes.Singleton diff --git a/docs/docs/en/api/faststream/utils/context/ContextRepo.md b/docs/docs/en/api/faststream/utils/context/ContextRepo.md deleted file mode 100644 index 50a7133aeb..0000000000 --- a/docs/docs/en/api/faststream/utils/context/ContextRepo.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.utils.context.ContextRepo diff --git a/docs/docs/en/api/faststream/utils/context/builders/Context.md b/docs/docs/en/api/faststream/utils/context/builders/Context.md deleted file mode 100644 index 6cdf6f36fe..0000000000 --- a/docs/docs/en/api/faststream/utils/context/builders/Context.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.utils.context.builders.Context diff --git a/docs/docs/en/api/faststream/utils/context/builders/Header.md b/docs/docs/en/api/faststream/utils/context/builders/Header.md deleted file mode 100644 index e3f6e41ba6..0000000000 --- a/docs/docs/en/api/faststream/utils/context/builders/Header.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.utils.context.builders.Header diff --git a/docs/docs/en/api/faststream/utils/context/builders/Path.md b/docs/docs/en/api/faststream/utils/context/builders/Path.md deleted file mode 100644 index 5203903c45..0000000000 --- a/docs/docs/en/api/faststream/utils/context/builders/Path.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.utils.context.builders.Path diff --git a/docs/docs/en/api/faststream/utils/context/repository/ContextRepo.md b/docs/docs/en/api/faststream/utils/context/repository/ContextRepo.md deleted file mode 100644 index ad968d8954..0000000000 --- a/docs/docs/en/api/faststream/utils/context/repository/ContextRepo.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.utils.context.repository.ContextRepo diff --git a/docs/docs/en/api/faststream/utils/context/types/Context.md b/docs/docs/en/api/faststream/utils/context/types/Context.md deleted file mode 100644 index 3ac9c51fad..0000000000 --- a/docs/docs/en/api/faststream/utils/context/types/Context.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.utils.context.types.Context diff --git a/docs/docs/en/api/faststream/utils/context/types/resolve_context_by_name.md b/docs/docs/en/api/faststream/utils/context/types/resolve_context_by_name.md deleted file mode 100644 index 60ab9fc23c..0000000000 --- a/docs/docs/en/api/faststream/utils/context/types/resolve_context_by_name.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.utils.context.types.resolve_context_by_name diff --git a/docs/docs/en/api/faststream/utils/data/filter_by_dict.md b/docs/docs/en/api/faststream/utils/data/filter_by_dict.md deleted file mode 100644 index 87d03b5288..0000000000 --- a/docs/docs/en/api/faststream/utils/data/filter_by_dict.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.utils.data.filter_by_dict diff --git a/docs/docs/en/api/faststream/utils/functions/call_or_await.md b/docs/docs/en/api/faststream/utils/functions/call_or_await.md deleted file mode 100644 index 9bb63aa18c..0000000000 --- a/docs/docs/en/api/faststream/utils/functions/call_or_await.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: fast_depends.utils.run_async diff --git a/docs/docs/en/api/faststream/utils/functions/drop_response_type.md b/docs/docs/en/api/faststream/utils/functions/drop_response_type.md deleted file mode 100644 index a39e8a2699..0000000000 --- a/docs/docs/en/api/faststream/utils/functions/drop_response_type.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.utils.functions.drop_response_type diff --git a/docs/docs/en/api/faststream/utils/functions/fake_context.md b/docs/docs/en/api/faststream/utils/functions/fake_context.md deleted file mode 100644 index 3943186ba4..0000000000 --- a/docs/docs/en/api/faststream/utils/functions/fake_context.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.utils.functions.fake_context diff --git a/docs/docs/en/api/faststream/utils/functions/return_input.md b/docs/docs/en/api/faststream/utils/functions/return_input.md deleted file mode 100644 index d5514e013f..0000000000 --- a/docs/docs/en/api/faststream/utils/functions/return_input.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.utils.functions.return_input diff --git a/docs/docs/en/api/faststream/utils/functions/sync_fake_context.md b/docs/docs/en/api/faststream/utils/functions/sync_fake_context.md deleted file mode 100644 index 0860846843..0000000000 --- a/docs/docs/en/api/faststream/utils/functions/sync_fake_context.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.utils.functions.sync_fake_context diff --git a/docs/docs/en/api/faststream/utils/functions/timeout_scope.md b/docs/docs/en/api/faststream/utils/functions/timeout_scope.md deleted file mode 100644 index 1577a7593a..0000000000 --- a/docs/docs/en/api/faststream/utils/functions/timeout_scope.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.utils.functions.timeout_scope diff --git a/docs/docs/en/api/faststream/utils/functions/to_async.md b/docs/docs/en/api/faststream/utils/functions/to_async.md deleted file mode 100644 index 715b43d3ac..0000000000 --- a/docs/docs/en/api/faststream/utils/functions/to_async.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.utils.functions.to_async diff --git a/docs/docs/en/api/faststream/utils/no_cast/NoCast.md b/docs/docs/en/api/faststream/utils/no_cast/NoCast.md deleted file mode 100644 index 4fcc6054ba..0000000000 --- a/docs/docs/en/api/faststream/utils/no_cast/NoCast.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.utils.no_cast.NoCast diff --git a/docs/docs/en/api/faststream/utils/nuid/NUID.md b/docs/docs/en/api/faststream/utils/nuid/NUID.md deleted file mode 100644 index 4e43844efe..0000000000 --- a/docs/docs/en/api/faststream/utils/nuid/NUID.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.utils.nuid.NUID diff --git a/docs/docs/en/api/faststream/utils/path/compile_path.md b/docs/docs/en/api/faststream/utils/path/compile_path.md deleted file mode 100644 index 136d5ab1b9..0000000000 --- a/docs/docs/en/api/faststream/utils/path/compile_path.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.utils.path.compile_path From 07fb94390e0f7ccfa1f3960129b790d9b61f8697 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Mon, 16 Sep 2024 21:53:50 +0300 Subject: [PATCH 164/245] fix: correct AsyncAPI 2.6.0 channel names --- faststream/specification/asyncapi/generate.py | 3 ++- .../specification/asyncapi/v2_6_0/generate.py | 4 ++-- tests/asyncapi/base/v2_6_0/arguments.py | 7 +++++-- tests/asyncapi/base/v3_0_0/arguments.py | 16 ++++++++++++---- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/faststream/specification/asyncapi/generate.py b/faststream/specification/asyncapi/generate.py index 9bf186604c..ae93722d99 100644 --- a/faststream/specification/asyncapi/generate.py +++ b/faststream/specification/asyncapi/generate.py @@ -13,7 +13,8 @@ def get_app_schema( - app: "Application", version: Union[Literal["3.0.0", "2.6.0"], str] = "3.0.0" + app: "Application", + version: Union[Literal["3.0.0", "2.6.0"], str] = "3.0.0", ) -> BaseSchema: if version.startswith("3.0."): return get_app_schema_v3(app) diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index 405efba399..0be5b73f1c 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -143,13 +143,13 @@ def get_broker_channels( for h in broker._subscribers.values(): schema = h.schema() channels.update( - {clear_key(key): channel_from_spec(channel) for key, channel in schema.items()} + {key: channel_from_spec(channel) for key, channel in schema.items()} ) for p in broker._publishers.values(): schema = p.schema() channels.update( - {clear_key(key): channel_from_spec(channel) for key, channel in schema.items()} + {key: channel_from_spec(channel) for key, channel in schema.items()} ) return channels diff --git a/tests/asyncapi/base/v2_6_0/arguments.py b/tests/asyncapi/base/v2_6_0/arguments.py index 74c81466f9..6a64f834e5 100644 --- a/tests/asyncapi/base/v2_6_0/arguments.py +++ b/tests/asyncapi/base/v2_6_0/arguments.py @@ -43,13 +43,16 @@ async def handle(msg): ... schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() - assert next(iter(schema["channels"].keys())) == "." + assert next(iter(schema["channels"].keys())) == "/" assert next(iter(schema["components"]["messages"].keys())) == ".:Message" assert schema["components"]["messages"][".:Message"]["title"] == "/:Message" assert next(iter(schema["components"]["schemas"].keys())) == ".:Message:Payload" - assert schema["components"]["schemas"][".:Message:Payload"]["title"] == "/:Message:Payload" + assert ( + schema["components"]["schemas"][".:Message:Payload"]["title"] + == "/:Message:Payload" + ) def test_docstring_description(self): broker = self.broker_class() diff --git a/tests/asyncapi/base/v3_0_0/arguments.py b/tests/asyncapi/base/v3_0_0/arguments.py index 1a9fbd24c3..7e694b7a1c 100644 --- a/tests/asyncapi/base/v3_0_0/arguments.py +++ b/tests/asyncapi/base/v3_0_0/arguments.py @@ -49,11 +49,19 @@ async def handle(msg): ... assert next(iter(schema["operations"].keys())) == ".Subscribe" - assert next(iter(schema["components"]["messages"].keys())) == ".:SubscribeMessage" - assert schema["components"]["messages"][".:SubscribeMessage"]["title"] == "/:SubscribeMessage" - + assert ( + next(iter(schema["components"]["messages"].keys())) == ".:SubscribeMessage" + ) + assert ( + schema["components"]["messages"][".:SubscribeMessage"]["title"] + == "/:SubscribeMessage" + ) + assert next(iter(schema["components"]["schemas"].keys())) == ".:Message:Payload" - assert schema["components"]["schemas"][".:Message:Payload"]["title"] == "/:Message:Payload" + assert ( + schema["components"]["schemas"][".:Message:Payload"]["title"] + == "/:Message:Payload" + ) def test_docstring_description(self): broker = self.broker_factory() From 5d4cac1f217d598ab99d488f6a718d699bb88a67 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Mon, 16 Sep 2024 23:25:59 +0300 Subject: [PATCH 165/245] refactor: remove global broker from context --- faststream/_internal/broker/broker.py | 10 ++-- tests/asyncapi/base/v2_6_0/arguments.py | 67 ++++++++++++------------- 2 files changed, 37 insertions(+), 40 deletions(-) diff --git a/faststream/_internal/broker/broker.py b/faststream/_internal/broker/broker.py index 54aa0acd22..50c235e0c3 100644 --- a/faststream/_internal/broker/broker.py +++ b/faststream/_internal/broker/broker.py @@ -19,7 +19,6 @@ from typing_extensions import Annotated, Doc, Self from faststream._internal._compat import is_test_env -from faststream._internal.context.repository import context from faststream._internal.log.logging import set_logger_fmt from faststream._internal.proto import SetupAble from faststream._internal.subscriber.proto import SubscriberProto @@ -185,10 +184,6 @@ def __init__( *self._middlewares, ) - # TODO: move this context to Handlers' extra_context to support multiple brokers - context.set_global("logger", self.logger) - context.set_global("broker", self) - # FastDepends args self._is_apply_types = apply_types self._is_validate = validate @@ -269,7 +264,10 @@ def _subscriber_setup_extra(self) -> "AnyDict": "logger": self.logger, "producer": self._producer, "graceful_timeout": self.graceful_timeout, - "extra_context": {}, + "extra_context": { + "broker": self, + "logger": self.logger, + }, # broker options "broker_parser": self._parser, "broker_decoder": self._decoder, diff --git a/tests/asyncapi/base/v2_6_0/arguments.py b/tests/asyncapi/base/v2_6_0/arguments.py index 6a64f834e5..90b2b417f2 100644 --- a/tests/asyncapi/base/v2_6_0/arguments.py +++ b/tests/asyncapi/base/v2_6_0/arguments.py @@ -566,6 +566,39 @@ async def handle(user: Model): ... }, }, schema["components"] + def test_with_filter(self): + class User(pydantic.BaseModel): + name: str = "" + id: int + + broker = self.broker_class() + + sub = broker.subscriber("test") + + @sub( + filter=lambda m: m.content_type == "application/json", + ) + async def handle(id: int): ... + + @sub + async def handle_default(msg): ... + + schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + + assert ( + len( + next(iter(schema["components"]["messages"].values()))["payload"][ + "oneOf" + ] + ) + == 2 + ) + + payload = schema["components"]["schemas"] + + assert "Handle:Message:Payload" in list(payload.keys()) + assert "HandleDefault:Message:Payload" in list(payload.keys()) + class ArgumentsTestcase(FastAPICompatible): dependency_builder = staticmethod(Depends) @@ -635,37 +668,3 @@ async def handle(id: int, user: Optional[str] = None, message=Context()): ... "type": "object", } ) - - def test_with_filter(self): - # TODO: move it to FastAPICompatible with FastAPI refactore - class User(pydantic.BaseModel): - name: str = "" - id: int - - broker = self.broker_class() - - sub = broker.subscriber("test") - - @sub( - filter=lambda m: m.content_type == "application/json", - ) - async def handle(id: int): ... - - @sub - async def handle_default(msg): ... - - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() - - assert ( - len( - next(iter(schema["components"]["messages"].values()))["payload"][ - "oneOf" - ] - ) - == 2 - ) - - payload = schema["components"]["schemas"] - - assert "Handle:Message:Payload" in list(payload.keys()) - assert "HandleDefault:Message:Payload" in list(payload.keys()) From cc55a61a20456d03e42ce9bb22d7bf861c23c762 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Tue, 17 Sep 2024 19:19:10 +0300 Subject: [PATCH 166/245] tests: fix all tests --- examples/e04_msg_filter.py | 6 +- faststream/_internal/broker/broker.py | 8 +-- faststream/_internal/cli/main.py | 37 ++++++---- faststream/_internal/constants.py | 3 + faststream/_internal/proto.py | 2 +- faststream/_internal/publisher/proto.py | 2 +- faststream/_internal/publisher/usecase.py | 2 +- faststream/_internal/subscriber/call_item.py | 2 +- faststream/_internal/subscriber/proto.py | 2 +- faststream/_internal/subscriber/usecase.py | 4 +- faststream/_internal/testing/broker.py | 2 +- faststream/confluent/subscriber/usecase.py | 4 +- faststream/kafka/subscriber/usecase.py | 4 +- faststream/message/message.py | 20 ++++++ faststream/message/utils.py | 15 ++--- faststream/nats/subscriber/usecase.py | 4 +- faststream/rabbit/publisher/usecase.py | 4 +- faststream/rabbit/subscriber/usecase.py | 4 +- faststream/redis/subscriber/usecase.py | 4 +- .../specification/asyncapi/v2_6_0/generate.py | 2 +- .../specification/asyncapi/v3_0_0/generate.py | 2 +- tests/a_docs/redis/test_security.py | 2 +- tests/brokers/base/requests.py | 2 +- tests/cli/test_publish.py | 67 +++++++++++++------ 24 files changed, 133 insertions(+), 71 deletions(-) diff --git a/examples/e04_msg_filter.py b/examples/e04_msg_filter.py index cacdae63de..852c9442ed 100644 --- a/examples/e04_msg_filter.py +++ b/examples/e04_msg_filter.py @@ -5,13 +5,15 @@ broker = RabbitBroker("amqp://guest:guest@localhost:5672/") app = FastStream(broker) +subscriber = broker.subscriber("test-queue") -@broker.subscriber("test-queue", filter=lambda m: m.content_type == "application/json") + +@subscriber(filter=lambda m: m.content_type == "application/json") async def handle_json(msg, logger: Logger): logger.info(f"JSON message: {msg}") -@broker.subscriber("test-queue") +@subscriber async def handle_other_messages(msg, logger: Logger): logger.info(f"Default message: {msg}") diff --git a/faststream/_internal/broker/broker.py b/faststream/_internal/broker/broker.py index 50c235e0c3..20d6424246 100644 --- a/faststream/_internal/broker/broker.py +++ b/faststream/_internal/broker/broker.py @@ -222,7 +222,7 @@ async def connect(self, **kwargs: Any) -> ConnectionType: connection_kwargs = self._connection_kwargs.copy() connection_kwargs.update(kwargs) self._connection = await self._connect(**connection_kwargs) - self.setup() + self._setup() return self._connection @abstractmethod @@ -230,7 +230,7 @@ async def _connect(self) -> ConnectionType: """Connect to a resource.""" raise NotImplementedError() - def setup(self) -> None: + def _setup(self) -> None: """Prepare all Broker entities to startup.""" for h in self._subscribers.values(): self.setup_subscriber(h) @@ -246,7 +246,7 @@ def setup_subscriber( """Setup the Subscriber to prepare it to starting.""" data = self._subscriber_setup_extra.copy() data.update(kwargs) - subscriber.setup(**data) + subscriber._setup(**data) def setup_publisher( self, @@ -256,7 +256,7 @@ def setup_publisher( """Setup the Publisher to prepare it to starting.""" data = self._publisher_setup_extra.copy() data.update(kwargs) - publisher.setup(**data) + publisher._setup(**data) @property def _subscriber_setup_extra(self) -> "AnyDict": diff --git a/faststream/_internal/cli/main.py b/faststream/_internal/cli/main.py index 5920055485..3abb63a398 100644 --- a/faststream/_internal/cli/main.py +++ b/faststream/_internal/cli/main.py @@ -210,9 +210,19 @@ def _run( ) def publish( ctx: typer.Context, - app: str = typer.Argument(..., help="FastStream app instance, e.g., main:app."), - message: str = typer.Argument(..., help="Message to be published."), - rpc: bool = typer.Option(False, help="Enable RPC mode and system output."), + app: str = typer.Argument( + ..., + help="FastStream app instance, e.g., main:app.", + ), + message: str = typer.Argument( + ..., + help="Message to be published.", + ), + rpc: bool = typer.Option( + False, + is_flag=True, + help="Enable RPC mode and system output.", + ), is_factory: bool = typer.Option( False, "--factory", @@ -227,15 +237,12 @@ def publish( These are parsed and passed to the broker's publish method. """ app, extra = parse_cli_args(app, *ctx.args) + extra["message"] = message - extra["rpc"] = rpc + if "timeout" in extra: + extra["timeout"] = float(extra["timeout"]) try: - if not app: - raise ValueError("App parameter is required.") - if not message: - raise ValueError("Message parameter is required.") - _, app_obj = import_from_string(app) if callable(app_obj) and is_factory: app_obj = app_obj() @@ -243,7 +250,7 @@ def publish( if not app_obj.broker: raise ValueError("Broker instance not found in the app.") - result = anyio.run(publish_message, app_obj.broker, extra) + result = anyio.run(publish_message, app_obj.broker, rpc, extra) if rpc: typer.echo(result) @@ -253,10 +260,16 @@ def publish( sys.exit(1) -async def publish_message(broker: "BrokerUsecase[Any, Any]", extra: "AnyDict") -> Any: +async def publish_message( + broker: "BrokerUsecase[Any, Any]", rpc: bool, extra: "AnyDict" +) -> Any: try: async with broker: - return await broker.publish(**extra) + if rpc: + msg = await broker.request(**extra) + return msg + else: + return await broker.publish(**extra) except Exception as e: typer.echo(f"Error when broker was publishing: {e}") sys.exit(1) diff --git a/faststream/_internal/constants.py b/faststream/_internal/constants.py index 16c6a90415..c3d2f73b4a 100644 --- a/faststream/_internal/constants.py +++ b/faststream/_internal/constants.py @@ -15,6 +15,9 @@ class _EmptyPlaceholder: def __repr__(self) -> str: return "EMPTY" + def __bool__(self) -> bool: + return False + def __eq__(self, other: object) -> bool: if not isinstance(other, _EmptyPlaceholder): return NotImplemented diff --git a/faststream/_internal/proto.py b/faststream/_internal/proto.py index 54d988a763..cc6811167b 100644 --- a/faststream/_internal/proto.py +++ b/faststream/_internal/proto.py @@ -4,7 +4,7 @@ class SetupAble(Protocol): @abstractmethod - def setup(self) -> None: ... + def _setup(self) -> None: ... class Endpoint(SetupAble, Protocol): diff --git a/faststream/_internal/publisher/proto.py b/faststream/_internal/publisher/proto.py index 86addc8b35..9707fd6c12 100644 --- a/faststream/_internal/publisher/proto.py +++ b/faststream/_internal/publisher/proto.py @@ -94,7 +94,7 @@ def create() -> "PublisherProto[MsgType]": @override @abstractmethod - def setup( # type: ignore[override] + def _setup( # type: ignore[override] self, *, producer: Optional["ProducerProto"], diff --git a/faststream/_internal/publisher/usecase.py b/faststream/_internal/publisher/usecase.py index 71333dfbd9..584d6b6ff4 100644 --- a/faststream/_internal/publisher/usecase.py +++ b/faststream/_internal/publisher/usecase.py @@ -91,7 +91,7 @@ def add_middleware(self, middleware: "BrokerMiddleware[MsgType]") -> None: self._broker_middlewares = (*self._broker_middlewares, middleware) @override - def setup( # type: ignore[override] + def _setup( # type: ignore[override] self, *, producer: Optional["ProducerProto"], diff --git a/faststream/_internal/subscriber/call_item.py b/faststream/_internal/subscriber/call_item.py index 6ffa691fdc..6b550747d1 100644 --- a/faststream/_internal/subscriber/call_item.py +++ b/faststream/_internal/subscriber/call_item.py @@ -71,7 +71,7 @@ def __repr__(self) -> str: return f"<'{self.call_name}': filter='{filter_name}'>" @override - def setup( # type: ignore[override] + def _setup( # type: ignore[override] self, *, parser: "AsyncCallable", diff --git a/faststream/_internal/subscriber/proto.py b/faststream/_internal/subscriber/proto.py index 60ab953863..1fefc25817 100644 --- a/faststream/_internal/subscriber/proto.py +++ b/faststream/_internal/subscriber/proto.py @@ -51,7 +51,7 @@ def get_log_context( @override @abstractmethod - def setup( # type: ignore[override] + def _setup( # type: ignore[override] self, *, logger: Optional["LoggerProto"], diff --git a/faststream/_internal/subscriber/usecase.py b/faststream/_internal/subscriber/usecase.py index eefcd18c0c..6bc39cb158 100644 --- a/faststream/_internal/subscriber/usecase.py +++ b/faststream/_internal/subscriber/usecase.py @@ -143,7 +143,7 @@ def add_middleware(self, middleware: "BrokerMiddleware[MsgType]") -> None: self._broker_middlewares = (*self._broker_middlewares, middleware) @override - def setup( # type: ignore[override] + def _setup( # type: ignore[override] self, *, logger: Optional["LoggerProto"], @@ -181,7 +181,7 @@ def setup( # type: ignore[override] self._parser = async_parser self._decoder = async_decoder - call.setup( + call._setup( parser=async_parser, decoder=async_decoder, apply_types=apply_types, diff --git a/faststream/_internal/testing/broker.py b/faststream/_internal/testing/broker.py index fbe040b6ae..2be6ab8f81 100644 --- a/faststream/_internal/testing/broker.py +++ b/faststream/_internal/testing/broker.py @@ -120,7 +120,7 @@ def _patch_broker(self, broker: Broker) -> Generator[None, None, None]: yield def _fake_start(self, broker: Broker, *args: Any, **kwargs: Any) -> None: - broker.setup() + broker._setup() patch_broker_calls(broker) diff --git a/faststream/confluent/subscriber/usecase.py b/faststream/confluent/subscriber/usecase.py index 84480c3018..3bc8e25cdd 100644 --- a/faststream/confluent/subscriber/usecase.py +++ b/faststream/confluent/subscriber/usecase.py @@ -102,7 +102,7 @@ def __init__( self.builder = None @override - def setup( # type: ignore[override] + def _setup( # type: ignore[override] self, *, client_id: Optional[str], @@ -124,7 +124,7 @@ def setup( # type: ignore[override] self.client_id = client_id self.builder = builder - super().setup( + super()._setup( logger=logger, producer=producer, graceful_timeout=graceful_timeout, diff --git a/faststream/kafka/subscriber/usecase.py b/faststream/kafka/subscriber/usecase.py index d8d4a47134..cabc505d29 100644 --- a/faststream/kafka/subscriber/usecase.py +++ b/faststream/kafka/subscriber/usecase.py @@ -107,7 +107,7 @@ def __init__( self.task = None @override - def setup( # type: ignore[override] + def _setup( # type: ignore[override] self, *, client_id: Optional[str], @@ -129,7 +129,7 @@ def setup( # type: ignore[override] self.client_id = client_id self.builder = builder - super().setup( + super()._setup( logger=logger, producer=producer, graceful_timeout=graceful_timeout, diff --git a/faststream/message/message.py b/faststream/message/message.py index 592f51308e..2400d00127 100644 --- a/faststream/message/message.py +++ b/faststream/message/message.py @@ -55,6 +55,26 @@ def __init__( self.committed: Optional[AckStatus] = None self.processed = False + def __repr__(self) -> str: + inner = ", ".join( + filter( + bool, + ( + f"body={self.body}", + f"content_type={self.content_type}", + f"message_id={self.message_id}", + f"correlation_id={self.correlation_id}", + f"reply_to={self.reply_to}" if self.reply_to else "", + f"headers={self.headers}", + f"path={self.path}", + f"committed={self.committed}", + f"raw_message={self.raw_message}", + ), + ) + ) + + return f"{self.__class__.__name__}({inner})" + async def decode(self) -> Optional["DecodedMessage"]: """Serialize the message by lazy decoder.""" # TODO: make it lazy after `decoded_body` removed diff --git a/faststream/message/utils.py b/faststream/message/utils.py index 771ceac18b..490493a125 100644 --- a/faststream/message/utils.py +++ b/faststream/message/utils.py @@ -12,7 +12,7 @@ from uuid import uuid4 from faststream._internal._compat import dump_json, json_loads -from faststream._internal.constants import EMPTY, ContentTypes +from faststream._internal.constants import ContentTypes if TYPE_CHECKING: from faststream._internal.basic_types import DecodedMessage, SendableMessage @@ -30,20 +30,17 @@ def decode_message(message: "StreamMessage[Any]") -> "DecodedMessage": body: Any = getattr(message, "body", message) m: DecodedMessage = body - if (content_type := getattr(message, "content_type", EMPTY)) is not EMPTY: - content_type = cast(Optional[str], content_type) + if content_type := getattr(message, "content_type", False): + content_type = ContentTypes(cast(str, content_type)) - if not content_type: - with suppress(json.JSONDecodeError, UnicodeDecodeError): - m = json_loads(body) - - elif ContentTypes.text.value in content_type: + if content_type is ContentTypes.text: m = body.decode() - elif ContentTypes.json.value in content_type: + elif content_type is ContentTypes.json: m = json_loads(body) else: + # content-type not set with suppress(json.JSONDecodeError, UnicodeDecodeError): m = json_loads(body) diff --git a/faststream/nats/subscriber/usecase.py b/faststream/nats/subscriber/usecase.py index fc91ef8b88..de1e5e8137 100644 --- a/faststream/nats/subscriber/usecase.py +++ b/faststream/nats/subscriber/usecase.py @@ -126,7 +126,7 @@ def __init__( self.producer = None @override - def setup( # type: ignore[override] + def _setup( # type: ignore[override] self, *, connection: ConnectionType, @@ -146,7 +146,7 @@ def setup( # type: ignore[override] ) -> None: self._connection = connection - super().setup( + super()._setup( logger=logger, producer=producer, graceful_timeout=graceful_timeout, diff --git a/faststream/rabbit/publisher/usecase.py b/faststream/rabbit/publisher/usecase.py index d5c06d3dd1..c9bd51dd02 100644 --- a/faststream/rabbit/publisher/usecase.py +++ b/faststream/rabbit/publisher/usecase.py @@ -160,7 +160,7 @@ def __init__( self.virtual_host = "" @override - def setup( # type: ignore[override] + def _setup( # type: ignore[override] self, *, producer: Optional["AioPikaFastProducer"], @@ -169,7 +169,7 @@ def setup( # type: ignore[override] ) -> None: self.app_id = app_id self.virtual_host = virtual_host - super().setup(producer=producer) + super()._setup(producer=producer) @property def routing(self) -> str: diff --git a/faststream/rabbit/subscriber/usecase.py b/faststream/rabbit/subscriber/usecase.py index 0fb1c1cfbb..6a8c346db3 100644 --- a/faststream/rabbit/subscriber/usecase.py +++ b/faststream/rabbit/subscriber/usecase.py @@ -96,7 +96,7 @@ def __init__( self.declarer = None @override - def setup( # type: ignore[override] + def _setup( # type: ignore[override] self, *, app_id: Optional[str], @@ -120,7 +120,7 @@ def setup( # type: ignore[override] self.virtual_host = virtual_host self.declarer = declarer - super().setup( + super()._setup( logger=logger, producer=producer, graceful_timeout=graceful_timeout, diff --git a/faststream/redis/subscriber/usecase.py b/faststream/redis/subscriber/usecase.py index 6ef23b05f8..f576c47217 100644 --- a/faststream/redis/subscriber/usecase.py +++ b/faststream/redis/subscriber/usecase.py @@ -102,7 +102,7 @@ def __init__( self.task: Optional[asyncio.Task[None]] = None @override - def setup( # type: ignore[override] + def _setup( # type: ignore[override] self, *, connection: Optional["Redis[bytes]"], @@ -122,7 +122,7 @@ def setup( # type: ignore[override] ) -> None: self._client = connection - super().setup( + super()._setup( logger=logger, producer=producer, graceful_timeout=graceful_timeout, diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index 0be5b73f1c..c8d8dc823f 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -32,7 +32,7 @@ def get_app_schema(app: Application) -> Schema: if broker is None: # pragma: no cover raise RuntimeError() - broker.setup() + broker._setup() servers = get_broker_server(broker) channels = get_broker_channels(broker) diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index 97ca91c561..2bfcdc3eb5 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -40,7 +40,7 @@ def get_app_schema(app: Application) -> Schema: broker = app.broker if broker is None: # pragma: no cover raise RuntimeError() - broker.setup() + broker._setup() servers = get_broker_server(broker) channels = get_broker_channels(broker) diff --git a/tests/a_docs/redis/test_security.py b/tests/a_docs/redis/test_security.py index 9e3cc6fdc3..11b1217a16 100644 --- a/tests/a_docs/redis/test_security.py +++ b/tests/a_docs/redis/test_security.py @@ -35,7 +35,7 @@ async def test_base_security(): from docs.docs_src.redis.security.basic import broker async with broker: - await broker.ping(3.0) + await broker.ping(0.01) assert connection.call_args.kwargs["ssl"] diff --git a/tests/brokers/base/requests.py b/tests/brokers/base/requests.py index 78dcdcb58b..ae3f6eefe5 100644 --- a/tests/brokers/base/requests.py +++ b/tests/brokers/base/requests.py @@ -24,7 +24,7 @@ async def test_request_timeout(self, queue: str): @broker.subscriber(*args, **kwargs) async def handler(msg): - await anyio.sleep(1.0) + await anyio.sleep(0.01) return "Response" async with self.patch_broker(broker): diff --git a/tests/cli/test_publish.py b/tests/cli/test_publish.py index 06f58308f3..a718d6e693 100644 --- a/tests/cli/test_publish.py +++ b/tests/cli/test_publish.py @@ -1,6 +1,7 @@ from unittest.mock import AsyncMock, patch from dirty_equals import IsPartialDict +from typer.testing import CliRunner from faststream import FastStream from faststream._internal.cli.main import cli as faststream_app @@ -18,6 +19,8 @@ def get_mock_app(broker_type, producer_type) -> FastStream: broker.connect = AsyncMock() mock_producer = AsyncMock(spec=producer_type) mock_producer.publish = AsyncMock() + mock_producer._parser = AsyncMock() + mock_producer._decoder = AsyncMock() broker._producer = mock_producer return FastStream(broker) @@ -40,13 +43,13 @@ def test_publish_command_with_redis_options(runner): "fastream:app", "hello world", "--channel", - "test channel", + "channelname", "--reply_to", "tester", "--list", - "0.1", + "listname", "--stream", - "stream url", + "streamname", "--correlation_id", "someId", ], @@ -56,12 +59,11 @@ def test_publish_command_with_redis_options(runner): assert mock_app.broker._producer.publish.call_args.args[0] == "hello world" assert mock_app.broker._producer.publish.call_args.kwargs == IsPartialDict( - channel="test channel", reply_to="tester", - list="0.1", - stream="stream url", + stream="streamname", + list="listname", + channel="channelname", correlation_id="someId", - rpc=False, ) @@ -83,7 +85,7 @@ def test_publish_command_with_confluent_options(runner): "fastream:app", "hello world", "--topic", - "confluent topic", + "topicname", "--correlation_id", "someId", ], @@ -92,9 +94,8 @@ def test_publish_command_with_confluent_options(runner): assert result.exit_code == 0 assert mock_app.broker._producer.publish.call_args.args[0] == "hello world" assert mock_app.broker._producer.publish.call_args.kwargs == IsPartialDict( - topic="confluent topic", + topic="topicname", correlation_id="someId", - rpc=False, ) @@ -116,7 +117,7 @@ def test_publish_command_with_kafka_options(runner): "fastream:app", "hello world", "--topic", - "kafka topic", + "topicname", "--correlation_id", "someId", ], @@ -125,9 +126,8 @@ def test_publish_command_with_kafka_options(runner): assert result.exit_code == 0 assert mock_app.broker._producer.publish.call_args.args[0] == "hello world" assert mock_app.broker._producer.publish.call_args.kwargs == IsPartialDict( - topic="kafka topic", + topic="topicname", correlation_id="someId", - rpc=False, ) @@ -149,7 +149,7 @@ def test_publish_command_with_nats_options(runner): "fastream:app", "hello world", "--subject", - "nats subject", + "subjectname", "--reply_to", "tester", "--correlation_id", @@ -161,10 +161,9 @@ def test_publish_command_with_nats_options(runner): assert mock_app.broker._producer.publish.call_args.args[0] == "hello world" assert mock_app.broker._producer.publish.call_args.kwargs == IsPartialDict( - subject="nats subject", + subject="subjectname", reply_to="tester", correlation_id="someId", - rpc=False, ) @@ -187,8 +186,6 @@ def test_publish_command_with_rabbit_options(runner): "hello world", "--correlation_id", "someId", - "--raise_timeout", - "True", ], ) @@ -198,7 +195,37 @@ def test_publish_command_with_rabbit_options(runner): assert mock_app.broker._producer.publish.call_args.kwargs == IsPartialDict( { "correlation_id": "someId", - "raise_timeout": "True", - "rpc": False, } ) + + +@require_nats +def test_publish_nats_request_command(runner: CliRunner): + from faststream.nats import NatsBroker + from faststream.nats.publisher.producer import NatsFastProducer + + mock_app = get_mock_app(NatsBroker, NatsFastProducer) + + with patch( + "faststream._internal.cli.main.import_from_string", + return_value=(None, mock_app), + ): + runner.invoke( + faststream_app, + [ + "publish", + "fastream:app", + "hello world", + "--subject", + "subjectname", + "--rpc", + "--timeout", + "1.0", + ], + ) + + assert mock_app.broker._producer.request.call_args.args[0] == "hello world" + assert mock_app.broker._producer.request.call_args.kwargs == IsPartialDict( + subject="subjectname", + timeout=1.0, + ) From 0a6b83b11000db7a2f05c76c424c4cba29a0c7de Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Wed, 18 Sep 2024 19:00:22 +0300 Subject: [PATCH 167/245] tests: refactor tests --- tests/asgi/confluent/test_asgi.py | 4 +- tests/asgi/kafka/test_asgi.py | 4 +- tests/asgi/nats/test_asgi.py | 4 +- tests/asgi/rabbit/test_asgi.py | 4 +- tests/asgi/redis/test_asgi.py | 4 +- tests/asgi/testcase.py | 6 +- tests/brokers/base/basic.py | 22 +- tests/brokers/base/connection.py | 4 +- tests/brokers/base/consume.py | 19 +- tests/brokers/base/fastapi.py | 65 +++-- tests/brokers/base/middlewares.py | 228 ++++++++---------- tests/brokers/base/parser.py | 78 ++---- tests/brokers/base/publish.py | 9 - tests/brokers/base/requests.py | 6 - tests/brokers/base/router.py | 194 +++++++-------- tests/brokers/base/testclient.py | 51 ++-- tests/brokers/confluent/conftest.py | 24 +- tests/brokers/confluent/test_consume.py | 5 +- tests/brokers/confluent/test_fastapi.py | 21 +- tests/brokers/confluent/test_logger.py | 29 +-- tests/brokers/confluent/test_middlewares.py | 8 +- tests/brokers/confluent/test_parser.py | 5 +- tests/brokers/confluent/test_publish.py | 5 +- tests/brokers/confluent/test_requests.py | 14 +- tests/brokers/confluent/test_router.py | 19 +- tests/brokers/confluent/test_test_client.py | 116 ++++----- tests/brokers/kafka/conftest.py | 24 +- tests/brokers/kafka/test_consume.py | 5 +- tests/brokers/kafka/test_fastapi.py | 14 +- tests/brokers/kafka/test_middlewares.py | 8 +- tests/brokers/kafka/test_parser.py | 5 +- tests/brokers/kafka/test_publish.py | 5 +- tests/brokers/kafka/test_requests.py | 14 +- tests/brokers/kafka/test_router.py | 19 +- tests/brokers/kafka/test_test_client.py | 116 ++++----- tests/brokers/nats/conftest.py | 29 +-- tests/brokers/nats/test_consume.py | 5 +- tests/brokers/nats/test_fastapi.py | 24 +- tests/brokers/nats/test_middlewares.py | 8 +- tests/brokers/nats/test_parser.py | 5 +- tests/brokers/nats/test_publish.py | 4 +- tests/brokers/nats/test_requests.py | 6 +- tests/brokers/nats/test_router.py | 44 +++- tests/brokers/nats/test_test_client.py | 70 +++--- tests/brokers/rabbit/conftest.py | 24 -- tests/brokers/rabbit/core/test_depends.py | 10 +- .../rabbit/specific/test_nested_exchange.py | 6 +- tests/brokers/rabbit/test_consume.py | 5 +- tests/brokers/rabbit/test_fastapi.py | 11 +- tests/brokers/rabbit/test_middlewares.py | 8 +- tests/brokers/rabbit/test_parser.py | 5 +- tests/brokers/rabbit/test_publish.py | 5 +- tests/brokers/rabbit/test_requests.py | 6 +- tests/brokers/rabbit/test_router.py | 25 +- tests/brokers/rabbit/test_test_client.py | 40 ++- tests/brokers/redis/conftest.py | 28 +-- tests/brokers/redis/test_consume.py | 6 +- tests/brokers/redis/test_fastapi.py | 23 +- tests/brokers/redis/test_middlewares.py | 8 +- tests/brokers/redis/test_parser.py | 5 +- tests/brokers/redis/test_publish.py | 6 +- tests/brokers/redis/test_router.py | 90 ++++--- tests/brokers/redis/test_test_client.py | 32 ++- 63 files changed, 802 insertions(+), 894 deletions(-) diff --git a/tests/asgi/confluent/test_asgi.py b/tests/asgi/confluent/test_asgi.py index 75e4b37254..d9b60e34ae 100644 --- a/tests/asgi/confluent/test_asgi.py +++ b/tests/asgi/confluent/test_asgi.py @@ -3,8 +3,8 @@ class TestConfluentAsgi(AsgiTestcase): - def get_broker(self): - return KafkaBroker() + def get_broker(self, **kwargs): + return KafkaBroker(**kwargs) def get_test_broker(self, broker): return TestKafkaBroker(broker) diff --git a/tests/asgi/kafka/test_asgi.py b/tests/asgi/kafka/test_asgi.py index cb26b402dc..286c1d238c 100644 --- a/tests/asgi/kafka/test_asgi.py +++ b/tests/asgi/kafka/test_asgi.py @@ -3,8 +3,8 @@ class TestKafkaAsgi(AsgiTestcase): - def get_broker(self): - return KafkaBroker() + def get_broker(self, **kwargs): + return KafkaBroker(**kwargs) def get_test_broker(self, broker): return TestKafkaBroker(broker) diff --git a/tests/asgi/nats/test_asgi.py b/tests/asgi/nats/test_asgi.py index f54f52b25a..951beedd1d 100644 --- a/tests/asgi/nats/test_asgi.py +++ b/tests/asgi/nats/test_asgi.py @@ -3,8 +3,8 @@ class TestNatsAsgi(AsgiTestcase): - def get_broker(self): - return NatsBroker() + def get_broker(self, **kwargs): + return NatsBroker(**kwargs) def get_test_broker(self, broker): return TestNatsBroker(broker) diff --git a/tests/asgi/rabbit/test_asgi.py b/tests/asgi/rabbit/test_asgi.py index 9df4794225..76fc9fc173 100644 --- a/tests/asgi/rabbit/test_asgi.py +++ b/tests/asgi/rabbit/test_asgi.py @@ -3,8 +3,8 @@ class TestRabbitAsgi(AsgiTestcase): - def get_broker(self): - return RabbitBroker() + def get_broker(self, **kwargs): + return RabbitBroker(**kwargs) def get_test_broker(self, broker): return TestRabbitBroker(broker) diff --git a/tests/asgi/redis/test_asgi.py b/tests/asgi/redis/test_asgi.py index 3b3e5a38be..17c14df0ee 100644 --- a/tests/asgi/redis/test_asgi.py +++ b/tests/asgi/redis/test_asgi.py @@ -3,8 +3,8 @@ class TestRedisAsgi(AsgiTestcase): - def get_broker(self): - return RedisBroker() + def get_broker(self, **kwargs): + return RedisBroker(**kwargs) def get_test_broker(self, broker): return TestRedisBroker(broker) diff --git a/tests/asgi/testcase.py b/tests/asgi/testcase.py index fccfedb7c2..f5992cc537 100644 --- a/tests/asgi/testcase.py +++ b/tests/asgi/testcase.py @@ -8,11 +8,11 @@ class AsgiTestcase: - def get_broker(self) -> Any: - raise NotImplementedError() + def get_broker(self, **kwargs) -> Any: + raise NotImplementedError def get_test_broker(self, broker) -> Any: - raise NotImplementedError() + raise NotImplementedError def test_not_found(self): app = AsgiFastStream() diff --git a/tests/brokers/base/basic.py b/tests/brokers/base/basic.py index e550393052..1cfe01da6b 100644 --- a/tests/brokers/base/basic.py +++ b/tests/brokers/base/basic.py @@ -1,11 +1,31 @@ +from abc import abstractmethod from typing import Any, Dict, Tuple +from faststream._internal.broker.broker import BrokerUsecase + class BaseTestcaseConfig: timeout: float = 3.0 + @abstractmethod + def get_broker( + self, + apply_types: bool = False, + **kwargs: Any, + ) -> BrokerUsecase[Any, Any]: + raise NotImplementedError + + def patch_broker( + self, + broker: BrokerUsecase, + **kwargs: Any, + ) -> BrokerUsecase: + return broker + def get_subscriber_params( - self, *args: Any, **kwargs: Any + self, + *args: Any, + **kwargs: Any, ) -> Tuple[ Tuple[Any, ...], Dict[str, Any], diff --git a/tests/brokers/base/connection.py b/tests/brokers/base/connection.py index 8bd9319a59..9a1694a9d4 100644 --- a/tests/brokers/base/connection.py +++ b/tests/brokers/base/connection.py @@ -16,12 +16,10 @@ async def ping(self, broker) -> bool: return await broker.ping(timeout=5.0) @pytest.mark.asyncio - async def test_close_before_start(self, async_mock): + async def test_close_before_start(self): br = self.broker() assert br._connection is None await br.close() - br._connection = async_mock - await br._close() assert not br.running @pytest.mark.asyncio diff --git a/tests/brokers/base/consume.py b/tests/brokers/base/consume.py index 9c01be73b7..ccfa3987a7 100644 --- a/tests/brokers/base/consume.py +++ b/tests/brokers/base/consume.py @@ -1,6 +1,4 @@ import asyncio -from abc import abstractmethod -from typing import Any from unittest.mock import MagicMock import anyio @@ -8,7 +6,6 @@ from pydantic import BaseModel from faststream import Context, Depends -from faststream._internal.broker.broker import BrokerUsecase from faststream.exceptions import StopConsume from .basic import BaseTestcaseConfig @@ -16,13 +13,6 @@ @pytest.mark.asyncio class BrokerConsumeTestcase(BaseTestcaseConfig): - @abstractmethod - def get_broker(self, broker: BrokerUsecase) -> BrokerUsecase[Any, Any]: - raise NotImplementedError - - def patch_broker(self, broker: BrokerUsecase[Any, Any]) -> BrokerUsecase[Any, Any]: - return broker - async def test_consume( self, queue: str, @@ -213,10 +203,10 @@ async def test_consume_validate_false( event: asyncio.Event, mock: MagicMock, ): - consume_broker = self.get_broker() - - consume_broker._is_apply_types = True - consume_broker._is_validate = False + consume_broker = self.get_broker( + apply_types=True, + validate=False, + ) class Foo(BaseModel): x: int @@ -293,7 +283,6 @@ class BrokerRealConsumeTestcase(BrokerConsumeTestcase): async def test_get_one( self, queue: str, - event: asyncio.Event, mock: MagicMock, ): broker = self.get_broker(apply_types=True) diff --git a/tests/brokers/base/fastapi.py b/tests/brokers/base/fastapi.py index 62fb4cfa25..b9a227346c 100644 --- a/tests/brokers/base/fastapi.py +++ b/tests/brokers/base/fastapi.py @@ -1,6 +1,6 @@ import asyncio from contextlib import asynccontextmanager -from typing import Any, Callable, Type, TypeVar +from typing import Any, Type, TypeVar from unittest.mock import Mock import pytest @@ -9,7 +9,6 @@ from fastapi.testclient import TestClient from faststream import Response, context -from faststream._internal.basic_types import AnyCallable from faststream._internal.broker.broker import BrokerUsecase from faststream._internal.broker.router import BrokerRouter from faststream._internal.fastapi.context import Context @@ -199,8 +198,6 @@ async def resp(msg): @pytest.mark.asyncio class FastAPILocalTestcase(BaseTestcaseConfig): router_class: Type[StreamRouter[BrokerUsecase]] - broker_test: Callable[[Broker], Broker] - build_message: AnyCallable async def test_base(self, queue: str): router = self.router_class() @@ -214,11 +211,11 @@ async def test_base(self, queue: str): async def hello(): return "hi" - async with self.broker_test(router.broker): + async with self.patch_broker(router.broker) as br: with TestClient(app) as client: - assert client.app_state["broker"] is router.broker + assert client.app_state["broker"] is br - r = await router.broker.request( + r = await br.request( "hi", queue, timeout=0.5, @@ -237,11 +234,11 @@ async def test_request(self, queue: str): async def hello(): return Response("Hi!", headers={"x-header": "test"}) - async with self.broker_test(router.broker): + async with self.patch_broker(router.broker) as br: with TestClient(app) as client: assert not client.app_state.get("broker") - r = await router.broker.request( + r = await br.request( "hi", queue, timeout=0.5, @@ -260,11 +257,11 @@ async def test_base_without_state(self, queue: str): async def hello(): return "hi" - async with self.broker_test(router.broker): + async with self.patch_broker(router.broker) as br: with TestClient(app) as client: assert not client.app_state.get("broker") - r = await router.broker.request( + r = await br.request( "hi", queue, timeout=0.5, @@ -283,10 +280,10 @@ async def hello(msg: int): ... app.include_router(router) - async with self.broker_test(router.broker): + async with self.patch_broker(router.broker) as br: with TestClient(app): with pytest.raises(RequestValidationError): - await router.broker.publish("hi", queue) + await br.publish("hi", queue) async def test_headers(self, queue: str): router = self.router_class() @@ -297,8 +294,8 @@ async def test_headers(self, queue: str): async def hello(w=Header()): return w - async with self.broker_test(router.broker): - r = await router.broker.request( + async with self.patch_broker(router.broker) as br: + r = await br.request( "", queue, headers={"w": "hi"}, @@ -319,8 +316,8 @@ def dep(a): async def hello(a, w=Depends(dep)): return w - async with self.broker_test(router.broker): - r = await router.broker.request( + async with self.patch_broker(router.broker) as br: + r = await br.request( {"a": "hi"}, queue, timeout=0.5, @@ -345,8 +342,8 @@ async def hello(a, w=Depends(dep)): assert not mock.close.call_count return w - async with self.broker_test(router.broker): - r = await router.broker.request( + async with self.patch_broker(router.broker) as br: + r = await br.request( {"a": "hi"}, queue, timeout=0.5, @@ -368,8 +365,8 @@ def mock_dep(): async def hello(a): return a - async with self.broker_test(router.broker): - r = await router.broker.request("hi", queue, timeout=0.5) + async with self.patch_broker(router.broker) as br: + r = await br.request("hi", queue, timeout=0.5) assert await r.decode() == "hi", r mock.assert_called_once() @@ -389,8 +386,8 @@ def mock_dep(): async def hello(a): return a - async with self.broker_test(router.broker): - r = await router.broker.request( + async with self.patch_broker(router.broker) as br: + r = await br.request( "hi", queue, timeout=0.5, @@ -421,7 +418,7 @@ def test_shutdown_sync(app): async def test_shutdown_async(app): mock.async_shutdown_called() - async with self.broker_test(router.broker), router.lifespan_context(app): + async with self.patch_broker(router.broker), router.lifespan_context(app): pass mock.sync_called.assert_called_once() @@ -441,7 +438,7 @@ async def lifespan(app): app = FastAPI() app.include_router(router) - async with self.broker_test(router.broker), router.lifespan_context( + async with self.patch_broker(router.broker), router.lifespan_context( app ) as context: assert context["lifespan"] @@ -458,7 +455,7 @@ async def test_subscriber_mock(self, queue: str): async def m(): return "hi" - async with self.broker_test(router.broker) as rb: + async with self.patch_broker(router.broker) as rb: await rb.publish("hello", queue) m.mock.assert_called_once_with("hello") @@ -475,7 +472,7 @@ async def test_publisher_mock(self, queue: str): async def m(): return "response" - async with self.broker_test(router.broker) as rb: + async with self.patch_broker(router.broker) as rb: await rb.publish("hello", queue) publisher.mock.assert_called_with("response") @@ -500,18 +497,18 @@ async def hello_router2(): router.include_router(router2) app.include_router(router) - async with self.broker_test(router.broker): + async with self.patch_broker(router.broker) as br: with TestClient(app) as client: - assert client.app_state["broker"] is router.broker + assert client.app_state["broker"] is br - r = await router.broker.request( + r = await br.request( "hi", queue, timeout=0.5, ) assert await r.decode() == "hi", r - r = await router.broker.request( + r = await br.request( "hi", queue + "1", timeout=0.5, @@ -538,11 +535,11 @@ async def hello_router2(dep=Depends(dep1)): router.include_router(router2) app.include_router(router) - async with self.broker_test(router.broker): + async with self.patch_broker(router.broker) as br: with TestClient(app) as client: - assert client.app_state["broker"] is router.broker + assert client.app_state["broker"] is br - r = await router.broker.request( + r = await br.request( "hi", queue, timeout=0.5, diff --git a/tests/brokers/base/middlewares.py b/tests/brokers/base/middlewares.py index 1f33d372ea..b4de99b6d4 100644 --- a/tests/brokers/base/middlewares.py +++ b/tests/brokers/base/middlewares.py @@ -1,12 +1,10 @@ import asyncio -from typing import Type from unittest.mock import Mock, call import pytest from faststream import Context from faststream._internal.basic_types import DecodedMessage -from faststream._internal.broker.broker import BrokerUsecase from faststream.exceptions import SkipMessage from faststream.middlewares import BaseMiddleware, ExceptionMiddleware @@ -15,23 +13,11 @@ @pytest.mark.asyncio class LocalMiddlewareTestcase(BaseTestcaseConfig): - broker_class: Type[BrokerUsecase] - - @pytest.fixture - def raw_broker(self): - return None - - def patch_broker( - self, raw_broker: BrokerUsecase, broker: BrokerUsecase - ) -> BrokerUsecase: - return broker - async def test_subscriber_middleware( self, event: asyncio.Event, queue: str, mock: Mock, - raw_broker, ): async def mid(call_next, msg): mock.start(await msg.decode()) @@ -40,7 +26,7 @@ async def mid(call_next, msg): event.set() return result - broker = self.broker_class() + broker = self.get_broker() args, kwargs = self.get_subscriber_params(queue, middlewares=(mid,)) @@ -49,13 +35,11 @@ async def handler(m): mock.inner(m) return "end" - broker = self.patch_broker(raw_broker, broker) - - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(broker.publish("start", queue)), + asyncio.create_task(br.publish("start", queue)), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -72,7 +56,6 @@ async def test_publisher_middleware( event: asyncio.Event, queue: str, mock: Mock, - raw_broker, ): async def mid(call_next, msg, **kwargs): mock.enter() @@ -82,7 +65,7 @@ async def mid(call_next, msg, **kwargs): event.set() return result - broker = self.broker_class() + broker = self.get_broker() args, kwargs = self.get_subscriber_params(queue) @@ -93,13 +76,11 @@ async def handler(m): mock.inner(m) return "end" - broker = self.patch_broker(raw_broker, broker) - - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(broker.publish("start", queue)), + asyncio.create_task(br.publish("start", queue)), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -111,7 +92,7 @@ async def handler(m): assert mock.end.call_count == 2 async def test_local_middleware_not_shared_between_subscribers( - self, queue: str, mock: Mock, raw_broker + self, queue: str, mock: Mock ): event1 = asyncio.Event() event2 = asyncio.Event() @@ -122,7 +103,7 @@ async def mid(call_next, msg): mock.end() return result - broker = self.broker_class() + broker = self.get_broker() args, kwargs = self.get_subscriber_params(queue) args2, kwargs2 = self.get_subscriber_params( @@ -140,10 +121,8 @@ async def handler(m): mock() return "" - broker = self.patch_broker(raw_broker, broker) - - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() await asyncio.wait( ( asyncio.create_task(broker.publish("", queue)), @@ -161,7 +140,9 @@ async def handler(m): assert mock.call_count == 2 async def test_local_middleware_consume_not_shared_between_filters( - self, queue: str, mock: Mock, raw_broker + self, + queue: str, + mock: Mock, ): event1 = asyncio.Event() event2 = asyncio.Event() @@ -172,7 +153,7 @@ async def mid(call_next, msg): mock.end() return result - broker = self.broker_class() + broker = self.get_broker() args, kwargs = self.get_subscriber_params( queue, @@ -192,14 +173,12 @@ async def handler2(m): mock() return "" - broker = self.patch_broker(raw_broker, broker) - - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(broker.publish({"msg": "hi"}, queue)), - asyncio.create_task(broker.publish("", queue)), + asyncio.create_task(br.publish({"msg": "hi"}, queue)), + asyncio.create_task(br.publish("", queue)), asyncio.create_task(event1.wait()), asyncio.create_task(event2.wait()), ), @@ -212,7 +191,7 @@ async def handler2(m): mock.end.assert_called_once() assert mock.call_count == 2 - async def test_error_traceback(self, queue: str, mock: Mock, event, raw_broker): + async def test_error_traceback(self, queue: str, mock: Mock, event): async def mid(call_next, msg): try: result = await call_next(msg) @@ -222,7 +201,7 @@ async def mid(call_next, msg): else: return result - broker = self.broker_class() + broker = self.get_broker() args, kwargs = self.get_subscriber_params(queue, middlewares=(mid,)) @@ -231,14 +210,12 @@ async def handler2(m): event.set() raise ValueError() - broker = self.patch_broker(raw_broker, broker) - - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(broker.publish("", queue)), + asyncio.create_task(br.publish("", queue)), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -251,7 +228,10 @@ async def handler2(m): @pytest.mark.asyncio class MiddlewareTestcase(LocalMiddlewareTestcase): async def test_global_middleware( - self, event: asyncio.Event, queue: str, mock: Mock, raw_broker + self, + event: asyncio.Event, + queue: str, + mock: Mock, ): class mid(BaseMiddleware): # noqa: N801 async def on_receive(self): @@ -262,7 +242,7 @@ async def after_processed(self, exc_type, exc_val, exc_tb): mock.end() return await super().after_processed(exc_type, exc_val, exc_tb) - broker = self.broker_class( + broker = self.get_broker( middlewares=(mid,), ) @@ -273,13 +253,11 @@ async def handler(m): event.set() return "" - broker = self.patch_broker(raw_broker, broker) - - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(broker.publish("", queue)), + asyncio.create_task(br.publish("", queue)), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -294,7 +272,6 @@ async def test_add_global_middleware( event: asyncio.Event, queue: str, mock: Mock, - raw_broker, ): class mid(BaseMiddleware): # noqa: N801 async def on_receive(self): @@ -305,7 +282,7 @@ async def after_processed(self, exc_type, exc_val, exc_tb): mock.end() return await super().after_processed(exc_type, exc_val, exc_tb) - broker = self.broker_class() + broker = self.get_broker() # already registered subscriber args, kwargs = self.get_subscriber_params(queue) @@ -328,14 +305,12 @@ async def handler2(m): event2.set() return "" - broker = self.patch_broker(raw_broker, broker) - - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(broker.publish("", queue)), - asyncio.create_task(broker.publish("", f"{queue}1")), + asyncio.create_task(br.publish("", queue)), + asyncio.create_task(br.publish("", f"{queue}1")), asyncio.create_task(event.wait()), asyncio.create_task(event2.wait()), ), @@ -346,12 +321,17 @@ async def handler2(m): assert mock.start.call_count == 2 assert mock.end.call_count == 2 - async def test_patch_publish(self, queue: str, mock: Mock, event, raw_broker): + async def test_patch_publish( + self, + queue: str, + mock: Mock, + event: asyncio.Event, + ): class Mid(BaseMiddleware): async def on_publish(self, msg: str, *args, **kwargs) -> str: return msg * 2 - broker = self.broker_class(middlewares=(Mid,)) + broker = self.get_broker(middlewares=(Mid,)) args, kwargs = self.get_subscriber_params(queue) @@ -366,16 +346,12 @@ async def handler_resp(m): mock(m) event.set() - broker = self.patch_broker(raw_broker, broker) - - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task( - broker.publish("r", queue, reply_to=queue + "r") - ), + asyncio.create_task(br.publish("r", queue, reply_to=queue + "r")), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -389,7 +365,6 @@ async def test_global_publisher_middleware( event: asyncio.Event, queue: str, mock: Mock, - raw_broker, ): class Mid(BaseMiddleware): async def on_publish(self, msg: str, *args, **kwargs) -> str: @@ -403,7 +378,7 @@ async def after_publish(self, *args, **kwargs): if mock.end.call_count > 2: event.set() - broker = self.broker_class(middlewares=(Mid,)) + broker = self.get_broker(middlewares=(Mid,)) args, kwargs = self.get_subscriber_params(queue) @@ -414,13 +389,11 @@ async def handler(m): mock.inner(m) return m - broker = self.patch_broker(raw_broker, broker) - - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(broker.publish("1", queue)), + asyncio.create_task(br.publish("1", queue)), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -435,19 +408,11 @@ async def handler(m): @pytest.mark.asyncio class ExceptionMiddlewareTestcase(BaseTestcaseConfig): - broker_class: Type[BrokerUsecase] - - @pytest.fixture - def raw_broker(self): - return None - - def patch_broker( - self, raw_broker: BrokerUsecase, broker: BrokerUsecase - ) -> BrokerUsecase: - return broker - async def test_exception_middleware_default_msg( - self, event: asyncio.Event, queue: str, mock: Mock, raw_broker + self, + event: asyncio.Event, + queue: str, + mock: Mock, ): mid = ExceptionMiddleware() @@ -455,7 +420,7 @@ async def test_exception_middleware_default_msg( async def value_error_handler(exc): return "value" - broker = self.broker_class(middlewares=(mid,)) + broker = self.get_broker(apply_types=True, middlewares=(mid,)) args, kwargs = self.get_subscriber_params(queue) @@ -471,13 +436,11 @@ async def subscriber2(msg=Context("message")): mock(await msg.decode()) event.set() - broker = self.patch_broker(raw_broker, broker) - - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(broker.publish("", queue)), + asyncio.create_task(br.publish("", queue)), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -488,7 +451,10 @@ async def subscriber2(msg=Context("message")): mock.assert_called_once_with("value") async def test_exception_middleware_skip_msg( - self, event: asyncio.Event, queue: str, mock: Mock, raw_broker + self, + event: asyncio.Event, + queue: str, + mock: Mock, ): mid = ExceptionMiddleware() @@ -497,7 +463,7 @@ async def value_error_handler(exc): event.set() raise SkipMessage() - broker = self.broker_class(middlewares=(mid,)) + broker = self.get_broker(middlewares=(mid,)) args, kwargs = self.get_subscriber_params(queue) @broker.subscriber(*args, **kwargs) @@ -511,13 +477,11 @@ async def subscriber1(m): async def subscriber2(msg=Context("message")): mock(await msg.decode()) - broker = self.patch_broker(raw_broker, broker) - - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(broker.publish("", queue)), + asyncio.create_task(br.publish("", queue)), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -527,7 +491,10 @@ async def subscriber2(msg=Context("message")): assert mock.call_count == 0 async def test_exception_middleware_do_not_catch_skip_msg( - self, event: asyncio.Event, queue: str, mock: Mock, raw_broker + self, + event: asyncio.Event, + queue: str, + mock: Mock, ): mid = ExceptionMiddleware() @@ -535,7 +502,7 @@ async def test_exception_middleware_do_not_catch_skip_msg( async def value_error_handler(exc): mock() - broker = self.broker_class(middlewares=(mid,)) + broker = self.get_broker(middlewares=(mid,)) args, kwargs = self.get_subscriber_params(queue) @broker.subscriber(*args, **kwargs) @@ -543,13 +510,11 @@ async def subscriber(m): event.set() raise SkipMessage - broker = self.patch_broker(raw_broker, broker) - - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(broker.publish("", queue)), + asyncio.create_task(br.publish("", queue)), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -560,7 +525,10 @@ async def subscriber(m): assert mock.call_count == 0 async def test_exception_middleware_reraise( - self, event: asyncio.Event, queue: str, mock: Mock, raw_broker + self, + event: asyncio.Event, + queue: str, + mock: Mock, ): mid = ExceptionMiddleware() @@ -569,7 +537,7 @@ async def value_error_handler(exc): event.set() raise exc - broker = self.broker_class(middlewares=(mid,)) + broker = self.get_broker(middlewares=(mid,)) args, kwargs = self.get_subscriber_params(queue) @broker.subscriber(*args, **kwargs) @@ -583,13 +551,11 @@ async def subscriber1(m): async def subscriber2(msg=Context("message")): mock(await msg.decode()) - broker = self.patch_broker(raw_broker, broker) - - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(broker.publish("", queue)), + asyncio.create_task(br.publish("", queue)), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -599,7 +565,7 @@ async def subscriber2(msg=Context("message")): assert mock.call_count == 0 async def test_exception_middleware_different_handler( - self, event: asyncio.Event, queue: str, mock: Mock, raw_broker + self, event: asyncio.Event, queue: str, mock: Mock ): mid = ExceptionMiddleware() @@ -611,7 +577,7 @@ async def zero_error_handler(exc): async def value_error_handler(exc): return "value" - broker = self.broker_class(middlewares=(mid,)) + broker = self.get_broker(apply_types=True, middlewares=(mid,)) args, kwargs = self.get_subscriber_params(queue) publisher = broker.publisher(queue + "2") @@ -636,14 +602,12 @@ async def subscriber3(msg=Context("message")): if mock.call_count > 1: event.set() - broker = self.patch_broker(raw_broker, broker) - - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(broker.publish("", queue)), - asyncio.create_task(broker.publish("", queue + "1")), + asyncio.create_task(br.publish("", queue)), + asyncio.create_task(br.publish("", queue + "1")), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -678,7 +642,7 @@ async def value_error_handler(exc): ] async def test_exception_middleware_decoder_error( - self, event: asyncio.Event, queue: str, mock: Mock, raw_broker + self, event: asyncio.Event, queue: str, mock: Mock ): async def decoder( msg, @@ -692,7 +656,7 @@ async def decoder( async def value_error_handler(exc): event.set() - broker = self.broker_class(middlewares=(mid,), decoder=decoder) + broker = self.get_broker(middlewares=(mid,), decoder=decoder) args, kwargs = self.get_subscriber_params(queue) @@ -700,13 +664,11 @@ async def value_error_handler(exc): async def subscriber1(m): raise ZeroDivisionError - broker = self.patch_broker(raw_broker, broker) - - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(broker.publish("", queue)), + asyncio.create_task(br.publish("", queue)), asyncio.create_task(event.wait()), ), timeout=self.timeout, diff --git a/tests/brokers/base/parser.py b/tests/brokers/base/parser.py index cdb833c40b..2233539482 100644 --- a/tests/brokers/base/parser.py +++ b/tests/brokers/base/parser.py @@ -1,35 +1,20 @@ import asyncio -from typing import Type from unittest.mock import Mock import pytest -from faststream._internal.broker.broker import BrokerUsecase - from .basic import BaseTestcaseConfig @pytest.mark.asyncio class LocalCustomParserTestcase(BaseTestcaseConfig): - broker_class: Type[BrokerUsecase] - - @pytest.fixture - def raw_broker(self): - return None - - def patch_broker( - self, raw_broker: BrokerUsecase, broker: BrokerUsecase - ) -> BrokerUsecase: - return broker - async def test_local_parser( self, mock: Mock, queue: str, - raw_broker, event: asyncio.Event, ): - broker = self.broker_class() + broker = self.get_broker() async def custom_parser(msg, original): msg = await original(msg) @@ -42,13 +27,12 @@ async def custom_parser(msg, original): async def handle(m): event.set() - broker = self.patch_broker(raw_broker, broker) - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(broker.publish(b"hello", queue)), + asyncio.create_task(br.publish(b"hello", queue)), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -61,10 +45,9 @@ async def test_local_sync_decoder( self, mock: Mock, queue: str, - raw_broker, event: asyncio.Event, ): - broker = self.broker_class() + broker = self.get_broker() def custom_decoder(msg): mock(msg.body) @@ -76,13 +59,12 @@ def custom_decoder(msg): async def handle(m): event.set() - broker = self.patch_broker(raw_broker, broker) - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(broker.publish(b"hello", queue)), + asyncio.create_task(br.publish(b"hello", queue)), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -95,14 +77,13 @@ async def test_global_sync_decoder( self, mock: Mock, queue: str, - raw_broker, event: asyncio.Event, ): def custom_decoder(msg): mock(msg.body) return msg - broker = self.broker_class(decoder=custom_decoder) + broker = self.get_broker(decoder=custom_decoder) args, kwargs = self.get_subscriber_params(queue) @@ -110,13 +91,12 @@ def custom_decoder(msg): async def handle(m): event.set() - broker = self.patch_broker(raw_broker, broker) - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(broker.publish(b"hello", queue)), + asyncio.create_task(br.publish(b"hello", queue)), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -130,10 +110,9 @@ async def test_local_parser_no_share_between_subscribers( event: asyncio.Event, mock: Mock, queue: str, - raw_broker, ): event2 = asyncio.Event() - broker = self.broker_class() + broker = self.get_broker() async def custom_parser(msg, original): msg = await original(msg) @@ -151,14 +130,13 @@ async def handle(m): else: event.set() - broker = self.patch_broker(raw_broker, broker) - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(broker.publish(b"hello", queue)), - asyncio.create_task(broker.publish(b"hello", queue + "1")), + asyncio.create_task(br.publish(b"hello", queue)), + asyncio.create_task(br.publish(b"hello", queue + "1")), asyncio.create_task(event.wait()), asyncio.create_task(event2.wait()), ), @@ -173,10 +151,9 @@ async def test_local_parser_no_share_between_handlers( self, mock: Mock, queue: str, - raw_broker, event: asyncio.Event, ): - broker = self.broker_class() + broker = self.get_broker() args, kwargs = self.get_subscriber_params(queue) sub = broker.subscriber(*args, **kwargs) @@ -196,14 +173,13 @@ async def custom_parser(msg, original): async def handle2(m): event2.set() - broker = self.patch_broker(raw_broker, broker) - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(broker.publish({"msg": "hello"}, queue)), - asyncio.create_task(broker.publish(b"hello", queue)), + asyncio.create_task(br.publish({"msg": "hello"}, queue)), + asyncio.create_task(br.publish(b"hello", queue)), asyncio.create_task(event.wait()), asyncio.create_task(event2.wait()), ), @@ -220,7 +196,6 @@ async def test_global_parser( self, mock: Mock, queue: str, - raw_broker, event: asyncio.Event, ): async def custom_parser(msg, original): @@ -228,7 +203,7 @@ async def custom_parser(msg, original): mock(msg.body) return msg - broker = self.broker_class(parser=custom_parser) + broker = self.get_broker(parser=custom_parser) args, kwargs = self.get_subscriber_params(queue) @@ -236,13 +211,12 @@ async def custom_parser(msg, original): async def handle(m): event.set() - broker = self.patch_broker(raw_broker, broker) - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(broker.publish(b"hello", queue)), + asyncio.create_task(br.publish(b"hello", queue)), asyncio.create_task(event.wait()), ), timeout=self.timeout, diff --git a/tests/brokers/base/publish.py b/tests/brokers/base/publish.py index 8e10e8f5d0..c3828c43d4 100644 --- a/tests/brokers/base/publish.py +++ b/tests/brokers/base/publish.py @@ -1,5 +1,4 @@ import asyncio -from abc import abstractmethod from dataclasses import asdict, dataclass from datetime import datetime from typing import Any, Dict, List, Tuple @@ -11,7 +10,6 @@ from faststream import BaseMiddleware, Context, Response from faststream._internal._compat import dump_json, model_to_json -from faststream._internal.broker.broker import BrokerUsecase from .basic import BaseTestcaseConfig @@ -29,13 +27,6 @@ class SimpleDataclass: class BrokerPublishTestcase(BaseTestcaseConfig): - @abstractmethod - def get_broker(self, apply_types: bool = False) -> BrokerUsecase[Any, Any]: - raise NotImplementedError - - def patch_broker(self, broker: BrokerUsecase[Any, Any]) -> BrokerUsecase[Any, Any]: - return broker - @pytest.mark.asyncio @pytest.mark.parametrize( ("message", "message_type", "expected_message"), diff --git a/tests/brokers/base/requests.py b/tests/brokers/base/requests.py index ae3f6eefe5..b1053b203c 100644 --- a/tests/brokers/base/requests.py +++ b/tests/brokers/base/requests.py @@ -8,15 +8,9 @@ class RequestsTestcase(BaseTestcaseConfig): def get_middleware(self, **kwargs): raise NotImplementedError - def get_broker(self, **kwargs): - raise NotImplementedError - def get_router(self, **kwargs): raise NotImplementedError - def patch_broker(self, broker, **kwargs): - return broker - async def test_request_timeout(self, queue: str): broker = self.get_broker() diff --git a/tests/brokers/base/router.py b/tests/brokers/base/router.py index abd80e5da7..61c61ed944 100644 --- a/tests/brokers/base/router.py +++ b/tests/brokers/base/router.py @@ -5,8 +5,6 @@ import pytest from faststream import BaseMiddleware, Depends -from faststream._internal.basic_types import AnyCallable -from faststream._internal.broker.broker import BrokerUsecase from faststream._internal.broker.router import ( ArgsContainer, BrokerRouter, @@ -21,29 +19,17 @@ class RouterTestcase( LocalMiddlewareTestcase, LocalCustomParserTestcase, ): - build_message: AnyCallable route_class: Type[SubscriberRoute] publisher_class: Type[ArgsContainer] - def patch_broker(self, br: BrokerUsecase, router: BrokerRouter) -> BrokerUsecase: - br.include_router(router) - return br - - @pytest.fixture - def pub_broker(self, broker): - return broker - - @pytest.fixture - def raw_broker(self, pub_broker): - return pub_broker - async def test_empty_prefix( self, router: BrokerRouter, - pub_broker: BrokerUsecase, queue: str, event: asyncio.Event, ): + pub_broker = self.get_broker() + args, kwargs = self.get_subscriber_params(queue) @router.subscriber(*args, **kwargs) @@ -51,13 +37,12 @@ def subscriber(m): event.set() pub_broker.include_router(router) - - async with pub_broker: - await pub_broker.start() + async with self.patch_broker(pub_broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(pub_broker.publish("hello", queue)), + asyncio.create_task(br.publish("hello", queue)), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -68,10 +53,11 @@ def subscriber(m): async def test_not_empty_prefix( self, router: BrokerRouter, - pub_broker: BrokerUsecase, queue: str, event: asyncio.Event, ): + pub_broker = self.get_broker() + router.prefix = "test_" args, kwargs = self.get_subscriber_params(queue) @@ -81,13 +67,12 @@ def subscriber(m): event.set() pub_broker.include_router(router) - - async with pub_broker: - await pub_broker.start() + async with self.patch_broker(pub_broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(pub_broker.publish("hello", f"test_{queue}")), + asyncio.create_task(br.publish("hello", f"test_{queue}")), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -98,10 +83,11 @@ def subscriber(m): async def test_include_with_prefix( self, router: BrokerRouter, - pub_broker: BrokerUsecase, queue: str, event: asyncio.Event, ): + pub_broker = self.get_broker() + args, kwargs = self.get_subscriber_params(queue) @router.subscriber(*args, **kwargs) @@ -109,13 +95,12 @@ def subscriber(m): event.set() pub_broker.include_router(router, prefix="test_") - - async with pub_broker: - await pub_broker.start() + async with self.patch_broker(pub_broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(pub_broker.publish("hello", f"test_{queue}")), + asyncio.create_task(br.publish("hello", f"test_{queue}")), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -126,10 +111,11 @@ def subscriber(m): async def test_empty_prefix_publisher( self, router: BrokerRouter, - pub_broker: BrokerUsecase, queue: str, event: asyncio.Event, ): + pub_broker = self.get_broker() + args, kwargs = self.get_subscriber_params(queue) @router.subscriber(*args, **kwargs) @@ -144,13 +130,12 @@ def response(m): event.set() pub_broker.include_router(router) - - async with pub_broker: - await pub_broker.start() + async with self.patch_broker(pub_broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(pub_broker.publish("hello", queue)), + asyncio.create_task(br.publish("hello", queue)), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -161,10 +146,11 @@ def response(m): async def test_not_empty_prefix_publisher( self, router: BrokerRouter, - pub_broker: BrokerUsecase, queue: str, event: asyncio.Event, ): + pub_broker = self.get_broker() + router.prefix = "test_" args, kwargs = self.get_subscriber_params(queue) @@ -181,13 +167,12 @@ def response(m): event.set() pub_broker.include_router(router) - - async with pub_broker: - await pub_broker.start() + async with self.patch_broker(pub_broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(pub_broker.publish("hello", f"test_{queue}")), + asyncio.create_task(br.publish("hello", f"test_{queue}")), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -198,10 +183,11 @@ def response(m): async def test_manual_publisher( self, router: BrokerRouter, - pub_broker: BrokerUsecase, queue: str, event: asyncio.Event, ): + pub_broker = self.get_broker() + router.prefix = "test_" p = router.publisher(queue + "resp") @@ -219,13 +205,12 @@ def response(m): event.set() pub_broker.include_router(router) - - async with pub_broker: - await pub_broker.start() + async with self.patch_broker(pub_broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(pub_broker.publish("hello", f"test_{queue}")), + asyncio.create_task(br.publish("hello", f"test_{queue}")), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -238,26 +223,26 @@ async def test_delayed_handlers( event: asyncio.Event, router: BrokerRouter, queue: str, - pub_broker: BrokerUsecase, ): + pub_broker = self.get_broker() + def response(m): event.set() args, kwargs = self.get_subscriber_params(queue) - r = type(router)( + router = type(router)( prefix="test_", handlers=(self.route_class(response, *args, **kwargs),), ) - pub_broker.include_router(r) - - async with pub_broker: - await pub_broker.start() + pub_broker.include_router(router) + async with self.patch_broker(pub_broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(pub_broker.publish("hello", f"test_{queue}")), + asyncio.create_task(br.publish("hello", f"test_{queue}")), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -270,9 +255,10 @@ async def test_delayed_publishers( event: asyncio.Event, router: BrokerRouter, queue: str, - pub_broker: BrokerUsecase, mock: Mock, ): + pub_broker = self.get_broker() + def response(m): return m @@ -299,12 +285,12 @@ async def handler(msg): mock(msg) event.set() - async with pub_broker: - await pub_broker.start() + async with self.patch_broker(pub_broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(pub_broker.publish("hello", f"test_{queue}")), + asyncio.create_task(br.publish("hello", f"test_{queue}")), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -317,11 +303,12 @@ async def handler(msg): async def test_nested_routers_sub( self, router: BrokerRouter, - pub_broker: BrokerUsecase, queue: str, event: asyncio.Event, mock: Mock, ): + pub_broker = self.get_broker() + core_router = type(router)(prefix="test1_") router.prefix = "test2_" @@ -336,14 +323,12 @@ def subscriber(m): core_router.include_routers(router) pub_broker.include_routers(core_router) - async with pub_broker: - await pub_broker.start() + async with self.patch_broker(pub_broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task( - pub_broker.publish("hello", f"test1_test2_{queue}") - ), + asyncio.create_task(br.publish("hello", f"test1_test2_{queue}")), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -355,10 +340,11 @@ def subscriber(m): async def test_nested_routers_pub( self, router: BrokerRouter, - pub_broker: BrokerUsecase, queue: str, event: asyncio.Event, ): + pub_broker = self.get_broker() + core_router = type(router)(prefix="test1_") router.prefix = "test2_" @@ -378,16 +364,14 @@ def response(m): event.set() core_router.include_routers(router) - pub_broker.include_routers(core_router) + pub_broker.include_router(core_router) - async with pub_broker: - await pub_broker.start() + async with self.patch_broker(pub_broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task( - pub_broker.publish("hello", f"test1_test2_{queue}") - ), + asyncio.create_task(br.publish("hello", f"test1_test2_{queue}")), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -398,9 +382,10 @@ def response(m): async def test_router_dependencies( self, router: BrokerRouter, - pub_broker: BrokerUsecase, queue: str, ): + pub_broker = self.get_broker() + router = type(router)(dependencies=(Depends(lambda: 1),)) router2 = type(router)(dependencies=(Depends(lambda: 2),)) @@ -420,9 +405,10 @@ def subscriber(): ... async def test_router_include_with_dependencies( self, router: BrokerRouter, - pub_broker: BrokerUsecase, queue: str, ): + pub_broker = self.get_broker() + router2 = type(router)() args, kwargs = self.get_subscriber_params( @@ -443,9 +429,10 @@ def subscriber(): ... async def test_router_middlewares( self, router: BrokerRouter, - pub_broker: BrokerUsecase, queue: str, ): + pub_broker = self.get_broker() + router = type(router)(middlewares=(BaseMiddleware,)) router2 = type(router)(middlewares=(BaseMiddleware,)) @@ -467,9 +454,10 @@ def subscriber(): ... async def test_router_include_with_middlewares( self, router: BrokerRouter, - pub_broker: BrokerUsecase, queue: str, ): + pub_broker = self.get_broker() + router2 = type(router)() args, kwargs = self.get_subscriber_params(queue, middlewares=(3,)) @@ -491,11 +479,12 @@ def subscriber(): ... async def test_router_parser( self, router: BrokerRouter, - pub_broker: BrokerUsecase, queue: str, event: asyncio.Event, mock: Mock, ): + pub_broker = self.get_broker() + async def parser(msg, original): mock.parser() return await original(msg) @@ -515,14 +504,13 @@ async def decoder(msg, original): def subscriber(s): event.set() - pub_broker.include_routers(router) - - async with pub_broker: - await pub_broker.start() + pub_broker.include_router(router) + async with self.patch_broker(pub_broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(pub_broker.publish("hello", queue)), + asyncio.create_task(br.publish("hello", queue)), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -535,11 +523,12 @@ def subscriber(s): async def test_router_parser_override( self, router: BrokerRouter, - pub_broker: BrokerUsecase, queue: str, event: asyncio.Event, mock: Mock, ): + pub_broker = self.get_broker() + async def global_parser(msg, original): # pragma: no cover mock() return await original(msg) @@ -567,14 +556,13 @@ async def decoder(msg, original): def subscriber(s): event.set() - pub_broker.include_routers(router) - - async with pub_broker: - await pub_broker.start() + pub_broker.include_router(router) + async with self.patch_broker(pub_broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(pub_broker.publish("hello", queue)), + asyncio.create_task(br.publish("hello", queue)), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -588,17 +576,14 @@ def subscriber(s): @pytest.mark.asyncio class RouterLocalTestcase(RouterTestcase): - @pytest.fixture - def pub_broker(self, test_broker): - return test_broker - async def test_publisher_mock( self, router: BrokerRouter, - pub_broker: BrokerUsecase, queue: str, event: asyncio.Event, ): + pub_broker = self.get_broker() + pub = router.publisher(queue + "resp") args, kwargs = self.get_subscriber_params(queue) @@ -610,13 +595,12 @@ def subscriber(m): return "hi" pub_broker.include_router(router) - - async with pub_broker: - await pub_broker.start() + async with self.patch_broker(pub_broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(pub_broker.publish("hello", queue)), + asyncio.create_task(br.publish("hello", queue)), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -628,10 +612,11 @@ def subscriber(m): async def test_subscriber_mock( self, router: BrokerRouter, - pub_broker: BrokerUsecase, queue: str, event: asyncio.Event, ): + pub_broker = self.get_broker() + args, kwargs = self.get_subscriber_params(queue) @router.subscriber(*args, **kwargs) @@ -640,13 +625,12 @@ def subscriber(m): return "hi" pub_broker.include_router(router) - - async with pub_broker: - await pub_broker.start() + async with self.patch_broker(pub_broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(pub_broker.publish("hello", queue)), + asyncio.create_task(br.publish("hello", queue)), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -656,8 +640,12 @@ def subscriber(m): subscriber.mock.assert_called_with("hello") async def test_manual_publisher_mock( - self, router: BrokerRouter, queue: str, pub_broker: BrokerUsecase + self, + router: BrokerRouter, + queue: str, ): + pub_broker = self.get_broker() + publisher = router.publisher(queue + "resp") args, kwargs = self.get_subscriber_params(queue) @@ -667,7 +655,7 @@ async def m(m): await publisher.publish("response") pub_broker.include_router(router) - async with pub_broker: - await pub_broker.start() - await pub_broker.publish("hello", queue) + async with self.patch_broker(pub_broker) as br: + await br.start() + await br.publish("hello", queue) publisher.mock.assert_called_with("response") diff --git a/tests/brokers/base/testclient.py b/tests/brokers/base/testclient.py index 1262b45e2c..543a400b2a 100644 --- a/tests/brokers/base/testclient.py +++ b/tests/brokers/base/testclient.py @@ -5,17 +5,11 @@ import anyio import pytest -from faststream._internal.basic_types import AnyCallable -from faststream._internal.testing.broker import TestBroker - from .consume import BrokerConsumeTestcase from .publish import BrokerPublishTestcase class BrokerTestclientTestcase(BrokerPublishTestcase, BrokerConsumeTestcase): - build_message: AnyCallable - test_class: TestBroker - @abstractmethod def get_fake_producer_class(self) -> type: raise NotImplementedError @@ -30,9 +24,9 @@ async def test_subscriber_mock(self, queue: str): async def m(msg): pass - async with self.test_class(test_broker): - await test_broker.start() - await test_broker.publish("hello", queue) + async with self.patch_broker(test_broker) as br: + await br.start() + await br.publish("hello", queue) m.mock.assert_called_once_with("hello") @pytest.mark.asyncio @@ -48,9 +42,9 @@ async def test_publisher_mock(self, queue: str): async def m(msg): return "response" - async with self.test_class(test_broker): - await test_broker.start() - await test_broker.publish("hello", queue) + async with self.patch_broker(test_broker) as br: + await br.start() + await br.publish("hello", queue) publisher.mock.assert_called_with("response") @pytest.mark.asyncio @@ -71,12 +65,12 @@ async def m(msg): @test_broker.subscriber(*args2, **kwargs2) async def handler_response(msg): ... - async with self.test_class(test_broker): - await test_broker.start() + async with self.patch_broker(test_broker) as br: + await br.start() - assert len(test_broker._subscribers) == 2 + assert len(br._subscribers) == 2 - await test_broker.publish("hello", queue) + await br.publish("hello", queue) publisher.mock.assert_called_with("response") handler_response.mock.assert_called_once_with("response") @@ -92,9 +86,9 @@ async def test_manual_publisher_mock(self, queue: str): async def m(msg): await publisher.publish("response") - async with self.test_class(test_broker): - await test_broker.start() - await test_broker.publish("hello", queue) + async with self.patch_broker(test_broker) as br: + await br.start() + await br.publish("hello", queue) publisher.mock.assert_called_with("response") @pytest.mark.asyncio @@ -107,34 +101,33 @@ async def test_exception_raises(self, queue: str): async def m(msg): # pragma: no cover raise ValueError() - async with self.test_class(test_broker): - await test_broker.start() + async with self.patch_broker(test_broker) as br: + await br.start() with pytest.raises(ValueError): # noqa: PT011 - await test_broker.publish("hello", queue) + await br.publish("hello", queue) - async def test_broker_gets_patched_attrs_within_cm(self): + async def test_broker_gets_patched_attrs_within_cm(self, fake_producer_cls): test_broker = self.get_broker() - fake_producer_class = self.get_fake_producer_class() await test_broker.start() - async with self.test_class(test_broker) as br: + async with self.patch_broker(test_broker) as br: assert isinstance(br.start, Mock) assert isinstance(br._connect, Mock) assert isinstance(br.close, Mock) - assert isinstance(br._producer, fake_producer_class) + assert isinstance(br._producer, fake_producer_cls) assert not isinstance(br.start, Mock) assert not isinstance(br._connect, Mock) assert not isinstance(br.close, Mock) assert br._connection is not None - assert not isinstance(br._producer, fake_producer_class) + assert not isinstance(br._producer, fake_producer_cls) async def test_broker_with_real_doesnt_get_patched(self): test_broker = self.get_broker() await test_broker.start() - async with self.test_class(test_broker, with_real=True) as br: + async with self.patch_broker(test_broker, with_real=True) as br: assert not isinstance(br.start, Mock) assert not isinstance(br._connect, Mock) assert not isinstance(br.close, Mock) @@ -156,7 +149,7 @@ async def m(msg): await test_broker.start() - async with self.test_class(test_broker, with_real=True) as br: + async with self.patch_broker(test_broker, with_real=True) as br: await br.publish("hello", queue) await m.wait_call(self.timeout) diff --git a/tests/brokers/confluent/conftest.py b/tests/brokers/confluent/conftest.py index 291ca36f09..43981653e9 100644 --- a/tests/brokers/confluent/conftest.py +++ b/tests/brokers/confluent/conftest.py @@ -1,9 +1,8 @@ from dataclasses import dataclass import pytest -import pytest_asyncio -from faststream.confluent import KafkaBroker, KafkaRouter, TestKafkaBroker +from faststream.confluent import KafkaRouter @dataclass @@ -21,24 +20,3 @@ def settings(): @pytest.fixture def router(): return KafkaRouter() - - -@pytest_asyncio.fixture() -async def broker(settings): - broker = KafkaBroker(settings.url, apply_types=False) - async with broker: - yield broker - - -@pytest_asyncio.fixture() -async def full_broker(settings): - broker = KafkaBroker(settings.url) - async with broker: - yield broker - - -@pytest_asyncio.fixture() -async def test_broker(): - broker = KafkaBroker() - async with TestKafkaBroker(broker) as br: - yield br diff --git a/tests/brokers/confluent/test_consume.py b/tests/brokers/confluent/test_consume.py index f3eb5774cd..0e07d3cbbb 100644 --- a/tests/brokers/confluent/test_consume.py +++ b/tests/brokers/confluent/test_consume.py @@ -1,4 +1,5 @@ import asyncio +from typing import Any from unittest.mock import patch import pytest @@ -17,8 +18,8 @@ class TestConsume(ConfluentTestcaseConfig, BrokerRealConsumeTestcase): """A class to represent a test Kafka broker.""" - def get_broker(self, apply_types: bool = False): - return KafkaBroker(apply_types=apply_types) + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: + return KafkaBroker(apply_types=apply_types, **kwargs) @pytest.mark.asyncio async def test_consume_batch(self, queue: str): diff --git a/tests/brokers/confluent/test_fastapi.py b/tests/brokers/confluent/test_fastapi.py index 0de5bb7311..dc27c1f69a 100644 --- a/tests/brokers/confluent/test_fastapi.py +++ b/tests/brokers/confluent/test_fastapi.py @@ -1,12 +1,12 @@ import asyncio -from typing import List +from typing import Any, List from unittest.mock import Mock import pytest -from faststream.confluent import KafkaRouter +from faststream.confluent import KafkaBroker, KafkaRouter from faststream.confluent.fastapi import KafkaRouter as StreamRouter -from faststream.confluent.testing import TestKafkaBroker, build_message +from faststream.confluent.testing import TestKafkaBroker from tests.brokers.base.fastapi import FastAPILocalTestcase, FastAPITestcase from .basic import ConfluentTestcaseConfig @@ -32,11 +32,11 @@ async def hello(msg: List[str]): event.set() return mock(msg) - async with router.broker: - await router.broker.start() + async with self.patch_broker(router.broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task(router.broker.publish("hi", queue)), + asyncio.create_task(br.publish("hi", queue)), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -49,8 +49,9 @@ async def hello(msg: List[str]): class TestRouterLocal(ConfluentTestcaseConfig, FastAPILocalTestcase): router_class = StreamRouter broker_router_class = KafkaRouter - broker_test = staticmethod(TestKafkaBroker) - build_message = staticmethod(build_message) + + def patch_broker(self, broker: KafkaBroker, **kwargs: Any) -> TestKafkaBroker: + return TestKafkaBroker(broker, **kwargs) async def test_batch_testclient( self, @@ -67,10 +68,10 @@ async def hello(msg: List[str]): event.set() return mock(msg) - async with TestKafkaBroker(router.broker): + async with self.patch_broker(router.broker) as br: await asyncio.wait( ( - asyncio.create_task(router.broker.publish("hi", queue)), + asyncio.create_task(br.publish("hi", queue)), asyncio.create_task(event.wait()), ), timeout=self.timeout, diff --git a/tests/brokers/confluent/test_logger.py b/tests/brokers/confluent/test_logger.py index 1f91070402..33698d522e 100644 --- a/tests/brokers/confluent/test_logger.py +++ b/tests/brokers/confluent/test_logger.py @@ -1,10 +1,8 @@ -import asyncio import logging from typing import Any import pytest -from faststream._internal.broker.broker import BrokerUsecase from faststream.confluent import KafkaBroker from .basic import ConfluentTestcaseConfig @@ -14,26 +12,21 @@ class TestLogger(ConfluentTestcaseConfig): """A class to represent a test Kafka broker.""" - def get_broker(self, apply_types: bool = False): - return KafkaBroker(apply_types=apply_types) + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: + return KafkaBroker(apply_types=apply_types, **kwargs) - def patch_broker(self, broker: BrokerUsecase[Any, Any]) -> BrokerUsecase[Any, Any]: + def patch_broker(self, broker: KafkaBroker, **kwargs: Any) -> KafkaBroker: return broker @pytest.mark.asyncio - async def test_custom_logger( - self, - queue: str, - event: asyncio.Event, - ): + async def test_custom_logger(self, queue: str): test_logger = logging.getLogger("test_logger") - consume_broker = KafkaBroker(logger=test_logger) + consume_broker = self.get_broker(logger=test_logger) args, kwargs = self.get_subscriber_params(queue) @consume_broker.subscriber(*args, **kwargs) - def subscriber(m): - event.set() + def subscriber(m): ... async with self.patch_broker(consume_broker) as br: await br.start() @@ -44,13 +37,3 @@ def subscriber(m): producer_logger = br._producer._producer.logger assert producer_logger == test_logger - - await asyncio.wait( - ( - asyncio.create_task(br.publish("hello", queue)), - asyncio.create_task(event.wait()), - ), - timeout=10, - ) - - assert event.is_set() diff --git a/tests/brokers/confluent/test_middlewares.py b/tests/brokers/confluent/test_middlewares.py index 5ff72e0955..6836ee4411 100644 --- a/tests/brokers/confluent/test_middlewares.py +++ b/tests/brokers/confluent/test_middlewares.py @@ -1,3 +1,5 @@ +from typing import Any + import pytest from faststream.confluent import KafkaBroker @@ -11,9 +13,11 @@ @pytest.mark.confluent class TestMiddlewares(ConfluentTestcaseConfig, MiddlewareTestcase): - broker_class = KafkaBroker + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: + return KafkaBroker(apply_types=apply_types, **kwargs) @pytest.mark.confluent class TestExceptionMiddlewares(ConfluentTestcaseConfig, ExceptionMiddlewareTestcase): - broker_class = KafkaBroker + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: + return KafkaBroker(apply_types=apply_types, **kwargs) diff --git a/tests/brokers/confluent/test_parser.py b/tests/brokers/confluent/test_parser.py index 36a407e100..6dcaba712e 100644 --- a/tests/brokers/confluent/test_parser.py +++ b/tests/brokers/confluent/test_parser.py @@ -1,3 +1,5 @@ +from typing import Any + import pytest from faststream.confluent import KafkaBroker @@ -8,4 +10,5 @@ @pytest.mark.confluent class TestCustomParser(ConfluentTestcaseConfig, CustomParserTestcase): - broker_class = KafkaBroker + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: + return KafkaBroker(apply_types=apply_types, **kwargs) diff --git a/tests/brokers/confluent/test_publish.py b/tests/brokers/confluent/test_publish.py index c337953397..c181d5eb6e 100644 --- a/tests/brokers/confluent/test_publish.py +++ b/tests/brokers/confluent/test_publish.py @@ -1,4 +1,5 @@ import asyncio +from typing import Any from unittest.mock import Mock import pytest @@ -12,8 +13,8 @@ @pytest.mark.confluent class TestPublish(ConfluentTestcaseConfig, BrokerPublishTestcase): - def get_broker(self, apply_types: bool = False): - return KafkaBroker(apply_types=apply_types) + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: + return KafkaBroker(apply_types=apply_types, **kwargs) @pytest.mark.asyncio async def test_publish_batch(self, queue: str): diff --git a/tests/brokers/confluent/test_requests.py b/tests/brokers/confluent/test_requests.py index 39f4677113..484c49d0b0 100644 --- a/tests/brokers/confluent/test_requests.py +++ b/tests/brokers/confluent/test_requests.py @@ -1,3 +1,5 @@ +from typing import Any + import pytest from faststream import BaseMiddleware @@ -18,14 +20,14 @@ async def consume_scope(self, call_next, msg): @pytest.mark.asyncio class TestRequestTestClient(ConfluentTestcaseConfig, RequestsTestcase): - def get_middleware(self, **kwargs): + def get_middleware(self, **kwargs: Any): return Mid - def get_broker(self, **kwargs): - return KafkaBroker(**kwargs) - - def get_router(self, **kwargs): + def get_router(self, **kwargs: Any): return KafkaRouter(**kwargs) - def patch_broker(self, broker, **kwargs): + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: + return KafkaBroker(apply_types=apply_types, **kwargs) + + def patch_broker(self, broker: KafkaBroker, **kwargs: Any) -> TestKafkaBroker: return TestKafkaBroker(broker, **kwargs) diff --git a/tests/brokers/confluent/test_router.py b/tests/brokers/confluent/test_router.py index 746857d9de..0aeb07d0fa 100644 --- a/tests/brokers/confluent/test_router.py +++ b/tests/brokers/confluent/test_router.py @@ -1,6 +1,14 @@ +from typing import Any + import pytest -from faststream.confluent import KafkaPublisher, KafkaRoute, KafkaRouter +from faststream.confluent import ( + KafkaBroker, + KafkaPublisher, + KafkaRoute, + KafkaRouter, + TestKafkaBroker, +) from tests.brokers.base.router import RouterLocalTestcase, RouterTestcase from .basic import ConfluentTestcaseConfig @@ -12,8 +20,17 @@ class TestRouter(ConfluentTestcaseConfig, RouterTestcase): route_class = KafkaRoute publisher_class = KafkaPublisher + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: + return KafkaBroker(apply_types=apply_types, **kwargs) + class TestRouterLocal(ConfluentTestcaseConfig, RouterLocalTestcase): broker_class = KafkaRouter route_class = KafkaRoute publisher_class = KafkaPublisher + + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: + return KafkaBroker(apply_types=apply_types, **kwargs) + + def patch_broker(self, broker: KafkaBroker, **kwargs: Any) -> TestKafkaBroker: + return TestKafkaBroker(broker, **kwargs) diff --git a/tests/brokers/confluent/test_test_client.py b/tests/brokers/confluent/test_test_client.py index 82e9aefe91..26c86c4d68 100644 --- a/tests/brokers/confluent/test_test_client.py +++ b/tests/brokers/confluent/test_test_client.py @@ -1,4 +1,5 @@ import asyncio +from typing import Any from unittest.mock import patch import pytest @@ -16,18 +17,11 @@ @pytest.mark.asyncio class TestTestclient(ConfluentTestcaseConfig, BrokerTestclientTestcase): - """A class to represent a test Kafka broker.""" + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: + return KafkaBroker(apply_types=apply_types, **kwargs) - test_class = TestKafkaBroker - - def get_broker(self, apply_types: bool = False): - return KafkaBroker(apply_types=apply_types) - - def patch_broker(self, broker: KafkaBroker) -> TestKafkaBroker: - return TestKafkaBroker(broker) - - def get_fake_producer_class(self) -> type: - return FakeProducer + def patch_broker(self, broker: KafkaBroker, **kwargs: Any) -> TestKafkaBroker: + return TestKafkaBroker(broker, **kwargs) async def test_message_nack_seek( self, @@ -66,7 +60,7 @@ async def test_with_real_testclient( def subscriber(m): event.set() - async with TestKafkaBroker(broker, with_real=True) as br: + async with self.patch_broker(broker, with_real=True) as br: await asyncio.wait( ( asyncio.create_task(br.publish("hello", queue)), @@ -131,15 +125,15 @@ async def on_receive(self) -> None: routes.append(None) return await super().on_receive() - broker = KafkaBroker(middlewares=(Middleware,)) + broker = self.get_broker(middlewares=(Middleware,)) @broker.subscriber(queue) - async def h1(): ... + async def h1(msg): ... @broker.subscriber(queue + "1") - async def h2(): ... + async def h2(msg): ... - async with TestKafkaBroker(broker) as br: + async with self.patch_broker(broker) as br: await br.publish("", queue) await br.publish("", queue + "1") @@ -154,19 +148,19 @@ async def on_receive(self) -> None: routes.append(None) return await super().on_receive() - broker = KafkaBroker(middlewares=(Middleware,)) + broker = self.get_broker(middlewares=(Middleware,)) args, kwargs = self.get_subscriber_params(queue) @broker.subscriber(*args, **kwargs) - async def h1(): ... + async def h1(msg): ... args2, kwargs2 = self.get_subscriber_params(queue + "1") @broker.subscriber(*args2, **kwargs2) - async def h2(): ... + async def h2(msg): ... - async with TestKafkaBroker(broker, with_real=True) as br: + async with self.patch_broker(broker, with_real=True) as br: await br.publish("", queue) await br.publish("", queue + "1") await h1.wait_call(10) @@ -177,74 +171,82 @@ async def h2(): ... async def test_multiple_subscribers_different_groups( self, queue: str, - test_broker: KafkaBroker, ): - @test_broker.subscriber(queue, group_id="group1") - async def subscriber1(): ... + broker = self.get_broker() - @test_broker.subscriber(queue, group_id="group2") - async def subscriber2(): ... + @broker.subscriber(queue, group_id="group1") + async def subscriber1(msg): ... - await test_broker.start() - await test_broker.publish("", queue) + @broker.subscriber(queue, group_id="group2") + async def subscriber2(msg): ... - assert subscriber1.mock.call_count == 1 - assert subscriber2.mock.call_count == 1 + async with self.patch_broker(broker) as br: + await br.start() + await br.publish("", queue) + + assert subscriber1.mock.call_count == 1 + assert subscriber2.mock.call_count == 1 async def test_multiple_subscribers_same_group( self, queue: str, - test_broker: KafkaBroker, ): - @test_broker.subscriber(queue, group_id="group1") - async def subscriber1(): ... + broker = self.get_broker() + + @broker.subscriber(queue, group_id="group1") + async def subscriber1(msg): ... - @test_broker.subscriber(queue, group_id="group1") - async def subscriber2(): ... + @broker.subscriber(queue, group_id="group1") + async def subscriber2(msg): ... - await test_broker.start() - await test_broker.publish("", queue) + async with self.patch_broker(broker) as br: + await br.start() + await br.publish("", queue) - assert subscriber1.mock.call_count == 1 - assert subscriber2.mock.call_count == 0 + assert subscriber1.mock.call_count == 1 + assert subscriber2.mock.call_count == 0 async def test_multiple_batch_subscriber_with_different_group( self, - test_broker: KafkaBroker, queue: str, ): - @test_broker.subscriber(queue, batch=True, group_id="group1") - async def subscriber1(): ... + broker = self.get_broker() - @test_broker.subscriber(queue, batch=True, group_id="group2") - async def subscriber2(): ... + @broker.subscriber(queue, batch=True, group_id="group1") + async def subscriber1(msg): ... - await test_broker.start() - await test_broker.publish("", queue) + @broker.subscriber(queue, batch=True, group_id="group2") + async def subscriber2(msg): ... + + async with self.patch_broker(broker) as br: + await br.start() + await br.publish("", queue) - assert subscriber1.mock.call_count == 1 - assert subscriber2.mock.call_count == 1 + assert subscriber1.mock.call_count == 1 + assert subscriber2.mock.call_count == 1 async def test_multiple_batch_subscriber_with_same_group( self, - test_broker: KafkaBroker, queue: str, ): - @test_broker.subscriber(queue, batch=True, group_id="group1") - async def subscriber1(): ... + broker = self.get_broker() + + @broker.subscriber(queue, batch=True, group_id="group1") + async def subscriber1(msg): ... - @test_broker.subscriber(queue, batch=True, group_id="group1") - async def subscriber2(): ... + @broker.subscriber(queue, batch=True, group_id="group1") + async def subscriber2(msg): ... - await test_broker.start() - await test_broker.publish("", queue) + async with self.patch_broker(broker) as br: + await br.start() + await br.publish("", queue) - assert subscriber1.mock.call_count == 1 - assert subscriber2.mock.call_count == 0 + assert subscriber1.mock.call_count == 1 + assert subscriber2.mock.call_count == 0 @pytest.mark.confluent async def test_broker_gets_patched_attrs_within_cm(self): - await super().test_broker_gets_patched_attrs_within_cm() + await super().test_broker_gets_patched_attrs_within_cm(FakeProducer) @pytest.mark.confluent async def test_broker_with_real_doesnt_get_patched(self): diff --git a/tests/brokers/kafka/conftest.py b/tests/brokers/kafka/conftest.py index c20d0f9f28..96a78aa9bd 100644 --- a/tests/brokers/kafka/conftest.py +++ b/tests/brokers/kafka/conftest.py @@ -1,9 +1,8 @@ from dataclasses import dataclass import pytest -import pytest_asyncio -from faststream.kafka import KafkaBroker, KafkaRouter, TestKafkaBroker +from faststream.kafka import KafkaRouter @dataclass @@ -19,24 +18,3 @@ def settings(): @pytest.fixture def router(): return KafkaRouter() - - -@pytest_asyncio.fixture() -async def broker(settings): - broker = KafkaBroker(settings.url, apply_types=False) - async with broker: - yield broker - - -@pytest_asyncio.fixture() -async def full_broker(settings): - broker = KafkaBroker(settings.url) - async with broker: - yield broker - - -@pytest_asyncio.fixture() -async def test_broker(): - broker = KafkaBroker() - async with TestKafkaBroker(broker) as br: - yield br diff --git a/tests/brokers/kafka/test_consume.py b/tests/brokers/kafka/test_consume.py index 7da9f90a5f..9384ed2db2 100644 --- a/tests/brokers/kafka/test_consume.py +++ b/tests/brokers/kafka/test_consume.py @@ -1,4 +1,5 @@ import asyncio +from typing import Any from unittest.mock import patch import pytest @@ -13,8 +14,8 @@ @pytest.mark.kafka class TestConsume(BrokerRealConsumeTestcase): - def get_broker(self, apply_types: bool = False): - return KafkaBroker(apply_types=apply_types) + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: + return KafkaBroker(apply_types=apply_types, **kwargs) @pytest.mark.asyncio async def test_consume_by_pattern( diff --git a/tests/brokers/kafka/test_fastapi.py b/tests/brokers/kafka/test_fastapi.py index 509466bc65..8d8177fad9 100644 --- a/tests/brokers/kafka/test_fastapi.py +++ b/tests/brokers/kafka/test_fastapi.py @@ -1,12 +1,11 @@ import asyncio -from typing import List +from typing import Any, List from unittest.mock import Mock import pytest -from faststream.kafka import KafkaRouter +from faststream.kafka import KafkaBroker, KafkaRouter, TestKafkaBroker from faststream.kafka.fastapi import KafkaRouter as StreamRouter -from faststream.kafka.testing import TestKafkaBroker, build_message from tests.brokers.base.fastapi import FastAPILocalTestcase, FastAPITestcase @@ -45,8 +44,9 @@ async def hello(msg: List[str]): class TestRouterLocal(FastAPILocalTestcase): router_class = StreamRouter broker_router_class = KafkaRouter - broker_test = staticmethod(TestKafkaBroker) - build_message = staticmethod(build_message) + + def patch_broker(self, broker: KafkaBroker, **kwargs: Any) -> TestKafkaBroker: + return TestKafkaBroker(broker, **kwargs) async def test_batch_testclient( self, @@ -61,10 +61,10 @@ async def hello(msg: List[str]): event.set() return mock(msg) - async with TestKafkaBroker(router.broker): + async with self.patch_broker(router.broker) as br: await asyncio.wait( ( - asyncio.create_task(router.broker.publish("hi", queue)), + asyncio.create_task(br.publish("hi", queue)), asyncio.create_task(event.wait()), ), timeout=3, diff --git a/tests/brokers/kafka/test_middlewares.py b/tests/brokers/kafka/test_middlewares.py index ccfd657c8f..c563edf595 100644 --- a/tests/brokers/kafka/test_middlewares.py +++ b/tests/brokers/kafka/test_middlewares.py @@ -1,3 +1,5 @@ +from typing import Any + import pytest from faststream.kafka import KafkaBroker @@ -9,9 +11,11 @@ @pytest.mark.kafka class TestMiddlewares(MiddlewareTestcase): - broker_class = KafkaBroker + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: + return KafkaBroker(apply_types=apply_types, **kwargs) @pytest.mark.kafka class TestExceptionMiddlewares(ExceptionMiddlewareTestcase): - broker_class = KafkaBroker + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: + return KafkaBroker(apply_types=apply_types, **kwargs) diff --git a/tests/brokers/kafka/test_parser.py b/tests/brokers/kafka/test_parser.py index 1725c15e6c..d27095d351 100644 --- a/tests/brokers/kafka/test_parser.py +++ b/tests/brokers/kafka/test_parser.py @@ -1,3 +1,5 @@ +from typing import Any + import pytest from faststream.kafka import KafkaBroker @@ -6,4 +8,5 @@ @pytest.mark.kafka class TestCustomParser(CustomParserTestcase): - broker_class = KafkaBroker + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: + return KafkaBroker(apply_types=apply_types, **kwargs) diff --git a/tests/brokers/kafka/test_publish.py b/tests/brokers/kafka/test_publish.py index 5040a8662f..5dcfe797c0 100644 --- a/tests/brokers/kafka/test_publish.py +++ b/tests/brokers/kafka/test_publish.py @@ -1,4 +1,5 @@ import asyncio +from typing import Any from unittest.mock import Mock import pytest @@ -10,8 +11,8 @@ @pytest.mark.kafka class TestPublish(BrokerPublishTestcase): - def get_broker(self, apply_types: bool = False): - return KafkaBroker(apply_types=apply_types) + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: + return KafkaBroker(apply_types=apply_types, **kwargs) @pytest.mark.asyncio async def test_publish_batch(self, queue: str): diff --git a/tests/brokers/kafka/test_requests.py b/tests/brokers/kafka/test_requests.py index a518b2fa43..a44f41aad4 100644 --- a/tests/brokers/kafka/test_requests.py +++ b/tests/brokers/kafka/test_requests.py @@ -1,3 +1,5 @@ +from typing import Any + import pytest from faststream import BaseMiddleware @@ -16,14 +18,14 @@ async def consume_scope(self, call_next, msg): @pytest.mark.asyncio class TestRequestTestClient(RequestsTestcase): - def get_middleware(self, **kwargs): + def get_middleware(self, **kwargs: Any): return Mid - def get_broker(self, **kwargs): - return KafkaBroker(**kwargs) - - def get_router(self, **kwargs): + def get_router(self, **kwargs: Any): return KafkaRouter(**kwargs) - def patch_broker(self, broker, **kwargs): + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: + return KafkaBroker(apply_types=apply_types, **kwargs) + + def patch_broker(self, broker: KafkaBroker, **kwargs: Any) -> TestKafkaBroker: return TestKafkaBroker(broker, **kwargs) diff --git a/tests/brokers/kafka/test_router.py b/tests/brokers/kafka/test_router.py index 17ef78d942..48573b9da2 100644 --- a/tests/brokers/kafka/test_router.py +++ b/tests/brokers/kafka/test_router.py @@ -1,6 +1,14 @@ +from typing import Any + import pytest -from faststream.kafka import KafkaPublisher, KafkaRoute, KafkaRouter +from faststream.kafka import ( + KafkaBroker, + KafkaPublisher, + KafkaRoute, + KafkaRouter, + TestKafkaBroker, +) from tests.brokers.base.router import RouterLocalTestcase, RouterTestcase @@ -10,8 +18,17 @@ class TestRouter(RouterTestcase): route_class = KafkaRoute publisher_class = KafkaPublisher + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: + return KafkaBroker(apply_types=apply_types, **kwargs) + class TestRouterLocal(RouterLocalTestcase): broker_class = KafkaRouter route_class = KafkaRoute publisher_class = KafkaPublisher + + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: + return KafkaBroker(apply_types=apply_types, **kwargs) + + def patch_broker(self, broker: KafkaBroker, **kwargs: Any) -> TestKafkaBroker: + return TestKafkaBroker(broker, **kwargs) diff --git a/tests/brokers/kafka/test_test_client.py b/tests/brokers/kafka/test_test_client.py index 27fa522a11..ce439a1df4 100644 --- a/tests/brokers/kafka/test_test_client.py +++ b/tests/brokers/kafka/test_test_client.py @@ -1,4 +1,5 @@ import asyncio +from typing import Any from unittest.mock import patch import pytest @@ -14,16 +15,11 @@ @pytest.mark.asyncio class TestTestclient(BrokerTestclientTestcase): - test_class = TestKafkaBroker + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: + return KafkaBroker(apply_types=apply_types, **kwargs) - def get_broker(self, apply_types: bool = False): - return KafkaBroker(apply_types=apply_types) - - def patch_broker(self, broker: KafkaBroker) -> TestKafkaBroker: - return TestKafkaBroker(broker) - - def get_fake_producer_class(self) -> type: - return FakeProducer + def patch_broker(self, broker: KafkaBroker, **kwargs: Any) -> TestKafkaBroker: + return TestKafkaBroker(broker, **kwargs) async def test_partition_match( self, @@ -104,7 +100,7 @@ async def test_with_real_testclient( def subscriber(m): event.set() - async with TestKafkaBroker(broker, with_real=True) as br: + async with self.patch_broker(broker, with_real=True) as br: await asyncio.wait( ( asyncio.create_task(br.publish("hello", queue)), @@ -125,7 +121,7 @@ async def test_batch_pub_by_default_pub( async def m(msg): pass - async with TestKafkaBroker(broker) as br: + async with self.patch_broker(broker) as br: await br.publish("hello", queue) m.mock.assert_called_once_with(["hello"]) @@ -139,7 +135,7 @@ async def test_batch_pub_by_pub_batch( async def m(msg): pass - async with TestKafkaBroker(broker) as br: + async with self.patch_broker(broker) as br: await br.publish_batch("hello", topic=queue) m.mock.assert_called_once_with(["hello"]) @@ -156,7 +152,7 @@ async def test_batch_publisher_mock( async def m(msg): return 1, 2, 3 - async with TestKafkaBroker(broker) as br: + async with self.patch_broker(broker) as br: await br.publish("hello", queue) m.mock.assert_called_once_with("hello") publisher.mock.assert_called_once_with([1, 2, 3]) @@ -169,15 +165,15 @@ async def on_receive(self) -> None: routes.append(None) return await super().on_receive() - broker = KafkaBroker(middlewares=(Middleware,)) + broker = self.get_broker(middlewares=(Middleware,)) @broker.subscriber(queue) - async def h1(): ... + async def h1(msg): ... @broker.subscriber(queue + "1") - async def h2(): ... + async def h2(msg): ... - async with TestKafkaBroker(broker) as br: + async with self.patch_broker(broker) as br: await br.publish("", queue) await br.publish("", queue + "1") @@ -192,15 +188,15 @@ async def on_receive(self) -> None: routes.append(None) return await super().on_receive() - broker = KafkaBroker(middlewares=(Middleware,)) + broker = self.get_broker(middlewares=(Middleware,)) @broker.subscriber(queue) - async def h1(): ... + async def h1(msg): ... @broker.subscriber(queue + "1") - async def h2(): ... + async def h2(msg): ... - async with TestKafkaBroker(broker, with_real=True) as br: + async with self.patch_broker(broker, with_real=True) as br: await br.publish("", queue) await br.publish("", queue + "1") await h1.wait_call(3) @@ -211,74 +207,82 @@ async def h2(): ... async def test_multiple_subscribers_different_groups( self, queue: str, - test_broker: KafkaBroker, ): + test_broker = self.get_broker() + @test_broker.subscriber(queue, group_id="group1") - async def subscriber1(): ... + async def subscriber1(msg): ... @test_broker.subscriber(queue, group_id="group2") - async def subscriber2(): ... + async def subscriber2(msg): ... - await test_broker.start() - await test_broker.publish("", queue) + async with self.patch_broker(test_broker) as br: + await br.start() + await br.publish("", queue) - assert subscriber1.mock.call_count == 1 - assert subscriber2.mock.call_count == 1 + assert subscriber1.mock.call_count == 1 + assert subscriber2.mock.call_count == 1 async def test_multiple_subscribers_same_group( self, queue: str, - test_broker: KafkaBroker, ): - @test_broker.subscriber(queue, group_id="group1") - async def subscriber1(): ... + broker = self.get_broker() - @test_broker.subscriber(queue, group_id="group1") - async def subscriber2(): ... + @broker.subscriber(queue, group_id="group1") + async def subscriber1(msg): ... - await test_broker.start() - await test_broker.publish("", queue) + @broker.subscriber(queue, group_id="group1") + async def subscriber2(msg): ... - assert subscriber1.mock.call_count == 1 - assert subscriber2.mock.call_count == 0 + async with self.patch_broker(broker) as br: + await br.start() + await br.publish("", queue) + + assert subscriber1.mock.call_count == 1 + assert subscriber2.mock.call_count == 0 async def test_multiple_batch_subscriber_with_different_group( self, queue: str, - test_broker: KafkaBroker, ): - @test_broker.subscriber(queue, batch=True, group_id="group1") - async def subscriber1(): ... + broker = self.get_broker() - @test_broker.subscriber(queue, batch=True, group_id="group2") - async def subscriber2(): ... + @broker.subscriber(queue, batch=True, group_id="group1") + async def subscriber1(msg): ... - await test_broker.start() - await test_broker.publish("", queue) + @broker.subscriber(queue, batch=True, group_id="group2") + async def subscriber2(msg): ... - assert subscriber1.mock.call_count == 1 - assert subscriber2.mock.call_count == 1 + async with self.patch_broker(broker) as br: + await br.start() + await br.publish("", queue) + + assert subscriber1.mock.call_count == 1 + assert subscriber2.mock.call_count == 1 async def test_multiple_batch_subscriber_with_same_group( self, queue: str, - test_broker: KafkaBroker, ): - @test_broker.subscriber(queue, batch=True, group_id="group1") - async def subscriber1(): ... + broker = self.get_broker() + + @broker.subscriber(queue, batch=True, group_id="group1") + async def subscriber1(msg): ... - @test_broker.subscriber(queue, batch=True, group_id="group1") - async def subscriber2(): ... + @broker.subscriber(queue, batch=True, group_id="group1") + async def subscriber2(msg): ... - await test_broker.start() - await test_broker.publish("", queue) + async with self.patch_broker(broker) as br: + await br.start() + await br.publish("", queue) - assert subscriber1.mock.call_count == 1 - assert subscriber2.mock.call_count == 0 + assert subscriber1.mock.call_count == 1 + assert subscriber2.mock.call_count == 0 @pytest.mark.kafka async def test_broker_gets_patched_attrs_within_cm(self): - await super().test_broker_gets_patched_attrs_within_cm() + await super().test_broker_gets_patched_attrs_within_cm(FakeProducer) @pytest.mark.kafka async def test_broker_with_real_doesnt_get_patched(self): diff --git a/tests/brokers/nats/conftest.py b/tests/brokers/nats/conftest.py index 253cd709f2..1222cfc21f 100644 --- a/tests/brokers/nats/conftest.py +++ b/tests/brokers/nats/conftest.py @@ -1,14 +1,8 @@ from dataclasses import dataclass import pytest -import pytest_asyncio -from faststream.nats import ( - JStream, - NatsBroker, - NatsRouter, - TestNatsBroker, -) +from faststream.nats import JStream, NatsRouter @dataclass @@ -29,24 +23,3 @@ def stream(queue): @pytest.fixture def router(): return NatsRouter() - - -@pytest_asyncio.fixture() -async def broker(settings): - broker = NatsBroker([settings.url], apply_types=False) - async with broker: - yield broker - - -@pytest_asyncio.fixture() -async def full_broker(settings): - broker = NatsBroker([settings.url]) - async with broker: - yield broker - - -@pytest_asyncio.fixture() -async def test_broker(): - broker = NatsBroker() - async with TestNatsBroker(broker) as br: - yield br diff --git a/tests/brokers/nats/test_consume.py b/tests/brokers/nats/test_consume.py index a8b9778e4d..103cda134b 100644 --- a/tests/brokers/nats/test_consume.py +++ b/tests/brokers/nats/test_consume.py @@ -1,4 +1,5 @@ import asyncio +from typing import Any from unittest.mock import Mock, patch import pytest @@ -13,8 +14,8 @@ @pytest.mark.nats class TestConsume(BrokerRealConsumeTestcase): - def get_broker(self, apply_types: bool = False) -> NatsBroker: - return NatsBroker(apply_types=apply_types) + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> NatsBroker: + return NatsBroker(apply_types=apply_types, **kwargs) async def test_consume_js( self, diff --git a/tests/brokers/nats/test_fastapi.py b/tests/brokers/nats/test_fastapi.py index 3c7f5f205b..b286bdbe93 100644 --- a/tests/brokers/nats/test_fastapi.py +++ b/tests/brokers/nats/test_fastapi.py @@ -1,12 +1,11 @@ import asyncio -from typing import List +from typing import Any, List from unittest.mock import MagicMock import pytest -from faststream.nats import JStream, NatsRouter, PullSub +from faststream.nats import JStream, NatsBroker, NatsRouter, PullSub, TestNatsBroker from faststream.nats.fastapi import NatsRouter as StreamRouter -from faststream.nats.testing import TestNatsBroker, build_message from tests.brokers.base.fastapi import FastAPILocalTestcase, FastAPITestcase @@ -23,7 +22,7 @@ async def test_path( ): router = self.router_class() - @router.subscriber("in.{name}") + @router.subscriber(queue + ".{name}") def subscriber(msg: str, name: str): mock(msg=msg, name=name) event.set() @@ -32,7 +31,9 @@ def subscriber(msg: str, name: str): await router.broker.start() await asyncio.wait( ( - asyncio.create_task(router.broker.publish("hello", "in.john")), + asyncio.create_task( + router.broker.publish("hello", f"{queue}.john") + ), asyncio.create_task(event.wait()), ), timeout=3, @@ -76,8 +77,9 @@ def subscriber(m: List[str]): class TestRouterLocal(FastAPILocalTestcase): router_class = StreamRouter broker_router_class = NatsRouter - broker_test = staticmethod(TestNatsBroker) - build_message = staticmethod(build_message) + + def patch_broker(self, broker: NatsBroker, **kwargs: Any) -> NatsBroker: + return TestNatsBroker(broker, **kwargs) async def test_consume_batch( self, @@ -97,10 +99,10 @@ def subscriber(m: List[str]): mock(m) event.set() - async with self.broker_test(router.broker): + async with self.patch_broker(router.broker) as br: await asyncio.wait( ( - asyncio.create_task(router.broker.publish(b"hello", queue)), + asyncio.create_task(br.publish(b"hello", queue)), asyncio.create_task(event.wait()), ), timeout=3, @@ -116,8 +118,8 @@ async def test_path(self, queue: str): async def hello(name): return name - async with self.broker_test(router.broker): - r = await router.broker.request( + async with self.patch_broker(router.broker) as br: + r = await br.request( "hi", f"{queue}.john", timeout=0.5, diff --git a/tests/brokers/nats/test_middlewares.py b/tests/brokers/nats/test_middlewares.py index e1768dba88..ef9e609b31 100644 --- a/tests/brokers/nats/test_middlewares.py +++ b/tests/brokers/nats/test_middlewares.py @@ -1,3 +1,5 @@ +from typing import Any + import pytest from faststream.nats import NatsBroker @@ -9,9 +11,11 @@ @pytest.mark.nats class TestMiddlewares(MiddlewareTestcase): - broker_class = NatsBroker + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> NatsBroker: + return NatsBroker(apply_types=apply_types, **kwargs) @pytest.mark.nats class TestExceptionMiddlewares(ExceptionMiddlewareTestcase): - broker_class = NatsBroker + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> NatsBroker: + return NatsBroker(apply_types=apply_types, **kwargs) diff --git a/tests/brokers/nats/test_parser.py b/tests/brokers/nats/test_parser.py index a50b4d4d18..938b9b19fa 100644 --- a/tests/brokers/nats/test_parser.py +++ b/tests/brokers/nats/test_parser.py @@ -1,3 +1,5 @@ +from typing import Any + import pytest from faststream.nats import NatsBroker @@ -6,4 +8,5 @@ @pytest.mark.nats class TestCustomParser(CustomParserTestcase): - broker_class = NatsBroker + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> NatsBroker: + return NatsBroker(apply_types=apply_types, **kwargs) diff --git a/tests/brokers/nats/test_publish.py b/tests/brokers/nats/test_publish.py index e8af505124..92f3b994fc 100644 --- a/tests/brokers/nats/test_publish.py +++ b/tests/brokers/nats/test_publish.py @@ -12,8 +12,8 @@ class TestPublish(BrokerPublishTestcase): """Test publish method of NATS broker.""" - def get_broker(self, apply_types: bool = False) -> NatsBroker: - return NatsBroker(apply_types=apply_types) + def get_broker(self, apply_types: bool = False, **kwargs) -> NatsBroker: + return NatsBroker(apply_types=apply_types, **kwargs) @pytest.mark.asyncio async def test_response( diff --git a/tests/brokers/nats/test_requests.py b/tests/brokers/nats/test_requests.py index 19f9c2cb15..e8f626e99e 100644 --- a/tests/brokers/nats/test_requests.py +++ b/tests/brokers/nats/test_requests.py @@ -1,3 +1,5 @@ +from typing import Any + import pytest from faststream import BaseMiddleware @@ -19,8 +21,8 @@ class NatsRequestsTestcase(RequestsTestcase): def get_middleware(self, **kwargs): return Mid - def get_broker(self, **kwargs): - return NatsBroker(**kwargs) + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> NatsBroker: + return NatsBroker(apply_types=apply_types, **kwargs) def get_router(self, **kwargs): return NatsRouter(**kwargs) diff --git a/tests/brokers/nats/test_router.py b/tests/brokers/nats/test_router.py index c69c3e0bd9..341c6f35be 100644 --- a/tests/brokers/nats/test_router.py +++ b/tests/brokers/nats/test_router.py @@ -1,9 +1,17 @@ import asyncio +from typing import Any import pytest from faststream import Path -from faststream.nats import JStream, NatsBroker, NatsPublisher, NatsRoute, NatsRouter +from faststream.nats import ( + JStream, + NatsBroker, + NatsPublisher, + NatsRoute, + NatsRouter, + TestNatsBroker, +) from tests.brokers.base.router import RouterLocalTestcase, RouterTestcase @@ -13,13 +21,17 @@ class TestRouter(RouterTestcase): route_class = NatsRoute publisher_class = NatsPublisher + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> NatsBroker: + return NatsBroker(apply_types=apply_types, **kwargs) + async def test_router_path( self, event, mock, router: NatsRouter, - pub_broker, ): + pub_broker = self.get_broker(apply_types=True) + @router.subscriber("in.{name}.{id}") async def h( name: str = Path(), @@ -28,7 +40,6 @@ async def h( event.set() mock(name=name, id=id) - pub_broker._is_apply_types = True pub_broker.include_router(router) await pub_broker.start() @@ -43,8 +54,9 @@ async def test_path_as_first_with_prefix( event, mock, router: NatsRouter, - pub_broker, ): + pub_broker = self.get_broker(apply_types=True) + router.prefix = "root." @router.subscriber("{name}.nested") @@ -52,7 +64,6 @@ async def h(name: str = Path()): event.set() mock(name=name) - pub_broker._is_apply_types = True pub_broker.include_router(router) await pub_broker.start() @@ -67,8 +78,9 @@ async def test_router_path_with_prefix( event, mock, router: NatsRouter, - pub_broker, ): + pub_broker = self.get_broker(apply_types=True) + router.prefix = "test." @router.subscriber("in.{name}.{id}") @@ -79,7 +91,6 @@ async def h( event.set() mock(name=name, id=id) - pub_broker._is_apply_types = True pub_broker.include_router(router) await pub_broker.start() @@ -94,8 +105,9 @@ async def test_router_delay_handler_path( event, mock, router: NatsRouter, - pub_broker, ): + pub_broker = self.get_broker(apply_types=True) + async def h( name: str = Path(), id: int = Path("id"), @@ -105,7 +117,6 @@ async def h( r = type(router)(handlers=(self.route_class(h, subject="in.{name}.{id}"),)) - pub_broker._is_apply_types = True pub_broker.include_router(r) await pub_broker.start() @@ -120,8 +131,9 @@ async def test_delayed_handlers_with_queue( event, router: NatsRouter, queue: str, - pub_broker, ): + pub_broker = self.get_broker() + def response(m): event.set() @@ -145,15 +157,21 @@ def response(m): class TestRouterLocal(RouterLocalTestcase): - broker_class = NatsRouter route_class = NatsRoute publisher_class = NatsPublisher + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> NatsBroker: + return NatsBroker(apply_types=apply_types, **kwargs) + + def patch_broker(self, broker: NatsBroker, **kwargs: Any) -> NatsBroker: + return TestNatsBroker(broker, **kwargs) + async def test_include_stream( self, router: NatsRouter, - pub_broker: NatsBroker, ): + pub_broker = self.get_broker() + @router.subscriber("test", stream="stream") async def handler(): ... @@ -175,7 +193,7 @@ async def test_include_stream_with_subjects(self): router.include_router(sub_router) - broker = NatsBroker() + broker = self.get_broker() broker.include_router(router) assert set(stream.subjects) == { diff --git a/tests/brokers/nats/test_test_client.py b/tests/brokers/nats/test_test_client.py index 28c8526c25..8046e85ad3 100644 --- a/tests/brokers/nats/test_test_client.py +++ b/tests/brokers/nats/test_test_client.py @@ -1,37 +1,39 @@ import asyncio +from typing import Any import pytest from faststream import BaseMiddleware -from faststream.nats import ConsumerConfig, JStream, NatsBroker, PullSub, TestNatsBroker +from faststream.nats import ( + ConsumerConfig, + JStream, + NatsBroker, + PullSub, + TestNatsBroker, +) from faststream.nats.testing import FakeProducer from tests.brokers.base.testclient import BrokerTestclientTestcase @pytest.mark.asyncio class TestTestclient(BrokerTestclientTestcase): - test_class = TestNatsBroker + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> NatsBroker: + return NatsBroker(apply_types=apply_types, **kwargs) - def get_broker(self, apply_types: bool = False) -> NatsBroker: - return NatsBroker(apply_types=apply_types) - - def patch_broker(self, broker: NatsBroker) -> TestNatsBroker: - return TestNatsBroker(broker) - - def get_fake_producer_class(self) -> type: - return FakeProducer + def patch_broker(self, broker: NatsBroker, **kwargs: Any) -> NatsBroker: + return TestNatsBroker(broker, **kwargs) @pytest.mark.asyncio async def test_stream_publish( self, queue: str, ): - pub_broker = NatsBroker(apply_types=False) + pub_broker = self.get_broker(apply_types=False) @pub_broker.subscriber(queue, stream="test") async def m(msg): ... - async with TestNatsBroker(pub_broker) as br: + async with self.patch_broker(pub_broker) as br: await br.publish("Hi!", queue, stream="test") m.mock.assert_called_once_with("Hi!") @@ -40,12 +42,12 @@ async def test_wrong_stream_publish( self, queue: str, ): - pub_broker = NatsBroker(apply_types=False) + pub_broker = self.get_broker(apply_types=False) @pub_broker.subscriber(queue) async def m(msg): ... - async with TestNatsBroker(pub_broker) as br: + async with self.patch_broker(pub_broker) as br: await br.publish("Hi!", queue, stream="test") assert not m.mock.called @@ -61,7 +63,7 @@ async def test_with_real_testclient( def subscriber(m): event.set() - async with TestNatsBroker(broker, with_real=True) as br: + async with self.patch_broker(broker, with_real=True) as br: await asyncio.wait( ( asyncio.create_task(br.publish("hello", queue)), @@ -77,9 +79,9 @@ async def test_inbox_prefix_with_real( self, queue: str, ): - broker = NatsBroker(inbox_prefix="test") + broker = self.get_broker(inbox_prefix="test") - async with TestNatsBroker(broker, with_real=True) as br: + async with self.patch_broker(broker, with_real=True) as br: assert br._connection._inbox_prefix == b"test" assert "test" in str(br._connection.new_inbox()) @@ -91,15 +93,15 @@ async def on_receive(self) -> None: routes.append(None) return await super().on_receive() - broker = NatsBroker(middlewares=(Middleware,)) + broker = self.get_broker(middlewares=(Middleware,)) @broker.subscriber(queue) - async def h1(): ... + async def h1(m): ... @broker.subscriber(queue + "1") - async def h2(): ... + async def h2(m): ... - async with TestNatsBroker(broker) as br: + async with self.patch_broker(broker) as br: await br.publish("", queue) await br.publish("", queue + "1") @@ -114,15 +116,15 @@ async def on_receive(self) -> None: routes.append(None) return await super().on_receive() - broker = NatsBroker(middlewares=(Middleware,)) + broker = self.get_broker(middlewares=(Middleware,)) @broker.subscriber(queue) - async def h1(): ... + async def h1(m): ... @broker.subscriber(queue + "1") - async def h2(): ... + async def h2(m): ... - async with TestNatsBroker(broker, with_real=True) as br: + async with self.patch_broker(broker, with_real=True) as br: await br.publish("", queue) await br.publish("", queue + "1") await h1.wait_call(3) @@ -141,7 +143,7 @@ async def test_js_subscriber_mock( async def m(msg): pass - async with TestNatsBroker(broker) as br: + async with self.patch_broker(broker) as br: await br.publish("hello", queue, stream=stream.name) m.mock.assert_called_once_with("hello") @@ -159,7 +161,7 @@ async def test_js_publisher_mock( async def m(msg): return "response" - async with TestNatsBroker(broker) as br: + async with self.patch_broker(broker) as br: await br.publish("hello", queue, stream=stream.name) publisher.mock.assert_called_with("response") @@ -169,7 +171,7 @@ async def test_any_subject_routing(self): @broker.subscriber("test.*.subj.*") def subscriber(msg): ... - async with TestNatsBroker(broker) as br: + async with self.patch_broker(broker) as br: await br.publish("hello", "test.a.subj.b") subscriber.mock.assert_called_once_with("hello") @@ -179,7 +181,7 @@ async def test_ending_subject_routing(self): @broker.subscriber("test.>") def subscriber(msg): ... - async with TestNatsBroker(broker) as br: + async with self.patch_broker(broker) as br: await br.publish("hello", "test.a.subj.b") subscriber.mock.assert_called_once_with("hello") @@ -189,7 +191,7 @@ async def test_mixed_subject_routing(self): @broker.subscriber("*.*.subj.>") def subscriber(msg): ... - async with TestNatsBroker(broker) as br: + async with self.patch_broker(broker) as br: await br.publish("hello", "test.a.subj.b.c") subscriber.mock.assert_called_once_with("hello") @@ -203,7 +205,7 @@ async def test_consume_pull( @broker.subscriber(queue, stream=stream, pull_sub=PullSub(1)) def subscriber(m): ... - async with TestNatsBroker(broker) as br: + async with self.patch_broker(broker) as br: await br.publish("hello", queue) subscriber.mock.assert_called_once_with("hello") @@ -222,7 +224,7 @@ async def test_consume_batch( def subscriber(m): pass - async with TestNatsBroker(broker) as br: + async with self.patch_broker(broker) as br: await br.publish("hello", queue) subscriber.mock.assert_called_once_with(["hello"]) @@ -239,14 +241,14 @@ async def test_consume_with_filter( def subscriber(m): pass - async with TestNatsBroker(broker) as br: + async with self.patch_broker(broker) as br: await br.publish(1, f"{queue}.b") await br.publish(2, f"{queue}.a") subscriber.mock.assert_called_once_with(2) @pytest.mark.nats async def test_broker_gets_patched_attrs_within_cm(self): - await super().test_broker_gets_patched_attrs_within_cm() + await super().test_broker_gets_patched_attrs_within_cm(FakeProducer) @pytest.mark.nats async def test_broker_with_real_doesnt_get_patched(self): diff --git a/tests/brokers/rabbit/conftest.py b/tests/brokers/rabbit/conftest.py index 00ff9bcde3..9a3d18e7ef 100644 --- a/tests/brokers/rabbit/conftest.py +++ b/tests/brokers/rabbit/conftest.py @@ -1,13 +1,10 @@ from dataclasses import dataclass import pytest -import pytest_asyncio from faststream.rabbit import ( - RabbitBroker, RabbitExchange, RabbitRouter, - TestRabbitBroker, ) @@ -36,24 +33,3 @@ def settings(): @pytest.fixture def router(): return RabbitRouter() - - -@pytest_asyncio.fixture() -async def broker(settings): - broker = RabbitBroker(settings.url, apply_types=False) - async with broker: - yield broker - - -@pytest_asyncio.fixture() -async def full_broker(settings): - broker = RabbitBroker(settings.url) - async with broker: - yield broker - - -@pytest_asyncio.fixture() -async def test_broker(): - broker = RabbitBroker() - async with TestRabbitBroker(broker) as br: - yield br diff --git a/tests/brokers/rabbit/core/test_depends.py b/tests/brokers/rabbit/core/test_depends.py index 21f498d268..6a92636108 100644 --- a/tests/brokers/rabbit/core/test_depends.py +++ b/tests/brokers/rabbit/core/test_depends.py @@ -8,10 +8,9 @@ @pytest.mark.asyncio @pytest.mark.rabbit -async def test_broker_depends( - queue, - full_broker: RabbitBroker, -): +async def test_broker_depends(queue: str): + full_broker = RabbitBroker(apply_types=True) + def sync_depends(message: RabbitMessage): return message @@ -43,8 +42,9 @@ async def h( @pytest.mark.rabbit async def test_different_consumers_has_different_messages( context, - full_broker: RabbitBroker, ): + full_broker = RabbitBroker(apply_types=True) + message1 = None @full_broker.subscriber("test_different_consume_1") diff --git a/tests/brokers/rabbit/specific/test_nested_exchange.py b/tests/brokers/rabbit/specific/test_nested_exchange.py index d0fbe5a031..2b830f3e17 100644 --- a/tests/brokers/rabbit/specific/test_nested_exchange.py +++ b/tests/brokers/rabbit/specific/test_nested_exchange.py @@ -2,12 +2,14 @@ import pytest -from faststream.rabbit import ExchangeType, RabbitBroker, RabbitExchange, RabbitQueue +from faststream.rabbit import ExchangeType, RabbitBroker, RabbitExchange @pytest.mark.asyncio @pytest.mark.rabbit -async def test_bind_to(queue: RabbitQueue, broker: RabbitBroker): +async def test_bind_to(queue: str): + broker = RabbitBroker(apply_types=False) + consume = Event() async with broker: diff --git a/tests/brokers/rabbit/test_consume.py b/tests/brokers/rabbit/test_consume.py index cd2550429c..774af65d8c 100644 --- a/tests/brokers/rabbit/test_consume.py +++ b/tests/brokers/rabbit/test_consume.py @@ -1,4 +1,5 @@ import asyncio +from typing import Any from unittest.mock import patch import pytest @@ -13,8 +14,8 @@ @pytest.mark.rabbit class TestConsume(BrokerRealConsumeTestcase): - def get_broker(self, apply_types: bool = False) -> RabbitBroker: - return RabbitBroker(apply_types=apply_types) + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RabbitBroker: + return RabbitBroker(apply_types=apply_types, **kwargs) @pytest.mark.asyncio async def test_consume_from_exchange( diff --git a/tests/brokers/rabbit/test_fastapi.py b/tests/brokers/rabbit/test_fastapi.py index 0dd0fcef52..747e2c5610 100644 --- a/tests/brokers/rabbit/test_fastapi.py +++ b/tests/brokers/rabbit/test_fastapi.py @@ -5,7 +5,7 @@ from faststream.rabbit import ExchangeType, RabbitExchange, RabbitQueue, RabbitRouter from faststream.rabbit.fastapi import RabbitRouter as StreamRouter -from faststream.rabbit.testing import TestRabbitBroker, build_message +from faststream.rabbit.testing import TestRabbitBroker from tests.brokers.base.fastapi import FastAPILocalTestcase, FastAPITestcase @@ -57,8 +57,9 @@ def subscriber(msg: str, name: str): class TestRouterLocal(FastAPILocalTestcase): router_class = StreamRouter broker_router_class = RabbitRouter - broker_test = staticmethod(TestRabbitBroker) - build_message = staticmethod(build_message) + + def patch_broker(self, broker, **kwargs): + return TestRabbitBroker(broker, **kwargs) async def test_path(self): router = self.router_class() @@ -76,8 +77,8 @@ async def test_path(self): async def hello(name): return name - async with self.broker_test(router.broker): - r = await router.broker.request( + async with self.patch_broker(router.broker) as br: + r = await br.request( "hi", "in.john", "test", diff --git a/tests/brokers/rabbit/test_middlewares.py b/tests/brokers/rabbit/test_middlewares.py index 72e48958ee..e94c047d08 100644 --- a/tests/brokers/rabbit/test_middlewares.py +++ b/tests/brokers/rabbit/test_middlewares.py @@ -1,3 +1,5 @@ +from typing import Any + import pytest from faststream.rabbit import RabbitBroker @@ -9,9 +11,11 @@ @pytest.mark.rabbit class TestMiddlewares(MiddlewareTestcase): - broker_class = RabbitBroker + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RabbitBroker: + return RabbitBroker(apply_types=apply_types, **kwargs) @pytest.mark.rabbit class TestExceptionMiddlewares(ExceptionMiddlewareTestcase): - broker_class = RabbitBroker + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RabbitBroker: + return RabbitBroker(apply_types=apply_types, **kwargs) diff --git a/tests/brokers/rabbit/test_parser.py b/tests/brokers/rabbit/test_parser.py index 038f43ac93..a74bdf5d4e 100644 --- a/tests/brokers/rabbit/test_parser.py +++ b/tests/brokers/rabbit/test_parser.py @@ -1,3 +1,5 @@ +from typing import Any + import pytest from faststream.rabbit import RabbitBroker @@ -6,4 +8,5 @@ @pytest.mark.rabbit class TestCustomParser(CustomParserTestcase): - broker_class = RabbitBroker + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RabbitBroker: + return RabbitBroker(apply_types=apply_types, **kwargs) diff --git a/tests/brokers/rabbit/test_publish.py b/tests/brokers/rabbit/test_publish.py index 1e68f8ac1e..d049b71267 100644 --- a/tests/brokers/rabbit/test_publish.py +++ b/tests/brokers/rabbit/test_publish.py @@ -1,4 +1,5 @@ import asyncio +from typing import Any from unittest.mock import Mock, patch import pytest @@ -12,8 +13,8 @@ @pytest.mark.rabbit class TestPublish(BrokerPublishTestcase): - def get_broker(self, apply_types: bool = False) -> RabbitBroker: - return RabbitBroker(apply_types=apply_types) + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RabbitBroker: + return RabbitBroker(apply_types=apply_types, **kwargs) @pytest.mark.asyncio async def test_reply_config( diff --git a/tests/brokers/rabbit/test_requests.py b/tests/brokers/rabbit/test_requests.py index c0927eabc8..99ad9910ff 100644 --- a/tests/brokers/rabbit/test_requests.py +++ b/tests/brokers/rabbit/test_requests.py @@ -1,3 +1,5 @@ +from typing import Any + import pytest from faststream import BaseMiddleware @@ -20,8 +22,8 @@ class RabbitRequestsTestcase(RequestsTestcase): def get_middleware(self, **kwargs): return Mid - def get_broker(self, **kwargs): - return RabbitBroker(**kwargs) + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RabbitBroker: + return RabbitBroker(apply_types=apply_types, **kwargs) def get_router(self, **kwargs): return RabbitRouter(**kwargs) diff --git a/tests/brokers/rabbit/test_router.py b/tests/brokers/rabbit/test_router.py index 2d58bab9e9..1cde6673df 100644 --- a/tests/brokers/rabbit/test_router.py +++ b/tests/brokers/rabbit/test_router.py @@ -1,4 +1,5 @@ import asyncio +from typing import Any import pytest @@ -11,6 +12,7 @@ RabbitQueue, RabbitRoute, RabbitRouter, + TestRabbitBroker, ) from tests.brokers.base.router import RouterLocalTestcase, RouterTestcase @@ -21,13 +23,15 @@ class TestRouter(RouterTestcase): route_class = RabbitRoute publisher_class = RabbitPublisher + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RabbitBroker: + return RabbitBroker(apply_types=apply_types, **kwargs) + async def test_router_path( self, queue, event, mock, router, - pub_broker, ): @router.subscriber( RabbitQueue( @@ -46,7 +50,7 @@ async def h( event.set() mock(name=name, id=id) - pub_broker._is_apply_types = True + pub_broker = self.get_broker(apply_types=True) pub_broker.include_router(router) await pub_broker.start() @@ -66,7 +70,6 @@ async def test_router_delay_handler_path( event, mock, router, - pub_broker, ): async def h( name: str = Path(), @@ -91,7 +94,7 @@ async def h( ) ) - pub_broker._is_apply_types = True + pub_broker = self.get_broker(apply_types=True) pub_broker.include_router(r) await pub_broker.start() @@ -108,10 +111,11 @@ async def h( async def test_queue_obj( self, router: RabbitRouter, - broker: RabbitBroker, queue: str, event: asyncio.Event, ): + broker = self.get_broker() + router.prefix = "test/" r_queue = RabbitQueue(queue) @@ -140,10 +144,11 @@ def subscriber(m): async def test_queue_obj_with_routing_key( self, router: RabbitRouter, - broker: RabbitBroker, queue: str, event: asyncio.Event, ): + broker = self.get_broker() + router.prefix = "test/" r_queue = RabbitQueue("useless", routing_key=f"{queue}1") @@ -175,7 +180,6 @@ async def test_delayed_handlers_with_queue( event: asyncio.Event, router: RabbitRouter, queue: str, - pub_broker: RabbitBroker, ): def response(m): event.set() @@ -186,6 +190,7 @@ def response(m): prefix="test/", handlers=(self.route_class(response, queue=r_queue),) ) + pub_broker = self.get_broker() pub_broker.include_router(r) async with pub_broker: @@ -208,3 +213,9 @@ class TestRouterLocal(RouterLocalTestcase): broker_class = RabbitRouter route_class = RabbitRoute publisher_class = RabbitPublisher + + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RabbitBroker: + return RabbitBroker(apply_types=apply_types, **kwargs) + + def patch_broker(self, broker: RabbitBroker, **kwargs: Any) -> RabbitBroker: + return TestRabbitBroker(broker, **kwargs) diff --git a/tests/brokers/rabbit/test_test_client.py b/tests/brokers/rabbit/test_test_client.py index c2970a4107..ad0317eba5 100644 --- a/tests/brokers/rabbit/test_test_client.py +++ b/tests/brokers/rabbit/test_test_client.py @@ -1,4 +1,5 @@ import asyncio +from typing import Any import pytest @@ -20,14 +21,11 @@ class TestTestclient(BrokerTestclientTestcase): test_class = TestRabbitBroker - def get_broker(self, apply_types: bool = False) -> RabbitBroker: - return RabbitBroker(apply_types=apply_types) + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RabbitBroker: + return RabbitBroker(apply_types=apply_types, **kwargs) - def patch_broker(self, broker: RabbitBroker) -> RabbitBroker: - return TestRabbitBroker(broker) - - def get_fake_producer_class(self) -> type: - return FakeProducer + def patch_broker(self, broker: RabbitBroker, **kwargs: Any) -> RabbitBroker: + return TestRabbitBroker(broker, **kwargs) @pytest.mark.rabbit async def test_with_real_testclient( @@ -41,7 +39,7 @@ async def test_with_real_testclient( def subscriber(m): event.set() - async with TestRabbitBroker(broker, with_real=True) as br: + async with self.patch_broker(broker, with_real=True) as br: await asyncio.wait( ( asyncio.create_task(br.publish("hello", queue)), @@ -59,7 +57,7 @@ async def test_respect_routing_key(self): exchange=RabbitExchange("test", type=ExchangeType.TOPIC), routing_key="up" ) - async with TestRabbitBroker(broker): + async with self.patch_broker(broker): await publisher.publish("Hi!") publisher.mock.assert_called_once_with("Hi!") @@ -78,7 +76,7 @@ async def handler(m): async def handler2(m): return 2 - async with TestRabbitBroker(broker) as br: + async with self.patch_broker(broker) as br: await br.start() assert await (await br.request("", queue)).decode() == 1 @@ -102,7 +100,7 @@ async def test_fanout( async def handler(m): mock() - async with TestRabbitBroker(broker) as br: + async with self.patch_broker(broker) as br: await br.request("", exchange=exch) with pytest.raises(SubscriberNotFound): @@ -121,7 +119,7 @@ async def test_any_topic_routing(self): ) def subscriber(msg): ... - async with TestRabbitBroker(broker) as br: + async with self.patch_broker(broker) as br: await br.publish("hello", "test.a.subj.b", exchange=exch) subscriber.mock.assert_called_once_with("hello") @@ -136,7 +134,7 @@ async def test_ending_topic_routing(self): ) def subscriber(msg): ... - async with TestRabbitBroker(broker) as br: + async with self.patch_broker(broker) as br: await br.publish("hello", "test.a.subj.b", exchange=exch) subscriber.mock.assert_called_once_with("hello") @@ -151,7 +149,7 @@ async def test_mixed_topic_routing(self): ) def subscriber(msg): ... - async with TestRabbitBroker(broker) as br: + async with self.patch_broker(broker) as br: await br.publish("hello", "test.a.subj.b.c", exchange=exch) subscriber.mock.assert_called_once_with("hello") @@ -184,7 +182,7 @@ async def handler(msg): async def handler3(msg): return 3 - async with TestRabbitBroker(broker) as br: + async with self.patch_broker(broker) as br: assert ( await ( await br.request(exchange=exch, headers={"key": 2, "key2": 2}) @@ -225,7 +223,7 @@ async def handler3(msg: RabbitMessage): consume3.set() raise ValueError() - async with TestRabbitBroker(broker) as br: + async with self.patch_broker(broker) as br: await asyncio.wait( ( asyncio.create_task( @@ -256,7 +254,7 @@ async def on_receive(self) -> None: routes.append(None) return await super().on_receive() - broker = RabbitBroker(middlewares=(Middleware,)) + broker = self.get_broker(middlewares=(Middleware,)) @broker.subscriber(queue) async def h1(msg): ... @@ -264,7 +262,7 @@ async def h1(msg): ... @broker.subscriber(queue + "1") async def h2(msg): ... - async with TestRabbitBroker(broker) as br: + async with self.patch_broker(broker) as br: await br.publish("", queue) await br.publish("", queue + "1") @@ -279,7 +277,7 @@ async def on_receive(self) -> None: routes.append(None) return await super().on_receive() - broker = RabbitBroker(middlewares=(Middleware,)) + broker = self.get_broker(middlewares=(Middleware,)) @broker.subscriber(queue) async def h1(msg): ... @@ -287,7 +285,7 @@ async def h1(msg): ... @broker.subscriber(queue + "1") async def h2(msg): ... - async with TestRabbitBroker(broker, with_real=True) as br: + async with self.patch_broker(broker, with_real=True) as br: await br.publish("", queue) await br.publish("", queue + "1") await h1.wait_call(3) @@ -297,7 +295,7 @@ async def h2(msg): ... @pytest.mark.rabbit async def test_broker_gets_patched_attrs_within_cm(self): - await super().test_broker_gets_patched_attrs_within_cm() + await super().test_broker_gets_patched_attrs_within_cm(FakeProducer) @pytest.mark.rabbit async def test_broker_with_real_doesnt_get_patched(self): diff --git a/tests/brokers/redis/conftest.py b/tests/brokers/redis/conftest.py index 2066975eb8..f92a18a902 100644 --- a/tests/brokers/redis/conftest.py +++ b/tests/brokers/redis/conftest.py @@ -1,13 +1,8 @@ from dataclasses import dataclass import pytest -import pytest_asyncio -from faststream.redis import ( - RedisBroker, - RedisRouter, - TestRedisBroker, -) +from faststream.redis import RedisRouter @dataclass @@ -25,24 +20,3 @@ def settings(): @pytest.fixture def router(): return RedisRouter() - - -@pytest_asyncio.fixture() -async def broker(settings): - broker = RedisBroker(settings.url, apply_types=False) - async with broker: - yield broker - - -@pytest_asyncio.fixture() -async def full_broker(settings): - broker = RedisBroker(settings.url) - async with broker: - yield broker - - -@pytest_asyncio.fixture() -async def test_broker(): - broker = RedisBroker() - async with TestRedisBroker(broker) as br: - yield br diff --git a/tests/brokers/redis/test_consume.py b/tests/brokers/redis/test_consume.py index 467254a62f..e5ad72c41a 100644 --- a/tests/brokers/redis/test_consume.py +++ b/tests/brokers/redis/test_consume.py @@ -1,5 +1,5 @@ import asyncio -from typing import List +from typing import Any, List from unittest.mock import MagicMock, patch import pytest @@ -13,8 +13,8 @@ @pytest.mark.redis @pytest.mark.asyncio class TestConsume(BrokerRealConsumeTestcase): - def get_broker(self, apply_types: bool = False): - return RedisBroker(apply_types=apply_types) + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RedisBroker: + return RedisBroker(apply_types=apply_types, **kwargs) async def test_consume_native( self, diff --git a/tests/brokers/redis/test_fastapi.py b/tests/brokers/redis/test_fastapi.py index 9993419d5f..6e36a8c69e 100644 --- a/tests/brokers/redis/test_fastapi.py +++ b/tests/brokers/redis/test_fastapi.py @@ -1,12 +1,12 @@ import asyncio -from typing import List +from typing import Any, List from unittest.mock import Mock import pytest -from faststream.redis import ListSub, RedisRouter, StreamSub +from faststream.redis import ListSub, RedisBroker, RedisRouter, StreamSub from faststream.redis.fastapi import RedisRouter as StreamRouter -from faststream.redis.testing import TestRedisBroker, build_message +from faststream.redis.testing import TestRedisBroker from tests.brokers.base.fastapi import FastAPILocalTestcase, FastAPITestcase @@ -138,8 +138,9 @@ async def handler(msg: List[str]): class TestRouterLocal(FastAPILocalTestcase): router_class = StreamRouter broker_router_class = RedisRouter - broker_test = staticmethod(TestRedisBroker) - build_message = staticmethod(build_message) + + def patch_broker(self, broker: RedisBroker, **kwargs: Any) -> RedisBroker: + return TestRedisBroker(broker, **kwargs) async def test_batch_testclient( self, @@ -154,10 +155,10 @@ async def hello(msg: List[str]): event.set() return mock(msg) - async with TestRedisBroker(router.broker): + async with self.patch_broker(router.broker) as br: await asyncio.wait( ( - asyncio.create_task(router.broker.publish("hi", list=queue)), + asyncio.create_task(br.publish("hi", list=queue)), asyncio.create_task(event.wait()), ), timeout=3, @@ -179,10 +180,10 @@ async def hello(msg: List[str]): event.set() return mock(msg) - async with TestRedisBroker(router.broker): + async with self.patch_broker(router.broker) as br: await asyncio.wait( ( - asyncio.create_task(router.broker.publish("hi", stream=queue)), + asyncio.create_task(br.publish("hi", stream=queue)), asyncio.create_task(event.wait()), ), timeout=3, @@ -198,8 +199,8 @@ async def test_path(self, queue: str): async def hello(name): return name - async with self.broker_test(router.broker): - r = await router.broker.request( + async with self.patch_broker(router.broker) as br: + r = await br.request( "hi", f"{queue}.john", timeout=0.5, diff --git a/tests/brokers/redis/test_middlewares.py b/tests/brokers/redis/test_middlewares.py index 22f6894c3b..c3d6f0c4dc 100644 --- a/tests/brokers/redis/test_middlewares.py +++ b/tests/brokers/redis/test_middlewares.py @@ -1,3 +1,5 @@ +from typing import Any + import pytest from faststream.redis import RedisBroker @@ -9,9 +11,11 @@ @pytest.mark.redis class TestMiddlewares(MiddlewareTestcase): - broker_class = RedisBroker + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RedisBroker: + return RedisBroker(apply_types=apply_types, **kwargs) @pytest.mark.redis class TestExceptionMiddlewares(ExceptionMiddlewareTestcase): - broker_class = RedisBroker + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RedisBroker: + return RedisBroker(apply_types=apply_types, **kwargs) diff --git a/tests/brokers/redis/test_parser.py b/tests/brokers/redis/test_parser.py index c40306adc2..41a9a2f894 100644 --- a/tests/brokers/redis/test_parser.py +++ b/tests/brokers/redis/test_parser.py @@ -1,3 +1,5 @@ +from typing import Any + import pytest from faststream.redis import RedisBroker @@ -6,4 +8,5 @@ @pytest.mark.redis class TestCustomParser(CustomParserTestcase): - broker_class = RedisBroker + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RedisBroker: + return RedisBroker(apply_types=apply_types, **kwargs) diff --git a/tests/brokers/redis/test_publish.py b/tests/brokers/redis/test_publish.py index ebb348892e..4191ba6740 100644 --- a/tests/brokers/redis/test_publish.py +++ b/tests/brokers/redis/test_publish.py @@ -1,4 +1,5 @@ import asyncio +from typing import Any from unittest.mock import MagicMock, patch import pytest @@ -13,8 +14,8 @@ @pytest.mark.redis @pytest.mark.asyncio class TestPublish(BrokerPublishTestcase): - def get_broker(self, apply_types: bool = False): - return RedisBroker(apply_types=apply_types) + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RedisBroker: + return RedisBroker(apply_types=apply_types, **kwargs) async def test_list_publisher( self, @@ -184,7 +185,6 @@ async def resp(msg=Context("message")): correlation_id="1", ) - @pytest.mark.asyncio async def test_response_for_rpc( self, queue: str, diff --git a/tests/brokers/redis/test_router.py b/tests/brokers/redis/test_router.py index 7ef36317c4..6000245352 100644 --- a/tests/brokers/redis/test_router.py +++ b/tests/brokers/redis/test_router.py @@ -1,9 +1,16 @@ import asyncio +from typing import Any import pytest from faststream import Path -from faststream.redis import RedisBroker, RedisPublisher, RedisRoute, RedisRouter +from faststream.redis import ( + RedisBroker, + RedisPublisher, + RedisRoute, + RedisRouter, + TestRedisBroker, +) from tests.brokers.base.router import RouterLocalTestcase, RouterTestcase @@ -13,19 +20,29 @@ class TestRouter(RouterTestcase): route_class = RedisRoute publisher_class = RedisPublisher + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RedisBroker: + return RedisBroker(apply_types=apply_types, **kwargs) + class TestRouterLocal(RouterLocalTestcase): broker_class = RedisRouter route_class = RedisRoute publisher_class = RedisPublisher + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RedisBroker: + return RedisBroker(apply_types=apply_types, **kwargs) + + def patch_broker(self, broker: RedisBroker, **kwargs: Any) -> RedisBroker: + return TestRedisBroker(broker, **kwargs) + async def test_router_path( self, event, mock, router, - pub_broker, ): + pub_broker = self.get_broker(apply_types=True) + @router.subscriber("in.{name}.{id}") async def h( name: str = Path(), @@ -34,23 +51,24 @@ async def h( event.set() mock(name=name, id=id) - pub_broker._is_apply_types = True pub_broker.include_router(router) - await pub_broker.start() + async with self.patch_broker(pub_broker) as br: + await br.start() - await pub_broker.request("", "in.john.2") + await br.request("", "in.john.2") - assert event.is_set() - mock.assert_called_once_with(name="john", id=2) + assert event.is_set() + mock.assert_called_once_with(name="john", id=2) async def test_router_path_with_prefix( self, event, mock, router, - pub_broker, ): + pub_broker = self.get_broker(apply_types=True) + router.prefix = "test." @router.subscriber("in.{name}.{id}") @@ -61,23 +79,24 @@ async def h( event.set() mock(name=name, id=id) - pub_broker._is_apply_types = True pub_broker.include_router(router) - await pub_broker.start() + async with self.patch_broker(pub_broker) as br: + await br.start() - await pub_broker.request("", "test.in.john.2") + await br.request("", "test.in.john.2") - assert event.is_set() - mock.assert_called_once_with(name="john", id=2) + assert event.is_set() + mock.assert_called_once_with(name="john", id=2) async def test_router_delay_handler_path( self, event, mock, router, - pub_broker, ): + pub_broker = self.get_broker(apply_types=True) + async def h( name: str = Path(), id: int = Path("id"), @@ -87,22 +106,23 @@ async def h( r = type(router)(handlers=(self.route_class(h, channel="in.{name}.{id}"),)) - pub_broker._is_apply_types = True pub_broker.include_router(r) - await pub_broker.start() + async with self.patch_broker(pub_broker) as br: + await br.start() - await pub_broker.request("", "in.john.2") + await br.request("", "in.john.2") - assert event.is_set() - mock.assert_called_once_with(name="john", id=2) + assert event.is_set() + mock.assert_called_once_with(name="john", id=2) async def test_delayed_channel_handlers( self, event: asyncio.Event, queue: str, - pub_broker: RedisBroker, ): + pub_broker = self.get_broker() + def response(m): event.set() @@ -110,14 +130,12 @@ def response(m): pub_broker.include_router(r) - async with pub_broker: - await pub_broker.start() + async with self.patch_broker(pub_broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task( - pub_broker.publish("hello", channel=f"test_{queue}") - ), + asyncio.create_task(br.publish("hello", channel=f"test_{queue}")), asyncio.create_task(event.wait()), ), timeout=3, @@ -129,8 +147,9 @@ async def test_delayed_list_handlers( self, event: asyncio.Event, queue: str, - pub_broker: RedisBroker, ): + pub_broker = self.get_broker() + def response(m): event.set() @@ -138,14 +157,12 @@ def response(m): pub_broker.include_router(r) - async with pub_broker: - await pub_broker.start() + async with self.patch_broker(pub_broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task( - pub_broker.publish("hello", list=f"test_{queue}") - ), + asyncio.create_task(br.publish("hello", list=f"test_{queue}")), asyncio.create_task(event.wait()), ), timeout=3, @@ -157,8 +174,9 @@ async def test_delayed_stream_handlers( self, event: asyncio.Event, queue: str, - pub_broker: RedisBroker, ): + pub_broker = self.get_broker() + def response(m): event.set() @@ -166,14 +184,12 @@ def response(m): pub_broker.include_router(r) - async with pub_broker: - await pub_broker.start() + async with self.patch_broker(pub_broker) as br: + await br.start() await asyncio.wait( ( - asyncio.create_task( - pub_broker.publish("hello", stream=f"test_{queue}") - ), + asyncio.create_task(br.publish("hello", stream=f"test_{queue}")), asyncio.create_task(event.wait()), ), timeout=3, diff --git a/tests/brokers/redis/test_test_client.py b/tests/brokers/redis/test_test_client.py index a4c803fa3f..e38c3e3445 100644 --- a/tests/brokers/redis/test_test_client.py +++ b/tests/brokers/redis/test_test_client.py @@ -1,4 +1,5 @@ import asyncio +from typing import Any import pytest @@ -12,14 +13,11 @@ class TestTestclient(BrokerTestclientTestcase): test_class = TestRedisBroker - def get_broker(self, apply_types: bool = False) -> RedisBroker: - return RedisBroker(apply_types=apply_types) + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RedisBroker: + return RedisBroker(apply_types=apply_types, **kwargs) - def patch_broker(self, broker: RedisBroker) -> TestRedisBroker: - return TestRedisBroker(broker) - - def get_fake_producer_class(self) -> type: - return FakeProducer + def patch_broker(self, broker: RedisBroker, **kwargs: Any) -> TestRedisBroker: + return TestRedisBroker(broker, **kwargs) @pytest.mark.redis async def test_with_real_testclient( @@ -33,7 +31,7 @@ async def test_with_real_testclient( def subscriber(m): event.set() - async with TestRedisBroker(broker, with_real=True) as br: + async with self.patch_broker(broker, with_real=True) as br: await asyncio.wait( ( asyncio.create_task(br.publish("hello", queue)), @@ -52,15 +50,15 @@ async def on_receive(self) -> None: routes.append(None) return await super().on_receive() - broker = RedisBroker(middlewares=(Middleware,)) + broker = self.get_broker(middlewares=(Middleware,)) @broker.subscriber(queue) - async def h1(): ... + async def h1(m): ... @broker.subscriber(queue + "1") - async def h2(): ... + async def h2(m): ... - async with TestRedisBroker(broker) as br: + async with self.patch_broker(broker) as br: await br.publish("", queue) await br.publish("", queue + "1") @@ -75,15 +73,15 @@ async def on_receive(self) -> None: routes.append(None) return await super().on_receive() - broker = RedisBroker(middlewares=(Middleware,)) + broker = self.get_broker(middlewares=(Middleware,)) @broker.subscriber(queue) - async def h1(): ... + async def h1(m): ... @broker.subscriber(queue + "1") - async def h2(): ... + async def h2(m): ... - async with TestRedisBroker(broker, with_real=True) as br: + async with self.patch_broker(broker, with_real=True) as br: await br.publish("", queue) await br.publish("", queue + "1") await h1.wait_call(3) @@ -222,7 +220,7 @@ async def test_publish_to_none( @pytest.mark.redis async def test_broker_gets_patched_attrs_within_cm(self): - await super().test_broker_gets_patched_attrs_within_cm() + await super().test_broker_gets_patched_attrs_within_cm(FakeProducer) @pytest.mark.redis async def test_broker_with_real_doesnt_get_patched(self): From 865185e790808a11b07b21c56b1f256bbdfa992b Mon Sep 17 00:00:00 2001 From: Pastukhov Nikita Date: Fri, 20 Sep 2024 18:35:41 +0300 Subject: [PATCH 168/245] logging fsm * feat: refactor logging with FSM * refactor: delete subscribers without dict * refactor: new kafka logging * refactor: new confluent logging * docs: generate API References * tests: fix tests * tests: fix in-memory mocks * confluent: fix self.logger usage * confluent: fix logger usage * confluent: fix logger usage * confluent: make laze logging * confluent: check producer before setup * confluent: fix producer * tests: correct setup call order * fix: remove Confluent producer logger * fix: remove useless option * tests: fix confluent * fix confluent --------- Co-authored-by: Lancetnik --- docs/docs/SUMMARY.md | 12 +- ...LoggingBroker.md => KafkaParamsStorage.md} | 2 +- .../IncorrectState.md} | 2 +- .../broker/logging/KafkaParamsStorage.md} | 2 +- .../logging/LoggingMiddleware.md} | 2 +- .../broker/logging/NatsParamsStorage.md} | 2 +- .../broker/logging/RabbitParamsStorage.md | 11 ++ .../broker/logging/RedisParamsStorage.md | 11 ++ faststream/_internal/broker/abc_broker.py | 60 +++---- faststream/_internal/broker/broker.py | 133 +++++++-------- faststream/_internal/broker/logging_mixin.py | 93 ---------- faststream/_internal/cli/main.py | 1 + faststream/_internal/cli/utils/logs.py | 9 +- faststream/_internal/constants.py | 6 +- faststream/_internal/fastapi/router.py | 5 +- faststream/_internal/log/logging.py | 22 +-- faststream/_internal/proto.py | 5 +- faststream/_internal/setup/__init__.py | 17 ++ faststream/_internal/setup/fast_depends.py | 13 ++ faststream/_internal/setup/logger.py | 159 ++++++++++++++++++ faststream/_internal/setup/proto.py | 7 + faststream/_internal/setup/state.py | 99 +++++++++++ faststream/_internal/subscriber/call_item.py | 2 +- faststream/_internal/subscriber/usecase.py | 17 +- faststream/_internal/testing/broker.py | 14 +- faststream/app.py | 5 +- faststream/confluent/broker/broker.py | 46 ++--- faststream/confluent/broker/logging.py | 111 ++++++------ faststream/confluent/client.py | 33 ++-- faststream/confluent/subscriber/usecase.py | 13 +- faststream/confluent/testing.py | 4 + faststream/exceptions.py | 4 + faststream/kafka/broker/broker.py | 34 ++-- faststream/kafka/broker/logging.py | 110 ++++++------ faststream/kafka/subscriber/usecase.py | 13 +- faststream/middlewares/logging.py | 75 ++++----- faststream/nats/broker/broker.py | 54 +++--- faststream/nats/broker/logging.py | 118 ++++++------- faststream/nats/subscriber/usecase.py | 12 +- faststream/rabbit/broker/broker.py | 56 +++--- faststream/rabbit/broker/logging.py | 97 +++++------ faststream/rabbit/subscriber/usecase.py | 14 +- faststream/redis/broker/broker.py | 31 ++-- faststream/redis/broker/logging.py | 87 +++++----- faststream/redis/subscriber/usecase.py | 13 +- .../specification/asyncapi/v2_6_0/generate.py | 2 +- .../specification/asyncapi/v3_0_0/generate.py | 2 +- faststream/specification/proto.py | 13 ++ tests/brokers/base/testclient.py | 18 ++ tests/brokers/confluent/test_logger.py | 23 +-- tests/cli/rabbit/test_app.py | 68 +++++--- tests/cli/rabbit/test_logs.py | 7 +- tests/cli/test_publish.py | 42 ++--- tests/opentelemetry/basic.py | 35 ++-- .../opentelemetry/confluent/test_confluent.py | 38 ++--- tests/opentelemetry/kafka/test_kafka.py | 44 +++-- tests/opentelemetry/nats/test_nats.py | 21 ++- tests/opentelemetry/rabbit/test_rabbit.py | 12 +- tests/opentelemetry/redis/test_redis.py | 47 +++--- 59 files changed, 1116 insertions(+), 892 deletions(-) rename docs/docs/en/api/faststream/confluent/broker/logging/{KafkaLoggingBroker.md => KafkaParamsStorage.md} (65%) rename docs/docs/en/api/faststream/{nats/broker/logging/NatsLoggingBroker.md => exceptions/IncorrectState.md} (67%) rename docs/docs/en/api/faststream/{redis/broker/logging/RedisLoggingBroker.md => kafka/broker/logging/KafkaParamsStorage.md} (66%) rename docs/docs/en/api/faststream/{kafka/broker/logging/KafkaLoggingBroker.md => middlewares/logging/LoggingMiddleware.md} (66%) rename docs/docs/en/api/faststream/{rabbit/broker/logging/RabbitLoggingBroker.md => nats/broker/logging/NatsParamsStorage.md} (65%) create mode 100644 docs/docs/en/api/faststream/rabbit/broker/logging/RabbitParamsStorage.md create mode 100644 docs/docs/en/api/faststream/redis/broker/logging/RedisParamsStorage.md delete mode 100644 faststream/_internal/broker/logging_mixin.py create mode 100644 faststream/_internal/setup/__init__.py create mode 100644 faststream/_internal/setup/fast_depends.py create mode 100644 faststream/_internal/setup/logger.py create mode 100644 faststream/_internal/setup/proto.py create mode 100644 faststream/_internal/setup/state.py diff --git a/docs/docs/SUMMARY.md b/docs/docs/SUMMARY.md index 5739aad3e6..ee574189c4 100644 --- a/docs/docs/SUMMARY.md +++ b/docs/docs/SUMMARY.md @@ -245,7 +245,7 @@ search: - broker - [KafkaBroker](api/faststream/confluent/broker/broker/KafkaBroker.md) - logging - - [KafkaLoggingBroker](api/faststream/confluent/broker/logging/KafkaLoggingBroker.md) + - [KafkaParamsStorage](api/faststream/confluent/broker/logging/KafkaParamsStorage.md) - registrator - [KafkaRegistrator](api/faststream/confluent/broker/registrator/KafkaRegistrator.md) - client @@ -335,6 +335,7 @@ search: - [FastStreamException](api/faststream/exceptions/FastStreamException.md) - [HandlerException](api/faststream/exceptions/HandlerException.md) - [IgnoredException](api/faststream/exceptions/IgnoredException.md) + - [IncorrectState](api/faststream/exceptions/IncorrectState.md) - [NackMessage](api/faststream/exceptions/NackMessage.md) - [OperationForbiddenError](api/faststream/exceptions/OperationForbiddenError.md) - [RejectMessage](api/faststream/exceptions/RejectMessage.md) @@ -358,7 +359,7 @@ search: - broker - [KafkaBroker](api/faststream/kafka/broker/broker/KafkaBroker.md) - logging - - [KafkaLoggingBroker](api/faststream/kafka/broker/logging/KafkaLoggingBroker.md) + - [KafkaParamsStorage](api/faststream/kafka/broker/logging/KafkaParamsStorage.md) - registrator - [KafkaRegistrator](api/faststream/kafka/broker/registrator/KafkaRegistrator.md) - fastapi @@ -444,6 +445,7 @@ search: - [ignore_handler](api/faststream/middlewares/exception/ignore_handler.md) - logging - [CriticalLogMiddleware](api/faststream/middlewares/logging/CriticalLogMiddleware.md) + - [LoggingMiddleware](api/faststream/middlewares/logging/LoggingMiddleware.md) - nats - [AckPolicy](api/faststream/nats/AckPolicy.md) - [ConsumerConfig](api/faststream/nats/ConsumerConfig.md) @@ -473,7 +475,7 @@ search: - broker - [NatsBroker](api/faststream/nats/broker/broker/NatsBroker.md) - logging - - [NatsLoggingBroker](api/faststream/nats/broker/logging/NatsLoggingBroker.md) + - [NatsParamsStorage](api/faststream/nats/broker/logging/NatsParamsStorage.md) - registrator - [NatsRegistrator](api/faststream/nats/broker/registrator/NatsRegistrator.md) - fastapi @@ -617,7 +619,7 @@ search: - broker - [RabbitBroker](api/faststream/rabbit/broker/broker/RabbitBroker.md) - logging - - [RabbitLoggingBroker](api/faststream/rabbit/broker/logging/RabbitLoggingBroker.md) + - [RabbitParamsStorage](api/faststream/rabbit/broker/logging/RabbitParamsStorage.md) - registrator - [RabbitRegistrator](api/faststream/rabbit/broker/registrator/RabbitRegistrator.md) - fastapi @@ -699,7 +701,7 @@ search: - broker - [RedisBroker](api/faststream/redis/broker/broker/RedisBroker.md) - logging - - [RedisLoggingBroker](api/faststream/redis/broker/logging/RedisLoggingBroker.md) + - [RedisParamsStorage](api/faststream/redis/broker/logging/RedisParamsStorage.md) - registrator - [RedisRegistrator](api/faststream/redis/broker/registrator/RedisRegistrator.md) - fastapi diff --git a/docs/docs/en/api/faststream/confluent/broker/logging/KafkaLoggingBroker.md b/docs/docs/en/api/faststream/confluent/broker/logging/KafkaParamsStorage.md similarity index 65% rename from docs/docs/en/api/faststream/confluent/broker/logging/KafkaLoggingBroker.md rename to docs/docs/en/api/faststream/confluent/broker/logging/KafkaParamsStorage.md index ea238b6b85..900f945037 100644 --- a/docs/docs/en/api/faststream/confluent/broker/logging/KafkaLoggingBroker.md +++ b/docs/docs/en/api/faststream/confluent/broker/logging/KafkaParamsStorage.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.confluent.broker.logging.KafkaLoggingBroker +::: faststream.confluent.broker.logging.KafkaParamsStorage diff --git a/docs/docs/en/api/faststream/nats/broker/logging/NatsLoggingBroker.md b/docs/docs/en/api/faststream/exceptions/IncorrectState.md similarity index 67% rename from docs/docs/en/api/faststream/nats/broker/logging/NatsLoggingBroker.md rename to docs/docs/en/api/faststream/exceptions/IncorrectState.md index cd31396a61..2c890d5358 100644 --- a/docs/docs/en/api/faststream/nats/broker/logging/NatsLoggingBroker.md +++ b/docs/docs/en/api/faststream/exceptions/IncorrectState.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.nats.broker.logging.NatsLoggingBroker +::: faststream.exceptions.IncorrectState diff --git a/docs/docs/en/api/faststream/redis/broker/logging/RedisLoggingBroker.md b/docs/docs/en/api/faststream/kafka/broker/logging/KafkaParamsStorage.md similarity index 66% rename from docs/docs/en/api/faststream/redis/broker/logging/RedisLoggingBroker.md rename to docs/docs/en/api/faststream/kafka/broker/logging/KafkaParamsStorage.md index 58500b3c1f..f7c8136115 100644 --- a/docs/docs/en/api/faststream/redis/broker/logging/RedisLoggingBroker.md +++ b/docs/docs/en/api/faststream/kafka/broker/logging/KafkaParamsStorage.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.redis.broker.logging.RedisLoggingBroker +::: faststream.kafka.broker.logging.KafkaParamsStorage diff --git a/docs/docs/en/api/faststream/kafka/broker/logging/KafkaLoggingBroker.md b/docs/docs/en/api/faststream/middlewares/logging/LoggingMiddleware.md similarity index 66% rename from docs/docs/en/api/faststream/kafka/broker/logging/KafkaLoggingBroker.md rename to docs/docs/en/api/faststream/middlewares/logging/LoggingMiddleware.md index 1f8d5921b7..62e6dfa604 100644 --- a/docs/docs/en/api/faststream/kafka/broker/logging/KafkaLoggingBroker.md +++ b/docs/docs/en/api/faststream/middlewares/logging/LoggingMiddleware.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.kafka.broker.logging.KafkaLoggingBroker +::: faststream.middlewares.logging.LoggingMiddleware diff --git a/docs/docs/en/api/faststream/rabbit/broker/logging/RabbitLoggingBroker.md b/docs/docs/en/api/faststream/nats/broker/logging/NatsParamsStorage.md similarity index 65% rename from docs/docs/en/api/faststream/rabbit/broker/logging/RabbitLoggingBroker.md rename to docs/docs/en/api/faststream/nats/broker/logging/NatsParamsStorage.md index a3b3151d4b..25b77d4331 100644 --- a/docs/docs/en/api/faststream/rabbit/broker/logging/RabbitLoggingBroker.md +++ b/docs/docs/en/api/faststream/nats/broker/logging/NatsParamsStorage.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.rabbit.broker.logging.RabbitLoggingBroker +::: faststream.nats.broker.logging.NatsParamsStorage diff --git a/docs/docs/en/api/faststream/rabbit/broker/logging/RabbitParamsStorage.md b/docs/docs/en/api/faststream/rabbit/broker/logging/RabbitParamsStorage.md new file mode 100644 index 0000000000..e9e46da6af --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/broker/logging/RabbitParamsStorage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.broker.logging.RabbitParamsStorage diff --git a/docs/docs/en/api/faststream/redis/broker/logging/RedisParamsStorage.md b/docs/docs/en/api/faststream/redis/broker/logging/RedisParamsStorage.md new file mode 100644 index 0000000000..b7d1bb680a --- /dev/null +++ b/docs/docs/en/api/faststream/redis/broker/logging/RedisParamsStorage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.broker.logging.RedisParamsStorage diff --git a/faststream/_internal/broker/abc_broker.py b/faststream/_internal/broker/abc_broker.py index 9e9f268038..9bd6961515 100644 --- a/faststream/_internal/broker/abc_broker.py +++ b/faststream/_internal/broker/abc_broker.py @@ -90,43 +90,37 @@ def include_router( for h in router._subscribers.values(): h.add_prefix("".join((self.prefix, prefix))) - if (key := hash(h)) not in self._subscribers: - if include_in_schema is None: - h.include_in_schema = self._solve_include_in_schema( - h.include_in_schema - ) - else: - h.include_in_schema = include_in_schema - - h._broker_middlewares = ( - *self._middlewares, - *middlewares, - *h._broker_middlewares, - ) - h._broker_dependencies = ( - *self._dependencies, - *dependencies, - *h._broker_dependencies, - ) - self._subscribers = {**self._subscribers, key: h} + if include_in_schema is None: + h.include_in_schema = self._solve_include_in_schema(h.include_in_schema) + else: + h.include_in_schema = include_in_schema + + h._broker_middlewares = ( + *self._middlewares, + *middlewares, + *h._broker_middlewares, + ) + h._broker_dependencies = ( + *self._dependencies, + *dependencies, + *h._broker_dependencies, + ) + self._subscribers = {**self._subscribers, hash(h): h} for p in router._publishers.values(): p.add_prefix(self.prefix) - if (key := hash(p)) not in self._publishers: - if include_in_schema is None: - p.include_in_schema = self._solve_include_in_schema( - p.include_in_schema - ) - else: - p.include_in_schema = include_in_schema - - p._broker_middlewares = ( - *self._middlewares, - *middlewares, - *p._broker_middlewares, - ) - self._publishers = {**self._publishers, key: p} + if include_in_schema is None: + p.include_in_schema = self._solve_include_in_schema(p.include_in_schema) + else: + p.include_in_schema = include_in_schema + + p._broker_middlewares = ( + *self._middlewares, + *middlewares, + *p._broker_middlewares, + ) + self._publishers = {**self._publishers, hash(p): p} def include_routers( self, diff --git a/faststream/_internal/broker/broker.py b/faststream/_internal/broker/broker.py index 20d6424246..fb19fd61d1 100644 --- a/faststream/_internal/broker/broker.py +++ b/faststream/_internal/broker/broker.py @@ -1,4 +1,3 @@ -import logging from abc import abstractmethod from contextlib import AsyncExitStack from functools import partial @@ -19,8 +18,14 @@ from typing_extensions import Annotated, Doc, Self from faststream._internal._compat import is_test_env -from faststream._internal.log.logging import set_logger_fmt -from faststream._internal.proto import SetupAble +from faststream._internal.setup import ( + EmptyState, + FastDependsData, + LoggerState, + SetupAble, + SetupState, +) +from faststream._internal.setup.state import BaseState from faststream._internal.subscriber.proto import SubscriberProto from faststream._internal.types import ( AsyncCustomCallable, @@ -33,14 +38,14 @@ from faststream.exceptions import NOT_CONNECTED_YET from faststream.middlewares.logging import CriticalLogMiddleware -from .logging_mixin import LoggingBroker +from .abc_broker import ABCBroker if TYPE_CHECKING: from types import TracebackType from fast_depends.dependencies import Depends - from faststream._internal.basic_types import AnyDict, Decorator, LoggerProto + from faststream._internal.basic_types import AnyDict, Decorator from faststream._internal.publisher.proto import ( ProducerProto, PublisherProto, @@ -51,7 +56,7 @@ class BrokerUsecase( - LoggingBroker[MsgType], + ABCBroker[MsgType], SetupAble, Generic[MsgType, ConnectionType], ): @@ -60,6 +65,7 @@ class BrokerUsecase( url: Union[str, Sequence[str]] _connection: Optional[ConnectionType] _producer: Optional["ProducerProto"] + _state: BaseState def __init__( self, @@ -87,22 +93,7 @@ def __init__( ), ], # Logging args - default_logger: Annotated[ - logging.Logger, - Doc("Logger object to use if `logger` is not set."), - ], - logger: Annotated[ - Optional["LoggerProto"], - Doc("User specified logger to pass into Context and log service messages."), - ], - log_level: Annotated[ - int, - Doc("Service messages log level."), - ], - log_fmt: Annotated[ - Optional[str], - Doc("Default logger log format."), - ], + logger_state: LoggerState, # FastDepends args apply_types: Annotated[ bool, @@ -163,11 +154,6 @@ def __init__( # Broker is a root router include_in_schema=True, prefix="", - # Logging args - default_logger=default_logger, - log_level=log_level, - log_fmt=log_fmt, - logger=logger, ) self.running = False @@ -180,15 +166,19 @@ def __init__( # TODO: remove useless middleware filter if not is_test_env(): self._middlewares = ( - CriticalLogMiddleware(self.logger, log_level), + CriticalLogMiddleware(logger_state), *self._middlewares, ) - # FastDepends args - self._is_apply_types = apply_types - self._is_validate = validate - self._get_dependant = _get_dependant - self._call_decorators = _call_decorators + self._state = EmptyState( + depends_params=FastDependsData( + apply_types=apply_types, + is_validate=validate, + get_dependent=_get_dependant, + call_decorators=_call_decorators, + ), + logger_state=logger_state, + ) # AsyncAPI information self.url = specification_url @@ -213,8 +203,13 @@ async def __aexit__( @abstractmethod async def start(self) -> None: """Start the broker async use case.""" - self._abc_start() - await self.connect() + # TODO: filter by already running handlers after TestClient refactor + for handler in self._subscribers.values(): + self._state.logger_state.log( + f"`{handler.call_name}` waiting for messages", + extra=handler.get_log_context(None), + ) + await handler.start() async def connect(self, **kwargs: Any) -> ConnectionType: """Connect to a remote server.""" @@ -222,7 +217,7 @@ async def connect(self, **kwargs: Any) -> ConnectionType: connection_kwargs = self._connection_kwargs.copy() connection_kwargs.update(kwargs) self._connection = await self._connect(**connection_kwargs) - self._setup() + return self._connection @abstractmethod @@ -230,8 +225,33 @@ async def _connect(self) -> ConnectionType: """Connect to a resource.""" raise NotImplementedError() - def _setup(self) -> None: + def _setup(self, state: Optional[BaseState] = None) -> None: """Prepare all Broker entities to startup.""" + if not self._state: + # Fallback to default state if there no + # parent container like FastStream object + default_state = self._state.copy_to_state(SetupState) + + if state: + self._state = state.copy_with_params( + depends_params=default_state.depends_params, + logger_state=default_state.logger_state, + ) + else: + self._state = default_state + + if not self.running: + self.running = True + + for h in self._subscribers.values(): + log_context = h.get_log_context(None) + log_context.pop("message_id", None) + self._state.logger_state.params_storage.setup_log_contest(log_context) + + self._state._setup() + + # TODO: why we can't move it to running? + # TODO: can we setup subscriber in running broker automatically? for h in self._subscribers.values(): self.setup_subscriber(h) @@ -261,21 +281,18 @@ def setup_publisher( @property def _subscriber_setup_extra(self) -> "AnyDict": return { - "logger": self.logger, + "logger": self._state.logger_state.logger.logger, "producer": self._producer, "graceful_timeout": self.graceful_timeout, "extra_context": { "broker": self, - "logger": self.logger, + "logger": self._state.logger_state.logger.logger, }, # broker options "broker_parser": self._parser, "broker_decoder": self._decoder, # dependant args - "apply_types": self._is_apply_types, - "is_validate": self._is_validate, - "_get_dependant": self._get_dependant, - "_call_decorators": self._call_decorators, + "state": self._state, } @property @@ -290,21 +307,6 @@ def publisher(self, *args: Any, **kwargs: Any) -> "PublisherProto[MsgType]": self.setup_publisher(pub) return pub - def _abc_start(self) -> None: - for h in self._subscribers.values(): - log_context = h.get_log_context(None) - log_context.pop("message_id", None) - self._setup_log_context(**log_context) - - if not self.running: - self.running = True - - if not self.use_custom and self.logger is not None: - set_logger_fmt( - cast(logging.Logger, self.logger), - self._get_fmt(), - ) - async def close( self, exc_type: Optional[Type[BaseException]] = None, @@ -312,23 +314,10 @@ async def close( exc_tb: Optional["TracebackType"] = None, ) -> None: """Closes the object.""" - self.running = False - for h in self._subscribers.values(): await h.close() - if self._connection is not None: - await self._close(exc_type, exc_val, exc_tb) - - @abstractmethod - async def _close( - self, - exc_type: Optional[Type[BaseException]] = None, - exc_val: Optional[BaseException] = None, - exc_tb: Optional["TracebackType"] = None, - ) -> None: - """Close the object.""" - self._connection = None + self.running = False async def publish( self, diff --git a/faststream/_internal/broker/logging_mixin.py b/faststream/_internal/broker/logging_mixin.py deleted file mode 100644 index 3b8f401465..0000000000 --- a/faststream/_internal/broker/logging_mixin.py +++ /dev/null @@ -1,93 +0,0 @@ -import logging -from abc import abstractmethod -from typing import TYPE_CHECKING, Any, Optional - -from typing_extensions import Annotated, Doc - -from faststream._internal.constants import EMPTY -from faststream._internal.types import MsgType - -from .abc_broker import ABCBroker - -if TYPE_CHECKING: - from faststream._internal.basic_types import AnyDict, LoggerProto - - -class LoggingBroker(ABCBroker[MsgType]): - """A mixin class for logging.""" - - logger: Optional["LoggerProto"] - - @abstractmethod - def get_fmt(self) -> str: - """Fallback method to get log format if `log_fmt` if not specified.""" - raise NotImplementedError() - - @abstractmethod - def _setup_log_context(self) -> None: - raise NotImplementedError() - - def __init__( - self, - *args: Any, - default_logger: Annotated[ - logging.Logger, - Doc("Logger object to use if `logger` is not set."), - ], - logger: Annotated[ - Optional["LoggerProto"], - Doc("User specified logger to pass into Context and log service messages."), - ], - log_level: Annotated[ - int, - Doc("Service messages log level."), - ], - log_fmt: Annotated[ - Optional[str], - Doc("Default logger log format."), - ], - **kwargs: Any, - ) -> None: - if logger is not EMPTY: - self.logger = logger - self.use_custom = True - else: - self.logger = default_logger - self.use_custom = False - - self._msg_log_level = log_level - self._fmt = log_fmt - - super().__init__(*args, **kwargs) - - def _get_fmt(self) -> str: - """Get default logger format at broker startup.""" - return self._fmt or self.get_fmt() - - def _log( - self, - message: Annotated[ - str, - Doc("Log message."), - ], - log_level: Annotated[ - Optional[int], - Doc("Log record level. Use `__init__: log_level` option if not specified."), - ] = None, - extra: Annotated[ - Optional["AnyDict"], - Doc("Log record extra information."), - ] = None, - exc_info: Annotated[ - Optional[Exception], - Doc("Exception object to log traceback."), - ] = None, - ) -> None: - """Logs a message.""" - if self.logger is not None: - self.logger.log( - (log_level or self._msg_log_level), - message, - extra=extra, - exc_info=exc_info, - ) diff --git a/faststream/_internal/cli/main.py b/faststream/_internal/cli/main.py index 3abb63a398..29a874e083 100644 --- a/faststream/_internal/cli/main.py +++ b/faststream/_internal/cli/main.py @@ -250,6 +250,7 @@ def publish( if not app_obj.broker: raise ValueError("Broker instance not found in the app.") + app_obj._setup() result = anyio.run(publish_message, app_obj.broker, rpc, extra) if rpc: diff --git a/faststream/_internal/cli/utils/logs.py b/faststream/_internal/cli/utils/logs.py index 96f9f48bfd..4330f9cdb9 100644 --- a/faststream/_internal/cli/utils/logs.py +++ b/faststream/_internal/cli/utils/logs.py @@ -69,6 +69,9 @@ def set_log_level(level: int, app: "FastStream") -> None: if app.logger and getattr(app.logger, "setLevel", None): app.logger.setLevel(level) # type: ignore[attr-defined] - broker_logger: Optional[LoggerProto] = getattr(app.broker, "logger", None) - if broker_logger is not None and getattr(broker_logger, "setLevel", None): - broker_logger.setLevel(level) # type: ignore[attr-defined] + if app.broker: + broker_logger: Optional[LoggerProto] = ( + app.broker._state.logger_state.logger.logger + ) + if broker_logger is not None and getattr(broker_logger, "setLevel", None): + broker_logger.setLevel(level) # type: ignore[attr-defined] diff --git a/faststream/_internal/constants.py b/faststream/_internal/constants.py index c3d2f73b4a..16d984165e 100644 --- a/faststream/_internal/constants.py +++ b/faststream/_internal/constants.py @@ -11,7 +11,7 @@ class ContentTypes(str, Enum): json = "application/json" -class _EmptyPlaceholder: +class EmptyPlaceholder: def __repr__(self) -> str: return "EMPTY" @@ -19,10 +19,10 @@ def __bool__(self) -> bool: return False def __eq__(self, other: object) -> bool: - if not isinstance(other, _EmptyPlaceholder): + if not isinstance(other, EmptyPlaceholder): return NotImplemented return True -EMPTY: Any = _EmptyPlaceholder() +EMPTY: Any = EmptyPlaceholder() diff --git a/faststream/_internal/fastapi/router.py b/faststream/_internal/fastapi/router.py index 7bf691b96d..b03c23cc7d 100644 --- a/faststream/_internal/fastapi/router.py +++ b/faststream/_internal/fastapi/router.py @@ -36,6 +36,7 @@ from faststream._internal.fastapi.route import ( wrap_callable_to_fastapi_compatible, ) +from faststream._internal.setup import EmptyState from faststream._internal.types import ( MsgType, P_HandlerParams, @@ -166,6 +167,8 @@ def __init__( self.schema = None + self._state = EmptyState() + super().__init__( prefix=prefix, tags=tags, @@ -316,7 +319,7 @@ async def start_broker_lifespan( context = dict(maybe_context) context.update({"broker": self.broker}) - await self.broker.start() + await self._start_broker() for h in self._after_startup_hooks: h_context = await h(app) diff --git a/faststream/_internal/log/logging.py b/faststream/_internal/log/logging.py index a6139a0f2d..56c5a6d31b 100644 --- a/faststream/_internal/log/logging.py +++ b/faststream/_internal/log/logging.py @@ -49,24 +49,18 @@ def get_broker_logger( name: str, default_context: Mapping[str, str], message_id_ln: int, + fmt: str, ) -> logging.Logger: logger = logging.getLogger(f"faststream.access.{name}") + logger.setLevel(logging.INFO) logger.propagate = False logger.addFilter(ExtendedFilter(default_context, message_id_ln)) - logger.setLevel(logging.INFO) - return logger - - -def set_logger_fmt( - logger: logging.Logger, - fmt: str = "%(asctime)s %(levelname)s - %(message)s", -) -> None: handler = logging.StreamHandler(stream=sys.stdout) - - formatter = ColourizedFormatter( - fmt=fmt, - use_colors=True, + handler.setFormatter( + ColourizedFormatter( + fmt=fmt, + use_colors=True, + ) ) - handler.setFormatter(formatter) - logger.addHandler(handler) + return logger diff --git a/faststream/_internal/proto.py b/faststream/_internal/proto.py index cc6811167b..2ee3cb5106 100644 --- a/faststream/_internal/proto.py +++ b/faststream/_internal/proto.py @@ -1,10 +1,7 @@ from abc import abstractmethod from typing import Any, Optional, Protocol, Type, TypeVar, Union, overload - -class SetupAble(Protocol): - @abstractmethod - def _setup(self) -> None: ... +from .setup import SetupAble class Endpoint(SetupAble, Protocol): diff --git a/faststream/_internal/setup/__init__.py b/faststream/_internal/setup/__init__.py new file mode 100644 index 0000000000..7462d2c586 --- /dev/null +++ b/faststream/_internal/setup/__init__.py @@ -0,0 +1,17 @@ +from .fast_depends import FastDependsData +from .logger import LoggerParamsStorage, LoggerState +from .proto import SetupAble +from .state import EmptyState, SetupState + +__all__ = ( + # state + "SetupState", + "EmptyState", + # proto + "SetupAble", + # FastDepend + "FastDependsData", + # logging + "LoggerState", + "LoggerParamsStorage", +) diff --git a/faststream/_internal/setup/fast_depends.py b/faststream/_internal/setup/fast_depends.py new file mode 100644 index 0000000000..9122492539 --- /dev/null +++ b/faststream/_internal/setup/fast_depends.py @@ -0,0 +1,13 @@ +from dataclasses import dataclass +from typing import TYPE_CHECKING, Any, Callable, Optional, Sequence + +if TYPE_CHECKING: + from faststream._internal.basic_types import Decorator + + +@dataclass +class FastDependsData: + apply_types: bool + is_validate: bool + get_dependent: Optional[Callable[..., Any]] + call_decorators: Sequence["Decorator"] diff --git a/faststream/_internal/setup/logger.py b/faststream/_internal/setup/logger.py new file mode 100644 index 0000000000..216ddc1267 --- /dev/null +++ b/faststream/_internal/setup/logger.py @@ -0,0 +1,159 @@ +import warnings +from dataclasses import dataclass, field +from typing import Optional, Protocol, Type + +from faststream._internal.basic_types import AnyDict, LoggerProto +from faststream._internal.constants import EMPTY +from faststream.exceptions import IncorrectState + +from .proto import SetupAble + +__all__ = ( + "make_logger_state", + "LoggerState", + "LoggerParamsStorage", + "DefaultLoggerStorage", +) + + +def make_logger_state( + logger: Optional["LoggerProto"], + log_level: int, + log_fmt: Optional[str], + default_storag_cls: Type["DefaultLoggerStorage"], +) -> "LoggerState": + if logger is not EMPTY and log_fmt: + warnings.warn( + message="You can't set custom `logger` with `log_fmt` both.", + category=RuntimeWarning, + stacklevel=1, + ) + + if logger is EMPTY: + storage = default_storag_cls(log_fmt) + elif logger is None: + storage = _EmptyLoggerStorage() + else: + storage = _ManualLoggerStorage(logger) + + return LoggerState( + log_level=log_level, + params_storage=storage, + ) + + +class _LoggerObject(Protocol): + logger: Optional["LoggerProto"] + + def log( + self, + message: str, + log_level: int, + extra: Optional["AnyDict"] = None, + exc_info: Optional[Exception] = None, + ) -> None: ... + + +class _NotSetLoggerObject(_LoggerObject): + def __init__(self) -> None: + self.logger = None + + def log( + self, + message: str, + log_level: int, + extra: Optional["AnyDict"] = None, + exc_info: Optional[Exception] = None, + ) -> None: + raise IncorrectState("Logger object was not set up.") + + +class _EmptyLoggerObject(_LoggerObject): + def __init__(self) -> None: + self.logger = None + + def log( + self, + message: str, + log_level: int, + extra: Optional["AnyDict"] = None, + exc_info: Optional[Exception] = None, + ) -> None: + pass + + +class _RealLoggerObject(_LoggerObject): + def __init__(self, logger: "LoggerProto") -> None: + self.logger = logger + + def log( + self, + message: str, + log_level: int, + extra: Optional["AnyDict"] = None, + exc_info: Optional[Exception] = None, + ) -> None: + self.logger.log( + log_level, + message, + extra=extra, + exc_info=exc_info, + ) + + +class LoggerParamsStorage(Protocol): + def setup_log_contest(self, params: "AnyDict") -> None: ... + + def get_logger(self) -> Optional["LoggerProto"]: ... + + +class _EmptyLoggerStorage(LoggerParamsStorage): + def setup_log_contest(self, params: AnyDict) -> None: + pass + + def get_logger(self) -> None: + return None + + +class _ManualLoggerStorage(LoggerParamsStorage): + def __init__(self, logger: "LoggerProto") -> None: + self.__logger = logger + + def setup_log_contest(self, params: AnyDict) -> None: + pass + + def get_logger(self) -> LoggerProto: + return self.__logger + + +class DefaultLoggerStorage(LoggerParamsStorage): + def __init__(self, log_fmt: Optional[str]) -> None: + self._log_fmt = log_fmt + + +@dataclass +class LoggerState(SetupAble): + log_level: int + params_storage: LoggerParamsStorage + + logger: _LoggerObject = field(default=_NotSetLoggerObject(), init=False) + + def log( + self, + message: str, + log_level: Optional[int] = None, + extra: Optional["AnyDict"] = None, + exc_info: Optional[Exception] = None, + ) -> None: + self.logger.log( + log_level=(log_level or self.log_level), + message=message, + extra=extra, + exc_info=exc_info, + ) + + def _setup(self) -> None: + if logger := self.params_storage.get_logger(): + self.logger = _RealLoggerObject(logger) + else: + self.logger = _EmptyLoggerObject() diff --git a/faststream/_internal/setup/proto.py b/faststream/_internal/setup/proto.py new file mode 100644 index 0000000000..21b5eda882 --- /dev/null +++ b/faststream/_internal/setup/proto.py @@ -0,0 +1,7 @@ +from abc import abstractmethod +from typing import Protocol + + +class SetupAble(Protocol): + @abstractmethod + def _setup(self) -> None: ... diff --git a/faststream/_internal/setup/state.py b/faststream/_internal/setup/state.py new file mode 100644 index 0000000000..a2c33d5a3c --- /dev/null +++ b/faststream/_internal/setup/state.py @@ -0,0 +1,99 @@ +from abc import abstractmethod, abstractproperty +from typing import Optional, Type + +from faststream.exceptions import IncorrectState + +from .fast_depends import FastDependsData +from .logger import LoggerState +from .proto import SetupAble + + +class BaseState(SetupAble): + _depends_params: FastDependsData + _logger_params: LoggerState + + @abstractproperty + def depends_params(self) -> FastDependsData: + raise NotImplementedError + + @abstractproperty + def logger_state(self) -> LoggerState: + raise NotImplementedError + + @abstractmethod + def __bool__(self) -> bool: + raise NotImplementedError + + def _setup(self) -> None: + self.logger_state._setup() + + def copy_with_params( + self, + *, + depends_params: Optional[FastDependsData] = None, + logger_state: Optional[LoggerState] = None, + ) -> "SetupState": + return self.__class__( + logger_state=logger_state or self._logger_params, + depends_params=depends_params or self._depends_params, + ) + + def copy_to_state(self, state_cls: Type["SetupState"]) -> "SetupState": + return state_cls( + depends_params=self._depends_params, + logger_state=self._logger_params, + ) + + +class SetupState(BaseState): + """State after broker._setup() called.""" + + def __init__( + self, + *, + logger_state: LoggerState, + depends_params: FastDependsData, + ) -> None: + self._depends_params = depends_params + self._logger_params = logger_state + + @property + def depends_params(self) -> FastDependsData: + return self._depends_params + + @property + def logger_state(self) -> LoggerState: + return self._logger_params + + def __bool__(self) -> bool: + return True + + +class EmptyState(BaseState): + """Initial state for App, broker, etc.""" + + def __init__( + self, + *, + logger_state: Optional[LoggerState] = None, + depends_params: Optional[FastDependsData] = None, + ) -> None: + self._depends_params = depends_params + self._logger_params = logger_state + + @property + def depends_params(self) -> FastDependsData: + if not self._depends_params: + raise IncorrectState + + return self._depends_params + + @property + def logger_state(self) -> LoggerState: + if not self._logger_params: + raise IncorrectState + + return self._logger_params + + def __bool__(self) -> bool: + return False diff --git a/faststream/_internal/subscriber/call_item.py b/faststream/_internal/subscriber/call_item.py index 6b550747d1..264a5cf68b 100644 --- a/faststream/_internal/subscriber/call_item.py +++ b/faststream/_internal/subscriber/call_item.py @@ -14,7 +14,7 @@ from typing_extensions import override -from faststream._internal.proto import SetupAble +from faststream._internal.setup import SetupAble from faststream._internal.types import MsgType from faststream.exceptions import IgnoredException, SetupError diff --git a/faststream/_internal/subscriber/usecase.py b/faststream/_internal/subscriber/usecase.py index 6bc39cb158..27404749c7 100644 --- a/faststream/_internal/subscriber/usecase.py +++ b/faststream/_internal/subscriber/usecase.py @@ -46,6 +46,7 @@ BasePublisherProto, ProducerProto, ) + from faststream._internal.setup import SetupState from faststream._internal.types import ( AsyncCallable, BrokerMiddleware, @@ -154,10 +155,7 @@ def _setup( # type: ignore[override] broker_parser: Optional["CustomCallable"], broker_decoder: Optional["CustomCallable"], # dependant args - apply_types: bool, - is_validate: bool, - _get_dependant: Optional[Callable[..., Any]], - _call_decorators: Iterable["Decorator"], + state: "SetupState", ) -> None: self.lock = MultiLock() @@ -184,10 +182,13 @@ def _setup( # type: ignore[override] call._setup( parser=async_parser, decoder=async_decoder, - apply_types=apply_types, - is_validate=is_validate, - _get_dependant=_get_dependant, - _call_decorators=(*self._call_decorators, *_call_decorators), + apply_types=state.depends_params.apply_types, + is_validate=state.depends_params.is_validate, + _get_dependant=state.depends_params.get_dependent, + _call_decorators=( + *self._call_decorators, + *state.depends_params.call_decorators, + ), broker_dependencies=self._broker_dependencies, ) diff --git a/faststream/_internal/testing/broker.py b/faststream/_internal/testing/broker.py index 2be6ab8f81..b079a240bf 100644 --- a/faststream/_internal/testing/broker.py +++ b/faststream/_internal/testing/broker.py @@ -117,11 +117,10 @@ def _patch_broker(self, broker: Broker) -> Generator[None, None, None]: "ping", return_value=True, ): + broker._setup() yield def _fake_start(self, broker: Broker, *args: Any, **kwargs: Any) -> None: - broker._setup() - patch_broker_calls(broker) for p in broker._publishers.values(): @@ -169,9 +168,12 @@ def _fake_close( if getattr(p, "_fake_handler", None): p.reset_test() # type: ignore[attr-defined] - for sub in self._fake_subscribers: - self.broker._subscribers.pop(hash(sub), None) # type: ignore[attr-defined] - self._fake_subscribers = [] + self.broker._subscribers = { + hash(sub): sub + for sub in self.broker._subscribers.values() + if sub not in self._fake_subscribers + } + self._fake_subscribers.clear() for h in broker._subscribers.values(): h.running = False @@ -193,7 +195,7 @@ async def _fake_connect(broker: Broker, *args: Any, **kwargs: Any) -> None: def patch_broker_calls(broker: "BrokerUsecase[Any, Any]") -> None: """Patch broker calls.""" - broker._abc_start() + broker._setup() for handler in broker._subscribers.values(): for h in handler.calls: diff --git a/faststream/app.py b/faststream/app.py index cea10b9449..ef45aeef79 100644 --- a/faststream/app.py +++ b/faststream/app.py @@ -19,6 +19,7 @@ from faststream._internal.cli.supervisors.utils import set_exit from faststream._internal.context import context from faststream._internal.log.logging import logger +from faststream._internal.setup import EmptyState from faststream._internal.utils import apply_types from faststream._internal.utils.functions import ( drop_response_type, @@ -103,6 +104,7 @@ def __init__( ) self._should_exit = anyio.Event() + self._state = EmptyState() # Specification information self.title = title @@ -192,8 +194,7 @@ async def start( for func in self._on_startup_calling: await func(**run_extra_options) - if self.broker is not None: - await self.broker.start() + await self._start_broker() for func in self._after_startup_calling: await func() diff --git a/faststream/confluent/broker/broker.py b/faststream/confluent/broker/broker.py index 7b31cdf5ae..59b1063f0d 100644 --- a/faststream/confluent/broker/broker.py +++ b/faststream/confluent/broker/broker.py @@ -16,17 +16,14 @@ ) import anyio +import confluent_kafka from typing_extensions import Annotated, Doc, override from faststream.__about__ import SERVICE_NAME +from faststream._internal.broker.broker import BrokerUsecase from faststream._internal.constants import EMPTY from faststream._internal.utils.data import filter_by_dict -from faststream.confluent.broker.logging import KafkaLoggingBroker -from faststream.confluent.broker.registrator import KafkaRegistrator -from faststream.confluent.client import ( - AsyncConfluentConsumer, - AsyncConfluentProducer, -) +from faststream.confluent.client import AsyncConfluentConsumer, AsyncConfluentProducer from faststream.confluent.config import ConfluentFastConfig from faststream.confluent.publisher.producer import AsyncConfluentFastProducer from faststream.confluent.schemas.params import ConsumerConnectionParams @@ -34,6 +31,9 @@ from faststream.exceptions import NOT_CONNECTED_YET from faststream.message import gen_cor_id +from .logging import make_kafka_logger_state +from .registrator import KafkaRegistrator + if TYPE_CHECKING: from types import TracebackType @@ -60,7 +60,13 @@ class KafkaBroker( KafkaRegistrator, - KafkaLoggingBroker, + BrokerUsecase[ + Union[ + confluent_kafka.Message, + Tuple[confluent_kafka.Message, ...], + ], + Callable[..., AsyncConfluentConsumer], + ], ): url: List[str] _producer: Optional[AsyncConfluentFastProducer] @@ -384,9 +390,11 @@ def __init__( security=security, tags=tags, # Logging args - logger=logger, - log_level=log_level, - log_fmt=log_fmt, + logger_state=make_kafka_logger_state( + logger=logger, + log_level=log_level, + log_fmt=log_fmt, + ), # FastDepends args _get_dependant=_get_dependant, _call_decorators=_call_decorators, @@ -397,17 +405,19 @@ def __init__( self._producer = None self.config = ConfluentFastConfig(config) - async def _close( + async def close( self, exc_type: Optional[Type[BaseException]] = None, exc_val: Optional[BaseException] = None, exc_tb: Optional["TracebackType"] = None, ) -> None: + await super().close(exc_type, exc_val, exc_tb) + if self._producer is not None: # pragma: no branch await self._producer.stop() self._producer = None - await super()._close(exc_type, exc_val, exc_tb) + self._connection = None async def connect( self, @@ -435,7 +445,6 @@ async def _connect( # type: ignore[override] native_producer = AsyncConfluentProducer( **kwargs, client_id=client_id, - logger=self.logger, config=self.config, ) @@ -448,20 +457,15 @@ async def _connect( # type: ignore[override] return partial( AsyncConfluentConsumer, **filter_by_dict(ConsumerConnectionParams, kwargs), - logger=self.logger, + logger=self._state.logger_state, config=self.config, ) async def start(self) -> None: + await self.connect() + self._setup() await super().start() - for handler in self._subscribers.values(): - self._log( - f"`{handler.call_name}` waiting for messages", - extra=handler.get_log_context(None), - ) - await handler.start() - @property def _subscriber_setup_extra(self) -> "AnyDict": return { diff --git a/faststream/confluent/broker/logging.py b/faststream/confluent/broker/logging.py index 6c549f5dc6..ec17abb215 100644 --- a/faststream/confluent/broker/logging.py +++ b/faststream/confluent/broker/logging.py @@ -1,72 +1,67 @@ -import logging -from typing import TYPE_CHECKING, Any, Callable, ClassVar, Optional, Tuple, Union +from functools import partial +from typing import TYPE_CHECKING, Optional -from faststream._internal.broker.broker import BrokerUsecase -from faststream._internal.constants import EMPTY from faststream._internal.log.logging import get_broker_logger -from faststream.confluent.client import AsyncConfluentConsumer +from faststream._internal.setup.logger import ( + DefaultLoggerStorage, + make_logger_state, +) if TYPE_CHECKING: - import confluent_kafka + from faststream._internal.basic_types import AnyDict, LoggerProto - from faststream._internal.basic_types import LoggerProto - - -class KafkaLoggingBroker( - BrokerUsecase[ - Union["confluent_kafka.Message", Tuple["confluent_kafka.Message", ...]], - Callable[..., AsyncConfluentConsumer], - ] -): - """A class that extends the LoggingMixin class and adds additional functionality for logging Kafka related information.""" - - _max_topic_len: int - _max_group_len: int - __max_msg_id_ln: ClassVar[int] = 10 +class KafkaParamsStorage(DefaultLoggerStorage): def __init__( self, - *args: Any, - logger: Optional["LoggerProto"] = EMPTY, - log_level: int = logging.INFO, - log_fmt: Optional[str] = None, - **kwargs: Any, + log_fmt: Optional[str], ) -> None: - """Initialize the class.""" - super().__init__( - *args, - logger=logger, - # TODO: generate unique logger names to not share between brokers - default_logger=get_broker_logger( - name="confluent", - default_context={ - "topic": "", - "group_id": "", - }, - message_id_ln=self.__max_msg_id_ln, - ), - log_level=log_level, - log_fmt=log_fmt, - **kwargs, - ) + super().__init__(log_fmt) + self._max_topic_len = 4 self._max_group_len = 0 - def get_fmt(self) -> str: - return ( - "%(asctime)s %(levelname)-8s - " - + f"%(topic)-{self._max_topic_len}s | " - + (f"%(group_id)-{self._max_group_len}s | " if self._max_group_len else "") - + f"%(message_id)-{self.__max_msg_id_ln}s " - + "- %(message)s" + def setup_log_contest(self, params: "AnyDict") -> None: + self._max_topic_len = max( + ( + self._max_topic_len, + len(params.get("topic", "")), + ) + ) + self._max_group_len = max( + ( + self._max_group_len, + len(params.get("group_id", "")), + ) + ) + + def get_logger(self) -> Optional["LoggerProto"]: + message_id_ln = 10 + + # TODO: generate unique logger names to not share between brokers + return get_broker_logger( + name="confluent", + default_context={ + "topic": "", + "group_id": "", + }, + message_id_ln=message_id_ln, + fmt=self._log_fmt + or ( + "%(asctime)s %(levelname)-8s - " + + f"%(topic)-{self._max_topic_len}s | " + + ( + f"%(group_id)-{self._max_group_len}s | " + if self._max_group_len + else "" + ) + + f"%(message_id)-{message_id_ln}s " + + "- %(message)s" + ), ) - def _setup_log_context( - self, - *, - topic: str = "", - group_id: Optional[str] = None, - ) -> None: - """Set up log context.""" - self._max_topic_len = max((self._max_topic_len, len(topic))) - self._max_group_len = max((self._max_group_len, len(group_id or ""))) + +make_kafka_logger_state = partial( + make_logger_state, + default_storag_cls=KafkaParamsStorage, +) diff --git a/faststream/confluent/client.py b/faststream/confluent/client.py index 2c62873ef3..bd30ef2a56 100644 --- a/faststream/confluent/client.py +++ b/faststream/confluent/client.py @@ -30,6 +30,7 @@ from typing_extensions import NotRequired, TypedDict from faststream._internal.basic_types import AnyDict, LoggerProto + from faststream._internal.setup.logger import LoggerState class _SendKwargs(TypedDict): value: Optional[Union[str, bytes]] @@ -46,7 +47,6 @@ class AsyncConfluentProducer: def __init__( self, *, - logger: Optional["LoggerProto"], config: config_module.ConfluentFastConfig, bootstrap_servers: Union[str, List[str]] = "localhost", client_id: Optional[str] = None, @@ -68,8 +68,6 @@ def __init__( sasl_plain_password: Optional[str] = None, sasl_plain_username: Optional[str] = None, ) -> None: - self.logger = logger - if isinstance(bootstrap_servers, Iterable) and not isinstance( bootstrap_servers, str ): @@ -112,7 +110,7 @@ def __init__( } ) - self.producer = Producer(final_config, logger=self.logger) + self.producer = Producer(final_config) self.__running = True self._poll_task = asyncio.create_task(self._poll_loop()) @@ -223,7 +221,7 @@ def __init__( self, *topics: str, partitions: Sequence["TopicPartition"], - logger: Optional["LoggerProto"], + logger: "LoggerState", config: config_module.ConfluentFastConfig, bootstrap_servers: Union[str, List[str]] = "localhost", client_id: Optional[str] = "confluent-kafka-consumer", @@ -251,7 +249,7 @@ def __init__( sasl_plain_password: Optional[str] = None, sasl_plain_username: Optional[str] = None, ) -> None: - self.logger = logger + self.logger_state = logger if isinstance(bootstrap_servers, Iterable) and not isinstance( bootstrap_servers, str @@ -312,7 +310,7 @@ def __init__( ) self.config = final_config - self.consumer = Consumer(final_config, logger=self.logger) + self.consumer = Consumer(final_config) @property def topics_to_create(self) -> List[str]: @@ -322,13 +320,16 @@ async def start(self) -> None: """Starts the Kafka consumer and subscribes to the specified topics.""" if self.allow_auto_create_topics: await call_or_await( - create_topics, self.topics_to_create, self.config, self.logger + create_topics, + self.topics_to_create, + self.config, + self.logger_state.logger.logger, ) - elif self.logger: - self.logger.log( - logging.WARNING, - "Auto create topics is disabled. Make sure the topics exist.", + else: + self.logger_state.log( + log_level=logging.WARNING, + message="Auto create topics is disabled. Make sure the topics exist.", ) if self.topics: @@ -359,10 +360,10 @@ async def stop(self) -> None: # No offset stored issue is not a problem - https://github.com/confluentinc/confluent-kafka-python/issues/295#issuecomment-355907183 if "No offset stored" in str(e): pass - elif self.logger: - self.logger.log( - logging.ERROR, - "Consumer closing error occurred.", + else: + self.logger_state.log( + log_level=logging.ERROR, + message="Consumer closing error occurred.", exc_info=e, ) diff --git a/faststream/confluent/subscriber/usecase.py b/faststream/confluent/subscriber/usecase.py index 3bc8e25cdd..5b4cf0a6ff 100644 --- a/faststream/confluent/subscriber/usecase.py +++ b/faststream/confluent/subscriber/usecase.py @@ -26,8 +26,9 @@ if TYPE_CHECKING: from fast_depends.dependencies import Depends - from faststream._internal.basic_types import AnyDict, Decorator, LoggerProto + from faststream._internal.basic_types import AnyDict, LoggerProto from faststream._internal.publisher.proto import ProducerProto + from faststream._internal.setup import SetupState from faststream._internal.types import ( AsyncCallable, BrokerMiddleware, @@ -116,10 +117,7 @@ def _setup( # type: ignore[override] broker_parser: Optional["CustomCallable"], broker_decoder: Optional["CustomCallable"], # dependant args - apply_types: bool, - is_validate: bool, - _get_dependant: Optional[Callable[..., Any]], - _call_decorators: Iterable["Decorator"], + state: "SetupState", ) -> None: self.client_id = client_id self.builder = builder @@ -131,10 +129,7 @@ def _setup( # type: ignore[override] extra_context=extra_context, broker_parser=broker_parser, broker_decoder=broker_decoder, - apply_types=apply_types, - is_validate=is_validate, - _get_dependant=_get_dependant, - _call_decorators=_call_decorators, + state=state, ) @override diff --git a/faststream/confluent/testing.py b/faststream/confluent/testing.py index 13be8c316c..58704c3d6e 100644 --- a/faststream/confluent/testing.py +++ b/faststream/confluent/testing.py @@ -18,6 +18,7 @@ if TYPE_CHECKING: from faststream._internal.basic_types import SendableMessage + from faststream._internal.setup.logger import LoggerState from faststream.confluent.publisher.publisher import SpecificationPublisher from faststream.confluent.subscriber.usecase import LogicSubscriber @@ -88,6 +89,9 @@ def __init__(self, broker: KafkaBroker) -> None: self._parser = resolve_custom_func(broker._parser, default.parse_message) self._decoder = resolve_custom_func(broker._decoder, default.decode_message) + def _setup(self, logger_stater: "LoggerState") -> None: + pass + @override async def publish( # type: ignore[override] self, diff --git a/faststream/exceptions.py b/faststream/exceptions.py index f7774ed818..8c66a92808 100644 --- a/faststream/exceptions.py +++ b/faststream/exceptions.py @@ -111,6 +111,10 @@ class SubscriberNotFound(FastStreamException): """Raises as a service message or in tests.""" +class IncorrectState(FastStreamException): + """Raises in FSM at wrong state calling.""" + + class ContextError(FastStreamException, KeyError): """Raises if context exception occurred.""" diff --git a/faststream/kafka/broker/broker.py b/faststream/kafka/broker/broker.py index 156bae9964..6cb06bb057 100644 --- a/faststream/kafka/broker/broker.py +++ b/faststream/kafka/broker/broker.py @@ -22,16 +22,18 @@ from typing_extensions import Annotated, Doc, override from faststream.__about__ import SERVICE_NAME +from faststream._internal.broker.broker import BrokerUsecase from faststream._internal.constants import EMPTY from faststream._internal.utils.data import filter_by_dict from faststream.exceptions import NOT_CONNECTED_YET -from faststream.kafka.broker.logging import KafkaLoggingBroker -from faststream.kafka.broker.registrator import KafkaRegistrator from faststream.kafka.publisher.producer import AioKafkaFastProducer from faststream.kafka.schemas.params import ConsumerConnectionParams from faststream.kafka.security import parse_security from faststream.message import gen_cor_id +from .logging import make_kafka_logger_state +from .registrator import KafkaRegistrator + Partition = TypeVar("Partition") if TYPE_CHECKING: @@ -230,7 +232,10 @@ class KafkaInitKwargs(TypedDict, total=False): class KafkaBroker( KafkaRegistrator, - KafkaLoggingBroker, + BrokerUsecase[ + Union[aiokafka.ConsumerRecord, Tuple[aiokafka.ConsumerRecord, ...]], + Callable[..., aiokafka.AIOKafkaConsumer], + ], ): url: List[str] _producer: Optional["AioKafkaFastProducer"] @@ -565,9 +570,11 @@ def __init__( security=security, tags=tags, # Logging args - logger=logger, - log_level=log_level, - log_fmt=log_fmt, + logger_state=make_kafka_logger_state( + logger=logger, + log_level=log_level, + log_fmt=log_fmt, + ), # FastDepends args _get_dependant=_get_dependant, _call_decorators=_call_decorators, @@ -578,17 +585,19 @@ def __init__( self.client_id = client_id self._producer = None - async def _close( + async def close( self, exc_type: Optional[Type[BaseException]] = None, exc_val: Optional[BaseException] = None, exc_tb: Optional["TracebackType"] = None, ) -> None: + await super().close(exc_type, exc_val, exc_tb) + if self._producer is not None: # pragma: no branch await self._producer.stop() self._producer = None - await super()._close(exc_type, exc_val, exc_tb) + self._connection = None @override async def connect( # type: ignore[override] @@ -643,15 +652,10 @@ async def _connect( # type: ignore[override] async def start(self) -> None: """Connect broker to Kafka and startup all subscribers.""" + await self.connect() + self._setup() await super().start() - for handler in self._subscribers.values(): - self._log( - f"`{handler.call_name}` waiting for messages", - extra=handler.get_log_context(None), - ) - await handler.start() - @property def _subscriber_setup_extra(self) -> "AnyDict": return { diff --git a/faststream/kafka/broker/logging.py b/faststream/kafka/broker/logging.py index bb7fd2c6e7..5334f4a70d 100644 --- a/faststream/kafka/broker/logging.py +++ b/faststream/kafka/broker/logging.py @@ -1,71 +1,67 @@ -import logging -from typing import TYPE_CHECKING, Any, Callable, ClassVar, Optional, Tuple, Union +from functools import partial +from typing import TYPE_CHECKING, Optional -from faststream._internal.broker.broker import BrokerUsecase -from faststream._internal.constants import EMPTY from faststream._internal.log.logging import get_broker_logger +from faststream._internal.setup.logger import ( + DefaultLoggerStorage, + make_logger_state, +) if TYPE_CHECKING: - import aiokafka + from faststream._internal.basic_types import AnyDict, LoggerProto - from faststream._internal.basic_types import LoggerProto - - -class KafkaLoggingBroker( - BrokerUsecase[ - Union["aiokafka.ConsumerRecord", Tuple["aiokafka.ConsumerRecord", ...]], - Callable[..., "aiokafka.AIOKafkaConsumer"], - ] -): - """A class that extends the LoggingMixin class and adds additional functionality for logging Kafka related information.""" - - _max_topic_len: int - _max_group_len: int - __max_msg_id_ln: ClassVar[int] = 10 +class KafkaParamsStorage(DefaultLoggerStorage): def __init__( self, - *args: Any, - logger: Optional["LoggerProto"] = EMPTY, - log_level: int = logging.INFO, - log_fmt: Optional[str] = None, - **kwargs: Any, + log_fmt: Optional[str], ) -> None: - """Initialize the class.""" - super().__init__( - *args, - logger=logger, - # TODO: generate unique logger names to not share between brokers - default_logger=get_broker_logger( - name="kafka", - default_context={ - "topic": "", - "group_id": "", - }, - message_id_ln=self.__max_msg_id_ln, - ), - log_level=log_level, - log_fmt=log_fmt, - **kwargs, - ) + super().__init__(log_fmt) + self._max_topic_len = 4 self._max_group_len = 0 - def get_fmt(self) -> str: - return ( - "%(asctime)s %(levelname)-8s - " - + f"%(topic)-{self._max_topic_len}s | " - + (f"%(group_id)-{self._max_group_len}s | " if self._max_group_len else "") - + f"%(message_id)-{self.__max_msg_id_ln}s " - + "- %(message)s" + def setup_log_contest(self, params: "AnyDict") -> None: + self._max_topic_len = max( + ( + self._max_topic_len, + len(params.get("topic", "")), + ) + ) + self._max_group_len = max( + ( + self._max_group_len, + len(params.get("group_id", "")), + ) + ) + + def get_logger(self) -> Optional["LoggerProto"]: + message_id_ln = 10 + + # TODO: generate unique logger names to not share between brokers + return get_broker_logger( + name="kafka", + default_context={ + "topic": "", + "group_id": "", + }, + message_id_ln=message_id_ln, + fmt=self._log_fmt + or ( + "%(asctime)s %(levelname)-8s - " + + f"%(topic)-{self._max_topic_len}s | " + + ( + f"%(group_id)-{self._max_group_len}s | " + if self._max_group_len + else "" + ) + + f"%(message_id)-{message_id_ln}s " + + "- %(message)s" + ), ) - def _setup_log_context( - self, - *, - topic: str = "", - group_id: Optional[str] = None, - ) -> None: - """Set up log context.""" - self._max_topic_len = max((self._max_topic_len, len(topic))) - self._max_group_len = max((self._max_group_len, len(group_id or ""))) + +make_kafka_logger_state = partial( + make_logger_state, + default_storag_cls=KafkaParamsStorage, +) diff --git a/faststream/kafka/subscriber/usecase.py b/faststream/kafka/subscriber/usecase.py index cabc505d29..3a32f6016c 100644 --- a/faststream/kafka/subscriber/usecase.py +++ b/faststream/kafka/subscriber/usecase.py @@ -36,8 +36,9 @@ from aiokafka.abc import ConsumerRebalanceListener from fast_depends.dependencies import Depends - from faststream._internal.basic_types import AnyDict, Decorator, LoggerProto + from faststream._internal.basic_types import AnyDict, LoggerProto from faststream._internal.publisher.proto import ProducerProto + from faststream._internal.setup import SetupState from faststream.message import StreamMessage @@ -121,10 +122,7 @@ def _setup( # type: ignore[override] broker_parser: Optional["CustomCallable"], broker_decoder: Optional["CustomCallable"], # dependant args - apply_types: bool, - is_validate: bool, - _get_dependant: Optional[Callable[..., Any]], - _call_decorators: Iterable["Decorator"], + state: "SetupState", ) -> None: self.client_id = client_id self.builder = builder @@ -136,10 +134,7 @@ def _setup( # type: ignore[override] extra_context=extra_context, broker_parser=broker_parser, broker_decoder=broker_decoder, - apply_types=apply_types, - is_validate=is_validate, - _get_dependant=_get_dependant, - _call_decorators=_call_decorators, + state=state, ) async def start(self) -> None: diff --git a/faststream/middlewares/logging.py b/faststream/middlewares/logging.py index c0ab3c8479..df47735543 100644 --- a/faststream/middlewares/logging.py +++ b/faststream/middlewares/logging.py @@ -1,9 +1,8 @@ import logging from typing import TYPE_CHECKING, Any, Optional, Type -from typing_extensions import Self - from faststream._internal.context.repository import context +from faststream._internal.setup.logger import LoggerState from faststream.exceptions import IgnoredException from .base import BaseMiddleware @@ -11,63 +10,59 @@ if TYPE_CHECKING: from types import TracebackType - from faststream._internal.basic_types import LoggerProto from faststream.message import StreamMessage -class CriticalLogMiddleware(BaseMiddleware): - """A middleware class for logging critical errors.""" - - def __init__( - self, - logger: Optional["LoggerProto"], - log_level: int, - ) -> None: +class CriticalLogMiddleware: + def __init__(self, logger: LoggerState) -> None: """Initialize the class.""" self.logger = logger - self.log_level = log_level - def __call__(self, msg: Optional[Any]) -> Self: - """Call the object with a message.""" - self.msg = msg - return self + def __call__(self, msg: Optional[Any] = None) -> Any: + return LoggingMiddleware(logger=self.logger) + + +class LoggingMiddleware(BaseMiddleware): + """A middleware class for logging critical errors.""" + + def __init__(self, logger: LoggerState) -> None: + self.logger = logger async def on_consume( self, msg: "StreamMessage[Any]", ) -> "StreamMessage[Any]": - if self.logger is not None: - c = context.get_local("log_context", {}) - self.logger.log(self.log_level, "Received", extra=c) - + self.logger.log( + "Received", + extra=context.get_local("log_context", {}), + ) return await super().on_consume(msg) - async def after_processed( + async def __aexit__( self, exc_type: Optional[Type[BaseException]] = None, exc_val: Optional[BaseException] = None, exc_tb: Optional["TracebackType"] = None, ) -> bool: """Asynchronously called after processing.""" - if self.logger is not None: - c = context.get_local("log_context", {}) - - if exc_type: - if issubclass(exc_type, IgnoredException): - self.logger.log( - logging.INFO, - exc_val, - extra=c, - ) - else: - self.logger.log( - logging.ERROR, - f"{exc_type.__name__}: {exc_val}", - exc_info=exc_val, - extra=c, - ) - - self.logger.log(self.log_level, "Processed", extra=c) + c = context.get_local("log_context", {}) + + if exc_type: + if issubclass(exc_type, IgnoredException): + self.logger.log( + logging.INFO, + exc_val, + extra=c, + ) + else: + self.logger.log( + logging.ERROR, + f"{exc_type.__name__}: {exc_val}", + exc_info=exc_val, + extra=c, + ) + + self.logger.log("Processed", extra=c) await super().after_processed(exc_type, exc_val, exc_tb) diff --git a/faststream/nats/broker/broker.py b/faststream/nats/broker/broker.py index f07a278d6c..46942f6e5f 100644 --- a/faststream/nats/broker/broker.py +++ b/faststream/nats/broker/broker.py @@ -24,21 +24,25 @@ DEFAULT_PENDING_SIZE, DEFAULT_PING_INTERVAL, DEFAULT_RECONNECT_TIME_WAIT, + Client, ) +from nats.aio.msg import Msg from nats.errors import Error from nats.js.errors import BadRequestError from typing_extensions import Annotated, Doc, override from faststream.__about__ import SERVICE_NAME +from faststream._internal.broker.broker import BrokerUsecase from faststream._internal.constants import EMPTY from faststream.message import gen_cor_id -from faststream.nats.broker.logging import NatsLoggingBroker -from faststream.nats.broker.registrator import NatsRegistrator from faststream.nats.helpers import KVBucketDeclarer, OSBucketDeclarer from faststream.nats.publisher.producer import NatsFastProducer, NatsJSFastProducer from faststream.nats.security import parse_security from faststream.nats.subscriber.subscriber import SpecificationSubscriber +from .logging import make_nats_logger_state +from .registrator import NatsRegistrator + if TYPE_CHECKING: import ssl from types import TracebackType @@ -46,13 +50,11 @@ from fast_depends.dependencies import Depends from nats.aio.client import ( Callback, - Client, Credentials, ErrorCallback, JWTCallback, SignatureCallback, ) - from nats.aio.msg import Msg from nats.js.api import Placement, RePublish, StorageType from nats.js.client import JetStreamContext from nats.js.kv import KeyValue @@ -214,7 +216,7 @@ class NatsInitKwargs(TypedDict, total=False): class NatsBroker( NatsRegistrator, - NatsLoggingBroker, + BrokerUsecase[Msg, Client], ): """A class to represent a NATS broker.""" @@ -532,9 +534,11 @@ def __init__( security=security, tags=tags, # logging - logger=logger, - log_level=log_level, - log_fmt=log_fmt, + logger_state=make_nats_logger_state( + logger=logger, + log_level=log_level, + log_fmt=log_fmt, + ), # FastDepends args apply_types=apply_types, validate=validate, @@ -597,29 +601,29 @@ async def _connect(self, **kwargs: Any) -> "Client": return connection - async def _close( + async def close( self, exc_type: Optional[Type[BaseException]] = None, exc_val: Optional[BaseException] = None, exc_tb: Optional["TracebackType"] = None, ) -> None: - self._producer = None - self._js_producer = None - self.stream = None + await super().close(exc_type, exc_val, exc_tb) if self._connection is not None: await self._connection.drain() + self._connection = None - await super()._close(exc_type, exc_val, exc_tb) + self.stream = None + self._producer = None + self._js_producer = None self.__is_connected = False async def start(self) -> None: """Connect broker to NATS cluster and startup all subscribers.""" - await super().start() + await self.connect() + self._setup() - assert self._connection # nosec B101 assert self.stream, "Broker should be started already" # nosec B101 - assert self._producer, "Broker should be started already" # nosec B101 for stream in filter( lambda x: x.declare, @@ -645,7 +649,7 @@ async def start(self) -> None: ): old_config = (await self.stream.stream_info(stream.name)).config - self._log(str(e), logging.WARNING, log_context) + self._state.logger_state.log(str(e), logging.WARNING, log_context) await self.stream.update_stream( config=stream.config, subjects=tuple( @@ -654,19 +658,15 @@ async def start(self) -> None: ) else: # pragma: no cover - self._log(str(e), logging.ERROR, log_context, exc_info=e) + self._state.logger_state.log( + str(e), logging.ERROR, log_context, exc_info=e + ) finally: # prevent from double declaration stream.declare = False - # TODO: filter by already running handlers after TestClient refactor - for handler in self._subscribers.values(): - self._log( - f"`{handler.call_name}` waiting for messages", - extra=handler.get_log_context(None), - ) - await handler.start() + await super().start() @override async def publish( # type: ignore[override] @@ -923,7 +923,7 @@ async def wrapper(err: Exception) -> None: await error_cb(err) if isinstance(err, Error) and self.__is_connected: - self._log( + self._state.logger_state.log( f"Connection broken with {err!r}", logging.WARNING, c, exc_info=err ) self.__is_connected = False @@ -941,7 +941,7 @@ async def wrapper() -> None: await cb() if not self.__is_connected: - self._log("Connection established", logging.INFO, c) + self._state.logger_state.log("Connection established", logging.INFO, c) self.__is_connected = True return wrapper diff --git a/faststream/nats/broker/logging.py b/faststream/nats/broker/logging.py index dd163a1c77..0cf9ad45c3 100644 --- a/faststream/nats/broker/logging.py +++ b/faststream/nats/broker/logging.py @@ -1,74 +1,76 @@ -import logging -from typing import TYPE_CHECKING, Any, ClassVar, Optional +from functools import partial +from typing import TYPE_CHECKING, Optional -from nats.aio.client import Client -from nats.aio.msg import Msg - -from faststream._internal.broker.broker import BrokerUsecase -from faststream._internal.constants import EMPTY from faststream._internal.log.logging import get_broker_logger +from faststream._internal.setup.logger import ( + DefaultLoggerStorage, + make_logger_state, +) if TYPE_CHECKING: - from faststream._internal.basic_types import LoggerProto - + from faststream._internal.basic_types import AnyDict, LoggerProto -class NatsLoggingBroker(BrokerUsecase[Msg, Client]): - """A class that extends the LoggingMixin class and adds additional functionality for logging NATS related information.""" - - _max_queue_len: int - _max_subject_len: int - __max_msg_id_ln: ClassVar[int] = 10 +class NatsParamsStorage(DefaultLoggerStorage): def __init__( self, - *args: Any, - logger: Optional["LoggerProto"] = EMPTY, - log_level: int = logging.INFO, - log_fmt: Optional[str] = None, - **kwargs: Any, + log_fmt: Optional[str], ) -> None: - """Initialize the NATS logging mixin.""" - super().__init__( - *args, - logger=logger, - # TODO: generate unique logger names to not share between brokers - default_logger=get_broker_logger( - name="nats", - default_context={ - "subject": "", - "stream": "", - "queue": "", - }, - message_id_ln=self.__max_msg_id_ln, - ), - log_level=log_level, - log_fmt=log_fmt, - **kwargs, - ) + super().__init__(log_fmt) self._max_queue_len = 0 self._max_stream_len = 0 self._max_subject_len = 4 - def get_fmt(self) -> str: - """Fallback method to get log format if `log_fmt` if not specified.""" - return ( - "%(asctime)s %(levelname)-8s - " - + (f"%(stream)-{self._max_stream_len}s | " if self._max_stream_len else "") - + (f"%(queue)-{self._max_queue_len}s | " if self._max_queue_len else "") - + f"%(subject)-{self._max_subject_len}s | " - + f"%(message_id)-{self.__max_msg_id_ln}s - " - "%(message)s" + def setup_log_contest(self, params: "AnyDict") -> None: + self._max_subject_len = max( + ( + self._max_subject_len, + len(params.get("subject", "")), + ) + ) + self._max_queue_len = max( + ( + self._max_queue_len, + len(params.get("queue", "")), + ) + ) + self._max_stream_len = max( + ( + self._max_stream_len, + len(params.get("stream", "")), + ) + ) + + def get_logger(self) -> Optional["LoggerProto"]: + message_id_ln = 10 + + # TODO: generate unique logger names to not share between brokers + return get_broker_logger( + name="nats", + default_context={ + "subject": "", + "stream": "", + "queue": "", + }, + message_id_ln=message_id_ln, + fmt=self._log_fmt + or ( + "%(asctime)s %(levelname)-8s - " + + ( + f"%(stream)-{self._max_stream_len}s | " + if self._max_stream_len + else "" + ) + + (f"%(queue)-{self._max_queue_len}s | " if self._max_queue_len else "") + + f"%(subject)-{self._max_subject_len}s | " + + f"%(message_id)-{message_id_ln}s - " + "%(message)s" + ), ) - def _setup_log_context( - self, - *, - queue: Optional[str] = None, - subject: Optional[str] = None, - stream: Optional[str] = None, - ) -> None: - """Setup subscriber's information to generate default log format.""" - self._max_subject_len = max((self._max_subject_len, len(subject or ""))) - self._max_queue_len = max((self._max_queue_len, len(queue or ""))) - self._max_stream_len = max((self._max_stream_len, len(stream or ""))) + +make_nats_logger_state = partial( + make_logger_state, + default_storag_cls=NatsParamsStorage, +) diff --git a/faststream/nats/subscriber/usecase.py b/faststream/nats/subscriber/usecase.py index de1e5e8137..19c0778092 100644 --- a/faststream/nats/subscriber/usecase.py +++ b/faststream/nats/subscriber/usecase.py @@ -54,11 +54,11 @@ from faststream._internal.basic_types import ( AnyDict, - Decorator, LoggerProto, SendableMessage, ) from faststream._internal.publisher.proto import ProducerProto + from faststream._internal.setup import SetupState from faststream._internal.types import ( AsyncCallable, BrokerMiddleware, @@ -139,10 +139,7 @@ def _setup( # type: ignore[override] broker_parser: Optional["CustomCallable"], broker_decoder: Optional["CustomCallable"], # dependant args - apply_types: bool, - is_validate: bool, - _get_dependant: Optional[Callable[..., Any]], - _call_decorators: Iterable["Decorator"], + state: "SetupState", ) -> None: self._connection = connection @@ -153,10 +150,7 @@ def _setup( # type: ignore[override] extra_context=extra_context, broker_parser=broker_parser, broker_decoder=broker_decoder, - apply_types=apply_types, - is_validate=is_validate, - _get_dependant=_get_dependant, - _call_decorators=_call_decorators, + state=state, ) @property diff --git a/faststream/rabbit/broker/broker.py b/faststream/rabbit/broker/broker.py index 18b23f6a53..1548d42243 100644 --- a/faststream/rabbit/broker/broker.py +++ b/faststream/rabbit/broker/broker.py @@ -12,15 +12,14 @@ from urllib.parse import urlparse import anyio -from aio_pika import connect_robust +from aio_pika import IncomingMessage, RobustConnection, connect_robust from typing_extensions import Annotated, Doc, override from faststream.__about__ import SERVICE_NAME +from faststream._internal.broker.broker import BrokerUsecase from faststream._internal.constants import EMPTY from faststream.exceptions import NOT_CONNECTED_YET from faststream.message import gen_cor_id -from faststream.rabbit.broker.logging import RabbitLoggingBroker -from faststream.rabbit.broker.registrator import RabbitRegistrator from faststream.rabbit.helpers.declarer import RabbitDeclarer from faststream.rabbit.publisher.producer import AioPikaFastProducer from faststream.rabbit.schemas import ( @@ -29,18 +28,18 @@ RabbitQueue, ) from faststream.rabbit.security import parse_security -from faststream.rabbit.subscriber.subscriber import SpecificationSubscriber from faststream.rabbit.utils import build_url +from .logging import make_rabbit_logger_state +from .registrator import RabbitRegistrator + if TYPE_CHECKING: from ssl import SSLContext from types import TracebackType import aiormq from aio_pika import ( - IncomingMessage, RobustChannel, - RobustConnection, RobustExchange, RobustQueue, ) @@ -62,7 +61,7 @@ class RabbitBroker( RabbitRegistrator, - RabbitLoggingBroker, + BrokerUsecase[IncomingMessage, RobustConnection], ): """A class to represent a RabbitMQ broker.""" @@ -274,9 +273,11 @@ def __init__( security=security, tags=tags, # Logging args - logger=logger, - log_level=log_level, - log_fmt=log_fmt, + logger_state=make_rabbit_logger_state( + logger=logger, + log_level=log_level, + log_fmt=log_fmt, + ), # FastDepends args apply_types=apply_types, validate=validate, @@ -453,7 +454,6 @@ async def _connect( # type: ignore[override] ) if self._channel is None: # pragma: no branch - max_consumers = self._max_consumers channel = self._channel = cast( "RobustChannel", await connection.channel( @@ -472,40 +472,39 @@ async def _connect( # type: ignore[override] parser=self._parser, ) - if max_consumers: - c = SpecificationSubscriber.build_log_context( - None, - RabbitQueue(""), - RabbitExchange(""), - ) - self._log(f"Set max consumers to {max_consumers}", extra=c) - await channel.set_qos(prefetch_count=int(max_consumers)) + if self._max_consumers: + await channel.set_qos(prefetch_count=int(self._max_consumers)) return connection - async def _close( + async def close( self, exc_type: Optional[Type[BaseException]] = None, exc_val: Optional[BaseException] = None, exc_tb: Optional["TracebackType"] = None, ) -> None: + await super().close(exc_type, exc_val, exc_tb) + if self._channel is not None: if not self._channel.is_closed: await self._channel.close() self._channel = None - self.declarer = None - self._producer = None - if self._connection is not None: await self._connection.close() + self._connection = None - await super()._close(exc_type, exc_val, exc_tb) + self.declarer = None + self._producer = None async def start(self) -> None: """Connect broker to RabbitMQ and startup all subscribers.""" - await super().start() + await self.connect() + self._setup() + + if self._max_consumers: + self._state.logger_state.log(f"Set max consumers to {self._max_consumers}") assert self.declarer, NOT_CONNECTED_YET # nosec B101 @@ -513,12 +512,7 @@ async def start(self) -> None: if publisher.exchange is not None: await self.declare_exchange(publisher.exchange) - for subscriber in self._subscribers.values(): - self._log( - f"`{subscriber.call_name}` waiting for messages", - extra=subscriber.get_log_context(None), - ) - await subscriber.start() + await super().start() @override async def publish( # type: ignore[override] diff --git a/faststream/rabbit/broker/logging.py b/faststream/rabbit/broker/logging.py index cf104338a7..4074d3e6df 100644 --- a/faststream/rabbit/broker/logging.py +++ b/faststream/rabbit/broker/logging.py @@ -1,66 +1,59 @@ -import logging -from typing import TYPE_CHECKING, Any, ClassVar, Optional +from functools import partial +from typing import TYPE_CHECKING, Optional -from aio_pika import IncomingMessage, RobustConnection - -from faststream._internal.broker.broker import BrokerUsecase -from faststream._internal.constants import EMPTY from faststream._internal.log.logging import get_broker_logger +from faststream._internal.setup.logger import ( + DefaultLoggerStorage, + make_logger_state, +) if TYPE_CHECKING: - from faststream._internal.basic_types import LoggerProto - + from faststream._internal.basic_types import AnyDict, LoggerProto -class RabbitLoggingBroker(BrokerUsecase[IncomingMessage, RobustConnection]): - """A class that extends the LoggingMixin class and adds additional functionality for logging RabbitMQ related information.""" - - _max_queue_len: int - _max_exchange_len: int - __max_msg_id_ln: ClassVar[int] = 10 +class RabbitParamsStorage(DefaultLoggerStorage): def __init__( self, - *args: Any, - logger: Optional["LoggerProto"] = EMPTY, - log_level: int = logging.INFO, - log_fmt: Optional[str] = None, - **kwargs: Any, + log_fmt: Optional[str], ) -> None: - super().__init__( - *args, - logger=logger, - # TODO: generate unique logger names to not share between brokers - default_logger=get_broker_logger( - name="rabbit", - default_context={ - "queue": "", - "exchange": "", - }, - message_id_ln=self.__max_msg_id_ln, - ), - log_level=log_level, - log_fmt=log_fmt, - **kwargs, - ) + super().__init__(log_fmt) - self._max_queue_len = 4 self._max_exchange_len = 4 + self._max_queue_len = 4 - def get_fmt(self) -> str: - return ( - "%(asctime)s %(levelname)-8s - " - f"%(exchange)-{self._max_exchange_len}s | " - f"%(queue)-{self._max_queue_len}s | " - f"%(message_id)-{self.__max_msg_id_ln}s " - "- %(message)s" + def setup_log_contest(self, params: "AnyDict") -> None: + self._max_exchange_len = max( + self._max_exchange_len, + len(params.get("exchange", "")), + ) + self._max_queue_len = max( + self._max_queue_len, + len(params.get("queue", "")), ) - def _setup_log_context( - self, - *, - queue: Optional[str] = None, - exchange: Optional[str] = None, - ) -> None: - """Set up log context.""" - self._max_exchange_len = max(self._max_exchange_len, len(exchange or "")) - self._max_queue_len = max(self._max_queue_len, len(queue or "")) + def get_logger(self) -> "LoggerProto": + message_id_ln = 10 + + # TODO: generate unique logger names to not share between brokers + return get_broker_logger( + name="rabbit", + default_context={ + "queue": "", + "exchange": "", + }, + message_id_ln=message_id_ln, + fmt=self._log_fmt + or ( + "%(asctime)s %(levelname)-8s - " + f"%(exchange)-{self._max_exchange_len}s | " + f"%(queue)-{self._max_queue_len}s | " + f"%(message_id)-{message_id_ln}s " + "- %(message)s" + ), + ) + + +make_rabbit_logger_state = partial( + make_logger_state, + default_storag_cls=RabbitParamsStorage, +) diff --git a/faststream/rabbit/subscriber/usecase.py b/faststream/rabbit/subscriber/usecase.py index 6a8c346db3..f1bfff8a02 100644 --- a/faststream/rabbit/subscriber/usecase.py +++ b/faststream/rabbit/subscriber/usecase.py @@ -1,7 +1,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, Dict, Iterable, Optional, @@ -23,7 +22,8 @@ from aio_pika import IncomingMessage, RobustQueue from fast_depends.dependencies import Depends - from faststream._internal.basic_types import AnyDict, Decorator, LoggerProto + from faststream._internal.basic_types import AnyDict, LoggerProto + from faststream._internal.setup import SetupState from faststream._internal.types import BrokerMiddleware, CustomCallable from faststream.message import StreamMessage from faststream.rabbit.helpers.declarer import RabbitDeclarer @@ -111,10 +111,7 @@ def _setup( # type: ignore[override] broker_parser: Optional["CustomCallable"], broker_decoder: Optional["CustomCallable"], # dependant args - apply_types: bool, - is_validate: bool, - _get_dependant: Optional[Callable[..., Any]], - _call_decorators: Iterable["Decorator"], + state: "SetupState", ) -> None: self.app_id = app_id self.virtual_host = virtual_host @@ -127,10 +124,7 @@ def _setup( # type: ignore[override] extra_context=extra_context, broker_parser=broker_parser, broker_decoder=broker_decoder, - apply_types=apply_types, - is_validate=is_validate, - _get_dependant=_get_dependant, - _call_decorators=_call_decorators, + state=state, ) @override diff --git a/faststream/redis/broker/broker.py b/faststream/redis/broker/broker.py index 82e6423b14..18b96ff29b 100644 --- a/faststream/redis/broker/broker.py +++ b/faststream/redis/broker/broker.py @@ -26,14 +26,17 @@ from typing_extensions import Annotated, Doc, TypeAlias, override from faststream.__about__ import __version__ +from faststream._internal.broker.broker import BrokerUsecase from faststream._internal.constants import EMPTY from faststream.exceptions import NOT_CONNECTED_YET from faststream.message import gen_cor_id -from faststream.redis.broker.logging import RedisLoggingBroker -from faststream.redis.broker.registrator import RedisRegistrator +from faststream.redis.message import UnifyRedisDict from faststream.redis.publisher.producer import RedisFastProducer from faststream.redis.security import parse_security +from .logging import make_redis_logger_state +from .registrator import RedisRegistrator + if TYPE_CHECKING: from types import TracebackType @@ -83,7 +86,7 @@ class RedisInitKwargs(TypedDict, total=False): class RedisBroker( RedisRegistrator, - RedisLoggingBroker, + BrokerUsecase[UnifyRedisDict, "Redis[bytes]"], ): """Redis broker.""" @@ -239,9 +242,9 @@ def __init__( security=security, tags=tags, # logging - logger=logger, - log_level=log_level, - log_fmt=log_fmt, + logger_state=make_redis_logger_state( + logger=logger, log_level=log_level, log_fmt=log_fmt + ), # FastDepends args apply_types=apply_types, validate=validate, @@ -334,27 +337,23 @@ async def _connect( # type: ignore[override] ) return client - async def _close( + async def close( self, exc_type: Optional[Type[BaseException]] = None, exc_val: Optional[BaseException] = None, exc_tb: Optional["TracebackType"] = None, ) -> None: + await super().close(exc_type, exc_val, exc_tb) + if self._connection is not None: await self._connection.aclose() # type: ignore[attr-defined] - - await super()._close(exc_type, exc_val, exc_tb) + self._connection = None async def start(self) -> None: + await self.connect() + self._setup() await super().start() - for handler in self._subscribers.values(): - self._log( - f"`{handler.call_name}` waiting for messages", - extra=handler.get_log_context(None), - ) - await handler.start() - @property def _subscriber_setup_extra(self) -> "AnyDict": return { diff --git a/faststream/redis/broker/logging.py b/faststream/redis/broker/logging.py index 468da8162e..f3f89ad324 100644 --- a/faststream/redis/broker/logging.py +++ b/faststream/redis/broker/logging.py @@ -1,59 +1,54 @@ -import logging -from typing import TYPE_CHECKING, Any, ClassVar, Optional +from functools import partial +from typing import TYPE_CHECKING, Optional -from faststream._internal.broker.broker import BrokerUsecase -from faststream._internal.constants import EMPTY from faststream._internal.log.logging import get_broker_logger -from faststream.redis.message import UnifyRedisDict +from faststream._internal.setup.logger import ( + DefaultLoggerStorage, + make_logger_state, +) if TYPE_CHECKING: - from redis.asyncio.client import Redis # noqa: F401 + from faststream._internal.basic_types import AnyDict, LoggerProto - from faststream._internal.basic_types import LoggerProto - - -class RedisLoggingBroker(BrokerUsecase[UnifyRedisDict, "Redis[bytes]"]): - """A class that extends the LoggingMixin class and adds additional functionality for logging Redis related information.""" - - _max_channel_name: int - __max_msg_id_ln: ClassVar[int] = 10 +class RedisParamsStorage(DefaultLoggerStorage): def __init__( self, - *args: Any, - logger: Optional["LoggerProto"] = EMPTY, - log_level: int = logging.INFO, - log_fmt: Optional[str] = None, - **kwargs: Any, + log_fmt: Optional[str], ) -> None: - super().__init__( - *args, - logger=logger, - # TODO: generate unique logger names to not share between brokers - default_logger=get_broker_logger( - name="redis", - default_context={ - "channel": "", - }, - message_id_ln=self.__max_msg_id_ln, - ), - log_level=log_level, - log_fmt=log_fmt, - **kwargs, - ) + super().__init__(log_fmt) + self._max_channel_name = 4 - def get_fmt(self) -> str: - return ( - "%(asctime)s %(levelname)-8s - " - f"%(channel)-{self._max_channel_name}s | " - f"%(message_id)-{self.__max_msg_id_ln}s " - "- %(message)s" + def setup_log_contest(self, params: "AnyDict") -> None: + self._max_channel_name = max( + ( + self._max_channel_name, + len(params.get("channel", "")), + ) ) - def _setup_log_context( - self, - *, - channel: Optional[str] = None, - ) -> None: - self._max_channel_name = max((self._max_channel_name, len(channel or ""))) + def get_logger(self) -> Optional["LoggerProto"]: + message_id_ln = 10 + + # TODO: generate unique logger names to not share between brokers + return get_broker_logger( + name="redis", + default_context={ + "channel": "", + }, + message_id_ln=message_id_ln, + fmt=self._log_fmt + or ( + "%(asctime)s %(levelname)-8s - " + f"%(channel)-{self._max_channel_name}s | " + f"%(message_id)-{message_id_ln}s " + "- %(message)s" + ), + ) + + +make_redis_logger_state = partial( + make_logger_state, + default_storag_cls=RedisParamsStorage, +) diff --git a/faststream/redis/subscriber/usecase.py b/faststream/redis/subscriber/usecase.py index f576c47217..796dbeee2e 100644 --- a/faststream/redis/subscriber/usecase.py +++ b/faststream/redis/subscriber/usecase.py @@ -48,8 +48,9 @@ if TYPE_CHECKING: from fast_depends.dependencies import Depends - from faststream._internal.basic_types import AnyDict, Decorator, LoggerProto + from faststream._internal.basic_types import AnyDict, LoggerProto from faststream._internal.publisher.proto import ProducerProto + from faststream._internal.setup import SetupState from faststream._internal.types import ( AsyncCallable, BrokerMiddleware, @@ -115,10 +116,7 @@ def _setup( # type: ignore[override] broker_parser: Optional["CustomCallable"], broker_decoder: Optional["CustomCallable"], # dependant args - apply_types: bool, - is_validate: bool, - _get_dependant: Optional[Callable[..., Any]], - _call_decorators: Iterable["Decorator"], + state: "SetupState", ) -> None: self._client = connection @@ -129,10 +127,7 @@ def _setup( # type: ignore[override] extra_context=extra_context, broker_parser=broker_parser, broker_decoder=broker_decoder, - apply_types=apply_types, - is_validate=is_validate, - _get_dependant=_get_dependant, - _call_decorators=_call_decorators, + state=state, ) def _make_response_publisher( diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index c8d8dc823f..69fcbe84a5 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -32,7 +32,7 @@ def get_app_schema(app: Application) -> Schema: if broker is None: # pragma: no cover raise RuntimeError() - broker._setup() + app._setup() servers = get_broker_server(broker) channels = get_broker_channels(broker) diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index 2bfcdc3eb5..08ce96e6c4 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -40,7 +40,7 @@ def get_app_schema(app: Application) -> Schema: broker = app.broker if broker is None: # pragma: no cover raise RuntimeError() - broker._setup() + app._setup() servers = get_broker_server(broker) channels = get_broker_channels(broker) diff --git a/faststream/specification/proto.py b/faststream/specification/proto.py index de9514573b..776eb9ad16 100644 --- a/faststream/specification/proto.py +++ b/faststream/specification/proto.py @@ -11,6 +11,7 @@ AnyHttpUrl, ) from faststream._internal.broker.broker import BrokerUsecase + from faststream._internal.setup import SetupState from faststream.specification.schema.contact import Contact, ContactDict from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict from faststream.specification.schema.license import License, LicenseDict @@ -18,6 +19,8 @@ class Application(Protocol): + _state: "SetupState" + broker: Optional["BrokerUsecase[Any, Any]"] title: str @@ -30,6 +33,16 @@ class Application(Protocol): external_docs: Optional[Union["ExternalDocs", "ExternalDocsDict", "AnyDict"]] identifier: Optional[str] + def _setup(self) -> None: + if self.broker is not None: + self.broker._setup(self._state) + + async def _start_broker(self) -> None: + if self.broker is not None: + await self.broker.connect() + self._setup() + await self.broker.start() + class SpecificationProto(Protocol): """A class representing an asynchronous API operation.""" diff --git a/tests/brokers/base/testclient.py b/tests/brokers/base/testclient.py index 543a400b2a..f6d45d7cc7 100644 --- a/tests/brokers/base/testclient.py +++ b/tests/brokers/base/testclient.py @@ -14,6 +14,24 @@ class BrokerTestclientTestcase(BrokerPublishTestcase, BrokerConsumeTestcase): def get_fake_producer_class(self) -> type: raise NotImplementedError + @pytest.mark.asyncio + async def test_correct_clean_fake_subscribers(self): + broker = self.get_broker() + + @broker.subscriber("test") + async def handler1(msg): ... + + broker.publisher("test2") + broker.publisher("test") + + assert len(broker._subscribers) == 1 + + test_client = self.patch_broker(broker) + async with test_client as br: + assert len(br._subscribers) == 2 + + assert len(broker._subscribers) == 1 + @pytest.mark.asyncio async def test_subscriber_mock(self, queue: str): test_broker = self.get_broker() diff --git a/tests/brokers/confluent/test_logger.py b/tests/brokers/confluent/test_logger.py index 33698d522e..a956c8d40e 100644 --- a/tests/brokers/confluent/test_logger.py +++ b/tests/brokers/confluent/test_logger.py @@ -1,5 +1,4 @@ import logging -from typing import Any import pytest @@ -12,28 +11,20 @@ class TestLogger(ConfluentTestcaseConfig): """A class to represent a test Kafka broker.""" - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: - return KafkaBroker(apply_types=apply_types, **kwargs) - - def patch_broker(self, broker: KafkaBroker, **kwargs: Any) -> KafkaBroker: - return broker - @pytest.mark.asyncio async def test_custom_logger(self, queue: str): test_logger = logging.getLogger("test_logger") - consume_broker = self.get_broker(logger=test_logger) + broker = KafkaBroker(logger=test_logger) args, kwargs = self.get_subscriber_params(queue) - @consume_broker.subscriber(*args, **kwargs) + @broker.subscriber(*args, **kwargs) def subscriber(m): ... - async with self.patch_broker(consume_broker) as br: - await br.start() + await broker.start() - for sub in br._subscribers.values(): - consumer_logger = sub.consumer.logger - assert consumer_logger == test_logger + for sub in broker._subscribers.values(): + consumer_logger = sub.consumer.logger_state.logger.logger + assert consumer_logger == test_logger - producer_logger = br._producer._producer.logger - assert producer_logger == test_logger + await broker.close() diff --git a/tests/cli/rabbit/test_app.py b/tests/cli/rabbit/test_app.py index 104b515c0e..ca59ff5d4d 100644 --- a/tests/cli/rabbit/test_app.py +++ b/tests/cli/rabbit/test_app.py @@ -122,7 +122,9 @@ async def call2(): test_app = FastStream(broker=broker, after_startup=[call1, call2]) - with patch.object(test_app.broker, "start", async_mock.broker_start): + with patch.object(test_app.broker, "start", async_mock.broker_start), patch.object( + test_app.broker, "connect", async_mock.broker_connect + ): await test_app.start() mock.after_startup1.assert_called_once() @@ -130,7 +132,9 @@ async def call2(): @pytest.mark.asyncio -async def test_startup_lifespan_before_broker_started(async_mock, app: FastStream): +async def test_startup_lifespan_before_broker_started( + async_mock: AsyncMock, app: FastStream +): @app.on_startup async def call(): await async_mock.before() @@ -142,7 +146,9 @@ async def call_after(): async_mock.before.assert_awaited_once() async_mock.broker_start.assert_called_once() - with patch.object(app.broker, "start", async_mock.broker_start): + with patch.object(app.broker, "start", async_mock.broker_start), patch.object( + app.broker, "connect", async_mock.broker_connect + ): await app.start() async_mock.broker_start.assert_called_once() @@ -162,7 +168,9 @@ async def call2(): test_app = FastStream(broker=broker, after_shutdown=[call1, call2]) - with patch.object(test_app.broker, "start", async_mock.broker_start): + with patch.object(test_app.broker, "start", async_mock.broker_start), patch.object( + test_app.broker, "connect", async_mock.broker_connect + ): await test_app.stop() mock.after_shutdown1.assert_called_once() @@ -171,7 +179,7 @@ async def call2(): @pytest.mark.asyncio async def test_shutdown_lifespan_after_broker_stopped( - mock, async_mock, app: FastStream + mock, async_mock: AsyncMock, app: FastStream ): @app.after_shutdown async def call(): @@ -192,14 +200,15 @@ async def call_before(): @pytest.mark.asyncio -async def test_running(async_mock, app: FastStream): +async def test_running(async_mock: AsyncMock, app: FastStream): app.exit() with patch.object(app.broker, "start", async_mock.broker_run), patch.object( - app.broker, "close", async_mock.broker_stopped - ): + app.broker, "connect", async_mock.broker_connect + ), patch.object(app.broker, "close", async_mock.broker_stopped): await app.run() + async_mock.broker_connect.assert_called_once() async_mock.broker_run.assert_called_once() async_mock.broker_stopped.assert_called_once() @@ -217,7 +226,9 @@ async def f(): @pytest.mark.asyncio -async def test_running_lifespan_contextmanager(async_mock, mock: Mock, app: FastStream): +async def test_running_lifespan_contextmanager( + async_mock: AsyncMock, mock: Mock, app: FastStream +): @asynccontextmanager async def lifespan(env: str): mock.on(env) @@ -228,10 +239,11 @@ async def lifespan(env: str): app.exit() with patch.object(app.broker, "start", async_mock.broker_run), patch.object( - app.broker, "close", async_mock.broker_stopped - ): + app.broker, "connect", async_mock.broker_connect + ), patch.object(app.broker, "close", async_mock.broker_stopped): await app.run(run_extra_options={"env": "test"}) + async_mock.broker_connect.assert_called_once() async_mock.broker_run.assert_called_once() async_mock.broker_stopped.assert_called_once() @@ -241,30 +253,32 @@ async def lifespan(env: str): @pytest.mark.asyncio @pytest.mark.skipif(IS_WINDOWS, reason="does not run on windows") -async def test_stop_with_sigint(async_mock, app: FastStream): - with patch.object(app.broker, "start", async_mock.broker_run_sigint), patch.object( - app.broker, "close", async_mock.broker_stopped_sigint - ): +async def test_stop_with_sigint(async_mock: AsyncMock, app: FastStream): + with patch.object(app.broker, "start", async_mock.broker_run), patch.object( + app.broker, "connect", async_mock.broker_connect + ), patch.object(app.broker, "close", async_mock.broker_stopped): async with anyio.create_task_group() as tg: tg.start_soon(app.run) tg.start_soon(_kill, signal.SIGINT) - async_mock.broker_run_sigint.assert_called_once() - async_mock.broker_stopped_sigint.assert_called_once() + async_mock.broker_connect.assert_called_once() + async_mock.broker_run.assert_called_once() + async_mock.broker_stopped.assert_called_once() @pytest.mark.asyncio @pytest.mark.skipif(IS_WINDOWS, reason="does not run on windows") -async def test_stop_with_sigterm(async_mock, app: FastStream): - with patch.object(app.broker, "start", async_mock.broker_run_sigterm), patch.object( - app.broker, "close", async_mock.broker_stopped_sigterm - ): +async def test_stop_with_sigterm(async_mock: AsyncMock, app: FastStream): + with patch.object(app.broker, "start", async_mock.broker_run), patch.object( + app.broker, "connect", async_mock.broker_connect + ), patch.object(app.broker, "close", async_mock.broker_stopped): async with anyio.create_task_group() as tg: tg.start_soon(app.run) tg.start_soon(_kill, signal.SIGTERM) - async_mock.broker_run_sigterm.assert_called_once() - async_mock.broker_stopped_sigterm.assert_called_once() + async_mock.broker_connect.assert_called_once() + async_mock.broker_run.assert_called_once() + async_mock.broker_stopped.assert_called_once() @pytest.mark.asyncio @@ -333,8 +347,8 @@ async def lifespan(env: str): app = FastStream(app.broker, lifespan=lifespan) with patch.object(app.broker, "start", async_mock.broker_run), patch.object( - app.broker, "close", async_mock.broker_stopped - ): + app.broker, "connect", async_mock.broker_connect + ), patch.object(app.broker, "close", async_mock.broker_stopped): async with TestApp(app, {"env": "test"}): pass @@ -355,7 +369,9 @@ async def lifespan(env: str): with patch.object(app.broker, "start", async_mock.broker_run), patch.object( app.broker, "close", async_mock.broker_stopped - ), TestApp(app, {"env": "test"}): + ), patch.object(app.broker, "connect", async_mock.broker_connect), TestApp( + app, {"env": "test"} + ): pass async_mock.on.assert_awaited_once_with("test") diff --git a/tests/cli/rabbit/test_logs.py b/tests/cli/rabbit/test_logs.py index 92bf5beb67..6506f88524 100644 --- a/tests/cli/rabbit/test_logs.py +++ b/tests/cli/rabbit/test_logs.py @@ -20,12 +20,14 @@ ) def test_set_level(level, app: FastStream): level = get_log_level(level) + app._setup() set_log_level(level, app) - assert app.logger.level is app.broker.logger.level is level + broker_logger = app.broker._state.logger_state.logger.logger + assert app.logger.level is broker_logger.level is level @pytest.mark.parametrize( - ("level", "broker"), + ("level", "app"), ( # noqa: PT007 pytest.param( logging.CRITICAL, @@ -50,6 +52,7 @@ def test_set_level(level, app: FastStream): ), ) def test_set_level_to_none(level, app: FastStream): + app._setup() set_log_level(get_log_level(level), app) diff --git a/tests/cli/test_publish.py b/tests/cli/test_publish.py index a718d6e693..d73382a771 100644 --- a/tests/cli/test_publish.py +++ b/tests/cli/test_publish.py @@ -1,3 +1,4 @@ +from typing import Tuple from unittest.mock import AsyncMock, patch from dirty_equals import IsPartialDict @@ -14,7 +15,7 @@ ) -def get_mock_app(broker_type, producer_type) -> FastStream: +def get_mock_app(broker_type, producer_type) -> Tuple[FastStream, AsyncMock]: broker = broker_type() broker.connect = AsyncMock() mock_producer = AsyncMock(spec=producer_type) @@ -22,7 +23,7 @@ def get_mock_app(broker_type, producer_type) -> FastStream: mock_producer._parser = AsyncMock() mock_producer._decoder = AsyncMock() broker._producer = mock_producer - return FastStream(broker) + return FastStream(broker), mock_producer @require_redis @@ -30,7 +31,7 @@ def test_publish_command_with_redis_options(runner): from faststream.redis import RedisBroker from faststream.redis.publisher.producer import RedisFastProducer - mock_app = get_mock_app(RedisBroker, RedisFastProducer) + mock_app, producer_mock = get_mock_app(RedisBroker, RedisFastProducer) with patch( "faststream._internal.cli.main.import_from_string", @@ -57,8 +58,8 @@ def test_publish_command_with_redis_options(runner): assert result.exit_code == 0 - assert mock_app.broker._producer.publish.call_args.args[0] == "hello world" - assert mock_app.broker._producer.publish.call_args.kwargs == IsPartialDict( + assert producer_mock.publish.call_args.args[0] == "hello world" + assert producer_mock.publish.call_args.kwargs == IsPartialDict( reply_to="tester", stream="streamname", list="listname", @@ -72,7 +73,7 @@ def test_publish_command_with_confluent_options(runner): from faststream.confluent import KafkaBroker as ConfluentBroker from faststream.confluent.publisher.producer import AsyncConfluentFastProducer - mock_app = get_mock_app(ConfluentBroker, AsyncConfluentFastProducer) + mock_app, producer_mock = get_mock_app(ConfluentBroker, AsyncConfluentFastProducer) with patch( "faststream._internal.cli.main.import_from_string", @@ -92,8 +93,9 @@ def test_publish_command_with_confluent_options(runner): ) assert result.exit_code == 0 - assert mock_app.broker._producer.publish.call_args.args[0] == "hello world" - assert mock_app.broker._producer.publish.call_args.kwargs == IsPartialDict( + + assert producer_mock.publish.call_args.args[0] == "hello world" + assert producer_mock.publish.call_args.kwargs == IsPartialDict( topic="topicname", correlation_id="someId", ) @@ -104,7 +106,7 @@ def test_publish_command_with_kafka_options(runner): from faststream.kafka import KafkaBroker from faststream.kafka.publisher.producer import AioKafkaFastProducer - mock_app = get_mock_app(KafkaBroker, AioKafkaFastProducer) + mock_app, producer_mock = get_mock_app(KafkaBroker, AioKafkaFastProducer) with patch( "faststream._internal.cli.main.import_from_string", @@ -124,8 +126,8 @@ def test_publish_command_with_kafka_options(runner): ) assert result.exit_code == 0 - assert mock_app.broker._producer.publish.call_args.args[0] == "hello world" - assert mock_app.broker._producer.publish.call_args.kwargs == IsPartialDict( + assert producer_mock.publish.call_args.args[0] == "hello world" + assert producer_mock.publish.call_args.kwargs == IsPartialDict( topic="topicname", correlation_id="someId", ) @@ -136,7 +138,7 @@ def test_publish_command_with_nats_options(runner): from faststream.nats import NatsBroker from faststream.nats.publisher.producer import NatsFastProducer - mock_app = get_mock_app(NatsBroker, NatsFastProducer) + mock_app, producer_mock = get_mock_app(NatsBroker, NatsFastProducer) with patch( "faststream._internal.cli.main.import_from_string", @@ -159,8 +161,8 @@ def test_publish_command_with_nats_options(runner): assert result.exit_code == 0 - assert mock_app.broker._producer.publish.call_args.args[0] == "hello world" - assert mock_app.broker._producer.publish.call_args.kwargs == IsPartialDict( + assert producer_mock.publish.call_args.args[0] == "hello world" + assert producer_mock.publish.call_args.kwargs == IsPartialDict( subject="subjectname", reply_to="tester", correlation_id="someId", @@ -172,7 +174,7 @@ def test_publish_command_with_rabbit_options(runner): from faststream.rabbit import RabbitBroker from faststream.rabbit.publisher.producer import AioPikaFastProducer - mock_app = get_mock_app(RabbitBroker, AioPikaFastProducer) + mock_app, producer_mock = get_mock_app(RabbitBroker, AioPikaFastProducer) with patch( "faststream._internal.cli.main.import_from_string", @@ -191,8 +193,8 @@ def test_publish_command_with_rabbit_options(runner): assert result.exit_code == 0 - assert mock_app.broker._producer.publish.call_args.args[0] == "hello world" - assert mock_app.broker._producer.publish.call_args.kwargs == IsPartialDict( + assert producer_mock.publish.call_args.args[0] == "hello world" + assert producer_mock.publish.call_args.kwargs == IsPartialDict( { "correlation_id": "someId", } @@ -204,7 +206,7 @@ def test_publish_nats_request_command(runner: CliRunner): from faststream.nats import NatsBroker from faststream.nats.publisher.producer import NatsFastProducer - mock_app = get_mock_app(NatsBroker, NatsFastProducer) + mock_app, producer_mock = get_mock_app(NatsBroker, NatsFastProducer) with patch( "faststream._internal.cli.main.import_from_string", @@ -224,8 +226,8 @@ def test_publish_nats_request_command(runner: CliRunner): ], ) - assert mock_app.broker._producer.request.call_args.args[0] == "hello world" - assert mock_app.broker._producer.request.call_args.kwargs == IsPartialDict( + assert producer_mock.request.call_args.args[0] == "hello world" + assert producer_mock.request.call_args.kwargs == IsPartialDict( subject="subjectname", timeout=1.0, ) diff --git a/tests/opentelemetry/basic.py b/tests/opentelemetry/basic.py index 2207f7b0dc..5cd8b6b0ad 100644 --- a/tests/opentelemetry/basic.py +++ b/tests/opentelemetry/basic.py @@ -1,5 +1,5 @@ import asyncio -from typing import List, Optional, Tuple, Type, cast +from typing import Any, List, Optional, Tuple, cast from unittest.mock import Mock import pytest @@ -29,12 +29,21 @@ class LocalTelemetryTestcase(BaseTestcaseConfig): messaging_system: str include_messages_counters: bool - broker_class: Type[BrokerUsecase] resource: Resource = Resource.create(attributes={"service.name": "faststream.test"}) - telemetry_middleware_class: TelemetryMiddleware - def patch_broker(self, broker: BrokerUsecase) -> BrokerUsecase: + def get_broker( + self, + apply_types: bool = False, + **kwargs: Any, + ) -> BrokerUsecase[Any, Any]: + raise NotImplementedError + + def patch_broker( + self, + broker: BrokerUsecase[Any, Any], + **kwargs: Any, + ) -> BrokerUsecase[Any, Any]: return broker def destination_name(self, queue: str) -> str: @@ -163,7 +172,7 @@ async def test_subscriber_create_publish_process_span( trace_exporter: InMemorySpanExporter, ): mid = self.telemetry_middleware_class(tracer_provider=tracer_provider) - broker = self.broker_class(middlewares=(mid,)) + broker = self.get_broker(middlewares=(mid,)) args, kwargs = self.get_subscriber_params(queue) @@ -202,7 +211,7 @@ async def test_chain_subscriber_publisher( trace_exporter: InMemorySpanExporter, ): mid = self.telemetry_middleware_class(tracer_provider=tracer_provider) - broker = self.broker_class(middlewares=(mid,)) + broker = self.get_broker(middlewares=(mid,)) first_queue = queue second_queue = queue + "2" @@ -262,7 +271,7 @@ async def test_no_trace_context_create_process_span( trace_exporter: InMemorySpanExporter, ): mid = self.telemetry_middleware_class(tracer_provider=tracer_provider) - broker = self.broker_class(middlewares=(mid,)) + broker = self.get_broker(middlewares=(mid,)) args, kwargs = self.get_subscriber_params(queue) @@ -301,7 +310,7 @@ async def test_metrics( metric_reader: InMemoryMetricReader, ): mid = self.telemetry_middleware_class(meter_provider=meter_provider) - broker = self.broker_class(middlewares=(mid,)) + broker = self.get_broker(middlewares=(mid,)) args, kwargs = self.get_subscriber_params(queue) @@ -337,7 +346,7 @@ async def test_error_metrics( metric_reader: InMemoryMetricReader, ): mid = self.telemetry_middleware_class(meter_provider=meter_provider) - broker = self.broker_class(middlewares=(mid,)) + broker = self.get_broker(middlewares=(mid,)) expected_value_type = "ValueError" args, kwargs = self.get_subscriber_params(queue) @@ -377,7 +386,7 @@ async def test_span_in_context( trace_exporter: InMemorySpanExporter, ): mid = self.telemetry_middleware_class(tracer_provider=tracer_provider) - broker = self.broker_class(middlewares=(mid,)) + broker = self.get_broker(middlewares=(mid,), apply_types=True) args, kwargs = self.get_subscriber_params(queue) @@ -408,7 +417,7 @@ async def test_get_baggage( mock: Mock, ): mid = self.telemetry_middleware_class() - broker = self.broker_class(middlewares=(mid,)) + broker = self.get_broker(middlewares=(mid,), apply_types=True) expected_baggage = {"foo": "bar"} args, kwargs = self.get_subscriber_params(queue) @@ -447,7 +456,7 @@ async def test_clear_baggage( mock: Mock, ): mid = self.telemetry_middleware_class() - broker = self.broker_class(middlewares=(mid,)) + broker = self.get_broker(middlewares=(mid,), apply_types=True) first_queue = queue + "1" second_queue = queue + "2" @@ -494,7 +503,7 @@ async def test_modify_baggage( mock: Mock, ): mid = self.telemetry_middleware_class() - broker = self.broker_class(middlewares=(mid,)) + broker = self.get_broker(middlewares=(mid,), apply_types=True) expected_baggage = {"baz": "bar", "bar": "baz"} first_queue = queue + "1" diff --git a/tests/opentelemetry/confluent/test_confluent.py b/tests/opentelemetry/confluent/test_confluent.py index af914ebc9d..4d9844a6e6 100644 --- a/tests/opentelemetry/confluent/test_confluent.py +++ b/tests/opentelemetry/confluent/test_confluent.py @@ -1,5 +1,5 @@ import asyncio -from typing import Optional +from typing import Any, Optional from unittest.mock import Mock import pytest @@ -24,9 +24,11 @@ class TestTelemetry(ConfluentTestcaseConfig, LocalTelemetryTestcase): messaging_system = "kafka" include_messages_counters = True - broker_class = KafkaBroker telemetry_middleware_class = KafkaTelemetryMiddleware + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: + return KafkaBroker(apply_types=apply_types, **kwargs) + def assert_span( self, span: Span, @@ -73,7 +75,7 @@ async def test_batch( mid = self.telemetry_middleware_class( meter_provider=meter_provider, tracer_provider=tracer_provider ) - broker = self.broker_class(middlewares=(mid,)) + broker = self.get_broker(middlewares=(mid,), apply_types=True) expected_msg_count = 3 expected_link_count = 1 expected_link_attrs = {"messaging.batch.message_count": 3} @@ -91,13 +93,11 @@ async def handler(m, baggage: CurrentBaggage): mock(m) event.set() - broker = self.patch_broker(broker) - - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() tasks = ( asyncio.create_task( - broker.publish_batch( + br.publish_batch( 1, "hi", 3, @@ -139,7 +139,7 @@ async def test_batch_publish_with_single_consume( mid = self.telemetry_middleware_class( meter_provider=meter_provider, tracer_provider=tracer_provider ) - broker = self.broker_class(middlewares=(mid,)) + broker = self.get_broker(middlewares=(mid,), apply_types=True) msgs_queue = asyncio.Queue(maxsize=3) expected_msg_count = 3 expected_link_count = 1 @@ -155,11 +155,9 @@ async def handler(msg, baggage: CurrentBaggage): assert baggage.get_all_batch() == [] await msgs_queue.put(msg) - broker = self.patch_broker(broker) - - async with broker: - await broker.start() - await broker.publish_batch( + async with self.patch_broker(broker) as br: + await br.start() + await br.publish_batch( 1, "hi", 3, topic=queue, headers=Baggage({"foo": "bar"}).to_headers() ) result, _ = await asyncio.wait( @@ -205,7 +203,7 @@ async def test_single_publish_with_batch_consume( mid = self.telemetry_middleware_class( meter_provider=meter_provider, tracer_provider=tracer_provider ) - broker = self.broker_class(middlewares=(mid,)) + broker = self.get_broker(middlewares=(mid,), apply_types=True) expected_msg_count = 2 expected_link_count = 2 expected_span_count = 6 @@ -222,18 +220,16 @@ async def handler(m, baggage: CurrentBaggage): mock(m) event.set() - broker = self.patch_broker(broker) - - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() tasks = ( asyncio.create_task( - broker.publish( + br.publish( "hi", topic=queue, headers=Baggage({"foo": "bar"}).to_headers() ) ), asyncio.create_task( - broker.publish( + br.publish( "buy", topic=queue, headers=Baggage({"bar": "baz"}).to_headers() ) ), diff --git a/tests/opentelemetry/kafka/test_kafka.py b/tests/opentelemetry/kafka/test_kafka.py index a4f83748c4..db2249c1a2 100644 --- a/tests/opentelemetry/kafka/test_kafka.py +++ b/tests/opentelemetry/kafka/test_kafka.py @@ -1,5 +1,5 @@ import asyncio -from typing import Optional +from typing import Any, Optional from unittest.mock import Mock import pytest @@ -25,9 +25,11 @@ class TestTelemetry(LocalTelemetryTestcase): messaging_system = "kafka" include_messages_counters = True - broker_class = KafkaBroker telemetry_middleware_class = KafkaTelemetryMiddleware + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: + return KafkaBroker(apply_types=apply_types, **kwargs) + def assert_span( self, span: Span, @@ -74,7 +76,7 @@ async def test_batch( mid = self.telemetry_middleware_class( meter_provider=meter_provider, tracer_provider=tracer_provider ) - broker = self.broker_class(middlewares=(mid,)) + broker = self.get_broker(middlewares=(mid,), apply_types=True) expected_msg_count = 3 expected_link_count = 1 expected_link_attrs = {"messaging.batch.message_count": 3} @@ -92,13 +94,11 @@ async def handler(m, baggage: CurrentBaggage): mock(m) event.set() - broker = self.patch_broker(broker) - - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() tasks = ( asyncio.create_task( - broker.publish_batch( + br.publish_batch( 1, "hi", 3, @@ -140,7 +140,7 @@ async def test_batch_publish_with_single_consume( mid = self.telemetry_middleware_class( meter_provider=meter_provider, tracer_provider=tracer_provider ) - broker = self.broker_class(middlewares=(mid,)) + broker = self.get_broker(middlewares=(mid,), apply_types=True) msgs_queue = asyncio.Queue(maxsize=3) expected_msg_count = 3 expected_link_count = 1 @@ -156,11 +156,9 @@ async def handler(msg, baggage: CurrentBaggage): assert baggage.get_all_batch() == [] await msgs_queue.put(msg) - broker = self.patch_broker(broker) - - async with broker: - await broker.start() - await broker.publish_batch( + async with self.patch_broker(broker) as br: + await br.start() + await br.publish_batch( 1, "hi", 3, topic=queue, headers=Baggage({"foo": "bar"}).to_headers() ) result, _ = await asyncio.wait( @@ -206,7 +204,7 @@ async def test_single_publish_with_batch_consume( mid = self.telemetry_middleware_class( meter_provider=meter_provider, tracer_provider=tracer_provider ) - broker = self.broker_class(middlewares=(mid,)) + broker = self.get_broker(middlewares=(mid,), apply_types=True) expected_msg_count = 2 expected_link_count = 2 expected_span_count = 6 @@ -223,18 +221,16 @@ async def handler(m, baggage: CurrentBaggage): mock(m) event.set() - broker = self.patch_broker(broker) - - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() tasks = ( asyncio.create_task( - broker.publish( + br.publish( "hi", topic=queue, headers=Baggage({"foo": "bar"}).to_headers() ) ), asyncio.create_task( - broker.publish( + br.publish( "buy", topic=queue, headers=Baggage({"bar": "baz"}).to_headers() ) ), @@ -260,17 +256,19 @@ async def handler(m, baggage: CurrentBaggage): @pytest.mark.kafka class TestPublishWithTelemetry(TestPublish): - def get_broker(self, apply_types: bool = False): + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: return KafkaBroker( middlewares=(KafkaTelemetryMiddleware(),), apply_types=apply_types, + **kwargs, ) @pytest.mark.kafka class TestConsumeWithTelemetry(TestConsume): - def get_broker(self, apply_types: bool = False): + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: return KafkaBroker( middlewares=(KafkaTelemetryMiddleware(),), apply_types=apply_types, + **kwargs, ) diff --git a/tests/opentelemetry/nats/test_nats.py b/tests/opentelemetry/nats/test_nats.py index 88dc22d49c..6d03d901c8 100644 --- a/tests/opentelemetry/nats/test_nats.py +++ b/tests/opentelemetry/nats/test_nats.py @@ -1,4 +1,5 @@ import asyncio +from typing import Any from unittest.mock import Mock import pytest @@ -24,9 +25,11 @@ def stream(queue): class TestTelemetry(LocalTelemetryTestcase): messaging_system = "nats" include_messages_counters = True - broker_class = NatsBroker telemetry_middleware_class = NatsTelemetryMiddleware + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> NatsBroker: + return NatsBroker(apply_types=apply_types, **kwargs) + async def test_batch( self, event: asyncio.Event, @@ -41,7 +44,7 @@ async def test_batch( mid = self.telemetry_middleware_class( meter_provider=meter_provider, tracer_provider=tracer_provider ) - broker = self.broker_class(middlewares=(mid,)) + broker = self.get_broker(middlewares=(mid,)) expected_msg_count = 1 expected_span_count = 4 expected_proc_batch_count = 1 @@ -57,12 +60,10 @@ async def handler(m): mock(m) event.set() - broker = self.patch_broker(broker) - - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() tasks = ( - asyncio.create_task(broker.publish("hi", queue)), + asyncio.create_task(br.publish("hi", queue)), asyncio.create_task(event.wait()), ) await asyncio.wait(tasks, timeout=self.timeout) @@ -90,17 +91,19 @@ async def handler(m): @pytest.mark.nats class TestPublishWithTelemetry(TestPublish): - def get_broker(self, apply_types: bool = False): + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> NatsBroker: return NatsBroker( middlewares=(NatsTelemetryMiddleware(),), apply_types=apply_types, + **kwargs, ) @pytest.mark.nats class TestConsumeWithTelemetry(TestConsume): - def get_broker(self, apply_types: bool = False): + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> NatsBroker: return NatsBroker( middlewares=(NatsTelemetryMiddleware(),), apply_types=apply_types, + **kwargs, ) diff --git a/tests/opentelemetry/rabbit/test_rabbit.py b/tests/opentelemetry/rabbit/test_rabbit.py index 2a779cdd4b..582c2e6832 100644 --- a/tests/opentelemetry/rabbit/test_rabbit.py +++ b/tests/opentelemetry/rabbit/test_rabbit.py @@ -1,4 +1,4 @@ -from typing import Optional +from typing import Any, Optional import pytest from dirty_equals import IsInt, IsUUID @@ -24,9 +24,11 @@ def exchange(queue): class TestTelemetry(LocalTelemetryTestcase): messaging_system = "rabbitmq" include_messages_counters = False - broker_class = RabbitBroker telemetry_middleware_class = RabbitTelemetryMiddleware + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RabbitBroker: + return RabbitBroker(apply_types=apply_types, **kwargs) + def destination_name(self, queue: str) -> str: return f"default.{queue}" @@ -66,17 +68,19 @@ def assert_span( @pytest.mark.rabbit class TestPublishWithTelemetry(TestPublish): - def get_broker(self, apply_types: bool = False): + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RabbitBroker: return RabbitBroker( middlewares=(RabbitTelemetryMiddleware(),), apply_types=apply_types, + **kwargs, ) @pytest.mark.rabbit class TestConsumeWithTelemetry(TestConsume): - def get_broker(self, apply_types: bool = False): + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RabbitBroker: return RabbitBroker( middlewares=(RabbitTelemetryMiddleware(),), apply_types=apply_types, + **kwargs, ) diff --git a/tests/opentelemetry/redis/test_redis.py b/tests/opentelemetry/redis/test_redis.py index 8d8366ba10..871e347a2b 100644 --- a/tests/opentelemetry/redis/test_redis.py +++ b/tests/opentelemetry/redis/test_redis.py @@ -1,4 +1,5 @@ import asyncio +from typing import Any from unittest.mock import Mock import pytest @@ -24,9 +25,11 @@ class TestTelemetry(LocalTelemetryTestcase): messaging_system = "redis" include_messages_counters = True - broker_class = RedisBroker telemetry_middleware_class = RedisTelemetryMiddleware + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RedisBroker: + return RedisBroker(apply_types=apply_types, **kwargs) + async def test_batch( self, event: asyncio.Event, @@ -40,7 +43,7 @@ async def test_batch( mid = self.telemetry_middleware_class( meter_provider=meter_provider, tracer_provider=tracer_provider ) - broker = self.broker_class(middlewares=(mid,)) + broker = self.get_broker(middlewares=(mid,), apply_types=True) expected_msg_count = 3 expected_link_count = 1 expected_link_attrs = {"messaging.batch.message_count": 3} @@ -56,12 +59,10 @@ async def handler(m, baggage: CurrentBaggage): mock(m) event.set() - broker = self.patch_broker(broker) - - async with broker: - await broker.start() + async with self.patch_broker(broker) as br: + await br.start() tasks = ( - asyncio.create_task(broker.publish_batch(1, "hi", 3, list=queue)), + asyncio.create_task(br.publish_batch(1, "hi", 3, list=queue)), asyncio.create_task(event.wait()), ) await asyncio.wait(tasks, timeout=self.timeout) @@ -96,7 +97,7 @@ async def test_batch_publish_with_single_consume( mid = self.telemetry_middleware_class( meter_provider=meter_provider, tracer_provider=tracer_provider ) - broker = self.broker_class(middlewares=(mid,)) + broker = self.get_broker(middlewares=(mid,), apply_types=True) msgs_queue = asyncio.Queue(maxsize=3) expected_msg_count = 3 expected_link_count = 1 @@ -113,11 +114,9 @@ async def handler(msg, baggage: CurrentBaggage): assert baggage.get_all_batch() == expected_baggage_batch await msgs_queue.put(msg) - broker = self.patch_broker(broker) - - async with broker: - await broker.start() - await broker.publish_batch(1, "hi", 3, list=queue) + async with self.patch_broker(broker) as br: + await br.start() + await br.publish_batch(1, "hi", 3, list=queue) result, _ = await asyncio.wait( ( asyncio.create_task(msgs_queue.get()), @@ -161,7 +160,7 @@ async def test_single_publish_with_batch_consume( mid = self.telemetry_middleware_class( meter_provider=meter_provider, tracer_provider=tracer_provider ) - broker = self.broker_class(middlewares=(mid,)) + broker = self.get_broker(middlewares=(mid,), apply_types=True) expected_msg_count = 2 expected_link_count = 2 expected_span_count = 6 @@ -178,17 +177,15 @@ async def handler(m, baggage: CurrentBaggage): mock(m) event.set() - broker = self.patch_broker(broker) - - async with broker: + async with self.patch_broker(broker) as br: tasks = ( asyncio.create_task( - broker.publish( + br.publish( "hi", list=queue, headers=Baggage({"foo": "bar"}).to_headers() ) ), asyncio.create_task( - broker.publish( + br.publish( "buy", list=queue, headers=Baggage({"bar": "baz"}).to_headers() ) ), @@ -217,35 +214,39 @@ async def handler(m, baggage: CurrentBaggage): @pytest.mark.redis class TestPublishWithTelemetry(TestPublish): - def get_broker(self, apply_types: bool = False): + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RedisBroker: return RedisBroker( middlewares=(RedisTelemetryMiddleware(),), apply_types=apply_types, + **kwargs, ) @pytest.mark.redis class TestConsumeWithTelemetry(TestConsume): - def get_broker(self, apply_types: bool = False): + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RedisBroker: return RedisBroker( middlewares=(RedisTelemetryMiddleware(),), apply_types=apply_types, + **kwargs, ) @pytest.mark.redis class TestConsumeListWithTelemetry(TestConsumeList): - def get_broker(self, apply_types: bool = False): + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RedisBroker: return RedisBroker( middlewares=(RedisTelemetryMiddleware(),), apply_types=apply_types, + **kwargs, ) @pytest.mark.redis class TestConsumeStreamWithTelemetry(TestConsumeStream): - def get_broker(self, apply_types: bool = False): + def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RedisBroker: return RedisBroker( middlewares=(RedisTelemetryMiddleware(),), apply_types=apply_types, + **kwargs, ) From 2ac9c801e6ba324158c7ae2bddbfc71d88f83fbc Mon Sep 17 00:00:00 2001 From: Flosckow <66554425+Flosckow@users.noreply.github.com> Date: Sat, 21 Sep 2024 00:56:10 +0700 Subject: [PATCH 169/245] Feat: add process msg to broker.request methods (#1800) * Feat: add process msg to broker.request methods * Fix: add correct way to use process_msg * Fix: typo * Fix: lint * Fix: rename message vars, avoid overwrite * fix nats types * lint: fix RMQ types * lint: fix Kafka types * lint: fix Redis types * lint: fix Confluent types --------- Co-authored-by: Daniil Dumchenko Co-authored-by: Nikita Pastukhov --- faststream/_internal/broker/broker.py | 22 +++--- faststream/confluent/broker/broker.py | 4 +- faststream/confluent/publisher/usecase.py | 28 +++----- faststream/kafka/broker/broker.py | 4 +- faststream/kafka/publisher/usecase.py | 30 ++++----- faststream/nats/broker/broker.py | 4 +- faststream/nats/publisher/usecase.py | 30 ++++----- faststream/nats/testing.py | 4 +- faststream/rabbit/publisher/usecase.py | 33 ++++----- faststream/redis/broker/broker.py | 2 +- faststream/redis/publisher/usecase.py | 82 +++++++++-------------- 11 files changed, 100 insertions(+), 143 deletions(-) diff --git a/faststream/_internal/broker/broker.py b/faststream/_internal/broker/broker.py index fb19fd61d1..66572a8e8f 100644 --- a/faststream/_internal/broker/broker.py +++ b/faststream/_internal/broker/broker.py @@ -1,5 +1,4 @@ from abc import abstractmethod -from contextlib import AsyncExitStack from functools import partial from typing import ( TYPE_CHECKING, @@ -27,6 +26,7 @@ ) from faststream._internal.setup.state import BaseState from faststream._internal.subscriber.proto import SubscriberProto +from faststream._internal.subscriber.utils import process_msg from faststream._internal.types import ( AsyncCustomCallable, BrokerMiddleware, @@ -34,7 +34,7 @@ CustomCallable, MsgType, ) -from faststream._internal.utils.functions import return_input, to_async +from faststream._internal.utils.functions import to_async from faststream.exceptions import NOT_CONNECTED_YET from faststream.middlewares.logging import CriticalLogMiddleware @@ -50,7 +50,6 @@ ProducerProto, PublisherProto, ) - from faststream.message import StreamMessage from faststream.security import BaseSecurity from faststream.specification.schema.tag import Tag, TagDict @@ -358,16 +357,13 @@ async def request( **kwargs, ) - async with AsyncExitStack() as stack: - return_msg = return_input - for m in self._middlewares: - mid = m(published_msg) - await stack.enter_async_context(mid) - return_msg = partial(mid.consume_scope, return_msg) - - parsed_msg: StreamMessage[Any] = await producer._parser(published_msg) - parsed_msg._decoded_body = await producer._decoder(parsed_msg) - return await return_msg(parsed_msg) + message: Any = await process_msg( + msg=published_msg, + middlewares=self._middlewares, + parser=producer._parser, + decoder=producer._decoder, + ) + return message @abstractmethod async def ping(self, timeout: Optional[float]) -> bool: diff --git a/faststream/confluent/broker/broker.py b/faststream/confluent/broker/broker.py index 59b1063f0d..65d6ed24cc 100644 --- a/faststream/confluent/broker/broker.py +++ b/faststream/confluent/broker/broker.py @@ -489,10 +489,10 @@ async def publish( # type: ignore[override] no_confirm: bool = False, # extra options to be compatible with test client **kwargs: Any, - ) -> Optional[Any]: + ) -> None: correlation_id = correlation_id or gen_cor_id() - return await super().publish( + await super().publish( message, producer=self._producer, topic=topic, diff --git a/faststream/confluent/publisher/usecase.py b/faststream/confluent/publisher/usecase.py index d745c9144a..cb014305cd 100644 --- a/faststream/confluent/publisher/usecase.py +++ b/faststream/confluent/publisher/usecase.py @@ -1,4 +1,3 @@ -from contextlib import AsyncExitStack from functools import partial from itertools import chain from typing import ( @@ -18,8 +17,8 @@ from typing_extensions import override from faststream._internal.publisher.usecase import PublisherUsecase +from faststream._internal.subscriber.utils import process_msg from faststream._internal.types import MsgType -from faststream._internal.utils.functions import return_input from faststream.exceptions import NOT_CONNECTED_YET from faststream.message import gen_cor_id @@ -102,7 +101,7 @@ async def request( "correlation_id": correlation_id or gen_cor_id(), } - request: AsyncFunc = self._producer.request + request: Callable[..., Awaitable[Any]] = self._producer.request for pub_m in chain( ( @@ -115,18 +114,13 @@ async def request( published_msg = await request(message, **kwargs) - async with AsyncExitStack() as stack: - return_msg: Callable[[KafkaMessage], Awaitable[KafkaMessage]] = return_input - for m in self._broker_middlewares: - mid = m(published_msg) - await stack.enter_async_context(mid) - return_msg = partial(mid.consume_scope, return_msg) - - parsed_msg = await self._producer._parser(published_msg) - parsed_msg._decoded_body = await self._producer._decoder(parsed_msg) - return await return_msg(parsed_msg) - - raise AssertionError("unreachable") + msg: KafkaMessage = await process_msg( + msg=published_msg, + middlewares=self._broker_middlewares, + parser=self._producer._parser, + decoder=self._producer._decoder, + ) + return msg class DefaultPublisher(LogicPublisher[Message]): @@ -179,7 +173,7 @@ async def publish( no_confirm: bool = False, # publisher specific _extra_middlewares: Iterable["PublisherMiddleware"] = (), - ) -> Optional[Any]: + ) -> None: assert self._producer, NOT_CONNECTED_YET # nosec B101 kwargs: AnyDict = { @@ -194,7 +188,7 @@ async def publish( "correlation_id": correlation_id or gen_cor_id(), } - call: AsyncFunc = self._producer.publish + call: Callable[..., Awaitable[None]] = self._producer.publish for m in chain( ( diff --git a/faststream/kafka/broker/broker.py b/faststream/kafka/broker/broker.py index 6cb06bb057..be297c40c3 100644 --- a/faststream/kafka/broker/broker.py +++ b/faststream/kafka/broker/broker.py @@ -729,7 +729,7 @@ async def publish( # type: ignore[override] ] = False, # extra options to be compatible with test client **kwargs: Any, - ) -> Optional[Any]: + ) -> None: """Publish message directly. This method allows you to publish message in not AsyncAPI-documented way. You can use it in another frameworks @@ -739,7 +739,7 @@ async def publish( # type: ignore[override] """ correlation_id = correlation_id or gen_cor_id() - return await super().publish( + await super().publish( message, producer=self._producer, topic=topic, diff --git a/faststream/kafka/publisher/usecase.py b/faststream/kafka/publisher/usecase.py index f78bee9955..109d2a1bc2 100644 --- a/faststream/kafka/publisher/usecase.py +++ b/faststream/kafka/publisher/usecase.py @@ -1,4 +1,3 @@ -from contextlib import AsyncExitStack from functools import partial from itertools import chain from typing import ( @@ -18,8 +17,8 @@ from typing_extensions import Annotated, Doc, override from faststream._internal.publisher.usecase import PublisherUsecase +from faststream._internal.subscriber.utils import process_msg from faststream._internal.types import MsgType -from faststream._internal.utils.functions import return_input from faststream.exceptions import NOT_CONNECTED_YET from faststream.message import gen_cor_id @@ -146,7 +145,7 @@ async def request( headers = headers or self.headers correlation_id = correlation_id or gen_cor_id() - request: AsyncFunc = self._producer.request + request: Callable[..., Awaitable[Any]] = self._producer.request for pub_m in chain( ( @@ -168,18 +167,13 @@ async def request( timestamp_ms=timestamp_ms, ) - async with AsyncExitStack() as stack: - return_msg: Callable[[KafkaMessage], Awaitable[KafkaMessage]] = return_input - for m in self._broker_middlewares: - mid = m(published_msg) - await stack.enter_async_context(mid) - return_msg = partial(mid.consume_scope, return_msg) - - parsed_msg = await self._producer._parser(published_msg) - parsed_msg._decoded_body = await self._producer._decoder(parsed_msg) - return await return_msg(parsed_msg) - - raise AssertionError("unreachable") + msg: KafkaMessage = await process_msg( + msg=published_msg, + middlewares=self._broker_middlewares, + parser=self._producer._parser, + decoder=self._producer._decoder, + ) + return msg class DefaultPublisher(LogicPublisher[ConsumerRecord]): @@ -285,7 +279,7 @@ async def publish( Iterable["PublisherMiddleware"], Doc("Extra middlewares to wrap publishing process."), ] = (), - ) -> Optional[Any]: + ) -> None: assert self._producer, NOT_CONNECTED_YET # nosec B101 topic = topic or self.topic @@ -295,7 +289,7 @@ async def publish( reply_to = reply_to or self.reply_to correlation_id = correlation_id or gen_cor_id() - call: AsyncFunc = self._producer.publish + call: Callable[..., Awaitable[None]] = self._producer.publish for m in chain( ( @@ -306,7 +300,7 @@ async def publish( ): call = partial(m, call) - return await call( + await call( message, topic=topic, key=key, diff --git a/faststream/nats/broker/broker.py b/faststream/nats/broker/broker.py index 46942f6e5f..bddbd94224 100644 --- a/faststream/nats/broker/broker.py +++ b/faststream/nats/broker/broker.py @@ -719,7 +719,7 @@ async def publish( # type: ignore[override] Please, use `@broker.publisher(...)` or `broker.publisher(...).publish(...)` instead in a regular way. """ - publish_kwargs = { + publish_kwargs: AnyDict = { "subject": subject, "headers": headers, "reply_to": reply_to, @@ -737,7 +737,7 @@ async def publish( # type: ignore[override] } ) - return await super().publish( + await super().publish( message, producer=producer, correlation_id=correlation_id or gen_cor_id(), diff --git a/faststream/nats/publisher/usecase.py b/faststream/nats/publisher/usecase.py index fe0420047c..d802f996aa 100644 --- a/faststream/nats/publisher/usecase.py +++ b/faststream/nats/publisher/usecase.py @@ -1,4 +1,3 @@ -from contextlib import AsyncExitStack from functools import partial from itertools import chain from typing import ( @@ -16,12 +15,12 @@ from typing_extensions import Annotated, Doc, override from faststream._internal.publisher.usecase import PublisherUsecase -from faststream._internal.utils.functions import return_input +from faststream._internal.subscriber.utils import process_msg from faststream.exceptions import NOT_CONNECTED_YET from faststream.message import gen_cor_id if TYPE_CHECKING: - from faststream._internal.basic_types import AnyDict, AsyncFunc, SendableMessage + from faststream._internal.basic_types import AnyDict, SendableMessage from faststream._internal.types import BrokerMiddleware, PublisherMiddleware from faststream.nats.message import NatsMessage from faststream.nats.publisher.producer import NatsFastProducer, NatsJSFastProducer @@ -115,7 +114,7 @@ async def publish( if stream := stream or getattr(self.stream, "name", None): kwargs.update({"stream": stream, "timeout": timeout or self.timeout}) - call: AsyncFunc = self._producer.publish + call: Callable[..., Awaitable[Any]] = self._producer.publish for m in chain( ( @@ -126,7 +125,7 @@ async def publish( ): call = partial(m, call) - return await call(message, **kwargs) + await call(message, **kwargs) @override async def request( @@ -176,7 +175,7 @@ async def request( "correlation_id": correlation_id or gen_cor_id(), } - request: AsyncFunc = self._producer.request + request: Callable[..., Awaitable[Any]] = self._producer.request for pub_m in chain( ( @@ -192,18 +191,13 @@ async def request( **kwargs, ) - async with AsyncExitStack() as stack: - return_msg: Callable[[NatsMessage], Awaitable[NatsMessage]] = return_input - for m in self._broker_middlewares: - mid = m(published_msg) - await stack.enter_async_context(mid) - return_msg = partial(mid.consume_scope, return_msg) - - parsed_msg = await self._producer._parser(published_msg) - parsed_msg._decoded_body = await self._producer._decoder(parsed_msg) - return await return_msg(parsed_msg) - - raise AssertionError("unreachable") + msg: NatsMessage = await process_msg( + msg=published_msg, + middlewares=self._broker_middlewares, + parser=self._producer._parser, + decoder=self._producer._decoder, + ) + return msg def add_prefix(self, prefix: str) -> None: self.subject = prefix + self.subject diff --git a/faststream/nats/testing.py b/faststream/nats/testing.py index 31e21f3669..164aeafa43 100644 --- a/faststream/nats/testing.py +++ b/faststream/nats/testing.py @@ -29,8 +29,8 @@ class TestNatsBroker(TestBroker[NatsBroker]): def create_publisher_fake_subscriber( broker: NatsBroker, publisher: "SpecificationPublisher", - ) -> Tuple["LogicSubscriber[Any]", bool]: - sub: Optional[LogicSubscriber[Any]] = None + ) -> Tuple["LogicSubscriber[Any, Any]", bool]: + sub: Optional[LogicSubscriber[Any, Any]] = None publisher_stream = publisher.stream.name if publisher.stream else None for handler in broker._subscribers.values(): if _is_handler_suitable(handler, publisher.subject, publisher_stream): diff --git a/faststream/rabbit/publisher/usecase.py b/faststream/rabbit/publisher/usecase.py index c9bd51dd02..5b5ebdb021 100644 --- a/faststream/rabbit/publisher/usecase.py +++ b/faststream/rabbit/publisher/usecase.py @@ -1,4 +1,3 @@ -from contextlib import AsyncExitStack from copy import deepcopy from functools import partial from itertools import chain @@ -16,7 +15,7 @@ from typing_extensions import Annotated, Doc, TypedDict, Unpack, override from faststream._internal.publisher.usecase import PublisherUsecase -from faststream._internal.utils.functions import return_input +from faststream._internal.subscriber.utils import process_msg from faststream.exceptions import NOT_CONNECTED_YET from faststream.message import gen_cor_id from faststream.rabbit.schemas import BaseRMQInformation, RabbitQueue @@ -26,7 +25,7 @@ import aiormq from aio_pika.abc import DateType, HeadersType, TimeoutType - from faststream._internal.basic_types import AnyDict, AsyncFunc + from faststream._internal.basic_types import AnyDict from faststream._internal.types import BrokerMiddleware, PublisherMiddleware from faststream.rabbit.message import RabbitMessage from faststream.rabbit.publisher.producer import AioPikaFastProducer @@ -241,7 +240,10 @@ async def publish( **publish_kwargs, } - call: AsyncFunc = self._producer.publish + call: Callable[ + ..., + Awaitable[Optional[aiormq.abc.ConfirmationFrameType]], + ] = self._producer.publish for m in chain( ( @@ -313,7 +315,7 @@ async def request( **publish_kwargs, } - request: AsyncFunc = self._producer.request + request: Callable[..., Awaitable[Any]] = self._producer.request for pub_m in chain( ( @@ -329,20 +331,13 @@ async def request( **kwargs, ) - async with AsyncExitStack() as stack: - return_msg: Callable[[RabbitMessage], Awaitable[RabbitMessage]] = ( - return_input - ) - for m in self._broker_middlewares: - mid = m(published_msg) - await stack.enter_async_context(mid) - return_msg = partial(mid.consume_scope, return_msg) - - parsed_msg = await self._producer._parser(published_msg) - parsed_msg._decoded_body = await self._producer._decoder(parsed_msg) - return await return_msg(parsed_msg) - - raise AssertionError("unreachable") + msg: RabbitMessage = await process_msg( + msg=published_msg, + middlewares=self._broker_middlewares, + parser=self._producer._parser, + decoder=self._producer._decoder, + ) + return msg def add_prefix(self, prefix: str) -> None: """Include Publisher in router.""" diff --git a/faststream/redis/broker/broker.py b/faststream/redis/broker/broker.py index 18b96ff29b..bb4afd2582 100644 --- a/faststream/redis/broker/broker.py +++ b/faststream/redis/broker/broker.py @@ -411,7 +411,7 @@ async def publish( # type: ignore[override] Please, use `@broker.publisher(...)` or `broker.publisher(...).publish(...)` instead in a regular way. """ - return await super().publish( + await super().publish( message, producer=self._producer, correlation_id=correlation_id or gen_cor_id(), diff --git a/faststream/redis/publisher/usecase.py b/faststream/redis/publisher/usecase.py index 5dcd6785f5..1d84823c87 100644 --- a/faststream/redis/publisher/usecase.py +++ b/faststream/redis/publisher/usecase.py @@ -1,5 +1,4 @@ from abc import abstractmethod -from contextlib import AsyncExitStack from copy import deepcopy from functools import partial from itertools import chain @@ -8,14 +7,14 @@ from typing_extensions import Annotated, Doc, override from faststream._internal.publisher.usecase import PublisherUsecase -from faststream._internal.utils.functions import return_input +from faststream._internal.subscriber.utils import process_msg from faststream.exceptions import NOT_CONNECTED_YET from faststream.message import gen_cor_id from faststream.redis.message import UnifyRedisDict from faststream.redis.schemas import ListSub, PubSub, StreamSub if TYPE_CHECKING: - from faststream._internal.basic_types import AnyDict, AsyncFunc, SendableMessage + from faststream._internal.basic_types import AnyDict, SendableMessage from faststream._internal.types import BrokerMiddleware, PublisherMiddleware from faststream.redis.message import RedisMessage from faststream.redis.publisher.producer import RedisFastProducer @@ -145,7 +144,7 @@ async def publish( headers = headers or self.headers correlation_id = correlation_id or gen_cor_id() - call: AsyncFunc = self._producer.publish + call: Callable[..., Awaitable[None]] = self._producer.publish for m in chain( ( @@ -156,7 +155,7 @@ async def publish( ): call = partial(m, call) - return await call( + await call( message, channel=channel_sub.name, # basic args @@ -207,7 +206,7 @@ async def request( "correlation_id": correlation_id or gen_cor_id(), "timeout": timeout, } - request: AsyncFunc = self._producer.request + request: Callable[..., Awaitable[Any]] = self._producer.request for pub_m in chain( ( @@ -223,18 +222,13 @@ async def request( **kwargs, ) - async with AsyncExitStack() as stack: - return_msg: Callable[[RedisMessage], Awaitable[RedisMessage]] = return_input - for m in self._broker_middlewares: - mid = m(published_msg) - await stack.enter_async_context(mid) - return_msg = partial(mid.consume_scope, return_msg) - - parsed_msg = await self._producer._parser(published_msg) - parsed_msg._decoded_body = await self._producer._decoder(parsed_msg) - return await return_msg(parsed_msg) - - raise AssertionError("unreachable") + msg: RedisMessage = await process_msg( + msg=published_msg, + middlewares=self._broker_middlewares, + parser=self._producer._parser, + decoder=self._producer._decoder, + ) + return msg class ListPublisher(LogicPublisher): @@ -321,7 +315,7 @@ async def publish( reply_to = reply_to or self.reply_to correlation_id = correlation_id or gen_cor_id() - call: AsyncFunc = self._producer.publish + call: Callable[..., Awaitable[None]] = self._producer.publish for m in chain( ( @@ -332,7 +326,7 @@ async def publish( ): call = partial(m, call) - return await call( + await call( message, list=list_sub.name, # basic args @@ -384,7 +378,7 @@ async def request( "timeout": timeout, } - request: AsyncFunc = self._producer.request + request: Callable[..., Awaitable[Any]] = self._producer.request for pub_m in chain( ( @@ -400,18 +394,13 @@ async def request( **kwargs, ) - async with AsyncExitStack() as stack: - return_msg: Callable[[RedisMessage], Awaitable[RedisMessage]] = return_input - for m in self._broker_middlewares: - mid = m(published_msg) - await stack.enter_async_context(mid) - return_msg = partial(mid.consume_scope, return_msg) - - parsed_msg = await self._producer._parser(published_msg) - parsed_msg._decoded_body = await self._producer._decoder(parsed_msg) - return await return_msg(parsed_msg) - - raise AssertionError("unreachable") + msg: RedisMessage = await process_msg( + msg=published_msg, + middlewares=self._broker_middlewares, + parser=self._producer._parser, + decoder=self._producer._decoder, + ) + return msg class ListBatchPublisher(ListPublisher): @@ -447,7 +436,7 @@ async def publish( # type: ignore[override] list_sub = ListSub.validate(list or self.list) correlation_id = correlation_id or gen_cor_id() - call: AsyncFunc = self._producer.publish_batch + call: Callable[..., Awaitable[None]] = self._producer.publish_batch for m in chain( ( @@ -559,7 +548,7 @@ async def publish( headers = headers or self.headers correlation_id = correlation_id or gen_cor_id() - call: AsyncFunc = self._producer.publish + call: Callable[..., Awaitable[None]] = self._producer.publish for m in chain( ( @@ -570,7 +559,7 @@ async def publish( ): call = partial(m, call) - return await call( + await call( message, stream=stream_sub.name, maxlen=maxlen, @@ -630,7 +619,7 @@ async def request( "timeout": timeout, } - request: AsyncFunc = self._producer.request + request: Callable[..., Awaitable[Any]] = self._producer.request for pub_m in chain( ( @@ -646,15 +635,10 @@ async def request( **kwargs, ) - async with AsyncExitStack() as stack: - return_msg: Callable[[RedisMessage], Awaitable[RedisMessage]] = return_input - for m in self._broker_middlewares: - mid = m(published_msg) - await stack.enter_async_context(mid) - return_msg = partial(mid.consume_scope, return_msg) - - parsed_msg = await self._producer._parser(published_msg) - parsed_msg._decoded_body = await self._producer._decoder(parsed_msg) - return await return_msg(parsed_msg) - - raise AssertionError("unreachable") + msg: RedisMessage = await process_msg( + msg=published_msg, + middlewares=self._broker_middlewares, + parser=self._producer._parser, + decoder=self._producer._decoder, + ) + return msg From 3a8665f31e64ceaa148fa11bce9a0f998749645d Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Mon, 23 Sep 2024 20:02:00 +0300 Subject: [PATCH 170/245] refactor: remove hash logic --- faststream/_internal/broker/abc_broker.py | 30 +++-- faststream/_internal/broker/broker.py | 10 +- faststream/_internal/fastapi/router.py | 2 +- faststream/_internal/subscriber/usecase.py | 4 +- faststream/_internal/testing/broker.py | 18 ++- faststream/confluent/broker/registrator.py | 9 +- faststream/confluent/publisher/usecase.py | 3 - faststream/confluent/subscriber/usecase.py | 10 -- faststream/confluent/testing.py | 109 ++++++++++++------ faststream/kafka/broker/registrator.py | 7 +- faststream/kafka/publisher/usecase.py | 3 - faststream/kafka/subscriber/usecase.py | 13 --- faststream/kafka/testing.py | 109 ++++++++++++------ faststream/nats/broker/registrator.py | 8 +- faststream/nats/publisher/usecase.py | 3 - faststream/nats/schemas/kv_watch.py | 3 - faststream/nats/subscriber/usecase.py | 22 ---- faststream/nats/testing.py | 74 ++++++++---- faststream/rabbit/broker/broker.py | 2 +- faststream/rabbit/broker/registrator.py | 6 +- faststream/rabbit/publisher/usecase.py | 6 - faststream/rabbit/schemas/exchange.py | 1 + faststream/rabbit/schemas/queue.py | 1 + faststream/rabbit/subscriber/usecase.py | 11 -- faststream/rabbit/testing.py | 14 +-- faststream/redis/broker/registrator.py | 6 +- faststream/redis/publisher/usecase.py | 9 -- faststream/redis/schemas/list_sub.py | 3 - faststream/redis/schemas/pub_sub.py | 3 - faststream/redis/schemas/stream_sub.py | 7 -- faststream/redis/subscriber/usecase.py | 9 -- faststream/redis/testing.py | 8 +- .../asyncapi/base/schema/info.py | 9 +- .../specification/asyncapi/v2_6_0/generate.py | 4 +- .../specification/asyncapi/v3_0_0/generate.py | 8 +- tests/a_docs/confluent/basic/test_basic.py | 2 +- .../publishing/test_decorator.py | 10 +- .../getting_started/routers/test_delay.py | 40 +++---- .../routers/test_delay_equal.py | 60 +++++----- tests/a_docs/index/test_basic.py | 10 +- tests/a_docs/integration/fastapi/test_base.py | 10 +- .../integration/fastapi/test_routers.py | 2 +- tests/a_docs/kafka/basic/test_basic.py | 2 +- tests/a_docs/nats/test_direct.py | 2 +- tests/a_docs/redis/list/test_list_pub.py | 2 +- tests/a_docs/redis/stream/test_pub.py | 2 +- tests/asyncapi/base/v2_6_0/naming.py | 18 ++- tests/asyncapi/base/v3_0_0/naming.py | 18 ++- tests/brokers/base/router.py | 12 +- tests/brokers/confluent/test_logger.py | 2 +- tests/brokers/redis/test_consume.py | 4 +- .../router/test_delay_registration.py | 2 +- 52 files changed, 372 insertions(+), 370 deletions(-) diff --git a/faststream/_internal/broker/abc_broker.py b/faststream/_internal/broker/abc_broker.py index 9bd6961515..861cfa6299 100644 --- a/faststream/_internal/broker/abc_broker.py +++ b/faststream/_internal/broker/abc_broker.py @@ -4,7 +4,7 @@ Any, Generic, Iterable, - Mapping, + List, Optional, ) @@ -18,8 +18,8 @@ class ABCBroker(Generic[MsgType]): - _subscribers: Mapping[int, "SubscriberProto[MsgType]"] - _publishers: Mapping[int, "PublisherProto[MsgType]"] + _subscribers: List["SubscriberProto[MsgType]"] + _publishers: List["PublisherProto[MsgType]"] def __init__( self, @@ -34,8 +34,8 @@ def __init__( self.prefix = prefix self.include_in_schema = include_in_schema - self._subscribers = {} - self._publishers = {} + self._subscribers = [] + self._publishers = [] self._dependencies = dependencies self._middlewares = middlewares @@ -49,10 +49,10 @@ def add_middleware(self, middleware: "BrokerMiddleware[MsgType]") -> None: """ self._middlewares = (*self._middlewares, middleware) - for sub in self._subscribers.values(): + for sub in self._subscribers: sub.add_middleware(middleware) - for pub in self._publishers.values(): + for pub in self._publishers: pub.add_middleware(middleware) @abstractmethod @@ -61,9 +61,7 @@ def subscriber( subscriber: "SubscriberProto[MsgType]", ) -> "SubscriberProto[MsgType]": subscriber.add_prefix(self.prefix) - key = hash(subscriber) - subscriber = self._subscribers.get(key, subscriber) - self._subscribers = {**self._subscribers, key: subscriber} + self._subscribers.append(subscriber) return subscriber @abstractmethod @@ -72,9 +70,7 @@ def publisher( publisher: "PublisherProto[MsgType]", ) -> "PublisherProto[MsgType]": publisher.add_prefix(self.prefix) - key = hash(publisher) - publisher = self._publishers.get(key, publisher) - self._publishers = {**self._publishers, key: publisher} + self._publishers.append(publisher) return publisher def include_router( @@ -87,7 +83,7 @@ def include_router( include_in_schema: Optional[bool] = None, ) -> None: """Includes a router in the current object.""" - for h in router._subscribers.values(): + for h in router._subscribers: h.add_prefix("".join((self.prefix, prefix))) if include_in_schema is None: @@ -105,9 +101,9 @@ def include_router( *dependencies, *h._broker_dependencies, ) - self._subscribers = {**self._subscribers, hash(h): h} + self._subscribers.append(h) - for p in router._publishers.values(): + for p in router._publishers: p.add_prefix(self.prefix) if include_in_schema is None: @@ -120,7 +116,7 @@ def include_router( *middlewares, *p._broker_middlewares, ) - self._publishers = {**self._publishers, hash(p): p} + self._publishers.append(p) def include_routers( self, diff --git a/faststream/_internal/broker/broker.py b/faststream/_internal/broker/broker.py index 66572a8e8f..e7a7fe63cf 100644 --- a/faststream/_internal/broker/broker.py +++ b/faststream/_internal/broker/broker.py @@ -203,7 +203,7 @@ async def __aexit__( async def start(self) -> None: """Start the broker async use case.""" # TODO: filter by already running handlers after TestClient refactor - for handler in self._subscribers.values(): + for handler in self._subscribers: self._state.logger_state.log( f"`{handler.call_name}` waiting for messages", extra=handler.get_log_context(None), @@ -242,7 +242,7 @@ def _setup(self, state: Optional[BaseState] = None) -> None: if not self.running: self.running = True - for h in self._subscribers.values(): + for h in self._subscribers: log_context = h.get_log_context(None) log_context.pop("message_id", None) self._state.logger_state.params_storage.setup_log_contest(log_context) @@ -251,10 +251,10 @@ def _setup(self, state: Optional[BaseState] = None) -> None: # TODO: why we can't move it to running? # TODO: can we setup subscriber in running broker automatically? - for h in self._subscribers.values(): + for h in self._subscribers: self.setup_subscriber(h) - for p in self._publishers.values(): + for p in self._publishers: self.setup_publisher(p) def setup_subscriber( @@ -313,7 +313,7 @@ async def close( exc_tb: Optional["TracebackType"] = None, ) -> None: """Closes the object.""" - for h in self._subscribers.values(): + for h in self._subscribers: await h.close() self.running = False diff --git a/faststream/_internal/fastapi/router.py b/faststream/_internal/fastapi/router.py index b03c23cc7d..8bfac72e41 100644 --- a/faststream/_internal/fastapi/router.py +++ b/faststream/_internal/fastapi/router.py @@ -501,7 +501,7 @@ def include_router( # type: ignore[override] ) -> None: """Includes a router in the API.""" if isinstance(router, BrokerRouter): - for sub in router._subscribers.values(): + for sub in router._subscribers: sub._call_decorators = ( # type: ignore[attr-defined] self._add_api_mq_route( dependencies=(), diff --git a/faststream/_internal/subscriber/usecase.py b/faststream/_internal/subscriber/usecase.py index 27404749c7..7e9aba6f4c 100644 --- a/faststream/_internal/subscriber/usecase.py +++ b/faststream/_internal/subscriber/usecase.py @@ -81,9 +81,7 @@ def __init__( self.dependencies = dependencies -class SubscriberUsecase( - SubscriberProto[MsgType], -): +class SubscriberUsecase(SubscriberProto[MsgType]): """A class representing an asynchronous handler.""" lock: ContextManager[Any] diff --git a/faststream/_internal/testing/broker.py b/faststream/_internal/testing/broker.py index b079a240bf..5dda704c55 100644 --- a/faststream/_internal/testing/broker.py +++ b/faststream/_internal/testing/broker.py @@ -123,7 +123,7 @@ def _patch_broker(self, broker: Broker) -> Generator[None, None, None]: def _fake_start(self, broker: Broker, *args: Any, **kwargs: Any) -> None: patch_broker_calls(broker) - for p in broker._publishers.values(): + for p in broker._publishers: if getattr(p, "_fake_handler", None): continue @@ -154,7 +154,7 @@ async def publisher_response_subscriber(msg: Any) -> None: assert handler.mock # nosec B101 p.set_test(mock=handler.mock, with_fake=True) # type: ignore[attr-defined] - for subscriber in broker._subscribers.values(): + for subscriber in broker._subscribers: subscriber.running = True def _fake_close( @@ -164,18 +164,16 @@ def _fake_close( exc_val: Optional[BaseException] = None, exc_tb: Optional["TracebackType"] = None, ) -> None: - for p in broker._publishers.values(): + for p in broker._publishers: if getattr(p, "_fake_handler", None): p.reset_test() # type: ignore[attr-defined] - self.broker._subscribers = { - hash(sub): sub - for sub in self.broker._subscribers.values() - if sub not in self._fake_subscribers - } + self.broker._subscribers = [ + sub for sub in self.broker._subscribers if sub not in self._fake_subscribers + ] self._fake_subscribers.clear() - for h in broker._subscribers.values(): + for h in broker._subscribers: h.running = False for call in h.calls: call.handler.reset_test() @@ -197,6 +195,6 @@ def patch_broker_calls(broker: "BrokerUsecase[Any, Any]") -> None: """Patch broker calls.""" broker._setup() - for handler in broker._subscribers.values(): + for handler in broker._subscribers: for h in handler.calls: h.handler.set_test() diff --git a/faststream/confluent/broker/registrator.py b/faststream/confluent/broker/registrator.py index c674166124..10232d060a 100644 --- a/faststream/confluent/broker/registrator.py +++ b/faststream/confluent/broker/registrator.py @@ -3,6 +3,7 @@ Any, Dict, Iterable, + List, Literal, Optional, Sequence, @@ -50,11 +51,11 @@ class KafkaRegistrator( ): """Includable to KafkaBroker router.""" - _subscribers: Dict[ - int, Union["SpecificationBatchSubscriber", "SpecificationDefaultSubscriber"] + _subscribers: List[ + Union["SpecificationBatchSubscriber", "SpecificationDefaultSubscriber"] ] - _publishers: Dict[ - int, Union["SpecificationBatchPublisher", "SpecificationDefaultPublisher"] + _publishers: List[ + Union["SpecificationBatchPublisher", "SpecificationDefaultPublisher"] ] @overload # type: ignore[override] diff --git a/faststream/confluent/publisher/usecase.py b/faststream/confluent/publisher/usecase.py index cb014305cd..766c870fb6 100644 --- a/faststream/confluent/publisher/usecase.py +++ b/faststream/confluent/publisher/usecase.py @@ -67,9 +67,6 @@ def __init__( self._producer = None - def __hash__(self) -> int: - return hash(self.topic) - def add_prefix(self, prefix: str) -> None: self.topic = "".join((prefix, self.topic)) diff --git a/faststream/confluent/subscriber/usecase.py b/faststream/confluent/subscriber/usecase.py index 5b4cf0a6ff..54c05ce4ba 100644 --- a/faststream/confluent/subscriber/usecase.py +++ b/faststream/confluent/subscriber/usecase.py @@ -230,16 +230,6 @@ def topic_names(self) -> List[str]: else: return [f"{p.topic}-{p.partition}" for p in self.partitions] - @staticmethod - def get_routing_hash(topics: Iterable[str], group_id: Optional[str] = None) -> int: - return hash("".join((*topics, group_id or ""))) - - def __hash__(self) -> int: - return self.get_routing_hash( - topics=self.topic_names, - group_id=self.group_id, - ) - @staticmethod def build_log_context( message: Optional["StreamMessage[Any]"], diff --git a/faststream/confluent/testing.py b/faststream/confluent/testing.py index 58704c3d6e..fbf77555b3 100644 --- a/faststream/confluent/testing.py +++ b/faststream/confluent/testing.py @@ -1,5 +1,15 @@ from datetime import datetime -from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Tuple +from typing import ( + TYPE_CHECKING, + Any, + Callable, + Dict, + Generator, + Iterable, + List, + Optional, + Tuple, +) from unittest.mock import AsyncMock, MagicMock import anyio @@ -43,7 +53,7 @@ def create_publisher_fake_subscriber( publisher: "SpecificationPublisher[Any]", ) -> Tuple["LogicSubscriber[Any]", bool]: sub: Optional[LogicSubscriber[Any]] = None - for handler in broker._subscribers.values(): + for handler in broker._subscribers: if _is_handler_matches( handler, topic=publisher.topic, partition=publisher.partition ): @@ -118,15 +128,18 @@ async def publish( # type: ignore[override] reply_to=reply_to, ) - for handler in self.broker._subscribers.values(): # pragma: no branch - if _is_handler_matches(handler, topic, partition): - msg_to_send = ( - [incoming] - if isinstance(handler, SpecificationBatchSubscriber) - else incoming - ) + for handler in _find_handler( + self.broker._subscribers, + topic, + partition, + ): + msg_to_send = ( + [incoming] + if isinstance(handler, SpecificationBatchSubscriber) + else incoming + ) - await self._execute_handler(msg_to_send, topic, handler) + await self._execute_handler(msg_to_send, topic, handler) async def publish_batch( self, @@ -140,27 +153,30 @@ async def publish_batch( no_confirm: bool = False, ) -> None: """Publish a batch of messages to the Kafka broker.""" - for handler in self.broker._subscribers.values(): # pragma: no branch - if _is_handler_matches(handler, topic, partition): - messages = ( - build_message( - message=message, - topic=topic, - partition=partition, - timestamp_ms=timestamp_ms, - headers=headers, - correlation_id=correlation_id or gen_cor_id(), - reply_to=reply_to, - ) - for message in msgs + for handler in _find_handler( + self.broker._subscribers, + topic, + partition, + ): + messages = ( + build_message( + message=message, + topic=topic, + partition=partition, + timestamp_ms=timestamp_ms, + headers=headers, + correlation_id=correlation_id or gen_cor_id(), + reply_to=reply_to, ) + for message in msgs + ) - if isinstance(handler, SpecificationBatchSubscriber): - await self._execute_handler(list(messages), topic, handler) + if isinstance(handler, SpecificationBatchSubscriber): + await self._execute_handler(list(messages), topic, handler) - else: - for m in messages: - await self._execute_handler(m, topic, handler) + else: + for m in messages: + await self._execute_handler(m, topic, handler) return None @@ -187,16 +203,19 @@ async def request( # type: ignore[override] correlation_id=correlation_id or gen_cor_id(), ) - for handler in self.broker._subscribers.values(): # pragma: no branch - if _is_handler_matches(handler, topic, partition): - msg_to_send = ( - [incoming] - if isinstance(handler, SpecificationBatchSubscriber) - else incoming - ) + for handler in _find_handler( + self.broker._subscribers, + topic, + partition, + ): + msg_to_send = ( + [incoming] + if isinstance(handler, SpecificationBatchSubscriber) + else incoming + ) - with anyio.fail_after(timeout): - return await self._execute_handler(msg_to_send, topic, handler) + with anyio.fail_after(timeout): + return await self._execute_handler(msg_to_send, topic, handler) raise SubscriberNotFound @@ -307,6 +326,22 @@ def _fake_connection(*args: Any, **kwargs: Any) -> AsyncMock: return mock +def _find_handler( + subscribers: Iterable["LogicSubscriber[Any]"], + topic: str, + partition: Optional[int], +) -> Generator["LogicSubscriber[Any]", None, None]: + published_groups = set() + for handler in subscribers: # pragma: no branch + if _is_handler_matches(handler, topic, partition): + if handler.group_id: + if handler.group_id in published_groups: + continue + else: + published_groups.add(handler.group_id) + yield handler + + def _is_handler_matches( handler: "LogicSubscriber[Any]", topic: str, diff --git a/faststream/kafka/broker/registrator.py b/faststream/kafka/broker/registrator.py index 08bb18be47..10be770874 100644 --- a/faststream/kafka/broker/registrator.py +++ b/faststream/kafka/broker/registrator.py @@ -4,6 +4,7 @@ Callable, Dict, Iterable, + List, Literal, Optional, Sequence, @@ -53,12 +54,10 @@ class KafkaRegistrator( ): """Includable to KafkaBroker router.""" - _subscribers: Dict[ - int, + _subscribers: List[ Union["SpecificationBatchSubscriber", "SpecificationDefaultSubscriber"], ] - _publishers: Dict[ - int, + _publishers: List[ Union["SpecificationBatchPublisher", "SpecificationDefaultPublisher"], ] diff --git a/faststream/kafka/publisher/usecase.py b/faststream/kafka/publisher/usecase.py index 109d2a1bc2..d7894e9ac1 100644 --- a/faststream/kafka/publisher/usecase.py +++ b/faststream/kafka/publisher/usecase.py @@ -67,9 +67,6 @@ def __init__( self._producer = None - def __hash__(self) -> int: - return hash(self.topic) - def add_prefix(self, prefix: str) -> None: self.topic = "".join((prefix, self.topic)) diff --git a/faststream/kafka/subscriber/usecase.py b/faststream/kafka/subscriber/usecase.py index 3a32f6016c..b8715126ca 100644 --- a/faststream/kafka/subscriber/usecase.py +++ b/faststream/kafka/subscriber/usecase.py @@ -247,13 +247,6 @@ async def _consume(self) -> None: if msg: await self.consume(msg) - @staticmethod - def get_routing_hash( - topics: Iterable[str], - group_id: Optional[str] = None, - ) -> int: - return hash("".join((*topics, group_id or ""))) - @property def topic_names(self) -> List[str]: if self._pattern: @@ -263,12 +256,6 @@ def topic_names(self) -> List[str]: else: return [f"{p.topic}-{p.partition}" for p in self.partitions] - def __hash__(self) -> int: - return self.get_routing_hash( - topics=self.topic_names, - group_id=self.group_id, - ) - @staticmethod def build_log_context( message: Optional["StreamMessage[Any]"], diff --git a/faststream/kafka/testing.py b/faststream/kafka/testing.py index bc87c5d2ed..0ab5f228c2 100755 --- a/faststream/kafka/testing.py +++ b/faststream/kafka/testing.py @@ -1,6 +1,15 @@ import re from datetime import datetime -from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Tuple +from typing import ( + TYPE_CHECKING, + Any, + Callable, + Dict, + Generator, + Iterable, + Optional, + Tuple, +) from unittest.mock import AsyncMock, MagicMock import anyio @@ -45,7 +54,7 @@ def create_publisher_fake_subscriber( publisher: "SpecificationPublisher[Any]", ) -> Tuple["LogicSubscriber[Any]", bool]: sub: Optional[LogicSubscriber[Any]] = None - for handler in broker._subscribers.values(): + for handler in broker._subscribers: if _is_handler_matches(handler, publisher.topic, publisher.partition): sub = handler break @@ -115,15 +124,18 @@ async def publish( # type: ignore[override] reply_to=reply_to, ) - for handler in self.broker._subscribers.values(): # pragma: no branch - if _is_handler_matches(handler, topic, partition): - msg_to_send = ( - [incoming] - if isinstance(handler, SpecificationBatchSubscriber) - else incoming - ) + for handler in _find_handler( + self.broker._subscribers, + topic, + partition, + ): + msg_to_send = ( + [incoming] + if isinstance(handler, SpecificationBatchSubscriber) + else incoming + ) - await self._execute_handler(msg_to_send, topic, handler) + await self._execute_handler(msg_to_send, topic, handler) @override async def request( # type: ignore[override] @@ -148,16 +160,19 @@ async def request( # type: ignore[override] correlation_id=correlation_id, ) - for handler in self.broker._subscribers.values(): # pragma: no branch - if _is_handler_matches(handler, topic, partition): - msg_to_send = ( - [incoming] - if isinstance(handler, SpecificationBatchSubscriber) - else incoming - ) + for handler in _find_handler( + self.broker._subscribers, + topic, + partition, + ): + msg_to_send = ( + [incoming] + if isinstance(handler, SpecificationBatchSubscriber) + else incoming + ) - with anyio.fail_after(timeout): - return await self._execute_handler(msg_to_send, topic, handler) + with anyio.fail_after(timeout): + return await self._execute_handler(msg_to_send, topic, handler) raise SubscriberNotFound @@ -173,27 +188,31 @@ async def publish_batch( no_confirm: bool = False, ) -> None: """Publish a batch of messages to the Kafka broker.""" - for handler in self.broker._subscribers.values(): # pragma: no branch - if _is_handler_matches(handler, topic, partition): - messages = ( - build_message( - message=message, - topic=topic, - partition=partition, - timestamp_ms=timestamp_ms, - headers=headers, - correlation_id=correlation_id, - reply_to=reply_to, - ) - for message in msgs + for handler in _find_handler( + self.broker._subscribers, + topic, + partition, + ): + messages = ( + build_message( + message=message, + topic=topic, + partition=partition, + timestamp_ms=timestamp_ms, + headers=headers, + correlation_id=correlation_id, + reply_to=reply_to, ) + for message in msgs + ) - if isinstance(handler, SpecificationBatchSubscriber): - await self._execute_handler(list(messages), topic, handler) + if isinstance(handler, SpecificationBatchSubscriber): + await self._execute_handler(list(messages), topic, handler) + + else: + for m in messages: + await self._execute_handler(m, topic, handler) - else: - for m in messages: - await self._execute_handler(m, topic, handler) return None async def _execute_handler( @@ -259,6 +278,22 @@ def _fake_connection(*args: Any, **kwargs: Any) -> AsyncMock: return mock +def _find_handler( + subscribers: Iterable["LogicSubscriber[Any]"], + topic: str, + partition: Optional[int], +) -> Generator["LogicSubscriber[Any]", None, None]: + published_groups = set() + for handler in subscribers: # pragma: no branch + if _is_handler_matches(handler, topic, partition): + if handler.group_id: + if handler.group_id in published_groups: + continue + else: + published_groups.add(handler.group_id) + yield handler + + def _is_handler_matches( handler: "LogicSubscriber[Any]", topic: str, diff --git a/faststream/nats/broker/registrator.py b/faststream/nats/broker/registrator.py index 8e5a3c99d3..5a13f02966 100644 --- a/faststream/nats/broker/registrator.py +++ b/faststream/nats/broker/registrator.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Any, Dict, Iterable, Optional, Union, cast +from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Optional, Union, cast from nats.js import api from typing_extensions import Annotated, Doc, override @@ -26,8 +26,8 @@ class NatsRegistrator(ABCBroker["Msg"]): """Includable to NatsBroker router.""" - _subscribers: Dict[int, "SpecificationSubscriber"] - _publishers: Dict[int, "SpecificationPublisher"] + _subscribers: List["SpecificationSubscriber"] + _publishers: List["SpecificationPublisher"] def __init__(self, **kwargs: Any) -> None: self._stream_builder = StreamBuilder() @@ -350,7 +350,7 @@ def include_router( # type: ignore[override] ) -> None: sub_streams = router._stream_builder.objects.copy() - sub_router_subjects = [sub.subject for sub in router._subscribers.values()] + sub_router_subjects = [sub.subject for sub in router._subscribers] for stream in sub_streams.values(): new_subjects = [] diff --git a/faststream/nats/publisher/usecase.py b/faststream/nats/publisher/usecase.py index d802f996aa..c458126839 100644 --- a/faststream/nats/publisher/usecase.py +++ b/faststream/nats/publisher/usecase.py @@ -66,9 +66,6 @@ def __init__( self.headers = headers self.reply_to = reply_to - def __hash__(self) -> int: - return hash(self.subject) - @override async def publish( self, diff --git a/faststream/nats/schemas/kv_watch.py b/faststream/nats/schemas/kv_watch.py index 24707a2fe6..0489618273 100644 --- a/faststream/nats/schemas/kv_watch.py +++ b/faststream/nats/schemas/kv_watch.py @@ -50,6 +50,3 @@ def __init__( self.timeout = timeout self.declare = declare - - def __hash__(self) -> int: - return hash(self.name) diff --git a/faststream/nats/subscriber/usecase.py b/faststream/nats/subscriber/usecase.py index 19c0778092..9a44ddf6e2 100644 --- a/faststream/nats/subscriber/usecase.py +++ b/faststream/nats/subscriber/usecase.py @@ -231,22 +231,6 @@ def add_prefix(self, prefix: str) -> None: def _resolved_subject_string(self) -> str: return self.subject or ", ".join(self.config.filter_subjects or ()) - def __hash__(self) -> int: - return self.get_routing_hash(self._resolved_subject_string) - - @staticmethod - def get_routing_hash( - subject: Annotated[ - str, - Doc("NATS subject to consume messages"), - ], - ) -> int: - """Get handler hash by outer data. - - Using to find handler in `broker.handlers` dictionary. - """ - return hash(subject) - class _DefaultSubscriber(LogicSubscriber[ConnectionType, MsgType]): def __init__( @@ -1165,9 +1149,6 @@ def _make_response_publisher( """Create FakePublisher object to use it as one of `publishers` in `self.consume` scope.""" return () - def __hash__(self) -> int: - return hash(self.kv_watch) + hash(self.subject) - def get_log_context( self, message: Annotated[ @@ -1321,9 +1302,6 @@ def _make_response_publisher( """Create FakePublisher object to use it as one of `publishers` in `self.consume` scope.""" return () - def __hash__(self) -> int: - return hash(self.subject) - def get_log_context( self, message: Annotated[ diff --git a/faststream/nats/testing.py b/faststream/nats/testing.py index 164aeafa43..ceabb66ed9 100644 --- a/faststream/nats/testing.py +++ b/faststream/nats/testing.py @@ -1,4 +1,14 @@ -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union +from typing import ( + TYPE_CHECKING, + Any, + Dict, + Generator, + Iterable, + List, + Optional, + Tuple, + Union, +) from unittest.mock import AsyncMock import anyio @@ -32,8 +42,8 @@ def create_publisher_fake_subscriber( ) -> Tuple["LogicSubscriber[Any, Any]", bool]: sub: Optional[LogicSubscriber[Any, Any]] = None publisher_stream = publisher.stream.name if publisher.stream else None - for handler in broker._subscribers.values(): - if _is_handler_suitable(handler, publisher.subject, publisher_stream): + for handler in broker._subscribers: + if _is_handler_matches(handler, publisher.subject, publisher_stream): sub = handler break @@ -86,16 +96,19 @@ async def publish( # type: ignore[override] reply_to=reply_to, ) - for handler in self.broker._subscribers.values(): # pragma: no branch - if _is_handler_suitable(handler, subject, stream): - msg: Union[List[PatchedMessage], PatchedMessage] + for handler in _find_handler( + self.broker._subscribers, + subject, + stream, + ): + msg: Union[List[PatchedMessage], PatchedMessage] - if (pull := getattr(handler, "pull_sub", None)) and pull.batch: - msg = [incoming] - else: - msg = incoming + if (pull := getattr(handler, "pull_sub", None)) and pull.batch: + msg = [incoming] + else: + msg = incoming - await self._execute_handler(msg, subject, handler) + await self._execute_handler(msg, subject, handler) return None @@ -118,17 +131,20 @@ async def request( # type: ignore[override] correlation_id=correlation_id, ) - for handler in self.broker._subscribers.values(): # pragma: no branch - if _is_handler_suitable(handler, subject, stream): - msg: Union[List[PatchedMessage], PatchedMessage] + for handler in _find_handler( + self.broker._subscribers, + subject, + stream, + ): + msg: Union[List[PatchedMessage], PatchedMessage] - if (pull := getattr(handler, "pull_sub", None)) and pull.batch: - msg = [incoming] - else: - msg = incoming + if (pull := getattr(handler, "pull_sub", None)) and pull.batch: + msg = [incoming] + else: + msg = incoming - with anyio.fail_after(timeout): - return await self._execute_handler(msg, subject, handler) + with anyio.fail_after(timeout): + return await self._execute_handler(msg, subject, handler) raise SubscriberNotFound @@ -148,7 +164,23 @@ async def _execute_handler( ) -def _is_handler_suitable( +def _find_handler( + subscribers: Iterable["LogicSubscriber[Any]"], + subject: str, + stream: Optional[str] = None, +) -> Generator["LogicSubscriber[Any]", None, None]: + published_queues = set() + for handler in subscribers: # pragma: no branch + if _is_handler_matches(handler, subject, stream): + if queue := getattr(handler, "queue", None): + if queue in published_queues: + continue + else: + published_queues.add(queue) + yield handler + + +def _is_handler_matches( handler: "LogicSubscriber[Any, Any]", subject: str, stream: Optional[str] = None, diff --git a/faststream/rabbit/broker/broker.py b/faststream/rabbit/broker/broker.py index 1548d42243..d9999feb74 100644 --- a/faststream/rabbit/broker/broker.py +++ b/faststream/rabbit/broker/broker.py @@ -508,7 +508,7 @@ async def start(self) -> None: assert self.declarer, NOT_CONNECTED_YET # nosec B101 - for publisher in self._publishers.values(): + for publisher in self._publishers: if publisher.exchange is not None: await self.declare_exchange(publisher.exchange) diff --git a/faststream/rabbit/broker/registrator.py b/faststream/rabbit/broker/registrator.py index 8564aa0846..9f9773e62d 100644 --- a/faststream/rabbit/broker/registrator.py +++ b/faststream/rabbit/broker/registrator.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Any, Dict, Iterable, Optional, Union, cast +from typing import TYPE_CHECKING, Any, Iterable, List, Optional, Union, cast from typing_extensions import Annotated, Doc, override @@ -29,8 +29,8 @@ class RabbitRegistrator(ABCBroker["IncomingMessage"]): """Includable to RabbitBroker router.""" - _subscribers: Dict[int, "SpecificationSubscriber"] - _publishers: Dict[int, "SpecificationPublisher"] + _subscribers: List["SpecificationSubscriber"] + _publishers: List["SpecificationPublisher"] @override def subscriber( # type: ignore[override] diff --git a/faststream/rabbit/publisher/usecase.py b/faststream/rabbit/publisher/usecase.py index 5b5ebdb021..6ca24446c7 100644 --- a/faststream/rabbit/publisher/usecase.py +++ b/faststream/rabbit/publisher/usecase.py @@ -19,7 +19,6 @@ from faststream.exceptions import NOT_CONNECTED_YET from faststream.message import gen_cor_id from faststream.rabbit.schemas import BaseRMQInformation, RabbitQueue -from faststream.rabbit.subscriber.usecase import LogicSubscriber if TYPE_CHECKING: import aiormq @@ -175,11 +174,6 @@ def routing(self) -> str: """Return real routing_key of Publisher.""" return self.routing_key or self.queue.routing - def __hash__(self) -> int: - return LogicSubscriber.get_routing_hash(self.queue, self.exchange) + hash( - self.routing_key - ) - @override async def publish( self, diff --git a/faststream/rabbit/schemas/exchange.py b/faststream/rabbit/schemas/exchange.py index 414cba87f9..1461b721a8 100644 --- a/faststream/rabbit/schemas/exchange.py +++ b/faststream/rabbit/schemas/exchange.py @@ -29,6 +29,7 @@ class RabbitExchange(NameRequired): ) def __hash__(self) -> int: + """Supports hash to store real objects in declarer.""" return sum( ( hash(self.name), diff --git a/faststream/rabbit/schemas/queue.py b/faststream/rabbit/schemas/queue.py index 231be101e3..1c20d136df 100644 --- a/faststream/rabbit/schemas/queue.py +++ b/faststream/rabbit/schemas/queue.py @@ -35,6 +35,7 @@ class RabbitQueue(NameRequired): ) def __hash__(self) -> int: + """Supports hash to store real objects in declarer.""" return sum( ( hash(self.name), diff --git a/faststream/rabbit/subscriber/usecase.py b/faststream/rabbit/subscriber/usecase.py index f1bfff8a02..7a00c64878 100644 --- a/faststream/rabbit/subscriber/usecase.py +++ b/faststream/rabbit/subscriber/usecase.py @@ -220,17 +220,6 @@ def _make_response_publisher( ), ) - def __hash__(self) -> int: - return self.get_routing_hash(self.queue, self.exchange) - - @staticmethod - def get_routing_hash( - queue: "RabbitQueue", - exchange: Optional["RabbitExchange"] = None, - ) -> int: - """Calculate the routing hash for a RabbitMQ queue and exchange.""" - return hash(queue) + hash(exchange or "") - @staticmethod def build_log_context( message: Optional["StreamMessage[Any]"], diff --git a/faststream/rabbit/testing.py b/faststream/rabbit/testing.py index 75026edaac..31069bab85 100644 --- a/faststream/rabbit/testing.py +++ b/faststream/rabbit/testing.py @@ -60,8 +60,8 @@ def create_publisher_fake_subscriber( publisher: SpecificationPublisher, ) -> Tuple["LogicSubscriber", bool]: sub: Optional[LogicSubscriber] = None - for handler in broker._subscribers.values(): - if _is_handler_suitable( + for handler in broker._subscribers: + if _is_handler_matches( handler, publisher.routing, {}, @@ -234,8 +234,8 @@ async def publish( # type: ignore[override] timestamp=timestamp, ) - for handler in self.broker._subscribers.values(): # pragma: no branch - if _is_handler_suitable( + for handler in self.broker._subscribers: # pragma: no branch + if _is_handler_matches( handler, incoming.routing_key, incoming.headers, exch ): await self._execute_handler(incoming, handler) @@ -286,8 +286,8 @@ async def request( # type: ignore[override] timestamp=timestamp, ) - for handler in self.broker._subscribers.values(): # pragma: no branch - if _is_handler_suitable( + for handler in self.broker._subscribers: # pragma: no branch + if _is_handler_matches( handler, incoming.routing_key, incoming.headers, exch ): with anyio.fail_after(timeout): @@ -308,7 +308,7 @@ async def _execute_handler( ) -def _is_handler_suitable( +def _is_handler_matches( handler: "LogicSubscriber", routing_key: str, headers: "Mapping[Any, Any]", diff --git a/faststream/redis/broker/registrator.py b/faststream/redis/broker/registrator.py index 0d822da7bb..38cc160bde 100644 --- a/faststream/redis/broker/registrator.py +++ b/faststream/redis/broker/registrator.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Any, Dict, Iterable, Optional, Union, cast +from typing import TYPE_CHECKING, Any, Iterable, List, Optional, Union, cast from typing_extensions import Annotated, Doc, override @@ -25,8 +25,8 @@ class RedisRegistrator(ABCBroker[UnifyRedisDict]): """Includable to RedisBroker router.""" - _subscribers: Dict[int, "SubsciberType"] - _publishers: Dict[int, "PublisherType"] + _subscribers: List["SubsciberType"] + _publishers: List["PublisherType"] @override def subscriber( # type: ignore[override] diff --git a/faststream/redis/publisher/usecase.py b/faststream/redis/publisher/usecase.py index 1d84823c87..c65175a029 100644 --- a/faststream/redis/publisher/usecase.py +++ b/faststream/redis/publisher/usecase.py @@ -88,9 +88,6 @@ def __init__( self.channel = channel - def __hash__(self) -> int: - return hash(f"publisher:pubsub:{self.channel.name}") - @override def subscriber_property(self, *, name_only: bool) -> "AnyDict": return { @@ -260,9 +257,6 @@ def __init__( self.list = list - def __hash__(self) -> int: - return hash(f"publisher:list:{self.list.name}") - @override def subscriber_property(self, *, name_only: bool) -> "AnyDict": return { @@ -484,9 +478,6 @@ def __init__( self.stream = stream - def __hash__(self) -> int: - return hash(f"publisher:stream:{self.stream.name}") - @override def subscriber_property(self, *, name_only: bool) -> "AnyDict": return { diff --git a/faststream/redis/schemas/list_sub.py b/faststream/redis/schemas/list_sub.py index 53660bb546..571100e651 100644 --- a/faststream/redis/schemas/list_sub.py +++ b/faststream/redis/schemas/list_sub.py @@ -30,6 +30,3 @@ def __init__( @cached_property def records(self) -> Optional[int]: return self.max_records if self.batch else None - - def __hash__(self) -> int: - return hash(f"list:{self.name}") diff --git a/faststream/redis/schemas/pub_sub.py b/faststream/redis/schemas/pub_sub.py index 4ec950256b..c4e60ee201 100644 --- a/faststream/redis/schemas/pub_sub.py +++ b/faststream/redis/schemas/pub_sub.py @@ -32,6 +32,3 @@ def __init__( self.path_regex = reg self.pattern = channel if pattern else None self.polling_interval = polling_interval - - def __hash__(self) -> int: - return hash(f"pubsub:{self.name}") diff --git a/faststream/redis/schemas/stream_sub.py b/faststream/redis/schemas/stream_sub.py index cbc4cd8504..cc1fa59070 100644 --- a/faststream/redis/schemas/stream_sub.py +++ b/faststream/redis/schemas/stream_sub.py @@ -55,10 +55,3 @@ def __init__( self.last_id = last_id self.maxlen = maxlen self.max_records = max_records - - def __hash__(self) -> int: - if self.group is not None: - return hash( - f"stream:{self.name} group:{self.group} consumer:{self.consumer}" - ) - return hash(f"stream:{self.name}") diff --git a/faststream/redis/subscriber/usecase.py b/faststream/redis/subscriber/usecase.py index 796dbeee2e..351ed34842 100644 --- a/faststream/redis/subscriber/usecase.py +++ b/faststream/redis/subscriber/usecase.py @@ -249,9 +249,6 @@ def __init__( self.channel = channel self.subscription = None - def __hash__(self) -> int: - return hash(self.channel) - def get_log_context( self, message: Optional["BrokerStreamMessage[Any]"], @@ -373,9 +370,6 @@ def __init__( self.list_sub = list - def __hash__(self) -> int: - return hash(self.list_sub) - def get_log_context( self, message: Optional["BrokerStreamMessage[Any]"], @@ -582,9 +576,6 @@ def __init__( self.stream_sub = stream self.last_id = stream.last_id - def __hash__(self) -> int: - return hash(self.stream_sub) - def get_log_context( self, message: Optional["BrokerStreamMessage[Any]"], diff --git a/faststream/redis/testing.py b/faststream/redis/testing.py index c729305229..c8a491b1dd 100644 --- a/faststream/redis/testing.py +++ b/faststream/redis/testing.py @@ -58,7 +58,7 @@ def create_publisher_fake_subscriber( named_property = publisher.subscriber_property(name_only=True) visitors = (ChannelVisitor(), ListVisitor(), StreamVisitor()) - for handler in broker._subscribers.values(): # pragma: no branch + for handler in broker._subscribers: # pragma: no branch for visitor in visitors: if visitor.visit(**named_property, sub=handler): sub = handler @@ -133,7 +133,7 @@ async def publish( destination = _make_destionation_kwargs(channel, list, stream) visitors = (ChannelVisitor(), ListVisitor(), StreamVisitor()) - for handler in self.broker._subscribers.values(): # pragma: no branch + for handler in self.broker._subscribers: # pragma: no branch for visitor in visitors: if visited_ch := visitor.visit(**destination, sub=handler): msg = visitor.get_message( @@ -170,7 +170,7 @@ async def request( # type: ignore[override] destination = _make_destionation_kwargs(channel, list, stream) visitors = (ChannelVisitor(), ListVisitor(), StreamVisitor()) - for handler in self.broker._subscribers.values(): # pragma: no branch + for handler in self.broker._subscribers: # pragma: no branch for visitor in visitors: if visited_ch := visitor.visit(**destination, sub=handler): msg = visitor.get_message( @@ -201,7 +201,7 @@ async def publish_batch( ] visitor = ListVisitor() - for handler in self.broker._subscribers.values(): # pragma: no branch + for handler in self.broker._subscribers: # pragma: no branch if visitor.visit(list=list, sub=handler): casted_handler = cast(_ListHandlerMixin, handler) diff --git a/faststream/specification/asyncapi/base/schema/info.py b/faststream/specification/asyncapi/base/schema/info.py index c808a49d06..428dcb4a86 100644 --- a/faststream/specification/asyncapi/base/schema/info.py +++ b/faststream/specification/asyncapi/base/schema/info.py @@ -6,13 +6,12 @@ class BaseInfo(BaseModel): - """A class to represent information. + """A class to represent AsyncAPI application information. Attributes: - title : title of the information - version : version of the information (default: "1.0.0") - description : description of the information (default: "") - + title : application title + version : application version (default: "1.0.0") + description : application description (default: "") """ title: str diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index 69fcbe84a5..690eccd014 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -140,13 +140,13 @@ def get_broker_channels( """Get the broker channels for an application.""" channels = {} - for h in broker._subscribers.values(): + for h in broker._subscribers: schema = h.schema() channels.update( {key: channel_from_spec(channel) for key, channel in schema.items()} ) - for p in broker._publishers.values(): + for p in broker._publishers: schema = p.schema() channels.update( {key: channel_from_spec(channel) for key, channel in schema.items()} diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index 08ce96e6c4..03b1f3c67c 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -142,7 +142,7 @@ def get_broker_operations( """Get the broker operations for an application.""" operations = {} - for h in broker._subscribers.values(): + for h in broker._subscribers: for channel_name, specs_channel in h.schema().items(): channel_name = clear_key(channel_name) @@ -151,7 +151,7 @@ def get_broker_operations( specs_channel.subscribe, Action.RECEIVE, channel_name ) - for p in broker._publishers.values(): + for p in broker._publishers: for channel_name, specs_channel in p.schema().items(): channel_name = clear_key(channel_name) @@ -169,7 +169,7 @@ def get_broker_channels( """Get the broker channels for an application.""" channels = {} - for sub in broker._subscribers.values(): + for sub in broker._subscribers: channels_schema_v3_0 = {} for channel_name, specs_channel in sub.schema().items(): if specs_channel.subscribe: @@ -188,7 +188,7 @@ def get_broker_channels( channels.update(channels_schema_v3_0) - for pub in broker._publishers.values(): + for pub in broker._publishers: channels_schema_v3_0 = {} for channel_name, specs_channel in pub.schema().items(): if specs_channel.publish: diff --git a/tests/a_docs/confluent/basic/test_basic.py b/tests/a_docs/confluent/basic/test_basic.py index 60828d8564..dc64e08a9e 100644 --- a/tests/a_docs/confluent/basic/test_basic.py +++ b/tests/a_docs/confluent/basic/test_basic.py @@ -7,7 +7,7 @@ async def test_basic(): from docs.docs_src.confluent.basic.basic import broker, on_input_data - publisher = list(broker._publishers.values())[0] # noqa: RUF015 + publisher = broker._publishers[0] async with TestKafkaBroker(broker) as br: await br.publish({"data": 1.0}, "input_data") diff --git a/tests/a_docs/getting_started/publishing/test_decorator.py b/tests/a_docs/getting_started/publishing/test_decorator.py index e97d65e567..5d5ebc5592 100644 --- a/tests/a_docs/getting_started/publishing/test_decorator.py +++ b/tests/a_docs/getting_started/publishing/test_decorator.py @@ -24,7 +24,7 @@ async def test_decorator_kafka(): async with TestKafkaBroker(broker), TestApp(app): handle.mock.assert_called_once_with("") handle_next.mock.assert_called_once_with("Hi!") - next(iter(broker._publishers.values())).mock.assert_called_once_with("Hi!") + next(iter(broker._publishers)).mock.assert_called_once_with("Hi!") @pytest.mark.asyncio @@ -41,7 +41,7 @@ async def test_decorator_confluent(): async with TestConfluentKafkaBroker(broker), TestApp(app): handle.mock.assert_called_once_with("") handle_next.mock.assert_called_once_with("Hi!") - next(iter(broker._publishers.values())).mock.assert_called_once_with("Hi!") + next(iter(broker._publishers)).mock.assert_called_once_with("Hi!") @pytest.mark.asyncio @@ -58,7 +58,7 @@ async def test_decorator_rabbit(): async with TestRabbitBroker(broker), TestApp(app): handle.mock.assert_called_once_with("") handle_next.mock.assert_called_once_with("Hi!") - next(iter(broker._publishers.values())).mock.assert_called_once_with("Hi!") + next(iter(broker._publishers)).mock.assert_called_once_with("Hi!") @pytest.mark.asyncio @@ -75,7 +75,7 @@ async def test_decorator_nats(): async with TestNatsBroker(broker), TestApp(app): handle.mock.assert_called_once_with("") handle_next.mock.assert_called_once_with("Hi!") - next(iter(broker._publishers.values())).mock.assert_called_once_with("Hi!") + next(iter(broker._publishers)).mock.assert_called_once_with("Hi!") @pytest.mark.asyncio @@ -92,4 +92,4 @@ async def test_decorator_redis(): async with TestRedisBroker(broker), TestApp(app): handle.mock.assert_called_once_with("") handle_next.mock.assert_called_once_with("Hi!") - next(iter(broker._publishers.values())).mock.assert_called_once_with("Hi!") + next(iter(broker._publishers)).mock.assert_called_once_with("Hi!") diff --git a/tests/a_docs/getting_started/routers/test_delay.py b/tests/a_docs/getting_started/routers/test_delay.py index 733c278fe5..031b9cd8c3 100644 --- a/tests/a_docs/getting_started/routers/test_delay.py +++ b/tests/a_docs/getting_started/routers/test_delay.py @@ -20,11 +20,11 @@ async def test_delay_router_kafka(): from faststream.kafka import TestKafkaBroker async with TestKafkaBroker(broker) as br, TestApp(app): - next(iter(br._subscribers.values())).calls[ - 0 - ].handler.mock.assert_called_once_with({"name": "John", "user_id": 1}) + next(iter(br._subscribers)).calls[0].handler.mock.assert_called_once_with( + {"name": "John", "user_id": 1} + ) - next(iter(br._publishers.values())).mock.assert_called_once_with("Hi!") + next(iter(br._publishers)).mock.assert_called_once_with("Hi!") @pytest.mark.asyncio @@ -37,11 +37,11 @@ async def test_delay_router_confluent(): from faststream.confluent import TestKafkaBroker as TestConfluentKafkaBroker async with TestConfluentKafkaBroker(broker) as br, TestApp(app): - next(iter(br._subscribers.values())).calls[ - 0 - ].handler.mock.assert_called_once_with({"name": "John", "user_id": 1}) + next(iter(br._subscribers)).calls[0].handler.mock.assert_called_once_with( + {"name": "John", "user_id": 1} + ) - next(iter(br._publishers.values())).mock.assert_called_once_with("Hi!") + next(iter(br._publishers)).mock.assert_called_once_with("Hi!") @pytest.mark.asyncio @@ -54,11 +54,11 @@ async def test_delay_router_rabbit(): from faststream.rabbit import TestRabbitBroker async with TestRabbitBroker(broker) as br, TestApp(app): - next(iter(br._subscribers.values())).calls[ - 0 - ].handler.mock.assert_called_once_with({"name": "John", "user_id": 1}) + next(iter(br._subscribers)).calls[0].handler.mock.assert_called_once_with( + {"name": "John", "user_id": 1} + ) - next(iter(br._publishers.values())).mock.assert_called_once_with("Hi!") + next(iter(br._publishers)).mock.assert_called_once_with("Hi!") @pytest.mark.asyncio @@ -71,11 +71,11 @@ async def test_delay_router_nats(): from faststream.nats import TestNatsBroker async with TestNatsBroker(broker) as br, TestApp(app): - next(iter(br._subscribers.values())).calls[ - 0 - ].handler.mock.assert_called_once_with({"name": "John", "user_id": 1}) + next(iter(br._subscribers)).calls[0].handler.mock.assert_called_once_with( + {"name": "John", "user_id": 1} + ) - next(iter(br._publishers.values())).mock.assert_called_once_with("Hi!") + next(iter(br._publishers)).mock.assert_called_once_with("Hi!") @pytest.mark.asyncio @@ -88,8 +88,8 @@ async def test_delay_router_redis(): from faststream.redis import TestRedisBroker async with TestRedisBroker(broker) as br, TestApp(app): - next(iter(br._subscribers.values())).calls[ - 0 - ].handler.mock.assert_called_once_with({"name": "John", "user_id": 1}) + next(iter(br._subscribers)).calls[0].handler.mock.assert_called_once_with( + {"name": "John", "user_id": 1} + ) - next(iter(br._publishers.values())).mock.assert_called_once_with("Hi!") + next(iter(br._publishers)).mock.assert_called_once_with("Hi!") diff --git a/tests/a_docs/getting_started/routers/test_delay_equal.py b/tests/a_docs/getting_started/routers/test_delay_equal.py index 8e34b434fc..d8e08079fd 100644 --- a/tests/a_docs/getting_started/routers/test_delay_equal.py +++ b/tests/a_docs/getting_started/routers/test_delay_equal.py @@ -22,15 +22,15 @@ async def test_delay_router_kafka(): ) from faststream.kafka import TestKafkaBroker - assert broker._subscribers.keys() == control_broker._subscribers.keys() - assert broker._publishers.keys() == control_broker._publishers.keys() + assert len(broker._subscribers) == len(control_broker._subscribers) + assert len(broker._publishers) == len(control_broker._publishers) async with TestKafkaBroker(broker) as br, TestApp(app): - next(iter(br._subscribers.values())).calls[ - 0 - ].handler.mock.assert_called_once_with({"name": "John", "user_id": 1}) + next(iter(br._subscribers)).calls[0].handler.mock.assert_called_once_with( + {"name": "John", "user_id": 1} + ) - next(iter(br._publishers.values())).mock.assert_called_once_with("Hi!") + next(iter(br._publishers)).mock.assert_called_once_with("Hi!") @pytest.mark.asyncio @@ -45,15 +45,15 @@ async def test_delay_router_confluent(): ) from faststream.confluent import TestKafkaBroker as TestConfluentKafkaBroker - assert broker._subscribers.keys() == control_broker._subscribers.keys() - assert broker._publishers.keys() == control_broker._publishers.keys() + assert len(broker._subscribers) == len(control_broker._subscribers) + assert len(broker._publishers) == len(control_broker._publishers) async with TestConfluentKafkaBroker(broker) as br, TestApp(app): - next(iter(br._subscribers.values())).calls[ - 0 - ].handler.mock.assert_called_once_with({"name": "John", "user_id": 1}) + next(iter(br._subscribers)).calls[0].handler.mock.assert_called_once_with( + {"name": "John", "user_id": 1} + ) - next(iter(br._publishers.values())).mock.assert_called_once_with("Hi!") + next(iter(br._publishers)).mock.assert_called_once_with("Hi!") @pytest.mark.asyncio @@ -68,15 +68,15 @@ async def test_delay_router_rabbit(): ) from faststream.rabbit import TestRabbitBroker - assert broker._subscribers.keys() == control_broker._subscribers.keys() - assert broker._publishers.keys() == control_broker._publishers.keys() + assert len(broker._subscribers) == len(control_broker._subscribers) + assert len(broker._publishers) == len(control_broker._publishers) async with TestRabbitBroker(broker) as br, TestApp(app): - next(iter(br._subscribers.values())).calls[ - 0 - ].handler.mock.assert_called_once_with({"name": "John", "user_id": 1}) + next(iter(br._subscribers)).calls[0].handler.mock.assert_called_once_with( + {"name": "John", "user_id": 1} + ) - next(iter(br._publishers.values())).mock.assert_called_once_with("Hi!") + next(iter(br._publishers)).mock.assert_called_once_with("Hi!") @pytest.mark.asyncio @@ -91,15 +91,15 @@ async def test_delay_router_nats(): ) from faststream.nats import TestNatsBroker - assert broker._subscribers.keys() == control_broker._subscribers.keys() - assert broker._publishers.keys() == control_broker._publishers.keys() + assert len(broker._subscribers) == len(control_broker._subscribers) + assert len(broker._publishers) == len(control_broker._publishers) async with TestNatsBroker(broker) as br, TestApp(app): - next(iter(br._subscribers.values())).calls[ - 0 - ].handler.mock.assert_called_once_with({"name": "John", "user_id": 1}) + next(iter(br._subscribers)).calls[0].handler.mock.assert_called_once_with( + {"name": "John", "user_id": 1} + ) - next(iter(br._publishers.values())).mock.assert_called_once_with("Hi!") + next(iter(br._publishers)).mock.assert_called_once_with("Hi!") @pytest.mark.asyncio @@ -114,12 +114,12 @@ async def test_delay_router_redis(): ) from faststream.redis import TestRedisBroker - assert broker._subscribers.keys() == control_broker._subscribers.keys() - assert broker._publishers.keys() == control_broker._publishers.keys() + assert len(broker._subscribers) == len(control_broker._subscribers) + assert len(broker._publishers) == len(control_broker._publishers) async with TestRedisBroker(broker) as br, TestApp(app): - next(iter(br._subscribers.values())).calls[ - 0 - ].handler.mock.assert_called_once_with({"name": "John", "user_id": 1}) + next(iter(br._subscribers)).calls[0].handler.mock.assert_called_once_with( + {"name": "John", "user_id": 1} + ) - next(iter(br._publishers.values())).mock.assert_called_once_with("Hi!") + next(iter(br._publishers)).mock.assert_called_once_with("Hi!") diff --git a/tests/a_docs/index/test_basic.py b/tests/a_docs/index/test_basic.py index e56f220300..0e0675318b 100644 --- a/tests/a_docs/index/test_basic.py +++ b/tests/a_docs/index/test_basic.py @@ -20,7 +20,7 @@ async def test_index_kafka_base(): handle_msg.mock.assert_called_once_with({"user": "John", "user_id": 1}) - list(br._publishers.values())[0].mock.assert_called_once_with( # noqa: RUF015 + list(br._publishers)[0].mock.assert_called_once_with( # noqa: RUF015 "User: 1 - John registered" ) @@ -36,7 +36,7 @@ async def test_index_confluent_base(): handle_msg.mock.assert_called_once_with({"user": "John", "user_id": 1}) - list(br._publishers.values())[0].mock.assert_called_once_with( # noqa: RUF015 + list(br._publishers)[0].mock.assert_called_once_with( # noqa: RUF015 "User: 1 - John registered" ) @@ -52,7 +52,7 @@ async def test_index_rabbit_base(): handle_msg.mock.assert_called_once_with({"user": "John", "user_id": 1}) - list(br._publishers.values())[0].mock.assert_called_once_with( # noqa: RUF015 + list(br._publishers)[0].mock.assert_called_once_with( # noqa: RUF015 "User: 1 - John registered" ) @@ -68,7 +68,7 @@ async def test_index_nats_base(): handle_msg.mock.assert_called_once_with({"user": "John", "user_id": 1}) - list(br._publishers.values())[0].mock.assert_called_once_with( # noqa: RUF015 + list(br._publishers)[0].mock.assert_called_once_with( # noqa: RUF015 "User: 1 - John registered" ) @@ -84,6 +84,6 @@ async def test_index_redis_base(): handle_msg.mock.assert_called_once_with({"user": "John", "user_id": 1}) - list(br._publishers.values())[0].mock.assert_called_once_with( # noqa: RUF015 + list(br._publishers)[0].mock.assert_called_once_with( # noqa: RUF015 "User: 1 - John registered" ) diff --git a/tests/a_docs/integration/fastapi/test_base.py b/tests/a_docs/integration/fastapi/test_base.py index 205db8d785..195afcecb5 100644 --- a/tests/a_docs/integration/fastapi/test_base.py +++ b/tests/a_docs/integration/fastapi/test_base.py @@ -24,7 +24,7 @@ async def test_fastapi_kafka_base(): hello.mock.assert_called_once_with({"m": {}}) - list(br._publishers.values())[0].mock.assert_called_with( # noqa: RUF015 + list(br._publishers)[0].mock.assert_called_with( # noqa: RUF015 {"response": "Hello, Kafka!"} ) @@ -43,7 +43,7 @@ async def test_fastapi_confluent_base(): hello.mock.assert_called_once_with({"m": {}}) - list(br._publishers.values())[0].mock.assert_called_with( # noqa: RUF015 + list(br._publishers)[0].mock.assert_called_with( # noqa: RUF015 {"response": "Hello, Kafka!"} ) @@ -62,7 +62,7 @@ async def test_fastapi_rabbit_base(): hello.mock.assert_called_once_with({"m": {}}) - list(br._publishers.values())[0].mock.assert_called_with( # noqa: RUF015 + list(br._publishers)[0].mock.assert_called_with( # noqa: RUF015 {"response": "Hello, Rabbit!"} ) @@ -81,7 +81,7 @@ async def test_fastapi_nats_base(): hello.mock.assert_called_once_with({"m": {}}) - list(br._publishers.values())[0].mock.assert_called_with( # noqa: RUF015 + list(br._publishers)[0].mock.assert_called_with( # noqa: RUF015 {"response": "Hello, NATS!"} ) @@ -100,6 +100,6 @@ async def test_fastapi_redis_base(): hello.mock.assert_called_once_with({"m": {}}) - list(br._publishers.values())[0].mock.assert_called_with( # noqa: RUF015 + list(br._publishers)[0].mock.assert_called_with( # noqa: RUF015 {"response": "Hello, Redis!"} ) diff --git a/tests/a_docs/integration/fastapi/test_routers.py b/tests/a_docs/integration/fastapi/test_routers.py index c8122b0414..19a7141dff 100644 --- a/tests/a_docs/integration/fastapi/test_routers.py +++ b/tests/a_docs/integration/fastapi/test_routers.py @@ -14,7 +14,7 @@ class BaseCase: def test_running(self, data): app, broker = data - handlers = broker._subscribers.values() + handlers = broker._subscribers assert len(handlers) == 2 for h in handlers: diff --git a/tests/a_docs/kafka/basic/test_basic.py b/tests/a_docs/kafka/basic/test_basic.py index 624cb73ca2..3af588c06d 100644 --- a/tests/a_docs/kafka/basic/test_basic.py +++ b/tests/a_docs/kafka/basic/test_basic.py @@ -7,7 +7,7 @@ async def test_basic(): from docs.docs_src.kafka.basic.basic import broker, on_input_data - publisher = list(broker._publishers.values())[0] # noqa: RUF015 + publisher = list(broker._publishers)[0] # noqa: RUF015 async with TestKafkaBroker(broker) as br: await br.publish({"data": 1.0}, "input_data") diff --git a/tests/a_docs/nats/test_direct.py b/tests/a_docs/nats/test_direct.py index d64e849fc8..1a01df10c7 100644 --- a/tests/a_docs/nats/test_direct.py +++ b/tests/a_docs/nats/test_direct.py @@ -4,7 +4,7 @@ @pytest.mark.asyncio -async def test_pattern(): +async def test_direct(): from docs.docs_src.nats.direct import ( app, base_handler1, diff --git a/tests/a_docs/redis/list/test_list_pub.py b/tests/a_docs/redis/list/test_list_pub.py index 0ef35761b4..ef26e83fd1 100644 --- a/tests/a_docs/redis/list/test_list_pub.py +++ b/tests/a_docs/redis/list/test_list_pub.py @@ -7,7 +7,7 @@ async def test_list_publisher(): from docs.docs_src.redis.list.list_pub import broker, on_input_data - publisher = list(broker._publishers.values())[0] # noqa: RUF015 + publisher = list(broker._publishers)[0] # noqa: RUF015 async with TestRedisBroker(broker) as br: await br.publish({"data": 1.0}, list="input-list") diff --git a/tests/a_docs/redis/stream/test_pub.py b/tests/a_docs/redis/stream/test_pub.py index 0656267f7b..5e435505d0 100644 --- a/tests/a_docs/redis/stream/test_pub.py +++ b/tests/a_docs/redis/stream/test_pub.py @@ -7,7 +7,7 @@ async def test_stream_pub(): from docs.docs_src.redis.stream.pub import broker, on_input_data - publisher = list(broker._publishers.values())[0] # noqa: RUF015 + publisher = list(broker._publishers)[0] # noqa: RUF015 async with TestRedisBroker(broker) as br: await br.publish({"data": 1.0}, stream="input-stream") diff --git a/tests/asyncapi/base/v2_6_0/naming.py b/tests/asyncapi/base/v2_6_0/naming.py index bf8fd6c623..447308b15b 100644 --- a/tests/asyncapi/base/v2_6_0/naming.py +++ b/tests/asyncapi/base/v2_6_0/naming.py @@ -165,10 +165,12 @@ class FilterNaming(BaseNaming): def test_subscriber_filter_base(self): broker = self.broker_class() - @broker.subscriber("test") + sub = broker.subscriber("test") + + @sub async def handle_user_created(msg: str): ... - @broker.subscriber("test") + @sub async def handle_user_id(msg: int): ... schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() @@ -189,10 +191,12 @@ async def handle_user_id(msg: int): ... def test_subscriber_filter_pydantic(self): broker = self.broker_class() - @broker.subscriber("test") + sub = broker.subscriber("test") + + @sub async def handle_user_created(msg: create_model("SimpleModel")): ... - @broker.subscriber("test") + @sub async def handle_user_id(msg: int): ... schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() @@ -213,10 +217,12 @@ async def handle_user_id(msg: int): ... def test_subscriber_filter_with_title(self): broker = self.broker_class() - @broker.subscriber("test", title="custom") + sub = broker.subscriber("test", title="custom") + + @sub async def handle_user_created(msg: str): ... - @broker.subscriber("test", title="custom") + @sub async def handle_user_id(msg: int): ... schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() diff --git a/tests/asyncapi/base/v3_0_0/naming.py b/tests/asyncapi/base/v3_0_0/naming.py index 0759aa6894..5ccb01d8d8 100644 --- a/tests/asyncapi/base/v3_0_0/naming.py +++ b/tests/asyncapi/base/v3_0_0/naming.py @@ -169,10 +169,12 @@ class FilterNaming(BaseNaming): def test_subscriber_filter_base(self): broker = self.broker_class() - @broker.subscriber("test") + sub = broker.subscriber("test") + + @sub async def handle_user_created(msg: str): ... - @broker.subscriber("test") + @sub async def handle_user_id(msg: int): ... schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() @@ -193,10 +195,12 @@ async def handle_user_id(msg: int): ... def test_subscriber_filter_pydantic(self): broker = self.broker_class() - @broker.subscriber("test") + sub = broker.subscriber("test") + + @sub async def handle_user_created(msg: create_model("SimpleModel")): ... - @broker.subscriber("test") + @sub async def handle_user_id(msg: int): ... schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() @@ -217,10 +221,12 @@ async def handle_user_id(msg: int): ... def test_subscriber_filter_with_title(self): broker = self.broker_class() - @broker.subscriber("test", title="custom") + sub = broker.subscriber("test", title="custom") + + @sub async def handle_user_created(msg: str): ... - @broker.subscriber("test", title="custom") + @sub async def handle_user_id(msg: int): ... schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() diff --git a/tests/brokers/base/router.py b/tests/brokers/base/router.py index 61c61ed944..afb647d2cf 100644 --- a/tests/brokers/base/router.py +++ b/tests/brokers/base/router.py @@ -399,7 +399,7 @@ def subscriber(): ... router.include_router(router2) pub_broker.include_routers(router) - sub = next(iter(pub_broker._subscribers.values())) + sub = next(iter(pub_broker._subscribers)) assert len((*sub._broker_dependencies, *sub.calls[0].dependencies)) == 3 async def test_router_include_with_dependencies( @@ -422,7 +422,7 @@ def subscriber(): ... router.include_router(router2, dependencies=(Depends(lambda: 2),)) pub_broker.include_router(router, dependencies=(Depends(lambda: 1),)) - sub = next(iter(pub_broker._subscribers.values())) + sub = next(iter(pub_broker._subscribers)) dependencies = (*sub._broker_dependencies, *sub.calls[0].dependencies) assert len(dependencies) == 3, dependencies @@ -445,8 +445,8 @@ def subscriber(): ... router.include_router(router2) pub_broker.include_routers(router) - sub = next(iter(pub_broker._subscribers.values())) - publisher = next(iter(pub_broker._publishers.values())) + sub = next(iter(pub_broker._subscribers)) + publisher = next(iter(pub_broker._publishers)) assert len((*sub._broker_middlewares, *sub.calls[0].item_middlewares)) == 3 assert len((*publisher._broker_middlewares, *publisher._middlewares)) == 3 @@ -469,8 +469,8 @@ def subscriber(): ... router.include_router(router2, middlewares=(BaseMiddleware,)) pub_broker.include_router(router, middlewares=(BaseMiddleware,)) - sub = next(iter(pub_broker._subscribers.values())) - publisher = next(iter(pub_broker._publishers.values())) + sub = next(iter(pub_broker._subscribers)) + publisher = next(iter(pub_broker._publishers)) sub_middlewares = (*sub._broker_middlewares, *sub.calls[0].item_middlewares) assert len(sub_middlewares) == 3, sub_middlewares diff --git a/tests/brokers/confluent/test_logger.py b/tests/brokers/confluent/test_logger.py index a956c8d40e..e651c2fb3a 100644 --- a/tests/brokers/confluent/test_logger.py +++ b/tests/brokers/confluent/test_logger.py @@ -23,7 +23,7 @@ def subscriber(m): ... await broker.start() - for sub in broker._subscribers.values(): + for sub in broker._subscribers: consumer_logger = sub.consumer.logger_state.logger.logger assert consumer_logger == test_logger diff --git a/tests/brokers/redis/test_consume.py b/tests/brokers/redis/test_consume.py index e5ad72c41a..a0256969a3 100644 --- a/tests/brokers/redis/test_consume.py +++ b/tests/brokers/redis/test_consume.py @@ -564,7 +564,7 @@ async def test_consume_group( ) async def handler(msg: RedisMessage): ... - assert next(iter(consume_broker._subscribers.values())).last_id == "$" + assert next(iter(consume_broker._subscribers)).last_id == "$" async def test_consume_group_with_last_id( self, @@ -577,7 +577,7 @@ async def test_consume_group_with_last_id( ) async def handler(msg: RedisMessage): ... - assert next(iter(consume_broker._subscribers.values())).last_id == "0" + assert next(iter(consume_broker._subscribers)).last_id == "0" async def test_consume_nack( self, diff --git a/tests/examples/router/test_delay_registration.py b/tests/examples/router/test_delay_registration.py index dc8197b8bd..805ff7243d 100644 --- a/tests/examples/router/test_delay_registration.py +++ b/tests/examples/router/test_delay_registration.py @@ -6,7 +6,7 @@ @pytest.mark.asyncio async def test_example(): - sub = next(iter(broker._subscribers.values())) + sub = next(iter(broker._subscribers)) sub.topic = "prefix_in" handle = sub.calls[0].handler From 27a910d52635aa40a273df04c691aee105eed2f0 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Wed, 25 Sep 2024 19:11:35 +0300 Subject: [PATCH 171/245] refactor: reuse HAS_TYPER in CLI --- faststream/__main__.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/faststream/__main__.py b/faststream/__main__.py index f5a5846c3e..d2b586d835 100644 --- a/faststream/__main__.py +++ b/faststream/__main__.py @@ -2,14 +2,9 @@ import warnings -try: - from faststream._internal.cli.main import cli -except ImportError: - has_typer = False -else: - has_typer = True +from faststream._internal._compat import HAS_TYPER -if not has_typer: +if not HAS_TYPER: raise ImportError( "\n\nYou're trying to use the FastStream CLI, " "\nbut you haven't installed the required dependencies." @@ -17,6 +12,8 @@ '\npip install "faststream[cli]"' ) +from faststream._internal.cli.main import cli + warnings.filterwarnings("default", category=ImportWarning, module="faststream") if __name__ == "__main__": From e2c89cd5f7f08bed85c3c63754adf55c6ee5f00c Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov <88668176+KrySeyt@users.noreply.github.com> Date: Tue, 1 Oct 2024 07:46:59 +0300 Subject: [PATCH 172/245] Update specs public API (#1799) * init * AsyncAPI2 * AsyncAPI3 * AsyncAPI facade * AsyncAPI facade refactoring to factory * Rename facade to factory * Remove specs interface from Faststream and AsgiFaststream * Tests update * fixes * tests fixes * tests fix * tests fix * fixes * fixes * docs: generate API References * asyncapi.py rename to facade.py * tests fix * docs: generate API References * merge conflict fix * docs: generate API References * Separation of AMQP bindings creation for AsyncAPI 3.0.0 and 2.6.0 * docs: generate API References * Correct cc for AMQP in AsyncAPI 3.0.0 * docs: generate API References --------- Co-authored-by: KrySeyt --- docs/docs/SUMMARY.md | 987 ++++++++++++++++++ .../app/CliRunState.md} | 2 +- .../app/OuterRunState.md} | 2 +- .../app/ServerState.md} | 2 +- .../StartupValidationError.md} | 2 +- .../specification/asyncapi/AsyncAPI.md | 11 + .../specification/asyncapi/AsyncAPIProto.md | 11 + .../asyncapi/base/AsyncAPIProto.md | 11 + .../asyncapi/base/asyncapi/AsyncAPIProto.md | 11 + .../asyncapi/factory/AsyncAPI.md | 11 + .../asyncapi/v2_6_0/AsyncAPI2.md | 11 + .../facade/AsyncAPI2.md} | 2 +- .../asyncapi/v3_0_0/AsyncAPI3.md | 11 + .../asyncapi/v3_0_0/facade/AsyncAPI3.md | 11 + .../schema/bindings/OperationBinding.md | 11 + .../schema/bindings/amqp/OperationBinding.md | 11 + .../schema/bindings/amqp/channel/from_spec.md | 11 + .../amqp/channel_binding_from_spec.md | 11 + .../amqp/operation/OperationBinding.md | 11 + .../bindings/amqp/operation/from_spec.md | 11 + .../amqp/operation_binding_from_spec.md | 11 + .../bindings/channel_binding_from_spec.md | 11 + .../schema/bindings/main/OperationBinding.md | 11 + .../schema/bindings/main/channel/from_spec.md | 11 + .../main/channel_binding_from_spec.md | 11 + .../main/operation/OperationBinding.md | 11 + .../bindings/main/operation/from_spec.md | 11 + .../main/operation_binding_from_spec.md | 11 + .../bindings/operation_binding_from_spec.md | 11 + .../specification/proto/SpecApplication.md | 11 + docs/docs/en/release.md | 26 + .../asyncapi_customization/custom_broker.py | 5 + .../asyncapi_customization/custom_handler.py | 5 + .../asyncapi_customization/custom_info.py | 7 +- .../asyncapi_customization/payload_info.py | 5 + docs/docs_src/kafka/basic/basic.py | 2 + faststream/_internal/cli/docs/app.py | 55 +- faststream/_internal/cli/main.py | 3 + faststream/_internal/cli/utils/imports.py | 27 +- faststream/_internal/fastapi/router.py | 14 +- faststream/app.py | 31 +- faststream/asgi/app.py | 37 - faststream/asgi/factories.py | 7 +- faststream/specification/asyncapi/__init__.py | 7 +- .../specification/asyncapi/base/__init__.py | 6 +- .../specification/asyncapi/base/asyncapi.py | 18 + faststream/specification/asyncapi/factory.py | 74 ++ faststream/specification/asyncapi/generate.py | 25 - .../specification/asyncapi/v2_6_0/__init__.py | 6 +- .../specification/asyncapi/v2_6_0/facade.py | 102 ++ .../specification/asyncapi/v2_6_0/generate.py | 56 +- .../v2_6_0/schema/bindings/amqp/channel.py | 1 - .../v2_6_0/schema/bindings/amqp/operation.py | 1 - .../specification/asyncapi/v3_0_0/__init__.py | 4 +- .../specification/asyncapi/v3_0_0/facade.py | 102 ++ .../specification/asyncapi/v3_0_0/generate.py | 57 +- .../v3_0_0/schema/bindings/__init__.py | 11 + .../v3_0_0/schema/bindings/amqp/__init__.py | 13 + .../v3_0_0/schema/bindings/amqp/channel.py | 23 + .../v3_0_0/schema/bindings/amqp/operation.py | 48 + .../v3_0_0/schema/bindings/main/__init__.py | 13 + .../v3_0_0/schema/bindings/main/channel.py | 17 + .../v3_0_0/schema/bindings/main/operation.py | 71 ++ .../asyncapi/v3_0_0/schema/channels.py | 6 +- .../asyncapi/v3_0_0/schema/operations.py | 8 +- .../specification/schema/bindings/amqp.py | 2 - .../asyncapi_customization/test_basic.py | 4 +- .../asyncapi_customization/test_broker.py | 5 +- .../asyncapi_customization/test_handler.py | 5 +- .../asyncapi_customization/test_info.py | 5 +- .../asyncapi_customization/test_payload.py | 5 +- tests/a_docs/rabbit/test_security.py | 7 +- tests/a_docs/redis/test_security.py | 7 +- tests/asyncapi/base/v2_6_0/arguments.py | 50 +- tests/asyncapi/base/v2_6_0/fastapi.py | 36 +- tests/asyncapi/base/v2_6_0/naming.py | 39 +- tests/asyncapi/base/v2_6_0/publisher.py | 23 +- tests/asyncapi/base/v2_6_0/router.py | 37 +- tests/asyncapi/base/v3_0_0/arguments.py | 50 +- tests/asyncapi/base/v3_0_0/fastapi.py | 28 +- tests/asyncapi/base/v3_0_0/naming.py | 40 +- tests/asyncapi/base/v3_0_0/publisher.py | 23 +- tests/asyncapi/base/v3_0_0/router.py | 37 +- .../confluent/v2_6_0/test_arguments.py | 4 +- .../confluent/v2_6_0/test_connection.py | 44 +- .../asyncapi/confluent/v2_6_0/test_fastapi.py | 12 +- .../asyncapi/confluent/v2_6_0/test_naming.py | 5 +- .../confluent/v2_6_0/test_publisher.py | 4 +- .../asyncapi/confluent/v2_6_0/test_router.py | 9 +- .../confluent/v2_6_0/test_security.py | 21 +- .../confluent/v3_0_0/test_arguments.py | 4 +- .../confluent/v3_0_0/test_connection.py | 47 +- .../asyncapi/confluent/v3_0_0/test_fastapi.py | 10 +- .../asyncapi/confluent/v3_0_0/test_naming.py | 5 +- .../confluent/v3_0_0/test_publisher.py | 4 +- .../asyncapi/confluent/v3_0_0/test_router.py | 9 +- .../confluent/v3_0_0/test_security.py | 21 +- tests/asyncapi/kafka/v2_6_0/test_app.py | 119 +-- tests/asyncapi/kafka/v2_6_0/test_arguments.py | 4 +- .../asyncapi/kafka/v2_6_0/test_connection.py | 45 +- tests/asyncapi/kafka/v2_6_0/test_fastapi.py | 12 +- tests/asyncapi/kafka/v2_6_0/test_naming.py | 5 +- tests/asyncapi/kafka/v2_6_0/test_publisher.py | 4 +- tests/asyncapi/kafka/v2_6_0/test_router.py | 9 +- tests/asyncapi/kafka/v2_6_0/test_security.py | 21 +- tests/asyncapi/kafka/v3_0_0/test_arguments.py | 4 +- .../asyncapi/kafka/v3_0_0/test_connection.py | 47 +- tests/asyncapi/kafka/v3_0_0/test_fastapi.py | 10 +- tests/asyncapi/kafka/v3_0_0/test_naming.py | 5 +- tests/asyncapi/kafka/v3_0_0/test_publisher.py | 4 +- tests/asyncapi/kafka/v3_0_0/test_router.py | 9 +- tests/asyncapi/kafka/v3_0_0/test_security.py | 21 +- tests/asyncapi/nats/v2_6_0/test_arguments.py | 4 +- tests/asyncapi/nats/v2_6_0/test_connection.py | 43 +- tests/asyncapi/nats/v2_6_0/test_fastapi.py | 6 +- tests/asyncapi/nats/v2_6_0/test_kv_schema.py | 5 +- tests/asyncapi/nats/v2_6_0/test_naming.py | 5 +- tests/asyncapi/nats/v2_6_0/test_obj_schema.py | 5 +- tests/asyncapi/nats/v2_6_0/test_publisher.py | 4 +- tests/asyncapi/nats/v2_6_0/test_router.py | 9 +- tests/asyncapi/nats/v3_0_0/test_arguments.py | 4 +- tests/asyncapi/nats/v3_0_0/test_connection.py | 47 +- tests/asyncapi/nats/v3_0_0/test_fastapi.py | 4 +- tests/asyncapi/nats/v3_0_0/test_kv_schema.py | 5 +- tests/asyncapi/nats/v3_0_0/test_naming.py | 5 +- tests/asyncapi/nats/v3_0_0/test_obj_schema.py | 5 +- tests/asyncapi/nats/v3_0_0/test_publisher.py | 4 +- tests/asyncapi/nats/v3_0_0/test_router.py | 9 +- .../asyncapi/rabbit/v2_6_0/test_arguments.py | 14 +- .../asyncapi/rabbit/v2_6_0/test_connection.py | 25 +- tests/asyncapi/rabbit/v2_6_0/test_fastapi.py | 12 +- tests/asyncapi/rabbit/v2_6_0/test_naming.py | 9 +- .../asyncapi/rabbit/v2_6_0/test_publisher.py | 10 +- tests/asyncapi/rabbit/v2_6_0/test_router.py | 9 +- tests/asyncapi/rabbit/v2_6_0/test_security.py | 9 +- .../asyncapi/rabbit/v3_0_0/test_arguments.py | 10 +- .../asyncapi/rabbit/v3_0_0/test_connection.py | 33 +- tests/asyncapi/rabbit/v3_0_0/test_fastapi.py | 17 +- tests/asyncapi/rabbit/v3_0_0/test_naming.py | 35 +- .../asyncapi/rabbit/v3_0_0/test_publisher.py | 34 +- tests/asyncapi/rabbit/v3_0_0/test_router.py | 23 +- tests/asyncapi/rabbit/v3_0_0/test_security.py | 27 +- tests/asyncapi/redis/v2_6_0/test_arguments.py | 12 +- .../asyncapi/redis/v2_6_0/test_connection.py | 35 +- tests/asyncapi/redis/v2_6_0/test_fastapi.py | 6 +- tests/asyncapi/redis/v2_6_0/test_naming.py | 13 +- tests/asyncapi/redis/v2_6_0/test_publisher.py | 8 +- tests/asyncapi/redis/v2_6_0/test_router.py | 9 +- tests/asyncapi/redis/v2_6_0/test_security.py | 9 +- tests/asyncapi/redis/v3_0_0/test_arguments.py | 12 +- .../asyncapi/redis/v3_0_0/test_connection.py | 35 +- tests/asyncapi/redis/v3_0_0/test_fastapi.py | 4 +- tests/asyncapi/redis/v3_0_0/test_naming.py | 19 +- tests/asyncapi/redis/v3_0_0/test_publisher.py | 8 +- tests/asyncapi/redis/v3_0_0/test_router.py | 15 +- tests/asyncapi/redis/v3_0_0/test_security.py | 27 +- tests/cli/utils/test_imports.py | 10 +- tests/conftest.py | 2 +- 158 files changed, 2689 insertions(+), 1041 deletions(-) rename docs/docs/en/api/faststream/{exceptions/ValidationError.md => asgi/app/CliRunState.md} (72%) rename docs/docs/en/api/faststream/{specification/proto/Application.md => asgi/app/OuterRunState.md} (70%) rename docs/docs/en/api/faststream/{app/catch_startup_validation_error.md => asgi/app/ServerState.md} (68%) rename docs/docs/en/api/faststream/{specification/asyncapi/get_app_schema.md => exceptions/StartupValidationError.md} (67%) create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/AsyncAPI.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/AsyncAPIProto.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/base/AsyncAPIProto.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/base/asyncapi/AsyncAPIProto.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/factory/AsyncAPI.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/AsyncAPI2.md rename docs/docs/en/api/faststream/specification/asyncapi/{generate/get_app_schema.md => v2_6_0/facade/AsyncAPI2.md} (63%) create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/AsyncAPI3.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/facade/AsyncAPI3.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel_binding_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation_binding_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/channel_binding_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel_binding_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation_binding_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/operation_binding_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/proto/SpecApplication.md create mode 100644 faststream/specification/asyncapi/base/asyncapi.py create mode 100644 faststream/specification/asyncapi/factory.py delete mode 100644 faststream/specification/asyncapi/generate.py create mode 100644 faststream/specification/asyncapi/v2_6_0/facade.py create mode 100644 faststream/specification/asyncapi/v3_0_0/facade.py create mode 100644 faststream/specification/asyncapi/v3_0_0/schema/bindings/__init__.py create mode 100644 faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/__init__.py create mode 100644 faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel.py create mode 100644 faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation.py create mode 100644 faststream/specification/asyncapi/v3_0_0/schema/bindings/main/__init__.py create mode 100644 faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel.py create mode 100644 faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation.py diff --git a/docs/docs/SUMMARY.md b/docs/docs/SUMMARY.md index 0e06be9bc7..c4578bdd7f 100644 --- a/docs/docs/SUMMARY.md +++ b/docs/docs/SUMMARY.md @@ -113,6 +113,993 @@ search: - [Message Information](redis/message.md) - [Security Configuration](redis/security.md) - [Reference - Code API](api/index.md) + - Public API + - faststream + - [BaseMiddleware](public_api/faststream/BaseMiddleware.md) + - [Context](public_api/faststream/Context.md) + - [Depends](public_api/faststream/Depends.md) + - [ExceptionMiddleware](public_api/faststream/ExceptionMiddleware.md) + - [FastStream](public_api/faststream/FastStream.md) + - [Header](public_api/faststream/Header.md) + - [Path](public_api/faststream/Path.md) + - [Response](public_api/faststream/Response.md) + - [TestApp](public_api/faststream/TestApp.md) + - [apply_types](public_api/faststream/apply_types.md) + - asgi + - [AsgiFastStream](public_api/faststream/asgi/AsgiFastStream.md) + - [AsgiResponse](public_api/faststream/asgi/AsgiResponse.md) + - [get](public_api/faststream/asgi/get.md) + - [make_asyncapi_asgi](public_api/faststream/asgi/make_asyncapi_asgi.md) + - [make_ping_asgi](public_api/faststream/asgi/make_ping_asgi.md) + - confluent + - [KafkaBroker](public_api/faststream/confluent/KafkaBroker.md) + - [KafkaPublisher](public_api/faststream/confluent/KafkaPublisher.md) + - [KafkaResponse](public_api/faststream/confluent/KafkaResponse.md) + - [KafkaRoute](public_api/faststream/confluent/KafkaRoute.md) + - [KafkaRouter](public_api/faststream/confluent/KafkaRouter.md) + - [TestApp](public_api/faststream/confluent/TestApp.md) + - [TestKafkaBroker](public_api/faststream/confluent/TestKafkaBroker.md) + - [TopicPartition](public_api/faststream/confluent/TopicPartition.md) + - kafka + - [KafkaBroker](public_api/faststream/kafka/KafkaBroker.md) + - [KafkaPublisher](public_api/faststream/kafka/KafkaPublisher.md) + - [KafkaResponse](public_api/faststream/kafka/KafkaResponse.md) + - [KafkaRoute](public_api/faststream/kafka/KafkaRoute.md) + - [KafkaRouter](public_api/faststream/kafka/KafkaRouter.md) + - [TestApp](public_api/faststream/kafka/TestApp.md) + - [TestKafkaBroker](public_api/faststream/kafka/TestKafkaBroker.md) + - [TopicPartition](public_api/faststream/kafka/TopicPartition.md) + - nats + - [AckPolicy](public_api/faststream/nats/AckPolicy.md) + - [ConsumerConfig](public_api/faststream/nats/ConsumerConfig.md) + - [DeliverPolicy](public_api/faststream/nats/DeliverPolicy.md) + - [DiscardPolicy](public_api/faststream/nats/DiscardPolicy.md) + - [ExternalStream](public_api/faststream/nats/ExternalStream.md) + - [JStream](public_api/faststream/nats/JStream.md) + - [KvWatch](public_api/faststream/nats/KvWatch.md) + - [NatsBroker](public_api/faststream/nats/NatsBroker.md) + - [NatsPublisher](public_api/faststream/nats/NatsPublisher.md) + - [NatsResponse](public_api/faststream/nats/NatsResponse.md) + - [NatsRoute](public_api/faststream/nats/NatsRoute.md) + - [NatsRouter](public_api/faststream/nats/NatsRouter.md) + - [ObjWatch](public_api/faststream/nats/ObjWatch.md) + - [Placement](public_api/faststream/nats/Placement.md) + - [PullSub](public_api/faststream/nats/PullSub.md) + - [RePublish](public_api/faststream/nats/RePublish.md) + - [ReplayPolicy](public_api/faststream/nats/ReplayPolicy.md) + - [RetentionPolicy](public_api/faststream/nats/RetentionPolicy.md) + - [StorageType](public_api/faststream/nats/StorageType.md) + - [StreamConfig](public_api/faststream/nats/StreamConfig.md) + - [StreamSource](public_api/faststream/nats/StreamSource.md) + - [TestApp](public_api/faststream/nats/TestApp.md) + - [TestNatsBroker](public_api/faststream/nats/TestNatsBroker.md) + - opentelemetry + - [Baggage](public_api/faststream/opentelemetry/Baggage.md) + - [TelemetryMiddleware](public_api/faststream/opentelemetry/TelemetryMiddleware.md) + - [TelemetrySettingsProvider](public_api/faststream/opentelemetry/TelemetrySettingsProvider.md) + - rabbit + - [ExchangeType](public_api/faststream/rabbit/ExchangeType.md) + - [RabbitBroker](public_api/faststream/rabbit/RabbitBroker.md) + - [RabbitExchange](public_api/faststream/rabbit/RabbitExchange.md) + - [RabbitPublisher](public_api/faststream/rabbit/RabbitPublisher.md) + - [RabbitQueue](public_api/faststream/rabbit/RabbitQueue.md) + - [RabbitResponse](public_api/faststream/rabbit/RabbitResponse.md) + - [RabbitRoute](public_api/faststream/rabbit/RabbitRoute.md) + - [RabbitRouter](public_api/faststream/rabbit/RabbitRouter.md) + - [TestApp](public_api/faststream/rabbit/TestApp.md) + - [TestRabbitBroker](public_api/faststream/rabbit/TestRabbitBroker.md) + - redis + - [ListSub](public_api/faststream/redis/ListSub.md) + - [PubSub](public_api/faststream/redis/PubSub.md) + - [RedisBroker](public_api/faststream/redis/RedisBroker.md) + - [RedisPublisher](public_api/faststream/redis/RedisPublisher.md) + - [RedisResponse](public_api/faststream/redis/RedisResponse.md) + - [RedisRoute](public_api/faststream/redis/RedisRoute.md) + - [RedisRouter](public_api/faststream/redis/RedisRouter.md) + - [StreamSub](public_api/faststream/redis/StreamSub.md) + - [TestApp](public_api/faststream/redis/TestApp.md) + - [TestRedisBroker](public_api/faststream/redis/TestRedisBroker.md) + - All API + - faststream + - [BaseMiddleware](api/faststream/BaseMiddleware.md) + - [Context](api/faststream/Context.md) + - [Depends](api/faststream/Depends.md) + - [ExceptionMiddleware](api/faststream/ExceptionMiddleware.md) + - [FastStream](api/faststream/FastStream.md) + - [Header](api/faststream/Header.md) + - [Path](api/faststream/Path.md) + - [Response](api/faststream/Response.md) + - [TestApp](api/faststream/TestApp.md) + - [apply_types](api/faststream/apply_types.md) + - app + - [FastStream](api/faststream/app/FastStream.md) + - asgi + - [AsgiFastStream](api/faststream/asgi/AsgiFastStream.md) + - [AsgiResponse](api/faststream/asgi/AsgiResponse.md) + - [get](api/faststream/asgi/get.md) + - [make_asyncapi_asgi](api/faststream/asgi/make_asyncapi_asgi.md) + - [make_ping_asgi](api/faststream/asgi/make_ping_asgi.md) + - app + - [AsgiFastStream](api/faststream/asgi/app/AsgiFastStream.md) + - [CliRunState](api/faststream/asgi/app/CliRunState.md) + - [OuterRunState](api/faststream/asgi/app/OuterRunState.md) + - [ServerState](api/faststream/asgi/app/ServerState.md) + - factories + - [make_asyncapi_asgi](api/faststream/asgi/factories/make_asyncapi_asgi.md) + - [make_ping_asgi](api/faststream/asgi/factories/make_ping_asgi.md) + - handlers + - [get](api/faststream/asgi/handlers/get.md) + - response + - [AsgiResponse](api/faststream/asgi/response/AsgiResponse.md) + - websocket + - [WebSocketClose](api/faststream/asgi/websocket/WebSocketClose.md) + - confluent + - [KafkaBroker](api/faststream/confluent/KafkaBroker.md) + - [KafkaPublisher](api/faststream/confluent/KafkaPublisher.md) + - [KafkaResponse](api/faststream/confluent/KafkaResponse.md) + - [KafkaRoute](api/faststream/confluent/KafkaRoute.md) + - [KafkaRouter](api/faststream/confluent/KafkaRouter.md) + - [TestApp](api/faststream/confluent/TestApp.md) + - [TestKafkaBroker](api/faststream/confluent/TestKafkaBroker.md) + - [TopicPartition](api/faststream/confluent/TopicPartition.md) + - broker + - [KafkaBroker](api/faststream/confluent/broker/KafkaBroker.md) + - broker + - [KafkaBroker](api/faststream/confluent/broker/broker/KafkaBroker.md) + - logging + - [KafkaParamsStorage](api/faststream/confluent/broker/logging/KafkaParamsStorage.md) + - registrator + - [KafkaRegistrator](api/faststream/confluent/broker/registrator/KafkaRegistrator.md) + - client + - [AsyncConfluentConsumer](api/faststream/confluent/client/AsyncConfluentConsumer.md) + - [AsyncConfluentProducer](api/faststream/confluent/client/AsyncConfluentProducer.md) + - [BatchBuilder](api/faststream/confluent/client/BatchBuilder.md) + - [check_msg_error](api/faststream/confluent/client/check_msg_error.md) + - [create_topics](api/faststream/confluent/client/create_topics.md) + - config + - [BrokerAddressFamily](api/faststream/confluent/config/BrokerAddressFamily.md) + - [BuiltinFeatures](api/faststream/confluent/config/BuiltinFeatures.md) + - [ClientDNSLookup](api/faststream/confluent/config/ClientDNSLookup.md) + - [CompressionCodec](api/faststream/confluent/config/CompressionCodec.md) + - [CompressionType](api/faststream/confluent/config/CompressionType.md) + - [ConfluentConfig](api/faststream/confluent/config/ConfluentConfig.md) + - [ConfluentFastConfig](api/faststream/confluent/config/ConfluentFastConfig.md) + - [Debug](api/faststream/confluent/config/Debug.md) + - [GroupProtocol](api/faststream/confluent/config/GroupProtocol.md) + - [IsolationLevel](api/faststream/confluent/config/IsolationLevel.md) + - [OffsetStoreMethod](api/faststream/confluent/config/OffsetStoreMethod.md) + - [SASLOAUTHBearerMethod](api/faststream/confluent/config/SASLOAUTHBearerMethod.md) + - [SecurityProtocol](api/faststream/confluent/config/SecurityProtocol.md) + - fastapi + - [Context](api/faststream/confluent/fastapi/Context.md) + - [KafkaRouter](api/faststream/confluent/fastapi/KafkaRouter.md) + - fastapi + - [KafkaRouter](api/faststream/confluent/fastapi/fastapi/KafkaRouter.md) + - message + - [ConsumerProtocol](api/faststream/confluent/message/ConsumerProtocol.md) + - [FakeConsumer](api/faststream/confluent/message/FakeConsumer.md) + - [KafkaMessage](api/faststream/confluent/message/KafkaMessage.md) + - opentelemetry + - [KafkaTelemetryMiddleware](api/faststream/confluent/opentelemetry/KafkaTelemetryMiddleware.md) + - middleware + - [KafkaTelemetryMiddleware](api/faststream/confluent/opentelemetry/middleware/KafkaTelemetryMiddleware.md) + - provider + - [BaseConfluentTelemetrySettingsProvider](api/faststream/confluent/opentelemetry/provider/BaseConfluentTelemetrySettingsProvider.md) + - [BatchConfluentTelemetrySettingsProvider](api/faststream/confluent/opentelemetry/provider/BatchConfluentTelemetrySettingsProvider.md) + - [ConfluentTelemetrySettingsProvider](api/faststream/confluent/opentelemetry/provider/ConfluentTelemetrySettingsProvider.md) + - [telemetry_attributes_provider_factory](api/faststream/confluent/opentelemetry/provider/telemetry_attributes_provider_factory.md) + - parser + - [AsyncConfluentParser](api/faststream/confluent/parser/AsyncConfluentParser.md) + - publisher + - producer + - [AsyncConfluentFastProducer](api/faststream/confluent/publisher/producer/AsyncConfluentFastProducer.md) + - publisher + - [SpecificationBatchPublisher](api/faststream/confluent/publisher/publisher/SpecificationBatchPublisher.md) + - [SpecificationDefaultPublisher](api/faststream/confluent/publisher/publisher/SpecificationDefaultPublisher.md) + - [SpecificationPublisher](api/faststream/confluent/publisher/publisher/SpecificationPublisher.md) + - usecase + - [BatchPublisher](api/faststream/confluent/publisher/usecase/BatchPublisher.md) + - [DefaultPublisher](api/faststream/confluent/publisher/usecase/DefaultPublisher.md) + - [LogicPublisher](api/faststream/confluent/publisher/usecase/LogicPublisher.md) + - response + - [KafkaResponse](api/faststream/confluent/response/KafkaResponse.md) + - router + - [KafkaPublisher](api/faststream/confluent/router/KafkaPublisher.md) + - [KafkaRoute](api/faststream/confluent/router/KafkaRoute.md) + - [KafkaRouter](api/faststream/confluent/router/KafkaRouter.md) + - schemas + - [TopicPartition](api/faststream/confluent/schemas/TopicPartition.md) + - params + - [ConsumerConnectionParams](api/faststream/confluent/schemas/params/ConsumerConnectionParams.md) + - partition + - [TopicPartition](api/faststream/confluent/schemas/partition/TopicPartition.md) + - security + - [parse_security](api/faststream/confluent/security/parse_security.md) + - subscriber + - factory + - [create_subscriber](api/faststream/confluent/subscriber/factory/create_subscriber.md) + - subscriber + - [SpecificationBatchSubscriber](api/faststream/confluent/subscriber/subscriber/SpecificationBatchSubscriber.md) + - [SpecificationDefaultSubscriber](api/faststream/confluent/subscriber/subscriber/SpecificationDefaultSubscriber.md) + - [SpecificationSubscriber](api/faststream/confluent/subscriber/subscriber/SpecificationSubscriber.md) + - usecase + - [BatchSubscriber](api/faststream/confluent/subscriber/usecase/BatchSubscriber.md) + - [DefaultSubscriber](api/faststream/confluent/subscriber/usecase/DefaultSubscriber.md) + - [LogicSubscriber](api/faststream/confluent/subscriber/usecase/LogicSubscriber.md) + - testing + - [FakeProducer](api/faststream/confluent/testing/FakeProducer.md) + - [MockConfluentMessage](api/faststream/confluent/testing/MockConfluentMessage.md) + - [TestKafkaBroker](api/faststream/confluent/testing/TestKafkaBroker.md) + - [build_message](api/faststream/confluent/testing/build_message.md) + - exceptions + - [AckMessage](api/faststream/exceptions/AckMessage.md) + - [ContextError](api/faststream/exceptions/ContextError.md) + - [FastStreamException](api/faststream/exceptions/FastStreamException.md) + - [HandlerException](api/faststream/exceptions/HandlerException.md) + - [IgnoredException](api/faststream/exceptions/IgnoredException.md) + - [IncorrectState](api/faststream/exceptions/IncorrectState.md) + - [NackMessage](api/faststream/exceptions/NackMessage.md) + - [OperationForbiddenError](api/faststream/exceptions/OperationForbiddenError.md) + - [RejectMessage](api/faststream/exceptions/RejectMessage.md) + - [SetupError](api/faststream/exceptions/SetupError.md) + - [SkipMessage](api/faststream/exceptions/SkipMessage.md) + - [StartupValidationError](api/faststream/exceptions/StartupValidationError.md) + - [StopApplication](api/faststream/exceptions/StopApplication.md) + - [StopConsume](api/faststream/exceptions/StopConsume.md) + - [SubscriberNotFound](api/faststream/exceptions/SubscriberNotFound.md) + - kafka + - [KafkaBroker](api/faststream/kafka/KafkaBroker.md) + - [KafkaPublisher](api/faststream/kafka/KafkaPublisher.md) + - [KafkaResponse](api/faststream/kafka/KafkaResponse.md) + - [KafkaRoute](api/faststream/kafka/KafkaRoute.md) + - [KafkaRouter](api/faststream/kafka/KafkaRouter.md) + - [TestApp](api/faststream/kafka/TestApp.md) + - [TestKafkaBroker](api/faststream/kafka/TestKafkaBroker.md) + - [TopicPartition](api/faststream/kafka/TopicPartition.md) + - broker + - [KafkaBroker](api/faststream/kafka/broker/KafkaBroker.md) + - broker + - [KafkaBroker](api/faststream/kafka/broker/broker/KafkaBroker.md) + - logging + - [KafkaParamsStorage](api/faststream/kafka/broker/logging/KafkaParamsStorage.md) + - registrator + - [KafkaRegistrator](api/faststream/kafka/broker/registrator/KafkaRegistrator.md) + - fastapi + - [Context](api/faststream/kafka/fastapi/Context.md) + - [KafkaRouter](api/faststream/kafka/fastapi/KafkaRouter.md) + - fastapi + - [KafkaRouter](api/faststream/kafka/fastapi/fastapi/KafkaRouter.md) + - message + - [ConsumerProtocol](api/faststream/kafka/message/ConsumerProtocol.md) + - [FakeConsumer](api/faststream/kafka/message/FakeConsumer.md) + - [KafkaAckableMessage](api/faststream/kafka/message/KafkaAckableMessage.md) + - [KafkaMessage](api/faststream/kafka/message/KafkaMessage.md) + - opentelemetry + - [KafkaTelemetryMiddleware](api/faststream/kafka/opentelemetry/KafkaTelemetryMiddleware.md) + - middleware + - [KafkaTelemetryMiddleware](api/faststream/kafka/opentelemetry/middleware/KafkaTelemetryMiddleware.md) + - provider + - [BaseKafkaTelemetrySettingsProvider](api/faststream/kafka/opentelemetry/provider/BaseKafkaTelemetrySettingsProvider.md) + - [BatchKafkaTelemetrySettingsProvider](api/faststream/kafka/opentelemetry/provider/BatchKafkaTelemetrySettingsProvider.md) + - [KafkaTelemetrySettingsProvider](api/faststream/kafka/opentelemetry/provider/KafkaTelemetrySettingsProvider.md) + - [telemetry_attributes_provider_factory](api/faststream/kafka/opentelemetry/provider/telemetry_attributes_provider_factory.md) + - parser + - [AioKafkaBatchParser](api/faststream/kafka/parser/AioKafkaBatchParser.md) + - [AioKafkaParser](api/faststream/kafka/parser/AioKafkaParser.md) + - publisher + - producer + - [AioKafkaFastProducer](api/faststream/kafka/publisher/producer/AioKafkaFastProducer.md) + - publisher + - [SpecificationBatchPublisher](api/faststream/kafka/publisher/publisher/SpecificationBatchPublisher.md) + - [SpecificationDefaultPublisher](api/faststream/kafka/publisher/publisher/SpecificationDefaultPublisher.md) + - [SpecificationPublisher](api/faststream/kafka/publisher/publisher/SpecificationPublisher.md) + - usecase + - [BatchPublisher](api/faststream/kafka/publisher/usecase/BatchPublisher.md) + - [DefaultPublisher](api/faststream/kafka/publisher/usecase/DefaultPublisher.md) + - [LogicPublisher](api/faststream/kafka/publisher/usecase/LogicPublisher.md) + - response + - [KafkaResponse](api/faststream/kafka/response/KafkaResponse.md) + - router + - [KafkaPublisher](api/faststream/kafka/router/KafkaPublisher.md) + - [KafkaRoute](api/faststream/kafka/router/KafkaRoute.md) + - [KafkaRouter](api/faststream/kafka/router/KafkaRouter.md) + - schemas + - params + - [ConsumerConnectionParams](api/faststream/kafka/schemas/params/ConsumerConnectionParams.md) + - security + - [parse_security](api/faststream/kafka/security/parse_security.md) + - subscriber + - factory + - [create_subscriber](api/faststream/kafka/subscriber/factory/create_subscriber.md) + - subscriber + - [SpecificationBatchSubscriber](api/faststream/kafka/subscriber/subscriber/SpecificationBatchSubscriber.md) + - [SpecificationDefaultSubscriber](api/faststream/kafka/subscriber/subscriber/SpecificationDefaultSubscriber.md) + - [SpecificationSubscriber](api/faststream/kafka/subscriber/subscriber/SpecificationSubscriber.md) + - usecase + - [BatchSubscriber](api/faststream/kafka/subscriber/usecase/BatchSubscriber.md) + - [DefaultSubscriber](api/faststream/kafka/subscriber/usecase/DefaultSubscriber.md) + - [LogicSubscriber](api/faststream/kafka/subscriber/usecase/LogicSubscriber.md) + - testing + - [FakeProducer](api/faststream/kafka/testing/FakeProducer.md) + - [TestKafkaBroker](api/faststream/kafka/testing/TestKafkaBroker.md) + - [build_message](api/faststream/kafka/testing/build_message.md) + - message + - [AckStatus](api/faststream/message/AckStatus.md) + - [StreamMessage](api/faststream/message/StreamMessage.md) + - [decode_message](api/faststream/message/decode_message.md) + - [encode_message](api/faststream/message/encode_message.md) + - [gen_cor_id](api/faststream/message/gen_cor_id.md) + - message + - [AckStatus](api/faststream/message/message/AckStatus.md) + - [StreamMessage](api/faststream/message/message/StreamMessage.md) + - utils + - [decode_message](api/faststream/message/utils/decode_message.md) + - [encode_message](api/faststream/message/utils/encode_message.md) + - [gen_cor_id](api/faststream/message/utils/gen_cor_id.md) + - middlewares + - [BaseMiddleware](api/faststream/middlewares/BaseMiddleware.md) + - [ExceptionMiddleware](api/faststream/middlewares/ExceptionMiddleware.md) + - base + - [BaseMiddleware](api/faststream/middlewares/base/BaseMiddleware.md) + - exception + - [BaseExceptionMiddleware](api/faststream/middlewares/exception/BaseExceptionMiddleware.md) + - [ExceptionMiddleware](api/faststream/middlewares/exception/ExceptionMiddleware.md) + - [ignore_handler](api/faststream/middlewares/exception/ignore_handler.md) + - logging + - [CriticalLogMiddleware](api/faststream/middlewares/logging/CriticalLogMiddleware.md) + - [LoggingMiddleware](api/faststream/middlewares/logging/LoggingMiddleware.md) + - nats + - [AckPolicy](api/faststream/nats/AckPolicy.md) + - [ConsumerConfig](api/faststream/nats/ConsumerConfig.md) + - [DeliverPolicy](api/faststream/nats/DeliverPolicy.md) + - [DiscardPolicy](api/faststream/nats/DiscardPolicy.md) + - [ExternalStream](api/faststream/nats/ExternalStream.md) + - [JStream](api/faststream/nats/JStream.md) + - [KvWatch](api/faststream/nats/KvWatch.md) + - [NatsBroker](api/faststream/nats/NatsBroker.md) + - [NatsPublisher](api/faststream/nats/NatsPublisher.md) + - [NatsResponse](api/faststream/nats/NatsResponse.md) + - [NatsRoute](api/faststream/nats/NatsRoute.md) + - [NatsRouter](api/faststream/nats/NatsRouter.md) + - [ObjWatch](api/faststream/nats/ObjWatch.md) + - [Placement](api/faststream/nats/Placement.md) + - [PullSub](api/faststream/nats/PullSub.md) + - [RePublish](api/faststream/nats/RePublish.md) + - [ReplayPolicy](api/faststream/nats/ReplayPolicy.md) + - [RetentionPolicy](api/faststream/nats/RetentionPolicy.md) + - [StorageType](api/faststream/nats/StorageType.md) + - [StreamConfig](api/faststream/nats/StreamConfig.md) + - [StreamSource](api/faststream/nats/StreamSource.md) + - [TestApp](api/faststream/nats/TestApp.md) + - [TestNatsBroker](api/faststream/nats/TestNatsBroker.md) + - broker + - [NatsBroker](api/faststream/nats/broker/NatsBroker.md) + - broker + - [NatsBroker](api/faststream/nats/broker/broker/NatsBroker.md) + - logging + - [NatsParamsStorage](api/faststream/nats/broker/logging/NatsParamsStorage.md) + - registrator + - [NatsRegistrator](api/faststream/nats/broker/registrator/NatsRegistrator.md) + - fastapi + - [Context](api/faststream/nats/fastapi/Context.md) + - [NatsRouter](api/faststream/nats/fastapi/NatsRouter.md) + - fastapi + - [NatsRouter](api/faststream/nats/fastapi/fastapi/NatsRouter.md) + - helpers + - [KVBucketDeclarer](api/faststream/nats/helpers/KVBucketDeclarer.md) + - [OSBucketDeclarer](api/faststream/nats/helpers/OSBucketDeclarer.md) + - [StreamBuilder](api/faststream/nats/helpers/StreamBuilder.md) + - bucket_declarer + - [KVBucketDeclarer](api/faststream/nats/helpers/bucket_declarer/KVBucketDeclarer.md) + - obj_storage_declarer + - [OSBucketDeclarer](api/faststream/nats/helpers/obj_storage_declarer/OSBucketDeclarer.md) + - object_builder + - [StreamBuilder](api/faststream/nats/helpers/object_builder/StreamBuilder.md) + - message + - [NatsBatchMessage](api/faststream/nats/message/NatsBatchMessage.md) + - [NatsKvMessage](api/faststream/nats/message/NatsKvMessage.md) + - [NatsMessage](api/faststream/nats/message/NatsMessage.md) + - [NatsObjMessage](api/faststream/nats/message/NatsObjMessage.md) + - opentelemetry + - [NatsTelemetryMiddleware](api/faststream/nats/opentelemetry/NatsTelemetryMiddleware.md) + - middleware + - [NatsTelemetryMiddleware](api/faststream/nats/opentelemetry/middleware/NatsTelemetryMiddleware.md) + - provider + - [BaseNatsTelemetrySettingsProvider](api/faststream/nats/opentelemetry/provider/BaseNatsTelemetrySettingsProvider.md) + - [NatsBatchTelemetrySettingsProvider](api/faststream/nats/opentelemetry/provider/NatsBatchTelemetrySettingsProvider.md) + - [NatsTelemetrySettingsProvider](api/faststream/nats/opentelemetry/provider/NatsTelemetrySettingsProvider.md) + - [telemetry_attributes_provider_factory](api/faststream/nats/opentelemetry/provider/telemetry_attributes_provider_factory.md) + - parser + - [BatchParser](api/faststream/nats/parser/BatchParser.md) + - [JsParser](api/faststream/nats/parser/JsParser.md) + - [KvParser](api/faststream/nats/parser/KvParser.md) + - [NatsBaseParser](api/faststream/nats/parser/NatsBaseParser.md) + - [NatsParser](api/faststream/nats/parser/NatsParser.md) + - [ObjParser](api/faststream/nats/parser/ObjParser.md) + - publisher + - producer + - [NatsFastProducer](api/faststream/nats/publisher/producer/NatsFastProducer.md) + - [NatsJSFastProducer](api/faststream/nats/publisher/producer/NatsJSFastProducer.md) + - publisher + - [SpecificationPublisher](api/faststream/nats/publisher/publisher/SpecificationPublisher.md) + - usecase + - [LogicPublisher](api/faststream/nats/publisher/usecase/LogicPublisher.md) + - response + - [NatsResponse](api/faststream/nats/response/NatsResponse.md) + - router + - [NatsPublisher](api/faststream/nats/router/NatsPublisher.md) + - [NatsRoute](api/faststream/nats/router/NatsRoute.md) + - [NatsRouter](api/faststream/nats/router/NatsRouter.md) + - schemas + - [JStream](api/faststream/nats/schemas/JStream.md) + - [KvWatch](api/faststream/nats/schemas/KvWatch.md) + - [ObjWatch](api/faststream/nats/schemas/ObjWatch.md) + - [PullSub](api/faststream/nats/schemas/PullSub.md) + - js_stream + - [JStream](api/faststream/nats/schemas/js_stream/JStream.md) + - [compile_nats_wildcard](api/faststream/nats/schemas/js_stream/compile_nats_wildcard.md) + - [is_subject_match_wildcard](api/faststream/nats/schemas/js_stream/is_subject_match_wildcard.md) + - kv_watch + - [KvWatch](api/faststream/nats/schemas/kv_watch/KvWatch.md) + - obj_watch + - [ObjWatch](api/faststream/nats/schemas/obj_watch/ObjWatch.md) + - pull_sub + - [PullSub](api/faststream/nats/schemas/pull_sub/PullSub.md) + - security + - [parse_security](api/faststream/nats/security/parse_security.md) + - subscriber + - factory + - [create_subscriber](api/faststream/nats/subscriber/factory/create_subscriber.md) + - subscriber + - [SpecificationBatchPullStreamSubscriber](api/faststream/nats/subscriber/subscriber/SpecificationBatchPullStreamSubscriber.md) + - [SpecificationConcurrentCoreSubscriber](api/faststream/nats/subscriber/subscriber/SpecificationConcurrentCoreSubscriber.md) + - [SpecificationConcurrentPullStreamSubscriber](api/faststream/nats/subscriber/subscriber/SpecificationConcurrentPullStreamSubscriber.md) + - [SpecificationConcurrentPushStreamSubscriber](api/faststream/nats/subscriber/subscriber/SpecificationConcurrentPushStreamSubscriber.md) + - [SpecificationCoreSubscriber](api/faststream/nats/subscriber/subscriber/SpecificationCoreSubscriber.md) + - [SpecificationKeyValueWatchSubscriber](api/faststream/nats/subscriber/subscriber/SpecificationKeyValueWatchSubscriber.md) + - [SpecificationObjStoreWatchSubscriber](api/faststream/nats/subscriber/subscriber/SpecificationObjStoreWatchSubscriber.md) + - [SpecificationPullStreamSubscriber](api/faststream/nats/subscriber/subscriber/SpecificationPullStreamSubscriber.md) + - [SpecificationStreamSubscriber](api/faststream/nats/subscriber/subscriber/SpecificationStreamSubscriber.md) + - [SpecificationSubscriber](api/faststream/nats/subscriber/subscriber/SpecificationSubscriber.md) + - subscription + - [UnsubscribeAdapter](api/faststream/nats/subscriber/subscription/UnsubscribeAdapter.md) + - [Unsubscriptable](api/faststream/nats/subscriber/subscription/Unsubscriptable.md) + - [Watchable](api/faststream/nats/subscriber/subscription/Watchable.md) + - usecase + - [BatchPullStreamSubscriber](api/faststream/nats/subscriber/usecase/BatchPullStreamSubscriber.md) + - [ConcurrentCoreSubscriber](api/faststream/nats/subscriber/usecase/ConcurrentCoreSubscriber.md) + - [ConcurrentPullStreamSubscriber](api/faststream/nats/subscriber/usecase/ConcurrentPullStreamSubscriber.md) + - [ConcurrentPushStreamSubscriber](api/faststream/nats/subscriber/usecase/ConcurrentPushStreamSubscriber.md) + - [CoreSubscriber](api/faststream/nats/subscriber/usecase/CoreSubscriber.md) + - [KeyValueWatchSubscriber](api/faststream/nats/subscriber/usecase/KeyValueWatchSubscriber.md) + - [LogicSubscriber](api/faststream/nats/subscriber/usecase/LogicSubscriber.md) + - [ObjStoreWatchSubscriber](api/faststream/nats/subscriber/usecase/ObjStoreWatchSubscriber.md) + - [PullStreamSubscriber](api/faststream/nats/subscriber/usecase/PullStreamSubscriber.md) + - [PushStreamSubscription](api/faststream/nats/subscriber/usecase/PushStreamSubscription.md) + - testing + - [FakeProducer](api/faststream/nats/testing/FakeProducer.md) + - [PatchedMessage](api/faststream/nats/testing/PatchedMessage.md) + - [TestNatsBroker](api/faststream/nats/testing/TestNatsBroker.md) + - [build_message](api/faststream/nats/testing/build_message.md) + - opentelemetry + - [Baggage](api/faststream/opentelemetry/Baggage.md) + - [TelemetryMiddleware](api/faststream/opentelemetry/TelemetryMiddleware.md) + - [TelemetrySettingsProvider](api/faststream/opentelemetry/TelemetrySettingsProvider.md) + - baggage + - [Baggage](api/faststream/opentelemetry/baggage/Baggage.md) + - consts + - [MessageAction](api/faststream/opentelemetry/consts/MessageAction.md) + - middleware + - [BaseTelemetryMiddleware](api/faststream/opentelemetry/middleware/BaseTelemetryMiddleware.md) + - [TelemetryMiddleware](api/faststream/opentelemetry/middleware/TelemetryMiddleware.md) + - provider + - [TelemetrySettingsProvider](api/faststream/opentelemetry/provider/TelemetrySettingsProvider.md) + - params + - [Context](api/faststream/params/Context.md) + - [Depends](api/faststream/params/Depends.md) + - [Header](api/faststream/params/Header.md) + - [Path](api/faststream/params/Path.md) + - no_cast + - [NoCastField](api/faststream/params/no_cast/NoCastField.md) + - params + - [Context](api/faststream/params/params/Context.md) + - [Header](api/faststream/params/params/Header.md) + - [Path](api/faststream/params/params/Path.md) + - rabbit + - [ExchangeType](api/faststream/rabbit/ExchangeType.md) + - [RabbitBroker](api/faststream/rabbit/RabbitBroker.md) + - [RabbitExchange](api/faststream/rabbit/RabbitExchange.md) + - [RabbitPublisher](api/faststream/rabbit/RabbitPublisher.md) + - [RabbitQueue](api/faststream/rabbit/RabbitQueue.md) + - [RabbitResponse](api/faststream/rabbit/RabbitResponse.md) + - [RabbitRoute](api/faststream/rabbit/RabbitRoute.md) + - [RabbitRouter](api/faststream/rabbit/RabbitRouter.md) + - [TestApp](api/faststream/rabbit/TestApp.md) + - [TestRabbitBroker](api/faststream/rabbit/TestRabbitBroker.md) + - broker + - [RabbitBroker](api/faststream/rabbit/broker/RabbitBroker.md) + - broker + - [RabbitBroker](api/faststream/rabbit/broker/broker/RabbitBroker.md) + - logging + - [RabbitParamsStorage](api/faststream/rabbit/broker/logging/RabbitParamsStorage.md) + - registrator + - [RabbitRegistrator](api/faststream/rabbit/broker/registrator/RabbitRegistrator.md) + - fastapi + - [Context](api/faststream/rabbit/fastapi/Context.md) + - [RabbitRouter](api/faststream/rabbit/fastapi/RabbitRouter.md) + - router + - [RabbitRouter](api/faststream/rabbit/fastapi/router/RabbitRouter.md) + - helpers + - declarer + - [RabbitDeclarer](api/faststream/rabbit/helpers/declarer/RabbitDeclarer.md) + - message + - [RabbitMessage](api/faststream/rabbit/message/RabbitMessage.md) + - opentelemetry + - [RabbitTelemetryMiddleware](api/faststream/rabbit/opentelemetry/RabbitTelemetryMiddleware.md) + - middleware + - [RabbitTelemetryMiddleware](api/faststream/rabbit/opentelemetry/middleware/RabbitTelemetryMiddleware.md) + - provider + - [RabbitTelemetrySettingsProvider](api/faststream/rabbit/opentelemetry/provider/RabbitTelemetrySettingsProvider.md) + - parser + - [AioPikaParser](api/faststream/rabbit/parser/AioPikaParser.md) + - publisher + - producer + - [AioPikaFastProducer](api/faststream/rabbit/publisher/producer/AioPikaFastProducer.md) + - publisher + - [SpecificationPublisher](api/faststream/rabbit/publisher/publisher/SpecificationPublisher.md) + - usecase + - [LogicPublisher](api/faststream/rabbit/publisher/usecase/LogicPublisher.md) + - [PublishKwargs](api/faststream/rabbit/publisher/usecase/PublishKwargs.md) + - [RequestPublishKwargs](api/faststream/rabbit/publisher/usecase/RequestPublishKwargs.md) + - response + - [RabbitResponse](api/faststream/rabbit/response/RabbitResponse.md) + - router + - [RabbitPublisher](api/faststream/rabbit/router/RabbitPublisher.md) + - [RabbitRoute](api/faststream/rabbit/router/RabbitRoute.md) + - [RabbitRouter](api/faststream/rabbit/router/RabbitRouter.md) + - schemas + - [BaseRMQInformation](api/faststream/rabbit/schemas/BaseRMQInformation.md) + - [ExchangeType](api/faststream/rabbit/schemas/ExchangeType.md) + - [RabbitExchange](api/faststream/rabbit/schemas/RabbitExchange.md) + - [RabbitQueue](api/faststream/rabbit/schemas/RabbitQueue.md) + - constants + - [ExchangeType](api/faststream/rabbit/schemas/constants/ExchangeType.md) + - exchange + - [RabbitExchange](api/faststream/rabbit/schemas/exchange/RabbitExchange.md) + - proto + - [BaseRMQInformation](api/faststream/rabbit/schemas/proto/BaseRMQInformation.md) + - queue + - [RabbitQueue](api/faststream/rabbit/schemas/queue/RabbitQueue.md) + - security + - [parse_security](api/faststream/rabbit/security/parse_security.md) + - subscriber + - factory + - [create_subscriber](api/faststream/rabbit/subscriber/factory/create_subscriber.md) + - subscriber + - [SpecificationSubscriber](api/faststream/rabbit/subscriber/subscriber/SpecificationSubscriber.md) + - usecase + - [LogicSubscriber](api/faststream/rabbit/subscriber/usecase/LogicSubscriber.md) + - testing + - [FakeProducer](api/faststream/rabbit/testing/FakeProducer.md) + - [PatchedMessage](api/faststream/rabbit/testing/PatchedMessage.md) + - [TestRabbitBroker](api/faststream/rabbit/testing/TestRabbitBroker.md) + - [apply_pattern](api/faststream/rabbit/testing/apply_pattern.md) + - [build_message](api/faststream/rabbit/testing/build_message.md) + - utils + - [build_url](api/faststream/rabbit/utils/build_url.md) + - [is_routing_exchange](api/faststream/rabbit/utils/is_routing_exchange.md) + - redis + - [ListSub](api/faststream/redis/ListSub.md) + - [PubSub](api/faststream/redis/PubSub.md) + - [RedisBroker](api/faststream/redis/RedisBroker.md) + - [RedisPublisher](api/faststream/redis/RedisPublisher.md) + - [RedisResponse](api/faststream/redis/RedisResponse.md) + - [RedisRoute](api/faststream/redis/RedisRoute.md) + - [RedisRouter](api/faststream/redis/RedisRouter.md) + - [StreamSub](api/faststream/redis/StreamSub.md) + - [TestApp](api/faststream/redis/TestApp.md) + - [TestRedisBroker](api/faststream/redis/TestRedisBroker.md) + - broker + - broker + - [RedisBroker](api/faststream/redis/broker/broker/RedisBroker.md) + - logging + - [RedisParamsStorage](api/faststream/redis/broker/logging/RedisParamsStorage.md) + - registrator + - [RedisRegistrator](api/faststream/redis/broker/registrator/RedisRegistrator.md) + - fastapi + - [Context](api/faststream/redis/fastapi/Context.md) + - [RedisRouter](api/faststream/redis/fastapi/RedisRouter.md) + - fastapi + - [RedisRouter](api/faststream/redis/fastapi/fastapi/RedisRouter.md) + - message + - [BatchListMessage](api/faststream/redis/message/BatchListMessage.md) + - [BatchStreamMessage](api/faststream/redis/message/BatchStreamMessage.md) + - [DefaultListMessage](api/faststream/redis/message/DefaultListMessage.md) + - [DefaultStreamMessage](api/faststream/redis/message/DefaultStreamMessage.md) + - [ListMessage](api/faststream/redis/message/ListMessage.md) + - [PubSubMessage](api/faststream/redis/message/PubSubMessage.md) + - [RedisBatchListMessage](api/faststream/redis/message/RedisBatchListMessage.md) + - [RedisBatchStreamMessage](api/faststream/redis/message/RedisBatchStreamMessage.md) + - [RedisListMessage](api/faststream/redis/message/RedisListMessage.md) + - [RedisMessage](api/faststream/redis/message/RedisMessage.md) + - [RedisStreamMessage](api/faststream/redis/message/RedisStreamMessage.md) + - [StreamMessage](api/faststream/redis/message/StreamMessage.md) + - [UnifyRedisDict](api/faststream/redis/message/UnifyRedisDict.md) + - [UnifyRedisMessage](api/faststream/redis/message/UnifyRedisMessage.md) + - opentelemetry + - [RedisTelemetryMiddleware](api/faststream/redis/opentelemetry/RedisTelemetryMiddleware.md) + - middleware + - [RedisTelemetryMiddleware](api/faststream/redis/opentelemetry/middleware/RedisTelemetryMiddleware.md) + - provider + - [RedisTelemetrySettingsProvider](api/faststream/redis/opentelemetry/provider/RedisTelemetrySettingsProvider.md) + - parser + - [RawMessage](api/faststream/redis/parser/RawMessage.md) + - [RedisBatchListParser](api/faststream/redis/parser/RedisBatchListParser.md) + - [RedisBatchStreamParser](api/faststream/redis/parser/RedisBatchStreamParser.md) + - [RedisListParser](api/faststream/redis/parser/RedisListParser.md) + - [RedisPubSubParser](api/faststream/redis/parser/RedisPubSubParser.md) + - [RedisStreamParser](api/faststream/redis/parser/RedisStreamParser.md) + - [SimpleParser](api/faststream/redis/parser/SimpleParser.md) + - publisher + - producer + - [RedisFastProducer](api/faststream/redis/publisher/producer/RedisFastProducer.md) + - publisher + - [AsyncAPIChannelPublisher](api/faststream/redis/publisher/publisher/AsyncAPIChannelPublisher.md) + - [AsyncAPIListBatchPublisher](api/faststream/redis/publisher/publisher/AsyncAPIListBatchPublisher.md) + - [AsyncAPIListPublisher](api/faststream/redis/publisher/publisher/AsyncAPIListPublisher.md) + - [AsyncAPIStreamPublisher](api/faststream/redis/publisher/publisher/AsyncAPIStreamPublisher.md) + - [SpecificationPublisher](api/faststream/redis/publisher/publisher/SpecificationPublisher.md) + - usecase + - [ChannelPublisher](api/faststream/redis/publisher/usecase/ChannelPublisher.md) + - [ListBatchPublisher](api/faststream/redis/publisher/usecase/ListBatchPublisher.md) + - [ListPublisher](api/faststream/redis/publisher/usecase/ListPublisher.md) + - [LogicPublisher](api/faststream/redis/publisher/usecase/LogicPublisher.md) + - [StreamPublisher](api/faststream/redis/publisher/usecase/StreamPublisher.md) + - response + - [RedisResponse](api/faststream/redis/response/RedisResponse.md) + - router + - [RedisPublisher](api/faststream/redis/router/RedisPublisher.md) + - [RedisRoute](api/faststream/redis/router/RedisRoute.md) + - [RedisRouter](api/faststream/redis/router/RedisRouter.md) + - schemas + - [ListSub](api/faststream/redis/schemas/ListSub.md) + - [PubSub](api/faststream/redis/schemas/PubSub.md) + - [StreamSub](api/faststream/redis/schemas/StreamSub.md) + - list_sub + - [ListSub](api/faststream/redis/schemas/list_sub/ListSub.md) + - proto + - [RedisAsyncAPIProtocol](api/faststream/redis/schemas/proto/RedisAsyncAPIProtocol.md) + - [validate_options](api/faststream/redis/schemas/proto/validate_options.md) + - pub_sub + - [PubSub](api/faststream/redis/schemas/pub_sub/PubSub.md) + - stream_sub + - [StreamSub](api/faststream/redis/schemas/stream_sub/StreamSub.md) + - security + - [parse_security](api/faststream/redis/security/parse_security.md) + - subscriber + - factory + - [create_subscriber](api/faststream/redis/subscriber/factory/create_subscriber.md) + - subscriber + - [AsyncAPIChannelSubscriber](api/faststream/redis/subscriber/subscriber/AsyncAPIChannelSubscriber.md) + - [AsyncAPIListBatchSubscriber](api/faststream/redis/subscriber/subscriber/AsyncAPIListBatchSubscriber.md) + - [AsyncAPIListSubscriber](api/faststream/redis/subscriber/subscriber/AsyncAPIListSubscriber.md) + - [AsyncAPIStreamBatchSubscriber](api/faststream/redis/subscriber/subscriber/AsyncAPIStreamBatchSubscriber.md) + - [AsyncAPIStreamSubscriber](api/faststream/redis/subscriber/subscriber/AsyncAPIStreamSubscriber.md) + - [SpecificationSubscriber](api/faststream/redis/subscriber/subscriber/SpecificationSubscriber.md) + - usecase + - [BatchListSubscriber](api/faststream/redis/subscriber/usecase/BatchListSubscriber.md) + - [BatchStreamSubscriber](api/faststream/redis/subscriber/usecase/BatchStreamSubscriber.md) + - [ChannelSubscriber](api/faststream/redis/subscriber/usecase/ChannelSubscriber.md) + - [ListSubscriber](api/faststream/redis/subscriber/usecase/ListSubscriber.md) + - [LogicSubscriber](api/faststream/redis/subscriber/usecase/LogicSubscriber.md) + - [StreamSubscriber](api/faststream/redis/subscriber/usecase/StreamSubscriber.md) + - testing + - [ChannelVisitor](api/faststream/redis/testing/ChannelVisitor.md) + - [FakeProducer](api/faststream/redis/testing/FakeProducer.md) + - [ListVisitor](api/faststream/redis/testing/ListVisitor.md) + - [StreamVisitor](api/faststream/redis/testing/StreamVisitor.md) + - [TestRedisBroker](api/faststream/redis/testing/TestRedisBroker.md) + - [Visitor](api/faststream/redis/testing/Visitor.md) + - [build_message](api/faststream/redis/testing/build_message.md) + - response + - [Response](api/faststream/response/Response.md) + - [ensure_response](api/faststream/response/ensure_response.md) + - response + - [Response](api/faststream/response/response/Response.md) + - utils + - [ensure_response](api/faststream/response/utils/ensure_response.md) + - security + - [BaseSecurity](api/faststream/security/BaseSecurity.md) + - [SASLGSSAPI](api/faststream/security/SASLGSSAPI.md) + - [SASLOAuthBearer](api/faststream/security/SASLOAuthBearer.md) + - [SASLPlaintext](api/faststream/security/SASLPlaintext.md) + - [SASLScram256](api/faststream/security/SASLScram256.md) + - [SASLScram512](api/faststream/security/SASLScram512.md) + - specification + - asyncapi + - [AsyncAPI](api/faststream/specification/asyncapi/AsyncAPI.md) + - [AsyncAPIProto](api/faststream/specification/asyncapi/AsyncAPIProto.md) + - [get_asyncapi_html](api/faststream/specification/asyncapi/get_asyncapi_html.md) + - base + - [AsyncAPIProto](api/faststream/specification/asyncapi/base/AsyncAPIProto.md) + - asyncapi + - [AsyncAPIProto](api/faststream/specification/asyncapi/base/asyncapi/AsyncAPIProto.md) + - schema + - [BaseInfo](api/faststream/specification/asyncapi/base/schema/BaseInfo.md) + - [BaseSchema](api/faststream/specification/asyncapi/base/schema/BaseSchema.md) + - info + - [BaseInfo](api/faststream/specification/asyncapi/base/schema/info/BaseInfo.md) + - schema + - [BaseSchema](api/faststream/specification/asyncapi/base/schema/schema/BaseSchema.md) + - factory + - [AsyncAPI](api/faststream/specification/asyncapi/factory/AsyncAPI.md) + - message + - [get_model_schema](api/faststream/specification/asyncapi/message/get_model_schema.md) + - [get_response_schema](api/faststream/specification/asyncapi/message/get_response_schema.md) + - [parse_handler_params](api/faststream/specification/asyncapi/message/parse_handler_params.md) + - site + - [get_asyncapi_html](api/faststream/specification/asyncapi/site/get_asyncapi_html.md) + - [serve_app](api/faststream/specification/asyncapi/site/serve_app.md) + - utils + - [clear_key](api/faststream/specification/asyncapi/utils/clear_key.md) + - [resolve_payloads](api/faststream/specification/asyncapi/utils/resolve_payloads.md) + - [to_camelcase](api/faststream/specification/asyncapi/utils/to_camelcase.md) + - v2_6_0 + - [AsyncAPI2](api/faststream/specification/asyncapi/v2_6_0/AsyncAPI2.md) + - [get_app_schema](api/faststream/specification/asyncapi/v2_6_0/get_app_schema.md) + - facade + - [AsyncAPI2](api/faststream/specification/asyncapi/v2_6_0/facade/AsyncAPI2.md) + - generate + - [get_app_schema](api/faststream/specification/asyncapi/v2_6_0/generate/get_app_schema.md) + - [get_broker_channels](api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_channels.md) + - [get_broker_server](api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_server.md) + - [move_pydantic_refs](api/faststream/specification/asyncapi/v2_6_0/generate/move_pydantic_refs.md) + - [resolve_channel_messages](api/faststream/specification/asyncapi/v2_6_0/generate/resolve_channel_messages.md) + - schema + - [Channel](api/faststream/specification/asyncapi/v2_6_0/schema/Channel.md) + - [Components](api/faststream/specification/asyncapi/v2_6_0/schema/Components.md) + - [Contact](api/faststream/specification/asyncapi/v2_6_0/schema/Contact.md) + - [CorrelationId](api/faststream/specification/asyncapi/v2_6_0/schema/CorrelationId.md) + - [ExternalDocs](api/faststream/specification/asyncapi/v2_6_0/schema/ExternalDocs.md) + - [Info](api/faststream/specification/asyncapi/v2_6_0/schema/Info.md) + - [License](api/faststream/specification/asyncapi/v2_6_0/schema/License.md) + - [Message](api/faststream/specification/asyncapi/v2_6_0/schema/Message.md) + - [Operation](api/faststream/specification/asyncapi/v2_6_0/schema/Operation.md) + - [Parameter](api/faststream/specification/asyncapi/v2_6_0/schema/Parameter.md) + - [Reference](api/faststream/specification/asyncapi/v2_6_0/schema/Reference.md) + - [Schema](api/faststream/specification/asyncapi/v2_6_0/schema/Schema.md) + - [Server](api/faststream/specification/asyncapi/v2_6_0/schema/Server.md) + - [ServerVariable](api/faststream/specification/asyncapi/v2_6_0/schema/ServerVariable.md) + - [Tag](api/faststream/specification/asyncapi/v2_6_0/schema/Tag.md) + - [channel_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/channel_from_spec.md) + - [contact_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/contact_from_spec.md) + - [docs_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/docs_from_spec.md) + - [license_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/license_from_spec.md) + - [message_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/message_from_spec.md) + - [operation_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/operation_from_spec.md) + - [tag_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/tag_from_spec.md) + - bindings + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/OperationBinding.md) + - [channel_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/channel_binding_from_spec.md) + - [operation_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/operation_binding_from_spec.md) + - amqp + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/OperationBinding.md) + - [channel_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel_binding_from_spec.md) + - [operation_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation_binding_from_spec.md) + - channel + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/ChannelBinding.md) + - [Exchange](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Exchange.md) + - [Queue](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Queue.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/from_spec.md) + - operation + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/OperationBinding.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/from_spec.md) + - kafka + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/OperationBinding.md) + - [channel_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel_binding_from_spec.md) + - [operation_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation_binding_from_spec.md) + - channel + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel/ChannelBinding.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel/from_spec.md) + - operation + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/OperationBinding.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/from_spec.md) + - main + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/OperationBinding.md) + - [channel_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel_binding_from_spec.md) + - [operation_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation_binding_from_spec.md) + - channel + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/ChannelBinding.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/from_spec.md) + - operation + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/OperationBinding.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/from_spec.md) + - nats + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/OperationBinding.md) + - [channel_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel_binding_from_spec.md) + - [operation_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation_binding_from_spec.md) + - channel + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel/ChannelBinding.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel/from_spec.md) + - operation + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/OperationBinding.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/from_spec.md) + - redis + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/OperationBinding.md) + - [channel_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel_binding_from_spec.md) + - [operation_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation_binding_from_spec.md) + - channel + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel/ChannelBinding.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel/from_spec.md) + - operation + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/OperationBinding.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/from_spec.md) + - sqs + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/OperationBinding.md) + - [channel_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel_binding_from_spec.md) + - [operation_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation_binding_from_spec.md) + - channel + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/ChannelBinding.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/from_spec.md) + - operation + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/OperationBinding.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/from_spec.md) + - channels + - [Channel](api/faststream/specification/asyncapi/v2_6_0/schema/channels/Channel.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/channels/from_spec.md) + - components + - [Components](api/faststream/specification/asyncapi/v2_6_0/schema/components/Components.md) + - contact + - [Contact](api/faststream/specification/asyncapi/v2_6_0/schema/contact/Contact.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/contact/from_spec.md) + - docs + - [ExternalDocs](api/faststream/specification/asyncapi/v2_6_0/schema/docs/ExternalDocs.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/docs/from_spec.md) + - info + - [Info](api/faststream/specification/asyncapi/v2_6_0/schema/info/Info.md) + - license + - [License](api/faststream/specification/asyncapi/v2_6_0/schema/license/License.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/license/from_spec.md) + - message + - [CorrelationId](api/faststream/specification/asyncapi/v2_6_0/schema/message/CorrelationId.md) + - [Message](api/faststream/specification/asyncapi/v2_6_0/schema/message/Message.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/message/from_spec.md) + - operations + - [Operation](api/faststream/specification/asyncapi/v2_6_0/schema/operations/Operation.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/operations/from_spec.md) + - schema + - [Schema](api/faststream/specification/asyncapi/v2_6_0/schema/schema/Schema.md) + - servers + - [Server](api/faststream/specification/asyncapi/v2_6_0/schema/servers/Server.md) + - [ServerVariable](api/faststream/specification/asyncapi/v2_6_0/schema/servers/ServerVariable.md) + - tag + - [Tag](api/faststream/specification/asyncapi/v2_6_0/schema/tag/Tag.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/tag/from_spec.md) + - utils + - [Parameter](api/faststream/specification/asyncapi/v2_6_0/schema/utils/Parameter.md) + - [Reference](api/faststream/specification/asyncapi/v2_6_0/schema/utils/Reference.md) + - v3_0_0 + - [AsyncAPI3](api/faststream/specification/asyncapi/v3_0_0/AsyncAPI3.md) + - [get_app_schema](api/faststream/specification/asyncapi/v3_0_0/get_app_schema.md) + - facade + - [AsyncAPI3](api/faststream/specification/asyncapi/v3_0_0/facade/AsyncAPI3.md) + - generate + - [get_app_schema](api/faststream/specification/asyncapi/v3_0_0/generate/get_app_schema.md) + - [get_broker_channels](api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_channels.md) + - [get_broker_operations](api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_operations.md) + - [get_broker_server](api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_server.md) + - schema + - [Channel](api/faststream/specification/asyncapi/v3_0_0/schema/Channel.md) + - [Components](api/faststream/specification/asyncapi/v3_0_0/schema/Components.md) + - [Info](api/faststream/specification/asyncapi/v3_0_0/schema/Info.md) + - [Operation](api/faststream/specification/asyncapi/v3_0_0/schema/Operation.md) + - [Schema](api/faststream/specification/asyncapi/v3_0_0/schema/Schema.md) + - [Server](api/faststream/specification/asyncapi/v3_0_0/schema/Server.md) + - [channel_from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/channel_from_spec.md) + - [operation_from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/operation_from_spec.md) + - bindings + - [OperationBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/OperationBinding.md) + - [channel_binding_from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/channel_binding_from_spec.md) + - [operation_binding_from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/operation_binding_from_spec.md) + - amqp + - [OperationBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/OperationBinding.md) + - [channel_binding_from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel_binding_from_spec.md) + - [operation_binding_from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation_binding_from_spec.md) + - channel + - [from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel/from_spec.md) + - operation + - [OperationBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation/OperationBinding.md) + - [from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation/from_spec.md) + - main + - [OperationBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/OperationBinding.md) + - [channel_binding_from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel_binding_from_spec.md) + - [operation_binding_from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation_binding_from_spec.md) + - channel + - [from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel/from_spec.md) + - operation + - [OperationBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation/OperationBinding.md) + - [from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation/from_spec.md) + - channels + - [Channel](api/faststream/specification/asyncapi/v3_0_0/schema/channels/Channel.md) + - [from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/channels/from_spec.md) + - components + - [Components](api/faststream/specification/asyncapi/v3_0_0/schema/components/Components.md) + - info + - [Info](api/faststream/specification/asyncapi/v3_0_0/schema/info/Info.md) + - operations + - [Action](api/faststream/specification/asyncapi/v3_0_0/schema/operations/Action.md) + - [Operation](api/faststream/specification/asyncapi/v3_0_0/schema/operations/Operation.md) + - [from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/operations/from_spec.md) + - schema + - [Schema](api/faststream/specification/asyncapi/v3_0_0/schema/schema/Schema.md) + - servers + - [Server](api/faststream/specification/asyncapi/v3_0_0/schema/servers/Server.md) + - proto + - [SpecApplication](api/faststream/specification/proto/SpecApplication.md) + - [SpecificationProto](api/faststream/specification/proto/SpecificationProto.md) + - schema + - bindings + - [ChannelBinding](api/faststream/specification/schema/bindings/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/schema/bindings/OperationBinding.md) + - amqp + - [ChannelBinding](api/faststream/specification/schema/bindings/amqp/ChannelBinding.md) + - [Exchange](api/faststream/specification/schema/bindings/amqp/Exchange.md) + - [OperationBinding](api/faststream/specification/schema/bindings/amqp/OperationBinding.md) + - [Queue](api/faststream/specification/schema/bindings/amqp/Queue.md) + - kafka + - [ChannelBinding](api/faststream/specification/schema/bindings/kafka/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/schema/bindings/kafka/OperationBinding.md) + - main + - [ChannelBinding](api/faststream/specification/schema/bindings/main/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/schema/bindings/main/OperationBinding.md) + - nats + - [ChannelBinding](api/faststream/specification/schema/bindings/nats/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/schema/bindings/nats/OperationBinding.md) + - redis + - [ChannelBinding](api/faststream/specification/schema/bindings/redis/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/schema/bindings/redis/OperationBinding.md) + - sqs + - [ChannelBinding](api/faststream/specification/schema/bindings/sqs/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/schema/bindings/sqs/OperationBinding.md) + - channel + - [Channel](api/faststream/specification/schema/channel/Channel.md) + - components + - [Components](api/faststream/specification/schema/components/Components.md) + - contact + - [Contact](api/faststream/specification/schema/contact/Contact.md) + - [ContactDict](api/faststream/specification/schema/contact/ContactDict.md) + - docs + - [ExternalDocs](api/faststream/specification/schema/docs/ExternalDocs.md) + - [ExternalDocsDict](api/faststream/specification/schema/docs/ExternalDocsDict.md) + - info + - [Info](api/faststream/specification/schema/info/Info.md) + - license + - [License](api/faststream/specification/schema/license/License.md) + - [LicenseDict](api/faststream/specification/schema/license/LicenseDict.md) + - message + - [CorrelationId](api/faststream/specification/schema/message/CorrelationId.md) + - [Message](api/faststream/specification/schema/message/Message.md) + - operation + - [Operation](api/faststream/specification/schema/operation/Operation.md) + - schema + - [BaseSchema](api/faststream/specification/schema/schema/BaseSchema.md) + - security + - [OauthFlowObj](api/faststream/specification/schema/security/OauthFlowObj.md) + - [OauthFlows](api/faststream/specification/schema/security/OauthFlows.md) + - [SecuritySchemaComponent](api/faststream/specification/schema/security/SecuritySchemaComponent.md) + - servers + - [Server](api/faststream/specification/schema/servers/Server.md) + - [ServerVariable](api/faststream/specification/schema/servers/ServerVariable.md) + - tag + - [Tag](api/faststream/specification/schema/tag/Tag.md) + - [TagDict](api/faststream/specification/schema/tag/TagDict.md) - [FastStream People](faststream-people.md) - Contributing - [Development](getting-started/contributing/CONTRIBUTING.md) diff --git a/docs/docs/en/api/faststream/exceptions/ValidationError.md b/docs/docs/en/api/faststream/asgi/app/CliRunState.md similarity index 72% rename from docs/docs/en/api/faststream/exceptions/ValidationError.md rename to docs/docs/en/api/faststream/asgi/app/CliRunState.md index 93dc0a73d1..1124f2d50b 100644 --- a/docs/docs/en/api/faststream/exceptions/ValidationError.md +++ b/docs/docs/en/api/faststream/asgi/app/CliRunState.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.exceptions.ValidationError +::: faststream.asgi.app.CliRunState diff --git a/docs/docs/en/api/faststream/specification/proto/Application.md b/docs/docs/en/api/faststream/asgi/app/OuterRunState.md similarity index 70% rename from docs/docs/en/api/faststream/specification/proto/Application.md rename to docs/docs/en/api/faststream/asgi/app/OuterRunState.md index c6889ac3b8..3789ea0461 100644 --- a/docs/docs/en/api/faststream/specification/proto/Application.md +++ b/docs/docs/en/api/faststream/asgi/app/OuterRunState.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.proto.Application +::: faststream.asgi.app.OuterRunState diff --git a/docs/docs/en/api/faststream/app/catch_startup_validation_error.md b/docs/docs/en/api/faststream/asgi/app/ServerState.md similarity index 68% rename from docs/docs/en/api/faststream/app/catch_startup_validation_error.md rename to docs/docs/en/api/faststream/asgi/app/ServerState.md index a53e4686f9..6d5e2c20c6 100644 --- a/docs/docs/en/api/faststream/app/catch_startup_validation_error.md +++ b/docs/docs/en/api/faststream/asgi/app/ServerState.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.app.catch_startup_validation_error +::: faststream.asgi.app.ServerState diff --git a/docs/docs/en/api/faststream/specification/asyncapi/get_app_schema.md b/docs/docs/en/api/faststream/exceptions/StartupValidationError.md similarity index 67% rename from docs/docs/en/api/faststream/specification/asyncapi/get_app_schema.md rename to docs/docs/en/api/faststream/exceptions/StartupValidationError.md index 3b4991f8e3..05b8e7b74d 100644 --- a/docs/docs/en/api/faststream/specification/asyncapi/get_app_schema.md +++ b/docs/docs/en/api/faststream/exceptions/StartupValidationError.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.asyncapi.get_app_schema +::: faststream.exceptions.StartupValidationError diff --git a/docs/docs/en/api/faststream/specification/asyncapi/AsyncAPI.md b/docs/docs/en/api/faststream/specification/asyncapi/AsyncAPI.md new file mode 100644 index 0000000000..f6c0b2de09 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/AsyncAPI.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.AsyncAPI diff --git a/docs/docs/en/api/faststream/specification/asyncapi/AsyncAPIProto.md b/docs/docs/en/api/faststream/specification/asyncapi/AsyncAPIProto.md new file mode 100644 index 0000000000..532ae1b999 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/AsyncAPIProto.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.AsyncAPIProto diff --git a/docs/docs/en/api/faststream/specification/asyncapi/base/AsyncAPIProto.md b/docs/docs/en/api/faststream/specification/asyncapi/base/AsyncAPIProto.md new file mode 100644 index 0000000000..21e1a6f41d --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/base/AsyncAPIProto.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.base.AsyncAPIProto diff --git a/docs/docs/en/api/faststream/specification/asyncapi/base/asyncapi/AsyncAPIProto.md b/docs/docs/en/api/faststream/specification/asyncapi/base/asyncapi/AsyncAPIProto.md new file mode 100644 index 0000000000..d246c776c2 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/base/asyncapi/AsyncAPIProto.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.base.asyncapi.AsyncAPIProto diff --git a/docs/docs/en/api/faststream/specification/asyncapi/factory/AsyncAPI.md b/docs/docs/en/api/faststream/specification/asyncapi/factory/AsyncAPI.md new file mode 100644 index 0000000000..9e68cc1f6c --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/factory/AsyncAPI.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.factory.AsyncAPI diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/AsyncAPI2.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/AsyncAPI2.md new file mode 100644 index 0000000000..b6ca4b870a --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/AsyncAPI2.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.AsyncAPI2 diff --git a/docs/docs/en/api/faststream/specification/asyncapi/generate/get_app_schema.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/facade/AsyncAPI2.md similarity index 63% rename from docs/docs/en/api/faststream/specification/asyncapi/generate/get_app_schema.md rename to docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/facade/AsyncAPI2.md index f878844de5..1807a92056 100644 --- a/docs/docs/en/api/faststream/specification/asyncapi/generate/get_app_schema.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/facade/AsyncAPI2.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.asyncapi.generate.get_app_schema +::: faststream.specification.asyncapi.v2_6_0.facade.AsyncAPI2 diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/AsyncAPI3.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/AsyncAPI3.md new file mode 100644 index 0000000000..4eb400a450 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/AsyncAPI3.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.AsyncAPI3 diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/facade/AsyncAPI3.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/facade/AsyncAPI3.md new file mode 100644 index 0000000000..5216f86a02 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/facade/AsyncAPI3.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.facade.AsyncAPI3 diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/OperationBinding.md new file mode 100644 index 0000000000..876f866f35 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/OperationBinding.md new file mode 100644 index 0000000000..325bba3f9e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.amqp.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel/from_spec.md new file mode 100644 index 0000000000..543112ccce --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.amqp.channel.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel_binding_from_spec.md new file mode 100644 index 0000000000..13fc791e80 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel_binding_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.amqp.channel_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation/OperationBinding.md new file mode 100644 index 0000000000..51c5024cc7 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.amqp.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation/from_spec.md new file mode 100644 index 0000000000..be10d174d9 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.amqp.operation.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation_binding_from_spec.md new file mode 100644 index 0000000000..17aecb0abd --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation_binding_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.amqp.operation_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/channel_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/channel_binding_from_spec.md new file mode 100644 index 0000000000..71d74cb263 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/channel_binding_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.channel_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/OperationBinding.md new file mode 100644 index 0000000000..c897790951 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.main.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel/from_spec.md new file mode 100644 index 0000000000..056c911d83 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.main.channel.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel_binding_from_spec.md new file mode 100644 index 0000000000..c50397eed5 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel_binding_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.main.channel_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation/OperationBinding.md new file mode 100644 index 0000000000..4e85a7f5e4 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.main.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation/from_spec.md new file mode 100644 index 0000000000..833a6e58c1 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.main.operation.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation_binding_from_spec.md new file mode 100644 index 0000000000..a00d249af4 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation_binding_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.main.operation_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/operation_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/operation_binding_from_spec.md new file mode 100644 index 0000000000..c76d126bf0 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/operation_binding_from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.operation_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/proto/SpecApplication.md b/docs/docs/en/api/faststream/specification/proto/SpecApplication.md new file mode 100644 index 0000000000..14e1bad727 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/proto/SpecApplication.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.proto.SpecApplication diff --git a/docs/docs/en/release.md b/docs/docs/en/release.md index e50c67b207..032b4bbad0 100644 --- a/docs/docs/en/release.md +++ b/docs/docs/en/release.md @@ -12,6 +12,32 @@ hide: --- # Release Notes +## 0.5.24 + +### What's Changed + +* Replace while-sleep with Event by [@Olegt0rr](https://github.com/Olegt0rr){.external-link target="_blank"} in [#1683](https://github.com/airtai/faststream/pull/1683){.external-link target="_blank"} +* feat: add explicit CLI import error by [@Lancetnik](https://github.com/Lancetnik){.external-link target="_blank"} in [#1785](https://github.com/airtai/faststream/pull/1785){.external-link target="_blank"} +* fix (#1780): replace / in generated json refs by [@Lancetnik](https://github.com/Lancetnik){.external-link target="_blank"} in [#1786](https://github.com/airtai/faststream/pull/1786){.external-link target="_blank"} +* Fix: this commit resolve #1765 by [@Flosckow](https://github.com/Flosckow){.external-link target="_blank"} in [#1789](https://github.com/airtai/faststream/pull/1789){.external-link target="_blank"} +* fix (#1792): make RMQ publisher.publish reply_to optional by [@Lancetnik](https://github.com/Lancetnik){.external-link target="_blank"} in [#1795](https://github.com/airtai/faststream/pull/1795){.external-link target="_blank"} +* fix (#1793): FastStream Response support in FastAPI integration by [@Lancetnik](https://github.com/Lancetnik){.external-link target="_blank"} in [#1796](https://github.com/airtai/faststream/pull/1796){.external-link target="_blank"} +* Update exception.md by [@pepellsd](https://github.com/pepellsd){.external-link target="_blank"} in [#1803](https://github.com/airtai/faststream/pull/1803){.external-link target="_blank"} +* Fixes the CI bug that allows PRs with failed tests to be merged. by [@davorrunje](https://github.com/davorrunje){.external-link target="_blank"} in [#1807](https://github.com/airtai/faststream/pull/1807){.external-link target="_blank"} +* feat: add CLI support for AsgiFastStream by [@Sehat1137](https://github.com/Sehat1137){.external-link target="_blank"} in [#1782](https://github.com/airtai/faststream/pull/1782){.external-link target="_blank"} +* docs: add contributors page by [@kumaranvpl](https://github.com/kumaranvpl){.external-link target="_blank"} in [#1808](https://github.com/airtai/faststream/pull/1808){.external-link target="_blank"} +* fix: correct dependency injection of custom context fields implementing partial __eq__/__ne__ by [@antoinehumbert](https://github.com/antoinehumbert){.external-link target="_blank"} in [#1809](https://github.com/airtai/faststream/pull/1809){.external-link target="_blank"} +* do not assume discriminator is not a property by @lecko-cngroup in [#1811](https://github.com/airtai/faststream/pull/1811){.external-link target="_blank"} + +### New Contributors + +* [@Olegt0rr](https://github.com/Olegt0rr){.external-link target="_blank"} made their first contribution in [#1683](https://github.com/airtai/faststream/pull/1683){.external-link target="_blank"} +* [@pepellsd](https://github.com/pepellsd){.external-link target="_blank"} made their first contribution in [#1803](https://github.com/airtai/faststream/pull/1803){.external-link target="_blank"} +* [@antoinehumbert](https://github.com/antoinehumbert){.external-link target="_blank"} made their first contribution in [#1809](https://github.com/airtai/faststream/pull/1809){.external-link target="_blank"} +* @lecko-cngroup made their first contribution in [#1811](https://github.com/airtai/faststream/pull/1811){.external-link target="_blank"} + +**Full Changelog**: [#0.5.23...0.5.24](https://github.com/airtai/faststream/compare/0.5.23...0.5.24){.external-link target="_blank"} + ## 0.5.23 ### What's Changed diff --git a/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_broker.py b/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_broker.py index 4ddcc20cb8..1157ddbd6d 100644 --- a/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_broker.py +++ b/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_broker.py @@ -1,5 +1,6 @@ from faststream import FastStream from faststream.kafka import KafkaBroker +from faststream.specification.asyncapi import AsyncAPI broker = KafkaBroker( "localhost:9092", @@ -7,6 +8,10 @@ specification_url="non-sensitive-url:9092", ) app = FastStream(broker) +docs_obj = AsyncAPI( + broker, + schema_version="2.6.0", +) @broker.publisher("output_data") diff --git a/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_handler.py b/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_handler.py index b48022e133..6382cc5712 100644 --- a/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_handler.py +++ b/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_handler.py @@ -2,6 +2,7 @@ from faststream import FastStream from faststream.kafka import KafkaBroker, KafkaMessage +from faststream.specification.asyncapi import AsyncAPI class DataBasic(BaseModel): @@ -12,6 +13,10 @@ class DataBasic(BaseModel): broker = KafkaBroker("localhost:9092") app = FastStream(broker) +docs_obj = AsyncAPI( + broker, + schema_version="2.6.0", +) @broker.publisher( diff --git a/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_info.py b/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_info.py index b72cad1946..8645296a34 100644 --- a/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_info.py +++ b/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_info.py @@ -1,4 +1,5 @@ from faststream import FastStream +from faststream.specification.asyncapi import AsyncAPI from faststream.specification.schema.license import License from faststream.specification.schema.contact import Contact from faststream.kafka import KafkaBroker @@ -8,12 +9,16 @@ This description supports **Markdown** syntax""" app = FastStream( broker, +) +docs_obj = AsyncAPI( + broker, title="My App", - version="1.0.0", + app_version="1.0.0", description=description, license=License(name="MIT", url="https://opensource.org/license/mit/"), terms_of_service="https://my-terms.com/", contact=Contact(name="support", url="https://help.com/"), + schema_version="2.6.0", ) @broker.publisher("output_data") diff --git a/docs/docs_src/getting_started/asyncapi/asyncapi_customization/payload_info.py b/docs/docs_src/getting_started/asyncapi/asyncapi_customization/payload_info.py index 87635921c8..541e2bdbb3 100644 --- a/docs/docs_src/getting_started/asyncapi/asyncapi_customization/payload_info.py +++ b/docs/docs_src/getting_started/asyncapi/asyncapi_customization/payload_info.py @@ -2,6 +2,7 @@ from faststream import FastStream from faststream.kafka import KafkaBroker +from faststream.specification.asyncapi import AsyncAPI class DataBasic(BaseModel): @@ -12,6 +13,10 @@ class DataBasic(BaseModel): broker = KafkaBroker("localhost:9092") app = FastStream(broker) +docs_obj = AsyncAPI( + broker, + schema_version="2.6.0", +) @broker.publisher("output_data") diff --git a/docs/docs_src/kafka/basic/basic.py b/docs/docs_src/kafka/basic/basic.py index 58d1666a1b..29b14a63f7 100644 --- a/docs/docs_src/kafka/basic/basic.py +++ b/docs/docs_src/kafka/basic/basic.py @@ -2,6 +2,7 @@ from faststream import FastStream, Logger from faststream.kafka import KafkaBroker +from faststream.specification.asyncapi import AsyncAPI class DataBasic(BaseModel): @@ -12,6 +13,7 @@ class DataBasic(BaseModel): broker = KafkaBroker("localhost:9092") app = FastStream(broker) +asyncapi = AsyncAPI(broker, schema_version="3.0.0") @broker.publisher("output_data") diff --git a/faststream/_internal/cli/docs/app.py b/faststream/_internal/cli/docs/app.py index e3b729b5d5..29f9c3f8f3 100644 --- a/faststream/_internal/cli/docs/app.py +++ b/faststream/_internal/cli/docs/app.py @@ -11,7 +11,7 @@ from faststream._internal._compat import json_dumps, model_parse from faststream._internal.cli.utils.imports import import_from_string from faststream.exceptions import INSTALL_WATCHFILES, INSTALL_YAML, SCHEMA_NOT_SUPPORTED -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPIProto from faststream.specification.asyncapi.site import serve_app from faststream.specification.asyncapi.v2_6_0.schema import Schema as SchemaV2_6 from faststream.specification.asyncapi.v3_0_0.schema import Schema as SchemaV3 @@ -21,9 +21,9 @@ @asyncapi_app.command(name="serve") def serve( - app: str = typer.Argument( + docs: str = typer.Argument( ..., - help="[python_module:FastStream] or [asyncapi.yaml/.json] - path to your application or documentation.", + help="[python_module:AsyncAPIProto] or [asyncapi.yaml/.json] - path to your application or documentation.", ), host: str = typer.Option( "localhost", @@ -55,18 +55,18 @@ def serve( ), ) -> None: """Serve project AsyncAPI schema.""" - if ":" in app: + if ":" in docs: if app_dir: # pragma: no branch sys.path.insert(0, app_dir) - module, _ = import_from_string(app) + module, _ = import_from_string(docs) module_parent = module.parent extra_extensions: Sequence[str] = () else: module_parent = Path.cwd() - schema_filepath = module_parent / app + schema_filepath = module_parent / docs extra_extensions = (schema_filepath.suffix,) if reload: @@ -75,25 +75,25 @@ def serve( except ImportError: warnings.warn(INSTALL_WATCHFILES, category=ImportWarning, stacklevel=1) - _parse_and_serve(app, host, port, is_factory) + _parse_and_serve(docs, host, port, is_factory) else: WatchReloader( target=_parse_and_serve, - args=(app, host, port, is_factory), + args=(docs, host, port, is_factory), reload_dirs=(str(module_parent),), extra_extensions=extra_extensions, ).run() else: - _parse_and_serve(app, host, port, is_factory) + _parse_and_serve(docs, host, port, is_factory) @asyncapi_app.command(name="gen") def gen( - app: str = typer.Argument( + asyncapi: str = typer.Argument( ..., - help="[python_module:FastStream] - path to your application.", + help="[python_module:AsyncAPIProto] - path to your AsyncAPI object.", ), yaml: bool = typer.Option( False, @@ -129,10 +129,14 @@ def gen( if app_dir: # pragma: no branch sys.path.insert(0, app_dir) - _, app_obj = import_from_string(app) - if callable(app_obj) and is_factory: - app_obj = app_obj() - raw_schema = get_app_schema(app_obj, asyncapi_version) + _, asyncapi_obj = import_from_string(asyncapi) + + if callable(asyncapi_obj) and is_factory: + asyncapi_obj = asyncapi_obj() + + assert isinstance(asyncapi_obj, AsyncAPIProto) + + raw_schema = asyncapi_obj.schema() if yaml: try: @@ -157,19 +161,22 @@ def gen( def _parse_and_serve( - app: str, + docs: str, host: str = "localhost", port: int = 8000, is_factory: bool = False, ) -> None: - if ":" in app: - _, app_obj = import_from_string(app) - if callable(app_obj) and is_factory: - app_obj = app_obj() - raw_schema = get_app_schema(app_obj, "2.6.0") + if ":" in docs: + _, docs_obj = import_from_string(docs) + if callable(docs_obj) and is_factory: + docs_obj = docs_obj() + + assert isinstance(docs_obj, AsyncAPIProto) + + raw_schema = docs_obj.schema() else: - schema_filepath = Path.cwd() / app + schema_filepath = Path.cwd() / docs if schema_filepath.suffix == ".json": data = schema_filepath.read_bytes() @@ -188,7 +195,7 @@ def _parse_and_serve( else: raise ValueError( - f"Unknown extension given - {app}; Please provide app in format [python_module:FastStream] or [asyncapi.yaml/.json] - path to your application or documentation" + f"Unknown extension given - {docs}; Please provide app in format [python_module:AsyncAPIProto] or [asyncapi.yaml/.json] - path to your application or documentation" ) for schema in (SchemaV3, SchemaV2_6): @@ -196,7 +203,7 @@ def _parse_and_serve( raw_schema = model_parse(schema, data) break else: - typer.echo(SCHEMA_NOT_SUPPORTED.format(schema_filename=app), err=True) + typer.echo(SCHEMA_NOT_SUPPORTED.format(schema_filename=docs), err=True) raise typer.Exit(1) serve_app(raw_schema, host, port) diff --git a/faststream/_internal/cli/main.py b/faststream/_internal/cli/main.py index c35ae460ee..c406c63365 100644 --- a/faststream/_internal/cli/main.py +++ b/faststream/_internal/cli/main.py @@ -234,9 +234,12 @@ def publish( try: _, app_obj = import_from_string(app) + if callable(app_obj) and is_factory: app_obj = app_obj() + assert isinstance(app_obj, FastStream), app_obj + if not app_obj.broker: raise ValueError("Broker instance not found in the app.") diff --git a/faststream/_internal/cli/utils/imports.py b/faststream/_internal/cli/utils/imports.py index c1cdc1fd26..e977a693dd 100644 --- a/faststream/_internal/cli/utils/imports.py +++ b/faststream/_internal/cli/utils/imports.py @@ -1,17 +1,14 @@ import importlib from importlib.util import module_from_spec, spec_from_file_location from pathlib import Path -from typing import TYPE_CHECKING, Tuple +from typing import Tuple import typer from faststream.exceptions import SetupError -if TYPE_CHECKING: - from faststream.app import FastStream - -def try_import_app(module: Path, app: str) -> "FastStream": +def try_import_app(module: Path, app: str) -> object: """Tries to import a FastStream app from a module.""" try: app_object = import_object(module, app) @@ -19,11 +16,11 @@ def try_import_app(module: Path, app: str) -> "FastStream": except FileNotFoundError as e: typer.echo(e, err=True) raise typer.BadParameter( - "Please, input module like [python_file:faststream_app_name] or [module:attribute]" + "Please, input module like [python_file:docs_object] or [module:attribute]" ) from e else: - return app_object # type: ignore + return app_object def import_object(module: Path, app: str) -> object: @@ -53,12 +50,12 @@ def import_object(module: Path, app: str) -> object: return obj -def get_app_path(app: str) -> Tuple[Path, str]: +def get_obj_path(obj_path: str) -> Tuple[Path, str]: """Get the application path.""" - if ":" not in app: - raise SetupError(f"`{app}` is not a FastStream") + if ":" not in obj_path: + raise SetupError(f"`{obj_path}` is not a path to object") - module, app_name = app.split(":", 2) + module, app_name = obj_path.split(":", 2) mod_path = Path.cwd() for i in module.split("."): @@ -67,7 +64,7 @@ def get_app_path(app: str) -> Tuple[Path, str]: return mod_path, app_name -def import_from_string(import_str: str) -> Tuple[Path, "FastStream"]: +def import_from_string(import_str: str) -> Tuple[Path, object]: """Import FastStream application from module specified by a string.""" if not isinstance(import_str, str): raise typer.BadParameter("Given value is not of type string") @@ -84,15 +81,15 @@ def import_from_string(import_str: str) -> Tuple[Path, "FastStream"]: ) except ModuleNotFoundError: - module_path, app_name = get_app_path(import_str) - instance = try_import_app(module_path, app_name) + module_path, import_obj_name = get_obj_path(import_str) + instance = try_import_app(module_path, import_obj_name) else: attr = module try: for attr_str in attrs_str.split("."): attr = getattr(attr, attr_str) - instance = attr # type: ignore[assignment] + instance = attr except AttributeError as e: typer.echo(e, err=True) diff --git a/faststream/_internal/fastapi/router.py b/faststream/_internal/fastapi/router.py index 617460b687..3d57432bdc 100644 --- a/faststream/_internal/fastapi/router.py +++ b/faststream/_internal/fastapi/router.py @@ -303,9 +303,17 @@ async def start_broker_lifespan( self.contact = app.contact self.license = app.license_info - from faststream.specification.asyncapi.generate import get_app_schema - - self.schema = get_app_schema(self) + from faststream.specification.asyncapi import AsyncAPI + + self.schema = AsyncAPI( + self.broker, + title=self.title, + description=self.description, + app_version=self.version, + contact=self.contact, + license=self.license, + schema_version="3.0.0" + ).schema() app.include_router(self.docs_router) diff --git a/faststream/app.py b/faststream/app.py index 6a2a80b371..8565e847ba 100644 --- a/faststream/app.py +++ b/faststream/app.py @@ -7,7 +7,6 @@ Sequence, Tuple, TypeVar, - Union, ) import anyio @@ -15,7 +14,7 @@ from faststream._internal._compat import ExceptionGroup from faststream._internal.application import Application -from faststream._internal.basic_types import AnyDict, AnyHttpUrl, Lifespan, LoggerProto +from faststream._internal.basic_types import Lifespan, LoggerProto from faststream._internal.broker.broker import BrokerUsecase from faststream._internal.cli.supervisors.utils import set_exit from faststream._internal.log import logger @@ -28,18 +27,12 @@ if TYPE_CHECKING: from faststream._internal.basic_types import ( AnyCallable, - AnyDict, - AnyHttpUrl, Lifespan, LoggerProto, SettingField, ) from faststream._internal.broker.broker import BrokerUsecase from faststream.asgi.types import ASGIApp - from faststream.specification.schema.contact import Contact, ContactDict - from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict - from faststream.specification.schema.license import License, LicenseDict - from faststream.specification.schema.tag import Tag class FastStream(Application): @@ -52,19 +45,6 @@ def __init__( # regular broker args logger: Optional["LoggerProto"] = logger, lifespan: Optional["Lifespan"] = None, - # AsyncAPI args, - title: str = "FastStream", - version: str = "0.1.0", - description: str = "", - terms_of_service: Optional["AnyHttpUrl"] = None, - license: Optional[Union["License", "LicenseDict", "AnyDict"]] = None, - contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] = None, - tags: Optional[Sequence[Union["Tag", "AnyDict"]]] = None, - external_docs: Optional[ - Union["ExternalDocs", "ExternalDocsDict", "AnyDict"] - ] = None, - identifier: Optional[str] = None, - # hooks on_startup: Sequence["AnyCallable"] = (), after_startup: Sequence["AnyCallable"] = (), on_shutdown: Sequence["AnyCallable"] = (), @@ -74,15 +54,6 @@ def __init__( broker=broker, logger=logger, lifespan=lifespan, - title=title, - version=version, - description=description, - terms_of_service=terms_of_service, - license=license, - contact=contact, - tags=tags, - external_docs=external_docs, - identifier=identifier, on_startup=on_startup, after_startup=after_startup, on_shutdown=on_shutdown, diff --git a/faststream/asgi/app.py b/faststream/asgi/app.py index 3e25cc4c2a..2c74344d79 100644 --- a/faststream/asgi/app.py +++ b/faststream/asgi/app.py @@ -12,7 +12,6 @@ Protocol, Sequence, Tuple, - Union, ) import anyio @@ -32,18 +31,12 @@ from faststream._internal.basic_types import ( AnyCallable, - AnyDict, - AnyHttpUrl, Lifespan, LoggerProto, SettingField, ) from faststream._internal.broker.broker import BrokerUsecase from faststream.asgi.types import ASGIApp, Receive, Scope, Send - from faststream.specification.schema.contact import Contact, ContactDict - from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict - from faststream.specification.schema.license import License, LicenseDict - from faststream.specification.schema.tag import Tag, TagDict class UvicornServerProtocol(Protocol): should_exit: bool @@ -93,18 +86,6 @@ def __init__( # regular broker args logger: Optional["LoggerProto"] = logger, lifespan: Optional["Lifespan"] = None, - # AsyncAPI args, - title: str = "FastStream", - version: str = "0.1.0", - description: str = "", - terms_of_service: Optional["AnyHttpUrl"] = None, - license: Optional[Union["License", "LicenseDict", "AnyDict"]] = None, - contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] = None, - tags: Optional[Sequence[Union["Tag", "TagDict", "AnyDict"]]] = None, - external_docs: Optional[ - Union["ExternalDocs", "ExternalDocsDict", "AnyDict"] - ] = None, - identifier: Optional[str] = None, # hooks on_startup: Sequence["AnyCallable"] = (), after_startup: Sequence["AnyCallable"] = (), @@ -115,15 +96,6 @@ def __init__( broker=broker, logger=logger, lifespan=lifespan, - title=title, - version=version, - description=description, - terms_of_service=terms_of_service, - license=license, - contact=contact, - tags=tags, - external_docs=external_docs, - identifier=identifier, on_startup=on_startup, after_startup=after_startup, on_shutdown=on_shutdown, @@ -150,15 +122,6 @@ def from_app( asyncapi_path=asyncapi_path, logger=app.logger, lifespan=None, - title=app.title, - version=app.version, - description=app.description, - terms_of_service=app.terms_of_service, - license=app.license, - contact=app.contact, - tags=app.specification_tags, - external_docs=app.external_docs, - identifier=app.identifier, ) asgi_app.lifespan_context = app.lifespan_context asgi_app._on_startup_calling = app._on_startup_calling diff --git a/faststream/asgi/factories.py b/faststream/asgi/factories.py index f079b9e183..f86a66e342 100644 --- a/faststream/asgi/factories.py +++ b/faststream/asgi/factories.py @@ -6,7 +6,7 @@ from faststream.asgi.handlers import get from faststream.asgi.response import AsgiResponse -from faststream.specification.asyncapi import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from faststream.specification.asyncapi.site import ( ASYNCAPI_CSS_DEFAULT_URL, ASYNCAPI_JS_DEFAULT_URL, @@ -51,9 +51,12 @@ def make_asyncapi_asgi( asyncapi_js_url: str = ASYNCAPI_JS_DEFAULT_URL, asyncapi_css_url: str = ASYNCAPI_CSS_DEFAULT_URL, ) -> "ASGIApp": + if app.broker is None: + raise RuntimeError() + return AsgiResponse( get_asyncapi_html( - get_app_schema(app, version="2.6.0"), + AsyncAPI(app.broker, schema_version="2.6.0").schema(), sidebar=sidebar, info=info, servers=servers, diff --git a/faststream/specification/asyncapi/__init__.py b/faststream/specification/asyncapi/__init__.py index 5b5a564ce1..533c3f0784 100644 --- a/faststream/specification/asyncapi/__init__.py +++ b/faststream/specification/asyncapi/__init__.py @@ -1,9 +1,12 @@ """AsyncAPI related functions.""" -from faststream.specification.asyncapi.generate import get_app_schema from faststream.specification.asyncapi.site import get_asyncapi_html +from .base import AsyncAPIProto +from .factory import AsyncAPI + __all__ = ( + "AsyncAPIProto", + "AsyncAPI", "get_asyncapi_html", - "get_app_schema", ) diff --git a/faststream/specification/asyncapi/base/__init__.py b/faststream/specification/asyncapi/base/__init__.py index 25ed570dda..5ca8980715 100644 --- a/faststream/specification/asyncapi/base/__init__.py +++ b/faststream/specification/asyncapi/base/__init__.py @@ -1,3 +1,5 @@ -from faststream.specification.asyncapi.base import schema +from .asyncapi import AsyncAPIProto -__all__ = ("schema",) +__all__ = ( + "AsyncAPIProto", +) diff --git a/faststream/specification/asyncapi/base/asyncapi.py b/faststream/specification/asyncapi/base/asyncapi.py new file mode 100644 index 0000000000..e9ef2a9334 --- /dev/null +++ b/faststream/specification/asyncapi/base/asyncapi.py @@ -0,0 +1,18 @@ +from typing import Any, Protocol, runtime_checkable + +from faststream.specification.asyncapi.base.schema import BaseSchema + + +@runtime_checkable +class AsyncAPIProto(Protocol): + def json(self) -> str: + ... + + def jsonable(self) -> Any: + ... + + def yaml(self) -> str: + ... + + def schema(self) -> BaseSchema: + ... diff --git a/faststream/specification/asyncapi/factory.py b/faststream/specification/asyncapi/factory.py new file mode 100644 index 0000000000..0d113d6d0c --- /dev/null +++ b/faststream/specification/asyncapi/factory.py @@ -0,0 +1,74 @@ +from typing import TYPE_CHECKING, Any, Literal, Optional, Sequence, Union + +from faststream._internal.broker.broker import BrokerUsecase +from faststream.specification.asyncapi.base.asyncapi import AsyncAPIProto +from faststream.specification.asyncapi.base.schema import BaseSchema +from faststream.specification.asyncapi.v2_6_0.facade import AsyncAPI2 +from faststream.specification.asyncapi.v3_0_0.facade import AsyncAPI3 + +if TYPE_CHECKING: + from faststream._internal.basic_types import AnyDict, AnyHttpUrl + from faststream.specification.schema.contact import Contact, ContactDict + from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict + from faststream.specification.schema.license import License, LicenseDict + from faststream.specification.schema.tag import Tag, TagDict + + +class AsyncAPI(AsyncAPIProto): + def __new__( # type: ignore[misc] + cls, + broker: BrokerUsecase[Any, Any], + /, + title: str = "FastStream", + app_version: str = "0.1.0", + schema_version: Union[Literal["3.0.0", "2.6.0"], str] = "3.0.0", + description: str = "", + terms_of_service: Optional["AnyHttpUrl"] = None, + license: Optional[Union["License", "LicenseDict", "AnyDict"]] = None, + contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] = None, + tags: Optional[Sequence[Union["Tag", "TagDict", "AnyDict"]]] = None, + external_docs: Optional[Union["ExternalDocs", "ExternalDocsDict", "AnyDict"]] = None, + identifier: Optional[str] = None, + ) -> AsyncAPIProto: + if schema_version.startswith("3.0."): + return AsyncAPI3( + broker, + title=title, + app_version=app_version, + schema_version=schema_version, + description=description, + terms_of_service=terms_of_service, + contact=contact, + license=license, + identifier=identifier, + tags=tags, + external_docs=external_docs, + ) + elif schema_version.startswith("2.6."): + return AsyncAPI2( + broker, + title=title, + app_version=app_version, + schema_version=schema_version, + description=description, + terms_of_service=terms_of_service, + contact=contact, + license=license, + identifier=identifier, + tags=tags, + external_docs=external_docs, + ) + else: + raise NotImplementedError(f"Unsupported schema version: {schema_version}") + + def json(self) -> str: # type: ignore[empty-body] + pass + + def jsonable(self) -> Any: + pass + + def yaml(self) -> str: # type: ignore[empty-body] + pass + + def schema(self) -> BaseSchema: # type: ignore[empty-body] + pass diff --git a/faststream/specification/asyncapi/generate.py b/faststream/specification/asyncapi/generate.py deleted file mode 100644 index a30e0910a9..0000000000 --- a/faststream/specification/asyncapi/generate.py +++ /dev/null @@ -1,25 +0,0 @@ -from typing import TYPE_CHECKING, Literal, Union - -from faststream.specification.asyncapi.base.schema import BaseSchema -from faststream.specification.asyncapi.v2_6_0.generate import ( - get_app_schema as get_app_schema_v2_6, -) -from faststream.specification.asyncapi.v3_0_0.generate import ( - get_app_schema as get_app_schema_v3, -) - -if TYPE_CHECKING: - from faststream.specification.proto import SpecApplication - - -def get_app_schema( - app: "SpecApplication", - version: Union[Literal["3.0.0", "2.6.0"], str] = "3.0.0", -) -> BaseSchema: - if version.startswith("3.0."): - return get_app_schema_v3(app) - - if version.startswith("2.6."): - return get_app_schema_v2_6(app) - - raise NotImplementedError(f"AsyncAPI version not supported: {version}") diff --git a/faststream/specification/asyncapi/v2_6_0/__init__.py b/faststream/specification/asyncapi/v2_6_0/__init__.py index afdcd53813..dd1af249b3 100644 --- a/faststream/specification/asyncapi/v2_6_0/__init__.py +++ b/faststream/specification/asyncapi/v2_6_0/__init__.py @@ -1,3 +1,7 @@ +from .facade import AsyncAPI2 from .generate import get_app_schema -__all__ = ("get_app_schema",) +__all__ = ( + "AsyncAPI2", + "get_app_schema", +) diff --git a/faststream/specification/asyncapi/v2_6_0/facade.py b/faststream/specification/asyncapi/v2_6_0/facade.py new file mode 100644 index 0000000000..6316fe72a2 --- /dev/null +++ b/faststream/specification/asyncapi/v2_6_0/facade.py @@ -0,0 +1,102 @@ +from typing import TYPE_CHECKING, Any, Optional, Sequence, Union + +from faststream._internal.broker.broker import BrokerUsecase +from faststream.specification.asyncapi.base.asyncapi import AsyncAPIProto +from faststream.specification.asyncapi.v2_6_0.generate import get_app_schema +from faststream.specification.asyncapi.v2_6_0.schema import Schema + +if TYPE_CHECKING: + from faststream._internal.basic_types import AnyDict, AnyHttpUrl + from faststream.specification.schema.contact import Contact, ContactDict + from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict + from faststream.specification.schema.license import License, LicenseDict + from faststream.specification.schema.tag import Tag, TagDict + + +class AsyncAPI2(AsyncAPIProto): + def __init__( + self, + broker: BrokerUsecase[Any, Any], + /, + title: str = "FastStream", + app_version: str = "0.1.0", + schema_version: str = "3.0.0", + description: str = "", + terms_of_service: Optional["AnyHttpUrl"] = None, + contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] = None, + license: Optional[Union["License", "LicenseDict", "AnyDict"]] = None, + identifier: Optional[str] = None, + tags: Optional[Sequence[Union["Tag", "TagDict", "AnyDict"]]] = None, + external_docs: Optional[Union["ExternalDocs", "ExternalDocsDict", "AnyDict"]] = None, + ) -> None: + self.broker = broker + self.title = title + self.app_version = app_version + self.schema_version = schema_version + self.description = description + self.terms_of_service = terms_of_service + self.contact = contact + self.license = license + self.identifier = identifier + self.tags = tags + self.external_docs = external_docs + + def json(self) -> str: + return get_app_schema( + self.broker, + title=self.title, + app_version=self.app_version, + schema_version=self.schema_version, + description=self.description, + terms_of_service=self.terms_of_service, + contact=self.contact, + license=self.license, + identifier=self.identifier, + tags=self.tags, + external_docs=self.external_docs, + ).to_json() + + def jsonable(self) -> Any: + return get_app_schema( + self.broker, + title=self.title, + app_version=self.app_version, + schema_version=self.schema_version, + description=self.description, + terms_of_service=self.terms_of_service, + contact=self.contact, + license=self.license, + identifier=self.identifier, + tags=self.tags, + external_docs=self.external_docs, + ).to_jsonable() + + def yaml(self) -> str: + return get_app_schema( + self.broker, + title=self.title, + app_version=self.app_version, + schema_version=self.schema_version, + description=self.description, + terms_of_service=self.terms_of_service, + contact=self.contact, + license=self.license, + identifier=self.identifier, + tags=self.tags, + external_docs=self.external_docs, + ).to_yaml() + + def schema(self) -> Schema: + return get_app_schema( + self.broker, + title=self.title, + app_version=self.app_version, + schema_version=self.schema_version, + description=self.description, + terms_of_service=self.terms_of_service, + contact=self.contact, + license=self.license, + identifier=self.identifier, + tags=self.tags, + external_docs=self.external_docs, + ) diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index c2dd08ee8e..9741d1992f 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -1,7 +1,7 @@ -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union +from typing import TYPE_CHECKING, Any, Dict, List, Optional, Sequence, Union from faststream._internal._compat import DEF_KEY -from faststream._internal.basic_types import AnyDict +from faststream._internal.basic_types import AnyDict, AnyHttpUrl from faststream._internal.constants import ContentTypes from faststream.specification.asyncapi.utils import clear_key from faststream.specification.asyncapi.v2_6_0.schema import ( @@ -19,20 +19,37 @@ tag_from_spec, ) from faststream.specification.asyncapi.v2_6_0.schema.message import Message -from faststream.specification.proto import SpecApplication if TYPE_CHECKING: from faststream._internal.broker.broker import BrokerUsecase from faststream._internal.types import ConnectionType, MsgType + from faststream.specification.schema.contact import Contact, ContactDict + from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict + from faststream.specification.schema.license import License, LicenseDict + from faststream.specification.schema.tag import ( + Tag as SpecsTag, + ) + from faststream.specification.schema.tag import ( + TagDict as SpecsTagDict, + ) -def get_app_schema(app: SpecApplication) -> Schema: +def get_app_schema( + broker: "BrokerUsecase[Any, Any]", + /, + title: str, + app_version: str, + schema_version: str, + description: str, + terms_of_service: Optional["AnyHttpUrl"], + contact: Optional[Union["Contact", "ContactDict", "AnyDict"]], + license: Optional[Union["License", "LicenseDict", "AnyDict"]], + identifier: Optional[str], + tags: Optional[Sequence[Union["SpecsTag", "SpecsTagDict", "AnyDict"]]], + external_docs: Optional[Union["ExternalDocs", "ExternalDocsDict", "AnyDict"]], +) -> Schema: """Get the application schema.""" - broker = app.broker - if broker is None: # pragma: no cover - raise RuntimeError() - - app._setup() + broker._setup() servers = get_broker_server(broker) channels = get_broker_channels(broker) @@ -48,19 +65,18 @@ def get_app_schema(app: SpecApplication) -> Schema: schema = Schema( info=Info( - title=app.title, - version=app.version, - description=app.description, - termsOfService=app.terms_of_service, - contact=contact_from_spec(app.contact) if app.contact else None, - license=license_from_spec(app.license) if app.license else None, + title=title, + version=app_version, + description=description, + termsOfService=terms_of_service, + contact=contact_from_spec(contact) if contact else None, + license=license_from_spec(license) if license else None, ), + asyncapi=schema_version, defaultContentType=ContentTypes.json.value, - id=app.identifier, - tags=[tag_from_spec(tag) for tag in app.specification_tags] - if app.specification_tags - else None, - externalDocs=docs_from_spec(app.external_docs) if app.external_docs else None, + id=identifier, + tags=[tag_from_spec(tag) for tag in tags] if tags else None, + externalDocs=docs_from_spec(external_docs) if external_docs else None, servers=servers, channels=channels, components=Components( diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py index 7012d31cfa..caf5140a78 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py @@ -96,7 +96,6 @@ def from_spec(cls, binding: spec.bindings.amqp.ChannelBinding) -> Self: return cls( **{ "is": binding.is_, - "bindingVersion": binding.bindingVersion, "queue": Queue.from_spec(binding.queue) if binding.queue is not None else None, diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation.py index de52f0fbb8..cd90dde96d 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation.py @@ -38,7 +38,6 @@ def from_spec(cls, binding: spec.bindings.amqp.OperationBinding) -> Self: deliveryMode=binding.deliveryMode, mandatory=binding.mandatory, priority=binding.priority, - bindingVersion=binding.bindingVersion, ) diff --git a/faststream/specification/asyncapi/v3_0_0/__init__.py b/faststream/specification/asyncapi/v3_0_0/__init__.py index be8f2c412c..490431d760 100644 --- a/faststream/specification/asyncapi/v3_0_0/__init__.py +++ b/faststream/specification/asyncapi/v3_0_0/__init__.py @@ -1,7 +1,7 @@ -from . import schema +from .facade import AsyncAPI3 from .generate import get_app_schema __all__ = ( - "schema", + "AsyncAPI3", "get_app_schema", ) diff --git a/faststream/specification/asyncapi/v3_0_0/facade.py b/faststream/specification/asyncapi/v3_0_0/facade.py new file mode 100644 index 0000000000..5632edbfcf --- /dev/null +++ b/faststream/specification/asyncapi/v3_0_0/facade.py @@ -0,0 +1,102 @@ +from typing import TYPE_CHECKING, Any, Optional, Sequence, Union + +from faststream._internal.broker.broker import BrokerUsecase +from faststream.specification.asyncapi.base.asyncapi import AsyncAPIProto +from faststream.specification.asyncapi.v3_0_0.generate import get_app_schema +from faststream.specification.asyncapi.v3_0_0.schema import Schema + +if TYPE_CHECKING: + from faststream._internal.basic_types import AnyDict, AnyHttpUrl + from faststream.specification.schema.contact import Contact, ContactDict + from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict + from faststream.specification.schema.license import License, LicenseDict + from faststream.specification.schema.tag import Tag, TagDict + + +class AsyncAPI3(AsyncAPIProto): + def __init__( + self, + broker: BrokerUsecase[Any, Any], + /, + title: str = "FastStream", + app_version: str = "0.1.0", + schema_version: str = "3.0.0", + description: str = "", + terms_of_service: Optional["AnyHttpUrl"] = None, + contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] = None, + license: Optional[Union["License", "LicenseDict", "AnyDict"]] = None, + identifier: Optional[str] = None, + tags: Optional[Sequence[Union["Tag", "TagDict", "AnyDict"]]] = None, + external_docs: Optional[Union["ExternalDocs", "ExternalDocsDict", "AnyDict"]] = None, + ) -> None: + self.broker = broker + self.title = title + self.app_version = app_version + self.schema_version = schema_version + self.description = description + self.terms_of_service = terms_of_service + self.contact = contact + self.license = license + self.identifier = identifier + self.tags = tags + self.external_docs = external_docs + + def json(self) -> str: + return get_app_schema( + self.broker, + title=self.title, + app_version=self.app_version, + schema_version=self.schema_version, + description=self.description, + terms_of_service=self.terms_of_service, + contact=self.contact, + license=self.license, + identifier=self.identifier, + tags=self.tags, + external_docs=self.external_docs, + ).to_json() + + def jsonable(self) -> Any: + return get_app_schema( + self.broker, + title=self.title, + app_version=self.app_version, + schema_version=self.schema_version, + description=self.description, + terms_of_service=self.terms_of_service, + contact=self.contact, + license=self.license, + identifier=self.identifier, + tags=self.tags, + external_docs=self.external_docs, + ).to_jsonable() + + def yaml(self) -> str: + return get_app_schema( + self.broker, + title=self.title, + app_version=self.app_version, + schema_version=self.schema_version, + description=self.description, + terms_of_service=self.terms_of_service, + contact=self.contact, + license=self.license, + identifier=self.identifier, + tags=self.tags, + external_docs=self.external_docs, + ).to_yaml() + + def schema(self) -> Schema: + return get_app_schema( + self.broker, + title=self.title, + app_version=self.app_version, + schema_version=self.schema_version, + description=self.description, + terms_of_service=self.terms_of_service, + contact=self.contact, + license=self.license, + identifier=self.identifier, + tags=self.tags, + external_docs=self.external_docs, + ) diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index f52a31d74d..92d85ae016 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -1,8 +1,8 @@ -from typing import TYPE_CHECKING, Dict, List, Optional, Union +from typing import TYPE_CHECKING, Any, Dict, List, Optional, Sequence, Union from urllib.parse import urlparse from faststream._internal._compat import DEF_KEY -from faststream._internal.basic_types import AnyDict +from faststream._internal.basic_types import AnyDict, AnyHttpUrl from faststream._internal.constants import ContentTypes from faststream.specification.asyncapi.utils import clear_key from faststream.specification.asyncapi.v2_6_0.generate import move_pydantic_refs @@ -28,19 +28,37 @@ from faststream.specification.asyncapi.v3_0_0.schema.operations import ( Action, ) -from faststream.specification.proto import SpecApplication if TYPE_CHECKING: from faststream._internal.broker.broker import BrokerUsecase from faststream._internal.types import ConnectionType, MsgType + from faststream.specification.schema.contact import Contact, ContactDict + from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict + from faststream.specification.schema.license import License, LicenseDict + from faststream.specification.schema.tag import ( + Tag as SpecsTag, + ) + from faststream.specification.schema.tag import ( + TagDict as SpecsTagDict, + ) -def get_app_schema(app: SpecApplication) -> Schema: +def get_app_schema( + broker: "BrokerUsecase[Any, Any]", + /, + title: str, + app_version: str, + schema_version: str, + description: str, + terms_of_service: Optional["AnyHttpUrl"], + contact: Optional[Union["Contact", "ContactDict", "AnyDict"]], + license: Optional[Union["License", "LicenseDict", "AnyDict"]], + identifier: Optional[str], + tags: Optional[Sequence[Union["SpecsTag", "SpecsTagDict", "AnyDict"]]], + external_docs: Optional[Union["ExternalDocs", "ExternalDocsDict", "AnyDict"]], +) -> Schema: """Get the application schema.""" - broker = app.broker - if broker is None: # pragma: no cover - raise RuntimeError() - app._setup() + broker._setup() servers = get_broker_server(broker) channels = get_broker_channels(broker) @@ -67,21 +85,22 @@ def get_app_schema(app: SpecApplication) -> Schema: schema = Schema( info=Info( - title=app.title, - version=app.version, - description=app.description, - termsOfService=app.terms_of_service, - contact=contact_from_spec(app.contact) if app.contact else None, - license=license_from_spec(app.license) if app.license else None, - tags=[tag_from_spec(tag) for tag in app.specification_tags] - if app.specification_tags + title=title, + version=app_version, + description=description, + termsOfService=terms_of_service, + contact=contact_from_spec(contact) if contact else None, + license=license_from_spec(license) if license else None, + tags=[tag_from_spec(tag) for tag in tags] + if tags else None, - externalDocs=docs_from_spec(app.external_docs) - if app.external_docs + externalDocs=docs_from_spec(external_docs) + if external_docs else None, ), + asyncapi=schema_version, defaultContentType=ContentTypes.json.value, - id=app.identifier, + id=identifier, servers=servers, channels=channels, operations=operations, diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/__init__.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/__init__.py new file mode 100644 index 0000000000..c825556112 --- /dev/null +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/__init__.py @@ -0,0 +1,11 @@ +from .main import ( + OperationBinding, + channel_binding_from_spec, + operation_binding_from_spec, +) + +__all__ = ( + "channel_binding_from_spec", + "OperationBinding", + "operation_binding_from_spec", +) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/__init__.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/__init__.py new file mode 100644 index 0000000000..f55fd4c5d7 --- /dev/null +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/__init__.py @@ -0,0 +1,13 @@ +from .channel import from_spec as channel_binding_from_spec +from .operation import ( + OperationBinding, +) +from .operation import ( + from_spec as operation_binding_from_spec, +) + +__all__ = ( + "channel_binding_from_spec", + "OperationBinding", + "operation_binding_from_spec", +) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel.py new file mode 100644 index 0000000000..d8d5d24cf4 --- /dev/null +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel.py @@ -0,0 +1,23 @@ +from faststream.specification import schema as spec +from faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp import ChannelBinding +from faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.channel import ( + Exchange, + Queue, +) + + +def from_spec(binding: spec.bindings.amqp.ChannelBinding) -> ChannelBinding: + return ChannelBinding( + **{ + "is": binding.is_, + "bindingVersion": "0.3.0", + + "queue": Queue.from_spec(binding.queue) + if binding.queue is not None + else None, + + "exchange": Exchange.from_spec(binding.exchange) + if binding.exchange is not None + else None, + } + ) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation.py new file mode 100644 index 0000000000..daf172f940 --- /dev/null +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation.py @@ -0,0 +1,48 @@ +"""AsyncAPI AMQP bindings. + +References: https://github.com/asyncapi/bindings/tree/master/amqp +""" + +from typing import List, Optional + +from pydantic import BaseModel, PositiveInt +from typing_extensions import Self + +from faststream.specification import schema as spec + + +class OperationBinding(BaseModel): + """A class to represent an operation binding. + + Attributes: + cc : optional string representing the cc + ack : boolean indicating if the operation is acknowledged + replyTo : optional dictionary representing the replyTo + bindingVersion : string representing the binding version + """ + + cc: Optional[List[str]] = None + ack: bool = True + replyTo: Optional[str] = None + deliveryMode: Optional[int] = None + mandatory: Optional[bool] = None + priority: Optional[PositiveInt] = None + bindingVersion: str = "0.3.0" + + @classmethod + def from_spec(cls, binding: spec.bindings.amqp.OperationBinding) -> Self: + return cls( + cc=[binding.cc] + if binding.cc is not None + else None, + + ack=binding.ack, + replyTo=binding.replyTo, + deliveryMode=binding.deliveryMode, + mandatory=binding.mandatory, + priority=binding.priority, + ) + + +def from_spec(binding: spec.bindings.amqp.OperationBinding) -> OperationBinding: + return OperationBinding.from_spec(binding) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/__init__.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/__init__.py new file mode 100644 index 0000000000..f55fd4c5d7 --- /dev/null +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/__init__.py @@ -0,0 +1,13 @@ +from .channel import from_spec as channel_binding_from_spec +from .operation import ( + OperationBinding, +) +from .operation import ( + from_spec as operation_binding_from_spec, +) + +__all__ = ( + "channel_binding_from_spec", + "OperationBinding", + "operation_binding_from_spec", +) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel.py new file mode 100644 index 0000000000..41aef76aaa --- /dev/null +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel.py @@ -0,0 +1,17 @@ +from faststream.specification import schema as spec +from faststream.specification.asyncapi.v2_6_0.schema.bindings import ChannelBinding +from faststream.specification.asyncapi.v2_6_0.schema.bindings.main import ( + channel_binding_from_spec, +) +from faststream.specification.asyncapi.v3_0_0.schema.bindings.amqp import ( + channel_binding_from_spec as amqp_channel_binding_from_spec, +) + + +def from_spec(binding: spec.bindings.ChannelBinding) -> ChannelBinding: + channel_binding = channel_binding_from_spec(binding) + + if binding.amqp: + channel_binding.amqp = amqp_channel_binding_from_spec(binding.amqp) + + return channel_binding diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation.py new file mode 100644 index 0000000000..d51b97436b --- /dev/null +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation.py @@ -0,0 +1,71 @@ +from typing import Optional + +from pydantic import BaseModel +from typing_extensions import Self + +from faststream._internal._compat import PYDANTIC_V2 +from faststream.specification import schema as spec +from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( + kafka as kafka_bindings, +) +from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( + nats as nats_bindings, +) +from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( + redis as redis_bindings, +) +from faststream.specification.asyncapi.v2_6_0.schema.bindings import sqs as sqs_bindings +from faststream.specification.asyncapi.v3_0_0.schema.bindings import ( + amqp as amqp_bindings, +) + + +class OperationBinding(BaseModel): + """A class to represent an operation binding. + + Attributes: + amqp : AMQP operation binding (optional) + kafka : Kafka operation binding (optional) + sqs : SQS operation binding (optional) + nats : NATS operation binding (optional) + redis : Redis operation binding (optional) + + """ + + amqp: Optional[amqp_bindings.OperationBinding] = None + kafka: Optional[kafka_bindings.OperationBinding] = None + sqs: Optional[sqs_bindings.OperationBinding] = None + nats: Optional[nats_bindings.OperationBinding] = None + redis: Optional[redis_bindings.OperationBinding] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" + + @classmethod + def from_spec(cls, binding: spec.bindings.OperationBinding) -> Self: + return cls( + amqp=amqp_bindings.operation_binding_from_spec(binding.amqp) + if binding.amqp is not None + else None, + kafka=kafka_bindings.operation_binding_from_spec(binding.kafka) + if binding.kafka is not None + else None, + sqs=sqs_bindings.operation_binding_from_spec(binding.sqs) + if binding.sqs is not None + else None, + nats=nats_bindings.operation_binding_from_spec(binding.nats) + if binding.nats is not None + else None, + redis=redis_bindings.operation_binding_from_spec(binding.redis) + if binding.redis is not None + else None, + ) + + +def from_spec(binding: spec.bindings.OperationBinding) -> OperationBinding: + return OperationBinding.from_spec(binding) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/channels.py b/faststream/specification/asyncapi/v3_0_0/schema/channels.py index 75021725ba..b7f4e5cf9a 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/channels.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/channels.py @@ -6,14 +6,14 @@ from faststream._internal._compat import PYDANTIC_V2 from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.schema.bindings import ChannelBinding -from faststream.specification.asyncapi.v2_6_0.schema.bindings.main import ( - channel_binding_from_spec, -) from faststream.specification.asyncapi.v2_6_0.schema.message import Message from faststream.specification.asyncapi.v2_6_0.schema.message import ( from_spec as message_from_spec, ) from faststream.specification.asyncapi.v2_6_0.schema.utils import Reference +from faststream.specification.asyncapi.v3_0_0.schema.bindings.main import ( + channel_binding_from_spec, +) class Channel(BaseModel): diff --git a/faststream/specification/asyncapi/v3_0_0/schema/operations.py b/faststream/specification/asyncapi/v3_0_0/schema/operations.py index ef06352522..2937c90afb 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/operations.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/operations.py @@ -7,14 +7,14 @@ from faststream._internal._compat import PYDANTIC_V2 from faststream._internal.basic_types import AnyDict from faststream.specification import schema as spec -from faststream.specification.asyncapi.v2_6_0.schema.bindings import OperationBinding -from faststream.specification.asyncapi.v2_6_0.schema.bindings.main import ( - operation_binding_from_spec, -) from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag from faststream.specification.asyncapi.v2_6_0.schema.utils import ( Reference, ) +from faststream.specification.asyncapi.v3_0_0.schema.bindings import OperationBinding +from faststream.specification.asyncapi.v3_0_0.schema.bindings.main import ( + operation_binding_from_spec, +) from faststream.specification.asyncapi.v3_0_0.schema.channels import Channel diff --git a/faststream/specification/schema/bindings/amqp.py b/faststream/specification/schema/bindings/amqp.py index 84ca21e3f5..42f29dd1c8 100644 --- a/faststream/specification/schema/bindings/amqp.py +++ b/faststream/specification/schema/bindings/amqp.py @@ -67,7 +67,6 @@ class ChannelBinding: """ is_: Literal["queue", "routingKey"] - bindingVersion: str = "0.2.0" queue: Optional[Queue] = None exchange: Optional[Exchange] = None @@ -89,4 +88,3 @@ class OperationBinding: deliveryMode: Optional[int] = None mandatory: Optional[bool] = None priority: Optional[int] = None - bindingVersion: str = "0.2.0" diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py index 191eb2aa0d..fe246acf96 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py @@ -1,9 +1,9 @@ from docs.docs_src.getting_started.asyncapi.asyncapi_customization.basic import app -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI def test_basic_customization(): - schema = get_app_schema(app, version="2.6.0").to_jsonable() + schema = AsyncAPI(app.broker, schema_version="2.6.0").jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_broker.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_broker.py index 2af48bd3f5..5b0483ba77 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_broker.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_broker.py @@ -1,11 +1,10 @@ from docs.docs_src.getting_started.asyncapi.asyncapi_customization.custom_broker import ( - app, + docs_obj, ) -from faststream.specification.asyncapi.generate import get_app_schema def test_broker_customization(): - schema = get_app_schema(app, version="2.6.0").to_jsonable() + schema = docs_obj.jsonable() assert schema["servers"] == { "development": { diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py index 8f15bc5405..cc0c895170 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py @@ -1,11 +1,10 @@ from docs.docs_src.getting_started.asyncapi.asyncapi_customization.custom_handler import ( - app, + docs_obj, ) -from faststream.specification.asyncapi.generate import get_app_schema def test_handler_customization(): - schema = get_app_schema(app, version="2.6.0").to_jsonable() + schema = docs_obj.jsonable() assert schema["channels"] == { "input_data:Consume": { diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_info.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_info.py index 5707e0ea40..4700abca36 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_info.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_info.py @@ -1,11 +1,10 @@ from docs.docs_src.getting_started.asyncapi.asyncapi_customization.custom_info import ( - app, + docs_obj, ) -from faststream.specification.asyncapi.generate import get_app_schema def test_info_customization(): - schema = get_app_schema(app, version="2.6.0").to_jsonable() + schema = docs_obj.jsonable() assert schema["info"] == { "title": "My App", diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_payload.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_payload.py index 8b63c40343..d94ec9f4ff 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_payload.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_payload.py @@ -1,11 +1,10 @@ from docs.docs_src.getting_started.asyncapi.asyncapi_customization.payload_info import ( - app, + docs_obj, ) -from faststream.specification.asyncapi.generate import get_app_schema def test_payload_customization(): - schema = get_app_schema(app, version="2.6.0").to_jsonable() + schema = docs_obj.jsonable() assert schema["components"]["schemas"] == { "DataBasic": { diff --git a/tests/a_docs/rabbit/test_security.py b/tests/a_docs/rabbit/test_security.py index 4a69d71057..aaeebb896c 100644 --- a/tests/a_docs/rabbit/test_security.py +++ b/tests/a_docs/rabbit/test_security.py @@ -1,8 +1,7 @@ import pytest from aiormq.exceptions import AMQPConnectionError -from faststream.app import FastStream -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI @pytest.mark.asyncio @@ -14,7 +13,7 @@ async def test_base_security(): async with broker: pass - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert schema == { "asyncapi": "2.6.0", "channels": {}, @@ -41,7 +40,7 @@ async def test_plaintext_security(): async with broker: pass - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert ( schema == { diff --git a/tests/a_docs/redis/test_security.py b/tests/a_docs/redis/test_security.py index 11b1217a16..70cd3d2949 100644 --- a/tests/a_docs/redis/test_security.py +++ b/tests/a_docs/redis/test_security.py @@ -5,8 +5,7 @@ import pytest from redis.exceptions import AuthenticationError -from faststream.app import FastStream -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI @contextmanager @@ -39,7 +38,7 @@ async def test_base_security(): assert connection.call_args.kwargs["ssl"] - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert schema == { "asyncapi": "2.6.0", "channels": {}, @@ -69,7 +68,7 @@ async def test_plaintext_security(): assert connection.call_args.kwargs["ssl"] - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert schema == { "asyncapi": "2.6.0", "channels": {}, diff --git a/tests/asyncapi/base/v2_6_0/arguments.py b/tests/asyncapi/base/v2_6_0/arguments.py index 90b2b417f2..775934ad87 100644 --- a/tests/asyncapi/base/v2_6_0/arguments.py +++ b/tests/asyncapi/base/v2_6_0/arguments.py @@ -8,10 +8,10 @@ from fastapi import Depends as APIDepends from typing_extensions import Annotated, Literal -from faststream import Context, FastStream +from faststream import Context from faststream._internal._compat import PYDANTIC_V2 from faststream._internal.broker.broker import BrokerUsecase -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.marks import pydantic_v2 @@ -21,7 +21,7 @@ class FastAPICompatible: def build_app(self, broker): """Patch it to test FastAPI scheme generation too.""" - return FastStream(broker) + return broker def test_custom_naming(self): broker = self.broker_class() @@ -29,7 +29,7 @@ def test_custom_naming(self): @broker.subscriber("test", title="custom_name", description="test description") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert key == "custom_name" @@ -41,7 +41,7 @@ def test_slash_in_title(self): @broker.subscriber("test", title="/") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() assert next(iter(schema["channels"].keys())) == "/" @@ -61,7 +61,7 @@ def test_docstring_description(self): async def handle(msg): """Test description.""" - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert key == "custom_name" @@ -75,7 +75,7 @@ def test_empty(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() payload = schema["components"]["schemas"] @@ -92,7 +92,7 @@ def test_no_type(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() payload = schema["components"]["schemas"] @@ -106,7 +106,7 @@ def test_simple_type(self): @broker.subscriber("test") async def handle(msg: int): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() payload = schema["components"]["schemas"] assert next(iter(schema["channels"].values())).get("description") is None @@ -121,7 +121,7 @@ def test_simple_optional_type(self): @broker.subscriber("test") async def handle(msg: Optional[int]): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() payload = schema["components"]["schemas"] @@ -145,7 +145,7 @@ def test_simple_type_with_default(self): @broker.subscriber("test") async def handle(msg: int = 1): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() payload = schema["components"]["schemas"] @@ -163,7 +163,7 @@ def test_multi_args_no_type(self): @broker.subscriber("test") async def handle(msg, another): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() payload = schema["components"]["schemas"] @@ -185,7 +185,7 @@ def test_multi_args_with_type(self): @broker.subscriber("test") async def handle(msg: str, another: int): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() payload = schema["components"]["schemas"] @@ -207,7 +207,7 @@ def test_multi_args_with_default(self): @broker.subscriber("test") async def handle(msg: str, another: Optional[int] = None): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() payload = schema["components"]["schemas"] @@ -247,7 +247,7 @@ class User: @broker.subscriber("test") async def handle(user: User): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() payload = schema["components"]["schemas"] @@ -273,7 +273,7 @@ class User(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: User): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() payload = schema["components"]["schemas"] @@ -304,7 +304,7 @@ class User(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: User): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() payload = schema["components"]["schemas"] @@ -342,7 +342,7 @@ class User(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: User, description: str = ""): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() payload = schema["components"]["schemas"] @@ -398,7 +398,7 @@ class Config: @broker.subscriber("test") async def handle(user: User): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() payload = schema["components"]["schemas"] @@ -430,7 +430,7 @@ def dep2(name2: str): @broker.subscriber("test", dependencies=dependencies) async def handle(id: int, message=message): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() payload = schema["components"]["schemas"] @@ -464,7 +464,7 @@ class Sub(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: descriminator): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = next(iter(schema["components"]["messages"].keys())) assert key == IsStr(regex=r"test[\w:]*:Handle:Message") @@ -519,7 +519,7 @@ class Model(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: Model): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = next(iter(schema["components"]["messages"].keys())) assert key == IsStr(regex=r"test[\w:]*:Handle:Message") @@ -583,7 +583,7 @@ async def handle(id: int): ... @sub async def handle_default(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() assert ( len( @@ -616,7 +616,7 @@ async def msg( ), ): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() payload = schema["components"]["schemas"] @@ -638,7 +638,7 @@ def test_ignores_custom_field(self): @broker.subscriber("test") async def handle(id: int, user: Optional[str] = None, message=Context()): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() payload = schema["components"]["schemas"] diff --git a/tests/asyncapi/base/v2_6_0/fastapi.py b/tests/asyncapi/base/v2_6_0/fastapi.py index 9cae10870d..34b694ba79 100644 --- a/tests/asyncapi/base/v2_6_0/fastapi.py +++ b/tests/asyncapi/base/v2_6_0/fastapi.py @@ -8,17 +8,17 @@ from faststream._internal.broker.broker import BrokerUsecase from faststream._internal.fastapi.router import StreamRouter from faststream._internal.types import MsgType -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI class FastAPITestCase: - broker_class: Type[StreamRouter[MsgType]] + router_class: Type[StreamRouter[MsgType]] broker_wrapper: Callable[[BrokerUsecase[MsgType, Any]], BrokerUsecase[MsgType, Any]] @pytest.mark.skip @pytest.mark.asyncio async def test_fastapi_full_information(self): - broker = self.broker_class( + router = self.router_class( protocol="custom", protocol_version="1.1.1", description="Test broker description", @@ -33,9 +33,9 @@ async def test_fastapi_full_information(self): contact={"name": "support", "url": "https://support.com"}, license_info={"name": "some", "url": "https://some.com"}, ) - app.include_router(broker) + app.include_router(router) - async with self.broker_wrapper(broker.broker): + async with self.broker_wrapper(router.broker): with TestClient(app) as client: response_json = client.get("/asyncapi_schema.json") @@ -71,35 +71,35 @@ async def test_fastapi_full_information(self): @pytest.mark.skip @pytest.mark.asyncio async def test_fastapi_asyncapi_routes(self): - broker = self.broker_class(schema_url="/asyncapi_schema") + router = self.router_class(schema_url="/asyncapi_schema") - @broker.subscriber("test") + @router.subscriber("test") async def handler(): ... app = FastAPI() - app.include_router(broker) + app.include_router(router) - async with self.broker_wrapper(broker.broker): + async with self.broker_wrapper(router.broker): with TestClient(app) as client: - schema = get_app_schema(broker, version="2.6.0") + schema = AsyncAPI(router.broker, schema_version="2.6.0") response_json = client.get("/asyncapi_schema.json") - assert response_json.json() == schema.to_jsonable() + assert response_json.json() == schema.jsonable() response_yaml = client.get("/asyncapi_schema.yaml") - assert response_yaml.text == schema.to_yaml() + assert response_yaml.text == schema.yaml() response_html = client.get("/asyncapi_schema") assert response_html.status_code == 200 @pytest.mark.asyncio async def test_fastapi_asyncapi_not_fount(self): - broker = self.broker_class(include_in_schema=False) + router = self.router_class(include_in_schema=False) app = FastAPI() - app.include_router(broker) + app.include_router(router) - async with self.broker_wrapper(broker.broker): + async with self.broker_wrapper(router.broker): with TestClient(app) as client: response_json = client.get("/asyncapi.json") assert response_json.status_code == 404 @@ -112,12 +112,12 @@ async def test_fastapi_asyncapi_not_fount(self): @pytest.mark.asyncio async def test_fastapi_asyncapi_not_fount_by_url(self): - broker = self.broker_class(schema_url=None) + router = self.router_class(schema_url=None) app = FastAPI() - app.include_router(broker) + app.include_router(router) - async with self.broker_wrapper(broker.broker): + async with self.broker_wrapper(router.broker): with TestClient(app) as client: response_json = client.get("/asyncapi.json") assert response_json.status_code == 404 diff --git a/tests/asyncapi/base/v2_6_0/naming.py b/tests/asyncapi/base/v2_6_0/naming.py index 447308b15b..e4f3ac7ef4 100644 --- a/tests/asyncapi/base/v2_6_0/naming.py +++ b/tests/asyncapi/base/v2_6_0/naming.py @@ -3,9 +3,8 @@ from dirty_equals import Contains, IsStr from pydantic import create_model -from faststream import FastStream from faststream._internal.broker.broker import BrokerUsecase -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI class BaseNaming: @@ -19,7 +18,7 @@ def test_subscriber_naming(self): @broker.subscriber("test") async def handle_user_created(msg: str): ... - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -39,7 +38,7 @@ def test_pydantic_subscriber_naming(self): @broker.subscriber("test") async def handle_user_created(msg: create_model("SimpleModel")): ... - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -58,7 +57,7 @@ def test_multi_subscribers_naming(self): @broker.subscriber("test2") async def handle_user_created(msg: str): ... - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated"), @@ -80,7 +79,7 @@ def test_subscriber_naming_manual(self): @broker.subscriber("test", title="custom") async def handle_user_created(msg: str): ... - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -95,7 +94,7 @@ def test_subscriber_naming_default(self): broker.subscriber("test") - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:Subscriber") @@ -114,7 +113,7 @@ def test_subscriber_naming_default_with_title(self): broker.subscriber("test", title="custom") - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -137,7 +136,7 @@ async def handle_user_created(msg: str): ... broker.subscriber("test2") broker.subscriber("test3") - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated"), @@ -173,7 +172,7 @@ async def handle_user_created(msg: str): ... @sub async def handle_user_id(msg: int): ... - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -199,7 +198,7 @@ async def handle_user_created(msg: create_model("SimpleModel")): ... @sub async def handle_user_id(msg: int): ... - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -225,7 +224,7 @@ async def handle_user_created(msg: str): ... @sub async def handle_user_id(msg: int): ... - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -244,7 +243,7 @@ def test_publisher_naming_base(self): @broker.publisher("test") async def handle_user_created() -> str: ... - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] @@ -262,7 +261,7 @@ def test_publisher_naming_pydantic(self): @broker.publisher("test") async def handle_user_created() -> create_model("SimpleModel"): ... - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] @@ -280,7 +279,7 @@ def test_publisher_manual_naming(self): @broker.publisher("test", title="custom") async def handle_user_created() -> str: ... - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -296,7 +295,7 @@ def test_publisher_with_schema_naming(self): @broker.publisher("test", schema=str) async def handle_user_created(): ... - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] @@ -314,7 +313,7 @@ def test_publisher_manual_naming_with_schema(self): @broker.publisher("test", title="custom", schema=str) async def handle_user_created(): ... - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -331,7 +330,7 @@ def test_multi_publishers_naming(self): @broker.publisher("test2") async def handle_user_created() -> str: ... - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() names = list(schema["channels"].keys()) assert names == Contains( @@ -362,7 +361,7 @@ async def handle_user_created() -> str: ... @pub async def handle() -> int: ... - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:Publisher"), @@ -388,7 +387,7 @@ async def handle_user_created() -> str: ... @pub async def handle() -> int: ... - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert list(schema["channels"].keys()) == ["custom"] diff --git a/tests/asyncapi/base/v2_6_0/publisher.py b/tests/asyncapi/base/v2_6_0/publisher.py index 3983996aea..d7e2cd9fba 100644 --- a/tests/asyncapi/base/v2_6_0/publisher.py +++ b/tests/asyncapi/base/v2_6_0/publisher.py @@ -2,9 +2,8 @@ import pydantic -from faststream import FastStream from faststream._internal.broker.broker import BrokerUsecase -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI class PublisherTestcase: @@ -12,7 +11,7 @@ class PublisherTestcase: def build_app(self, broker): """Patch it to test FastAPI scheme generation too.""" - return FastStream(broker) + return broker def test_publisher_with_description(self): broker = self.broker_class() @@ -20,7 +19,7 @@ def test_publisher_with_description(self): @broker.publisher("test", description="test description") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["description"] == "test description" @@ -31,7 +30,7 @@ def test_basic_publisher(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key].get("description") is None @@ -47,7 +46,7 @@ def test_none_publisher(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -59,7 +58,7 @@ def test_typed_publisher(self): @broker.publisher("test") async def handle(msg) -> int: ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -75,7 +74,7 @@ class User(pydantic.BaseModel): @broker.publisher("test") async def handle(msg) -> User: ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() payload = schema["components"]["schemas"] @@ -98,7 +97,7 @@ def test_delayed(self): @pub async def handle(msg) -> int: ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -109,7 +108,7 @@ def test_with_schema(self): broker.publisher("test", title="Custom", schema=int) - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -123,6 +122,6 @@ def test_not_include(self): async def handler(msg: str): pass - schema = get_app_schema(self.build_app(broker)) + schema = AsyncAPI(self.build_app(broker)) - assert schema.channels == {}, schema.channels + assert schema.jsonable()["channels"] == {}, schema.jsonable()["channels"] diff --git a/tests/asyncapi/base/v2_6_0/router.py b/tests/asyncapi/base/v2_6_0/router.py index dbb391baa6..aa847a8631 100644 --- a/tests/asyncapi/base/v2_6_0/router.py +++ b/tests/asyncapi/base/v2_6_0/router.py @@ -2,14 +2,13 @@ from dirty_equals import IsStr -from faststream import FastStream from faststream._internal.broker.broker import BrokerUsecase from faststream._internal.broker.router import ( ArgsContainer, BrokerRouter, SubscriberRoute, ) -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI class RouterTestcase: @@ -29,7 +28,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() payload = schema["components"]["schemas"] key = list(payload.keys())[0] # noqa: RUF015 @@ -52,8 +51,8 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker)) - schemas = schema.components.schemas + schema = AsyncAPI(broker, schema_version="2.6.0") + schemas = schema.jsonable()["components"]["schemas"] del schemas["Handle:Message:Payload"] for i, j in schemas.items(): @@ -72,8 +71,8 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker)) - assert schema.channels == {}, schema.channels + schema = AsyncAPI(broker, schema_version="2.6.0") + assert schema.jsonable()["channels"] == {}, schema.jsonable()["channels"] def test_not_include_in_method(self): broker = self.broker_class() @@ -85,8 +84,8 @@ async def handle(msg): ... broker.include_router(router, include_in_schema=False) - schema = get_app_schema(FastStream(broker)) - assert schema.channels == {}, schema.channels + schema = AsyncAPI(broker, schema_version="2.6.0") + assert schema.jsonable()["channels"] == {}, schema.jsonable()["channels"] def test_respect_subrouter(self): broker = self.broker_class() @@ -100,9 +99,9 @@ async def handle(msg): ... router.include_router(router2) broker.include_router(router) - schema = get_app_schema(FastStream(broker)) + schema = AsyncAPI(broker, schema_version="2.6.0") - assert schema.channels == {}, schema.channels + assert schema.jsonable()["channels"] == {}, schema.jsonable()["channels"] def test_not_include_subrouter(self): broker = self.broker_class() @@ -116,9 +115,9 @@ async def handle(msg): ... router.include_router(router2) broker.include_router(router) - schema = get_app_schema(FastStream(broker)) + schema = AsyncAPI(broker, schema_version="2.6.0") - assert schema.channels == {} + assert schema.jsonable()["channels"] == {} def test_not_include_subrouter_by_method(self): broker = self.broker_class() @@ -132,9 +131,9 @@ async def handle(msg): ... router.include_router(router2, include_in_schema=False) broker.include_router(router) - schema = get_app_schema(FastStream(broker)) + schema = AsyncAPI(broker, schema_version="2.6.0") - assert schema.channels == {} + assert schema.jsonable()["channels"] == {} def test_all_nested_routers_by_method(self): broker = self.broker_class() @@ -148,9 +147,9 @@ async def handle(msg): ... router.include_router(router2) broker.include_router(router, include_in_schema=False) - schema = get_app_schema(FastStream(broker)) + schema = AsyncAPI(broker, schema_version="2.6.0") - assert schema.channels == {} + assert schema.jsonable()["channels"] == {} def test_include_subrouter(self): broker = self.broker_class() @@ -164,6 +163,6 @@ async def handle(msg): ... router.include_router(router2) broker.include_router(router) - schema = get_app_schema(FastStream(broker)) + schema = AsyncAPI(broker, schema_version="2.6.0") - assert len(schema.channels) == 2 + assert len(schema.jsonable()["channels"]) == 2 diff --git a/tests/asyncapi/base/v3_0_0/arguments.py b/tests/asyncapi/base/v3_0_0/arguments.py index 7e694b7a1c..7370b7e009 100644 --- a/tests/asyncapi/base/v3_0_0/arguments.py +++ b/tests/asyncapi/base/v3_0_0/arguments.py @@ -8,11 +8,11 @@ from fastapi import Depends as APIDepends from typing_extensions import Annotated, Literal -from faststream import Context, FastStream +from faststream import Context from faststream._internal._compat import PYDANTIC_V2 from faststream._internal.broker.broker import BrokerUsecase from faststream._internal.fastapi import StreamRouter -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.marks import pydantic_v2 @@ -22,7 +22,7 @@ class FastAPICompatible: def build_app(self, broker): """Patch it to test FastAPI scheme generation too.""" - return FastStream(broker) + return broker def test_custom_naming(self): broker = self.broker_factory() @@ -30,7 +30,7 @@ def test_custom_naming(self): @broker.subscriber("test", title="custom_name", description="test description") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert key == "custom_name" @@ -42,7 +42,7 @@ def test_slash_in_title(self): @broker.subscriber("test", title="/") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() assert next(iter(schema["channels"].keys())) == "." assert schema["channels"]["."]["address"] == "/" @@ -70,7 +70,7 @@ def test_docstring_description(self): async def handle(msg): """Test description.""" - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert key == "custom_name" @@ -84,7 +84,7 @@ def test_empty(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() payload = schema["components"]["schemas"] @@ -101,7 +101,7 @@ def test_no_type(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() payload = schema["components"]["schemas"] @@ -115,7 +115,7 @@ def test_simple_type(self): @broker.subscriber("test") async def handle(msg: int): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() payload = schema["components"]["schemas"] assert next(iter(schema["channels"].values())).get("description") is None @@ -130,7 +130,7 @@ def test_simple_optional_type(self): @broker.subscriber("test") async def handle(msg: Optional[int]): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() payload = schema["components"]["schemas"] @@ -154,7 +154,7 @@ def test_simple_type_with_default(self): @broker.subscriber("test") async def handle(msg: int = 1): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() payload = schema["components"]["schemas"] @@ -172,7 +172,7 @@ def test_multi_args_no_type(self): @broker.subscriber("test") async def handle(msg, another): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() payload = schema["components"]["schemas"] @@ -194,7 +194,7 @@ def test_multi_args_with_type(self): @broker.subscriber("test") async def handle(msg: str, another: int): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() payload = schema["components"]["schemas"] @@ -216,7 +216,7 @@ def test_multi_args_with_default(self): @broker.subscriber("test") async def handle(msg: str, another: Optional[int] = None): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() payload = schema["components"]["schemas"] @@ -256,7 +256,7 @@ class User: @broker.subscriber("test") async def handle(user: User): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() payload = schema["components"]["schemas"] @@ -282,7 +282,7 @@ class User(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: User): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() payload = schema["components"]["schemas"] @@ -313,7 +313,7 @@ class User(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: User): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() payload = schema["components"]["schemas"] @@ -351,7 +351,7 @@ class User(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: User, description: str = ""): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() payload = schema["components"]["schemas"] @@ -407,7 +407,7 @@ class Config: @broker.subscriber("test") async def handle(user: User): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() payload = schema["components"]["schemas"] @@ -441,7 +441,7 @@ async def handle(id: int): ... @sub async def handle_default(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() assert ( len( @@ -472,7 +472,7 @@ def dep2(name2: str): @broker.subscriber("test", dependencies=dependencies) async def handle(id: int, message=message): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() payload = schema["components"]["schemas"] @@ -506,7 +506,7 @@ class Sub(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: descriminator): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() key = next(iter(schema["components"]["messages"].keys())) assert key == IsStr(regex=r"test[\w:]*:Handle:SubscribeMessage") @@ -562,7 +562,7 @@ class Model(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: Model): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() key = next(iter(schema["components"]["messages"].keys())) assert key == IsStr(regex=r"test[\w:]*:Handle:SubscribeMessage") @@ -626,7 +626,7 @@ async def msg( ), ): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() payload = schema["components"]["schemas"] @@ -648,7 +648,7 @@ def test_ignores_custom_field(self): @broker.subscriber("test") async def handle(id: int, user: Optional[str] = None, message=Context()): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() payload = schema["components"]["schemas"] diff --git a/tests/asyncapi/base/v3_0_0/fastapi.py b/tests/asyncapi/base/v3_0_0/fastapi.py index f1d4a1bafa..653acf0092 100644 --- a/tests/asyncapi/base/v3_0_0/fastapi.py +++ b/tests/asyncapi/base/v3_0_0/fastapi.py @@ -8,7 +8,7 @@ from faststream._internal.broker.broker import BrokerUsecase from faststream._internal.fastapi.router import StreamRouter from faststream._internal.types import MsgType -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI class FastAPITestCase: @@ -68,27 +68,35 @@ async def test_fastapi_full_information(self): "channels": {}, "operations": {}, "components": {"messages": {}, "schemas": {}}, - } + }, response_json.json() @pytest.mark.asyncio async def test_fastapi_asyncapi_routes(self): - broker = self.router_factory(schema_url="/asyncapi_schema") + router = self.router_factory(schema_url="/asyncapi_schema") - @broker.subscriber("test") + @router.subscriber("test") async def handler(): ... - app = FastAPI(lifespan=broker.lifespan_context) - app.include_router(broker) + app = FastAPI(lifespan=router.lifespan_context) + app.include_router(router) - async with self.broker_wrapper(broker.broker): + async with self.broker_wrapper(router.broker): with TestClient(app) as client: - schema = get_app_schema(broker, version="3.0.0") + schema = AsyncAPI( + router.broker, + title=router.title, + description=router.description, + app_version=router.version, + contact=router.contact, + license=router.license, + schema_version="3.0.0" + ) response_json = client.get("/asyncapi_schema.json") - assert response_json.json() == schema.to_jsonable() + assert response_json.json() == schema.jsonable(), schema.jsonable() response_yaml = client.get("/asyncapi_schema.yaml") - assert response_yaml.text == schema.to_yaml() + assert response_yaml.text == schema.yaml() response_html = client.get("/asyncapi_schema") assert response_html.status_code == 200 diff --git a/tests/asyncapi/base/v3_0_0/naming.py b/tests/asyncapi/base/v3_0_0/naming.py index 5ccb01d8d8..6852b3945a 100644 --- a/tests/asyncapi/base/v3_0_0/naming.py +++ b/tests/asyncapi/base/v3_0_0/naming.py @@ -3,9 +3,8 @@ from dirty_equals import Contains, IsStr from pydantic import create_model -from faststream import FastStream from faststream._internal.broker.broker import BrokerUsecase -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI class BaseNaming: @@ -18,8 +17,7 @@ def test_subscriber_naming(self): @broker.subscriber("test") async def handle_user_created(msg: str): ... - - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -39,7 +37,7 @@ def test_pydantic_subscriber_naming(self): @broker.subscriber("test") async def handle_user_created(msg: create_model("SimpleModel")): ... - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -58,7 +56,7 @@ def test_multi_subscribers_naming(self): @broker.subscriber("test2") async def handle_user_created(msg: str): ... - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated"), @@ -80,7 +78,7 @@ def test_subscriber_naming_manual(self): @broker.subscriber("test", title="custom") async def handle_user_created(msg: str): ... - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -97,7 +95,7 @@ def test_subscriber_naming_default(self): broker.subscriber("test") - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:Subscriber") @@ -116,7 +114,7 @@ def test_subscriber_naming_default_with_title(self): broker.subscriber("test", title="custom") - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -141,7 +139,7 @@ async def handle_user_created(msg: str): ... broker.subscriber("test2") broker.subscriber("test3") - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated"), @@ -177,7 +175,7 @@ async def handle_user_created(msg: str): ... @sub async def handle_user_id(msg: int): ... - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -203,7 +201,7 @@ async def handle_user_created(msg: create_model("SimpleModel")): ... @sub async def handle_user_id(msg: int): ... - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -229,7 +227,7 @@ async def handle_user_created(msg: str): ... @sub async def handle_user_id(msg: int): ... - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -250,7 +248,7 @@ def test_publisher_naming_base(self): @broker.publisher("test") async def handle_user_created() -> str: ... - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] @@ -268,7 +266,7 @@ def test_publisher_naming_pydantic(self): @broker.publisher("test") async def handle_user_created() -> create_model("SimpleModel"): ... - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] @@ -286,7 +284,7 @@ def test_publisher_manual_naming(self): @broker.publisher("test", title="custom") async def handle_user_created() -> str: ... - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -302,7 +300,7 @@ def test_publisher_with_schema_naming(self): @broker.publisher("test", schema=str) async def handle_user_created(): ... - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] @@ -320,7 +318,7 @@ def test_publisher_manual_naming_with_schema(self): @broker.publisher("test", title="custom", schema=str) async def handle_user_created(): ... - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -337,7 +335,7 @@ def test_multi_publishers_naming(self): @broker.publisher("test2") async def handle_user_created() -> str: ... - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() names = list(schema["channels"].keys()) assert names == Contains( @@ -368,7 +366,7 @@ async def handle_user_created() -> str: ... @pub async def handle() -> int: ... - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:Publisher"), @@ -394,7 +392,7 @@ async def handle_user_created() -> str: ... @pub async def handle() -> int: ... - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert list(schema["channels"].keys()) == ["custom"] diff --git a/tests/asyncapi/base/v3_0_0/publisher.py b/tests/asyncapi/base/v3_0_0/publisher.py index 908fb5232b..5cee8ca6b9 100644 --- a/tests/asyncapi/base/v3_0_0/publisher.py +++ b/tests/asyncapi/base/v3_0_0/publisher.py @@ -2,10 +2,9 @@ import pydantic -from faststream import FastStream from faststream._internal.broker.broker import BrokerUsecase from faststream._internal.fastapi import StreamRouter -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI class PublisherTestcase: @@ -13,7 +12,7 @@ class PublisherTestcase: def build_app(self, broker): """Patch it to test FastAPI scheme generation too.""" - return FastStream(broker) + return broker def test_publisher_with_description(self): broker = self.broker_factory() @@ -21,7 +20,7 @@ def test_publisher_with_description(self): @broker.publisher("test", description="test description") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["description"] == "test description" @@ -32,7 +31,7 @@ def test_basic_publisher(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key].get("description") is None @@ -48,7 +47,7 @@ def test_none_publisher(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -60,7 +59,7 @@ def test_typed_publisher(self): @broker.publisher("test") async def handle(msg) -> int: ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -76,7 +75,7 @@ class User(pydantic.BaseModel): @broker.publisher("test") async def handle(msg) -> User: ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() payload = schema["components"]["schemas"] @@ -99,7 +98,7 @@ def test_delayed(self): @pub async def handle(msg) -> int: ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -110,7 +109,7 @@ def test_with_schema(self): broker.publisher("test", title="Custom", schema=int) - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -124,6 +123,6 @@ def test_not_include(self): async def handler(msg: str): pass - schema = get_app_schema(self.build_app(broker)) + schema = AsyncAPI(self.build_app(broker)) - assert schema.channels == {}, schema.channels + assert schema.jsonable()["channels"] == {}, schema.jsonable()["channels"] diff --git a/tests/asyncapi/base/v3_0_0/router.py b/tests/asyncapi/base/v3_0_0/router.py index e7446dd1ef..d8242368bd 100644 --- a/tests/asyncapi/base/v3_0_0/router.py +++ b/tests/asyncapi/base/v3_0_0/router.py @@ -2,14 +2,13 @@ from dirty_equals import IsStr -from faststream import FastStream from faststream._internal.broker.broker import BrokerUsecase from faststream._internal.broker.router import ( ArgsContainer, BrokerRouter, SubscriberRoute, ) -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI class RouterTestcase: @@ -29,7 +28,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() payload = schema["components"]["schemas"] key = list(payload.keys())[0] # noqa: RUF015 @@ -52,8 +51,8 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker), version="3.0.0") - schemas = schema.components.schemas + schema = AsyncAPI(broker, schema_version="3.0.0") + schemas = schema.jsonable()["components"]["schemas"] del schemas["Handle:Message:Payload"] for i, j in schemas.items(): @@ -72,8 +71,8 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker), version="3.0.0") - assert schema.channels == {}, schema.channels + schema = AsyncAPI(broker, schema_version="3.0.0") + assert schema.jsonable()["channels"] == {}, schema.jsonable()["channels"] def test_not_include_in_method(self): broker = self.broker_class() @@ -85,8 +84,8 @@ async def handle(msg): ... broker.include_router(router, include_in_schema=False) - schema = get_app_schema(FastStream(broker), version="3.0.0") - assert schema.channels == {}, schema.channels + schema = AsyncAPI(broker, schema_version="3.0.0") + assert schema.jsonable()["channels"] == {}, schema.jsonable()["channels"] def test_respect_subrouter(self): broker = self.broker_class() @@ -100,9 +99,9 @@ async def handle(msg): ... router.include_router(router2) broker.include_router(router) - schema = get_app_schema(FastStream(broker), version="3.0.0") + schema = AsyncAPI(broker, schema_version="3.0.0") - assert schema.channels == {}, schema.channels + assert schema.jsonable()["channels"] == {}, schema.jsonable()["channels"] def test_not_include_subrouter(self): broker = self.broker_class() @@ -116,9 +115,9 @@ async def handle(msg): ... router.include_router(router2) broker.include_router(router) - schema = get_app_schema(FastStream(broker), version="3.0.0") + schema = AsyncAPI(broker, schema_version="3.0.0") - assert schema.channels == {} + assert schema.jsonable()["channels"] == {} def test_not_include_subrouter_by_method(self): broker = self.broker_class() @@ -132,9 +131,9 @@ async def handle(msg): ... router.include_router(router2, include_in_schema=False) broker.include_router(router) - schema = get_app_schema(FastStream(broker), version="3.0.0") + schema = AsyncAPI(broker, schema_version="3.0.0") - assert schema.channels == {} + assert schema.jsonable()["channels"] == {} def test_all_nested_routers_by_method(self): broker = self.broker_class() @@ -148,9 +147,9 @@ async def handle(msg): ... router.include_router(router2) broker.include_router(router, include_in_schema=False) - schema = get_app_schema(FastStream(broker), version="3.0.0") + schema = AsyncAPI(broker, schema_version="3.0.0") - assert schema.channels == {} + assert schema.jsonable()["channels"] == {} def test_include_subrouter(self): broker = self.broker_class() @@ -164,6 +163,6 @@ async def handle(msg): ... router.include_router(router2) broker.include_router(router) - schema = get_app_schema(FastStream(broker), version="3.0.0") + schema = AsyncAPI(broker, schema_version="3.0.0") - assert len(schema.channels) == 2 + assert len(schema.jsonable()["channels"]) == 2 diff --git a/tests/asyncapi/confluent/v2_6_0/test_arguments.py b/tests/asyncapi/confluent/v2_6_0/test_arguments.py index 7d1c1be4fa..994851d07e 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_arguments.py +++ b/tests/asyncapi/confluent/v2_6_0/test_arguments.py @@ -1,5 +1,5 @@ from faststream.confluent import KafkaBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase @@ -12,7 +12,7 @@ def test_subscriber_bindings(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/confluent/v2_6_0/test_connection.py b/tests/asyncapi/confluent/v2_6_0/test_connection.py index aae9eec527..6a503bc783 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_connection.py +++ b/tests/asyncapi/confluent/v2_6_0/test_connection.py @@ -1,22 +1,20 @@ -from faststream import FastStream + from faststream.confluent import KafkaBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from faststream.specification.schema.tag import Tag def test_base(): - schema = get_app_schema( - FastStream( - KafkaBroker( - "kafka:9092", - protocol="plaintext", - protocol_version="0.9.0", - description="Test description", - tags=(Tag(name="some-tag", description="experimental"),), - ) + schema = AsyncAPI( + KafkaBroker( + "kafka:9092", + protocol="plaintext", + protocol_version="0.9.0", + description="Test description", + tags=(Tag(name="some-tag", description="experimental"),), ), - version="2.6.0", - ).to_jsonable() + schema_version="2.6.0", + ).jsonable() assert schema == { "asyncapi": "2.6.0", @@ -37,9 +35,9 @@ def test_base(): def test_multi(): - schema = get_app_schema( - FastStream(KafkaBroker(["kafka:9092", "kafka:9093"])), version="2.6.0" - ).to_jsonable() + schema = AsyncAPI( + KafkaBroker(["kafka:9092", "kafka:9093"]), schema_version="2.6.0" + ).jsonable() assert schema == { "asyncapi": "2.6.0", @@ -63,15 +61,13 @@ def test_multi(): def test_custom(): - schema = get_app_schema( - FastStream( - KafkaBroker( - ["kafka:9092", "kafka:9093"], - specification_url=["kafka:9094", "kafka:9095"], - ) + schema = AsyncAPI( + KafkaBroker( + ["kafka:9092", "kafka:9093"], + specification_url=["kafka:9094", "kafka:9095"], ), - version="2.6.0", - ).to_jsonable() + schema_version="2.6.0", + ).jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/confluent/v2_6_0/test_fastapi.py b/tests/asyncapi/confluent/v2_6_0/test_fastapi.py index 3866a15b55..39bc487784 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/confluent/v2_6_0/test_fastapi.py @@ -1,16 +1,16 @@ -from typing import Type from faststream.confluent.fastapi import KafkaRouter from faststream.confluent.testing import TestKafkaBroker from faststream.security import SASLPlaintext -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.arguments import FastAPICompatible from tests.asyncapi.base.v2_6_0.fastapi import FastAPITestCase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase class TestRouterArguments(FastAPITestCase, FastAPICompatible): - broker_class: Type[KafkaRouter] = KafkaRouter + broker_class = staticmethod(lambda: KafkaRouter().broker) + router_class = KafkaRouter broker_wrapper = staticmethod(TestKafkaBroker) def build_app(self, router): @@ -18,7 +18,7 @@ def build_app(self, router): class TestRouterPublisher(PublisherTestcase): - broker_class = KafkaRouter + broker_class = staticmethod(lambda: KafkaRouter().broker) def build_app(self, router): return router @@ -27,9 +27,9 @@ def build_app(self, router): def test_fastapi_security_schema(): security = SASLPlaintext(username="user", password="pass", use_ssl=False) - broker = KafkaRouter("localhost:9092", security=security) + router = KafkaRouter("localhost:9092", security=security) - schema = get_app_schema(broker, version="2.6.0").to_jsonable() + schema = AsyncAPI(router.broker, schema_version="2.6.0").jsonable() assert schema["servers"]["development"] == { "protocol": "kafka", diff --git a/tests/asyncapi/confluent/v2_6_0/test_naming.py b/tests/asyncapi/confluent/v2_6_0/test_naming.py index f2d17b284b..156674cf1c 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_naming.py +++ b/tests/asyncapi/confluent/v2_6_0/test_naming.py @@ -1,6 +1,5 @@ -from faststream import FastStream from faststream.confluent import KafkaBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.naming import NamingTestCase @@ -13,7 +12,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/confluent/v2_6_0/test_publisher.py b/tests/asyncapi/confluent/v2_6_0/test_publisher.py index ea91e8da1f..e2d7746858 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_publisher.py +++ b/tests/asyncapi/confluent/v2_6_0/test_publisher.py @@ -1,5 +1,5 @@ from faststream.confluent import KafkaBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase @@ -12,7 +12,7 @@ def test_publisher_bindings(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/confluent/v2_6_0/test_router.py b/tests/asyncapi/confluent/v2_6_0/test_router.py index 81fedd42a8..145fc7fe80 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_router.py +++ b/tests/asyncapi/confluent/v2_6_0/test_router.py @@ -1,6 +1,5 @@ -from faststream import FastStream from faststream.confluent import KafkaBroker, KafkaPublisher, KafkaRoute, KafkaRouter -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v2_6_0.router import RouterTestcase @@ -22,7 +21,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert schema == { "asyncapi": "2.6.0", @@ -73,7 +72,7 @@ class TestRouterArguments(ArgumentsTestcase): def build_app(self, router): broker = KafkaBroker() broker.include_router(router) - return FastStream(broker) + return broker class TestRouterPublisher(PublisherTestcase): @@ -82,4 +81,4 @@ class TestRouterPublisher(PublisherTestcase): def build_app(self, router): broker = KafkaBroker() broker.include_router(router) - return FastStream(broker) + return broker diff --git a/tests/asyncapi/confluent/v2_6_0/test_security.py b/tests/asyncapi/confluent/v2_6_0/test_security.py index 946791dbb9..f5a1f0a8fb 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_security.py +++ b/tests/asyncapi/confluent/v2_6_0/test_security.py @@ -1,7 +1,6 @@ import ssl from copy import deepcopy -from faststream.app import FastStream from faststream.confluent import KafkaBroker from faststream.security import ( SASLGSSAPI, @@ -11,7 +10,7 @@ SASLScram256, SASLScram512, ) -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI basic_schema = { "asyncapi": "2.6.0", @@ -76,14 +75,13 @@ def test_base_security_schema(): security = BaseSecurity(ssl_context=ssl_context) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert schema == basic_schema @@ -97,14 +95,13 @@ def test_plaintext_security_schema(): ) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() plaintext_security_schema = deepcopy(basic_schema) plaintext_security_schema["servers"]["development"]["security"] = [ @@ -126,14 +123,13 @@ def test_scram256_security_schema(): ) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() sasl256_security_schema = deepcopy(basic_schema) sasl256_security_schema["servers"]["development"]["security"] = [{"scram256": []}] @@ -153,14 +149,13 @@ def test_scram512_security_schema(): ) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() sasl512_security_schema = deepcopy(basic_schema) sasl512_security_schema["servers"]["development"]["security"] = [{"scram512": []}] @@ -178,14 +173,13 @@ def test_oauthbearer_security_schema(): ) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() sasl_oauthbearer_security_schema = deepcopy(basic_schema) sasl_oauthbearer_security_schema["servers"]["development"]["security"] = [ @@ -203,14 +197,13 @@ def test_gssapi_security_schema(): security = SASLGSSAPI(ssl_context=ssl_context) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() gssapi_security_schema = deepcopy(basic_schema) gssapi_security_schema["servers"]["development"]["security"] = [{"gssapi": []}] diff --git a/tests/asyncapi/confluent/v3_0_0/test_arguments.py b/tests/asyncapi/confluent/v3_0_0/test_arguments.py index 048e7c7937..52c3e39ec7 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_arguments.py +++ b/tests/asyncapi/confluent/v3_0_0/test_arguments.py @@ -1,5 +1,5 @@ from faststream.confluent import KafkaBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase @@ -12,7 +12,7 @@ def test_subscriber_bindings(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/confluent/v3_0_0/test_connection.py b/tests/asyncapi/confluent/v3_0_0/test_connection.py index 6ff8e8c1a7..df99f96b2e 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_connection.py +++ b/tests/asyncapi/confluent/v3_0_0/test_connection.py @@ -1,22 +1,19 @@ -from faststream import FastStream from faststream.confluent import KafkaBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from faststream.specification.schema.tag import Tag def test_base(): - schema = get_app_schema( - FastStream( - KafkaBroker( - "kafka:9092", - protocol="plaintext", - protocol_version="0.9.0", - description="Test description", - tags=(Tag(name="some-tag", description="experimental"),), - ), + schema = AsyncAPI( + KafkaBroker( + "kafka:9092", + protocol="plaintext", + protocol_version="0.9.0", + description="Test description", + tags=(Tag(name="some-tag", description="experimental"),), ), - version="3.0.0", - ).to_jsonable() + schema_version="3.0.0", + ).jsonable() assert schema == { "asyncapi": "3.0.0", @@ -39,12 +36,10 @@ def test_base(): def test_multi(): - schema = get_app_schema( - FastStream( - KafkaBroker(["kafka:9092", "kafka:9093"]), - ), - version="3.0.0", - ).to_jsonable() + schema = AsyncAPI( + KafkaBroker(["kafka:9092", "kafka:9093"]), + schema_version="3.0.0", + ).jsonable() assert schema == { "asyncapi": "3.0.0", @@ -71,15 +66,13 @@ def test_multi(): def test_custom(): - schema = get_app_schema( - FastStream( - KafkaBroker( - ["kafka:9092", "kafka:9093"], - specification_url=["kafka:9094", "kafka:9095"], - ), + schema = AsyncAPI( + KafkaBroker( + ["kafka:9092", "kafka:9093"], + specification_url=["kafka:9094", "kafka:9095"], ), - version="3.0.0", - ).to_jsonable() + schema_version="3.0.0", + ).jsonable() assert schema == { "asyncapi": "3.0.0", diff --git a/tests/asyncapi/confluent/v3_0_0/test_fastapi.py b/tests/asyncapi/confluent/v3_0_0/test_fastapi.py index 2e4b23d2e7..fb3c2275e6 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/confluent/v3_0_0/test_fastapi.py @@ -1,14 +1,14 @@ from faststream.confluent.fastapi import KafkaRouter from faststream.confluent.testing import TestKafkaBroker from faststream.security import SASLPlaintext -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v3_0_0.arguments import FastAPICompatible from tests.asyncapi.base.v3_0_0.fastapi import FastAPITestCase from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase class TestRouterArguments(FastAPITestCase, FastAPICompatible): - broker_factory = staticmethod(lambda: KafkaRouter()) + broker_factory = staticmethod(lambda: KafkaRouter().broker) router_factory = KafkaRouter broker_wrapper = staticmethod(TestKafkaBroker) @@ -17,7 +17,7 @@ def build_app(self, router): class TestRouterPublisher(PublisherTestcase): - broker_factory = staticmethod(lambda: KafkaRouter()) + broker_factory = staticmethod(lambda: KafkaRouter().broker) def build_app(self, router): return router @@ -26,9 +26,9 @@ def build_app(self, router): def test_fastapi_security_schema(): security = SASLPlaintext(username="user", password="pass", use_ssl=False) - broker = KafkaRouter("localhost:9092", security=security) + router = KafkaRouter("localhost:9092", security=security) - schema = get_app_schema(broker).to_jsonable() + schema = AsyncAPI(router.broker, schema_version="3.0.0").jsonable() assert schema["servers"]["development"] == { "protocol": "kafka", diff --git a/tests/asyncapi/confluent/v3_0_0/test_naming.py b/tests/asyncapi/confluent/v3_0_0/test_naming.py index e599cc5f8e..c4b33a1469 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_naming.py +++ b/tests/asyncapi/confluent/v3_0_0/test_naming.py @@ -1,6 +1,5 @@ -from faststream import FastStream from faststream.confluent import KafkaBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v3_0_0.naming import NamingTestCase @@ -13,7 +12,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert schema == { "asyncapi": "3.0.0", diff --git a/tests/asyncapi/confluent/v3_0_0/test_publisher.py b/tests/asyncapi/confluent/v3_0_0/test_publisher.py index 85c42bda36..546050d22a 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_publisher.py +++ b/tests/asyncapi/confluent/v3_0_0/test_publisher.py @@ -1,5 +1,5 @@ from faststream.confluent import KafkaBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase @@ -12,7 +12,7 @@ def test_publisher_bindings(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/confluent/v3_0_0/test_router.py b/tests/asyncapi/confluent/v3_0_0/test_router.py index 8d526b8e35..985543fa22 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_router.py +++ b/tests/asyncapi/confluent/v3_0_0/test_router.py @@ -1,6 +1,5 @@ -from faststream import FastStream from faststream.confluent import KafkaBroker, KafkaPublisher, KafkaRoute, KafkaRouter -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v3_0_0.router import RouterTestcase @@ -22,7 +21,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert schema == { "info": {"title": "FastStream", "version": "0.1.0", "description": ""}, @@ -86,7 +85,7 @@ class TestRouterArguments(ArgumentsTestcase): def build_app(self, router): broker = KafkaBroker() broker.include_router(router) - return FastStream(broker) + return broker class TestRouterPublisher(PublisherTestcase): @@ -95,4 +94,4 @@ class TestRouterPublisher(PublisherTestcase): def build_app(self, router): broker = KafkaBroker() broker.include_router(router) - return FastStream(broker) + return broker diff --git a/tests/asyncapi/confluent/v3_0_0/test_security.py b/tests/asyncapi/confluent/v3_0_0/test_security.py index 72e63f4998..1d711487c7 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_security.py +++ b/tests/asyncapi/confluent/v3_0_0/test_security.py @@ -1,7 +1,6 @@ import ssl from copy import deepcopy -from faststream.app import FastStream from faststream.confluent import KafkaBroker from faststream.security import ( SASLGSSAPI, @@ -11,7 +10,7 @@ SASLScram256, SASLScram512, ) -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI basic_schema = { "info": {"title": "FastStream", "version": "0.1.0", "description": ""}, @@ -95,14 +94,13 @@ def test_base_security_schema(): security = BaseSecurity(ssl_context=ssl_context) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert schema == basic_schema @@ -116,14 +114,13 @@ def test_plaintext_security_schema(): ) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() plaintext_security_schema = deepcopy(basic_schema) plaintext_security_schema["servers"]["development"]["security"] = [ @@ -145,14 +142,13 @@ def test_scram256_security_schema(): ) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() sasl256_security_schema = deepcopy(basic_schema) sasl256_security_schema["servers"]["development"]["security"] = [{"scram256": []}] @@ -172,14 +168,13 @@ def test_scram512_security_schema(): ) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() sasl512_security_schema = deepcopy(basic_schema) sasl512_security_schema["servers"]["development"]["security"] = [{"scram512": []}] @@ -197,14 +192,13 @@ def test_oauthbearer_security_schema(): ) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() sasl_oauthbearer_security_schema = deepcopy(basic_schema) sasl_oauthbearer_security_schema["servers"]["development"]["security"] = [ @@ -222,14 +216,13 @@ def test_gssapi_security_schema(): security = SASLGSSAPI(ssl_context=ssl_context) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() gssapi_security_schema = deepcopy(basic_schema) gssapi_security_schema["servers"]["development"]["security"] = [{"gssapi": []}] diff --git a/tests/asyncapi/kafka/v2_6_0/test_app.py b/tests/asyncapi/kafka/v2_6_0/test_app.py index 3b50cb19a2..1b71dc7936 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_app.py +++ b/tests/asyncapi/kafka/v2_6_0/test_app.py @@ -1,6 +1,5 @@ -from faststream import FastStream from faststream.kafka import KafkaBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from faststream.specification.schema.contact import Contact from faststream.specification.schema.docs import ExternalDocs from faststream.specification.schema.license import License @@ -8,7 +7,7 @@ def test_base(): - schema = get_app_schema(FastStream(KafkaBroker()), version="2.6.0").to_jsonable() + schema = AsyncAPI(KafkaBroker(), schema_version="2.6.0").jsonable() assert schema == { "asyncapi": "2.6.0", @@ -27,15 +26,13 @@ def test_base(): def test_with_name(): - schema = get_app_schema( - FastStream( - KafkaBroker(), - title="My App", - version="1.0.0", - description="Test description", - ), - version="2.6.0", - ).to_jsonable() + schema = AsyncAPI( + KafkaBroker(), + title="My App", + app_version="1.0.0", + description="Test description", + schema_version="2.6.0", + ).jsonable() assert schema == { "asyncapi": "2.6.0", @@ -58,23 +55,21 @@ def test_with_name(): def test_full(): - schema = get_app_schema( - FastStream( - KafkaBroker(), - title="My App", - version="1.0.0", - description="Test description", - license=License(name="MIT", url="https://mit.com/"), - terms_of_service="https://my-terms.com/", - contact=Contact(name="support", url="https://help.com/"), - tags=(Tag(name="some-tag", description="experimental"),), - identifier="some-unique-uuid", - external_docs=ExternalDocs( - url="https://extra-docs.py/", - ), + schema = AsyncAPI( + KafkaBroker(), + title="My App", + app_version="1.0.0", + description="Test description", + license=License(name="MIT", url="https://mit.com/"), + terms_of_service="https://my-terms.com/", + contact=Contact(name="support", url="https://help.com/"), + tags=(Tag(name="some-tag", description="experimental"),), + identifier="some-unique-uuid", + external_docs=ExternalDocs( + url="https://extra-docs.py/", ), - version="2.6.0", - ).to_jsonable() + schema_version="2.6.0", + ).jsonable() assert schema == { "asyncapi": "2.6.0", @@ -103,23 +98,21 @@ def test_full(): def test_full_dict(): - schema = get_app_schema( - FastStream( - KafkaBroker(), - title="My App", - version="1.0.0", - description="Test description", - license={"name": "MIT", "url": "https://mit.com/"}, - terms_of_service="https://my-terms.com/", - contact={"name": "support", "url": "https://help.com/"}, - tags=({"name": "some-tag", "description": "experimental"},), - identifier="some-unique-uuid", - external_docs={ - "url": "https://extra-docs.py/", - }, - ), - version="2.6.0", - ).to_jsonable() + schema = AsyncAPI( + KafkaBroker(), + title="My App", + app_version="1.0.0", + description="Test description", + license={"name": "MIT", "url": "https://mit.com/"}, + terms_of_service="https://my-terms.com/", + contact={"name": "support", "url": "https://help.com/"}, + tags=({"name": "some-tag", "description": "experimental"},), + identifier="some-unique-uuid", + external_docs={ + "url": "https://extra-docs.py/", + }, + schema_version="2.6.0", + ).jsonable() assert schema == { "asyncapi": "2.6.0", @@ -148,26 +141,24 @@ def test_full_dict(): def test_extra(): - schema = get_app_schema( - FastStream( - KafkaBroker(), - title="My App", - version="1.0.0", - description="Test description", - license={"name": "MIT", "url": "https://mit.com/", "x-field": "extra"}, - terms_of_service="https://my-terms.com/", - contact={"name": "support", "url": "https://help.com/", "x-field": "extra"}, - tags=( - {"name": "some-tag", "description": "experimental", "x-field": "extra"}, - ), - identifier="some-unique-uuid", - external_docs={ - "url": "https://extra-docs.py/", - "x-field": "extra", - }, + schema = AsyncAPI( + KafkaBroker(), + title="My App", + app_version="1.0.0", + description="Test description", + license={"name": "MIT", "url": "https://mit.com/", "x-field": "extra"}, + terms_of_service="https://my-terms.com/", + contact={"name": "support", "url": "https://help.com/", "x-field": "extra"}, + tags=( + {"name": "some-tag", "description": "experimental", "x-field": "extra"}, ), - version="2.6.0", - ).to_jsonable() + identifier="some-unique-uuid", + external_docs={ + "url": "https://extra-docs.py/", + "x-field": "extra", + }, + schema_version="2.6.0", + ).jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/kafka/v2_6_0/test_arguments.py b/tests/asyncapi/kafka/v2_6_0/test_arguments.py index 317584540d..eee8de3cef 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_arguments.py +++ b/tests/asyncapi/kafka/v2_6_0/test_arguments.py @@ -1,5 +1,5 @@ from faststream.kafka import KafkaBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase @@ -12,7 +12,7 @@ def test_subscriber_bindings(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/kafka/v2_6_0/test_connection.py b/tests/asyncapi/kafka/v2_6_0/test_connection.py index fbde5a54f8..eeecdf8230 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_connection.py +++ b/tests/asyncapi/kafka/v2_6_0/test_connection.py @@ -1,22 +1,19 @@ -from faststream import FastStream from faststream.kafka import KafkaBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from faststream.specification.schema.tag import Tag def test_base(): - schema = get_app_schema( - FastStream( - KafkaBroker( - "kafka:9092", - protocol="plaintext", - protocol_version="0.9.0", - description="Test description", - tags=(Tag(name="some-tag", description="experimental"),), - ) + schema = AsyncAPI( + KafkaBroker( + "kafka:9092", + protocol="plaintext", + protocol_version="0.9.0", + description="Test description", + tags=(Tag(name="some-tag", description="experimental"),), ), - version="2.6.0", - ).to_jsonable() + schema_version="2.6.0", + ).jsonable() assert schema == { "asyncapi": "2.6.0", @@ -37,10 +34,10 @@ def test_base(): def test_multi(): - schema = get_app_schema( - FastStream(KafkaBroker(["kafka:9092", "kafka:9093"])), - version="2.6.0", - ).to_jsonable() + schema = AsyncAPI( + KafkaBroker(["kafka:9092", "kafka:9093"]), + schema_version="2.6.0", + ).jsonable() assert schema == { "asyncapi": "2.6.0", @@ -64,15 +61,13 @@ def test_multi(): def test_custom(): - schema = get_app_schema( - FastStream( - KafkaBroker( - ["kafka:9092", "kafka:9093"], - specification_url=["kafka:9094", "kafka:9095"], - ) + schema = AsyncAPI( + KafkaBroker( + ["kafka:9092", "kafka:9093"], + specification_url=["kafka:9094", "kafka:9095"], ), - version="2.6.0", - ).to_jsonable() + schema_version="2.6.0", + ).jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/kafka/v2_6_0/test_fastapi.py b/tests/asyncapi/kafka/v2_6_0/test_fastapi.py index bdc76a49a5..1d1a803edc 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/kafka/v2_6_0/test_fastapi.py @@ -1,16 +1,16 @@ -from typing import Type from faststream.kafka.fastapi import KafkaRouter from faststream.kafka.testing import TestKafkaBroker from faststream.security import SASLPlaintext -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.arguments import FastAPICompatible from tests.asyncapi.base.v2_6_0.fastapi import FastAPITestCase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase class TestRouterArguments(FastAPITestCase, FastAPICompatible): - broker_class: Type[KafkaRouter] = KafkaRouter + broker_class = staticmethod(lambda: KafkaRouter().broker) + router_class = KafkaRouter broker_wrapper = staticmethod(TestKafkaBroker) def build_app(self, router): @@ -18,7 +18,7 @@ def build_app(self, router): class TestRouterPublisher(PublisherTestcase): - broker_class = KafkaRouter + broker_class = staticmethod(lambda: KafkaRouter().broker) def build_app(self, router): return router @@ -27,9 +27,9 @@ def build_app(self, router): def test_fastapi_security_schema(): security = SASLPlaintext(username="user", password="pass", use_ssl=False) - broker = KafkaRouter("localhost:9092", security=security) + router = KafkaRouter("localhost:9092", security=security) - schema = get_app_schema(broker, version="2.6.0").to_jsonable() + schema = AsyncAPI(router.broker, schema_version="2.6.0").jsonable() assert schema["servers"]["development"] == { "protocol": "kafka", diff --git a/tests/asyncapi/kafka/v2_6_0/test_naming.py b/tests/asyncapi/kafka/v2_6_0/test_naming.py index b1565d7f2e..aa89287ee0 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_naming.py +++ b/tests/asyncapi/kafka/v2_6_0/test_naming.py @@ -1,6 +1,5 @@ -from faststream import FastStream from faststream.kafka import KafkaBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.naming import NamingTestCase @@ -13,7 +12,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/kafka/v2_6_0/test_publisher.py b/tests/asyncapi/kafka/v2_6_0/test_publisher.py index d09409b16a..9b054282e5 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_publisher.py +++ b/tests/asyncapi/kafka/v2_6_0/test_publisher.py @@ -1,5 +1,5 @@ from faststream.kafka import KafkaBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase @@ -12,7 +12,7 @@ def test_publisher_bindings(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/kafka/v2_6_0/test_router.py b/tests/asyncapi/kafka/v2_6_0/test_router.py index f389dbcfba..314689ffb6 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_router.py +++ b/tests/asyncapi/kafka/v2_6_0/test_router.py @@ -1,6 +1,5 @@ -from faststream import FastStream from faststream.kafka import KafkaBroker, KafkaPublisher, KafkaRoute, KafkaRouter -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v2_6_0.router import RouterTestcase @@ -22,7 +21,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert schema == { "asyncapi": "2.6.0", @@ -73,7 +72,7 @@ class TestRouterArguments(ArgumentsTestcase): def build_app(self, router): broker = KafkaBroker() broker.include_router(router) - return FastStream(broker) + return broker class TestRouterPublisher(PublisherTestcase): @@ -82,4 +81,4 @@ class TestRouterPublisher(PublisherTestcase): def build_app(self, router): broker = KafkaBroker() broker.include_router(router) - return FastStream(broker) + return broker diff --git a/tests/asyncapi/kafka/v2_6_0/test_security.py b/tests/asyncapi/kafka/v2_6_0/test_security.py index 3dbeb0710c..ddc10d5c37 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_security.py +++ b/tests/asyncapi/kafka/v2_6_0/test_security.py @@ -1,7 +1,6 @@ import ssl from copy import deepcopy -from faststream.app import FastStream from faststream.kafka import KafkaBroker from faststream.security import ( SASLGSSAPI, @@ -11,7 +10,7 @@ SASLScram256, SASLScram512, ) -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI basic_schema = { "asyncapi": "2.6.0", @@ -76,14 +75,13 @@ def test_base_security_schema(): security = BaseSecurity(ssl_context=ssl_context) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert schema == basic_schema @@ -97,14 +95,13 @@ def test_plaintext_security_schema(): ) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() plaintext_security_schema = deepcopy(basic_schema) plaintext_security_schema["servers"]["development"]["security"] = [ @@ -126,14 +123,13 @@ def test_scram256_security_schema(): ) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() sasl256_security_schema = deepcopy(basic_schema) sasl256_security_schema["servers"]["development"]["security"] = [{"scram256": []}] @@ -153,14 +149,13 @@ def test_scram512_security_schema(): ) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() sasl512_security_schema = deepcopy(basic_schema) sasl512_security_schema["servers"]["development"]["security"] = [{"scram512": []}] @@ -178,14 +173,13 @@ def test_oauthbearer_security_schema(): ) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() sasl_oauthbearer_security_schema = deepcopy(basic_schema) sasl_oauthbearer_security_schema["servers"]["development"]["security"] = [ @@ -205,14 +199,13 @@ def test_gssapi_security_schema(): ) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() gssapi_security_schema = deepcopy(basic_schema) gssapi_security_schema["servers"]["development"]["security"] = [{"gssapi": []}] diff --git a/tests/asyncapi/kafka/v3_0_0/test_arguments.py b/tests/asyncapi/kafka/v3_0_0/test_arguments.py index 6f9797c47a..4a95f34a84 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_arguments.py +++ b/tests/asyncapi/kafka/v3_0_0/test_arguments.py @@ -1,5 +1,5 @@ from faststream.kafka import KafkaBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase @@ -12,7 +12,7 @@ def test_subscriber_bindings(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/kafka/v3_0_0/test_connection.py b/tests/asyncapi/kafka/v3_0_0/test_connection.py index 7cefd97893..ceb90a2820 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_connection.py +++ b/tests/asyncapi/kafka/v3_0_0/test_connection.py @@ -1,22 +1,19 @@ -from faststream import FastStream from faststream.kafka import KafkaBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from faststream.specification.schema.tag import Tag def test_base(): - schema = get_app_schema( - FastStream( - KafkaBroker( - "kafka:9092", - protocol="plaintext", - protocol_version="0.9.0", - description="Test description", - tags=(Tag(name="some-tag", description="experimental"),), - ), + schema = AsyncAPI( + KafkaBroker( + "kafka:9092", + protocol="plaintext", + protocol_version="0.9.0", + description="Test description", + tags=(Tag(name="some-tag", description="experimental"),), ), - version="3.0.0", - ).to_jsonable() + schema_version="3.0.0", + ).jsonable() assert schema == { "asyncapi": "3.0.0", @@ -39,12 +36,10 @@ def test_base(): def test_multi(): - schema = get_app_schema( - FastStream( - KafkaBroker(["kafka:9092", "kafka:9093"]), - ), - version="3.0.0", - ).to_jsonable() + schema = AsyncAPI( + KafkaBroker(["kafka:9092", "kafka:9093"]), + schema_version="3.0.0", + ).jsonable() assert schema == { "asyncapi": "3.0.0", @@ -71,15 +66,13 @@ def test_multi(): def test_custom(): - schema = get_app_schema( - FastStream( - KafkaBroker( - ["kafka:9092", "kafka:9093"], - specification_url=["kafka:9094", "kafka:9095"], - ), + schema = AsyncAPI( + KafkaBroker( + ["kafka:9092", "kafka:9093"], + specification_url=["kafka:9094", "kafka:9095"], ), - version="3.0.0", - ).to_jsonable() + schema_version="3.0.0", + ).jsonable() assert schema == { "asyncapi": "3.0.0", diff --git a/tests/asyncapi/kafka/v3_0_0/test_fastapi.py b/tests/asyncapi/kafka/v3_0_0/test_fastapi.py index cb5b5dc71d..6f58c7b255 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/kafka/v3_0_0/test_fastapi.py @@ -1,14 +1,14 @@ from faststream.kafka.fastapi import KafkaRouter from faststream.kafka.testing import TestKafkaBroker from faststream.security import SASLPlaintext -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v3_0_0.arguments import FastAPICompatible from tests.asyncapi.base.v3_0_0.fastapi import FastAPITestCase from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase class TestRouterArguments(FastAPITestCase, FastAPICompatible): - broker_factory = KafkaRouter + broker_factory = staticmethod(lambda: KafkaRouter().broker) router_factory = KafkaRouter broker_wrapper = staticmethod(TestKafkaBroker) @@ -17,7 +17,7 @@ def build_app(self, router): class TestRouterPublisher(PublisherTestcase): - broker_factory = staticmethod(lambda: KafkaRouter()) + broker_factory = staticmethod(lambda: KafkaRouter().broker) def build_app(self, router): return router @@ -26,9 +26,9 @@ def build_app(self, router): def test_fastapi_security_schema(): security = SASLPlaintext(username="user", password="pass", use_ssl=False) - broker = KafkaRouter("localhost:9092", security=security) + router = KafkaRouter("localhost:9092", security=security) - schema = get_app_schema(broker).to_jsonable() + schema = AsyncAPI(router.broker, schema_version="3.0.0").jsonable() assert schema["servers"]["development"] == { "protocol": "kafka", diff --git a/tests/asyncapi/kafka/v3_0_0/test_naming.py b/tests/asyncapi/kafka/v3_0_0/test_naming.py index d843d5a192..40c09bd8ad 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_naming.py +++ b/tests/asyncapi/kafka/v3_0_0/test_naming.py @@ -1,6 +1,5 @@ -from faststream import FastStream from faststream.kafka import KafkaBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v3_0_0.naming import NamingTestCase @@ -13,7 +12,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert schema == { "asyncapi": "3.0.0", diff --git a/tests/asyncapi/kafka/v3_0_0/test_publisher.py b/tests/asyncapi/kafka/v3_0_0/test_publisher.py index 4333d91709..6086630267 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_publisher.py +++ b/tests/asyncapi/kafka/v3_0_0/test_publisher.py @@ -1,5 +1,5 @@ from faststream.kafka import KafkaBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase @@ -12,7 +12,7 @@ def test_publisher_bindings(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/kafka/v3_0_0/test_router.py b/tests/asyncapi/kafka/v3_0_0/test_router.py index 46a007d195..195842eb34 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_router.py +++ b/tests/asyncapi/kafka/v3_0_0/test_router.py @@ -1,6 +1,5 @@ -from faststream import FastStream from faststream.kafka import KafkaBroker, KafkaPublisher, KafkaRoute, KafkaRouter -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v3_0_0.router import RouterTestcase @@ -22,7 +21,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert schema == { "info": {"title": "FastStream", "version": "0.1.0", "description": ""}, @@ -86,7 +85,7 @@ class TestRouterArguments(ArgumentsTestcase): def build_app(self, router): broker = KafkaBroker() broker.include_router(router) - return FastStream(broker) + return broker class TestRouterPublisher(PublisherTestcase): @@ -95,4 +94,4 @@ class TestRouterPublisher(PublisherTestcase): def build_app(self, router): broker = KafkaBroker() broker.include_router(router) - return FastStream(broker) + return broker diff --git a/tests/asyncapi/kafka/v3_0_0/test_security.py b/tests/asyncapi/kafka/v3_0_0/test_security.py index ead58956e2..7308677064 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_security.py +++ b/tests/asyncapi/kafka/v3_0_0/test_security.py @@ -1,7 +1,6 @@ import ssl from copy import deepcopy -from faststream.app import FastStream from faststream.kafka import KafkaBroker from faststream.security import ( SASLGSSAPI, @@ -11,7 +10,7 @@ SASLScram256, SASLScram512, ) -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI basic_schema = { "info": {"title": "FastStream", "version": "0.1.0", "description": ""}, @@ -95,14 +94,13 @@ def test_base_security_schema(): security = BaseSecurity(ssl_context=ssl_context) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert schema == basic_schema @@ -116,14 +114,13 @@ def test_plaintext_security_schema(): ) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() plaintext_security_schema = deepcopy(basic_schema) plaintext_security_schema["servers"]["development"]["security"] = [ @@ -145,14 +142,13 @@ def test_scram256_security_schema(): ) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() sasl256_security_schema = deepcopy(basic_schema) sasl256_security_schema["servers"]["development"]["security"] = [{"scram256": []}] @@ -172,14 +168,13 @@ def test_scram512_security_schema(): ) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() sasl512_security_schema = deepcopy(basic_schema) sasl512_security_schema["servers"]["development"]["security"] = [{"scram512": []}] @@ -197,14 +192,13 @@ def test_oauthbearer_security_schema(): ) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() sasl_oauthbearer_security_schema = deepcopy(basic_schema) sasl_oauthbearer_security_schema["servers"]["development"]["security"] = [ @@ -224,14 +218,13 @@ def test_gssapi_security_schema(): ) broker = KafkaBroker("localhost:9092", security=security) - app = FastStream(broker) @broker.publisher("test_2") @broker.subscriber("test_1") async def test_topic(msg: str) -> str: pass - schema = get_app_schema(app, version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() gssapi_security_schema = deepcopy(basic_schema) gssapi_security_schema["servers"]["development"]["security"] = [{"gssapi": []}] diff --git a/tests/asyncapi/nats/v2_6_0/test_arguments.py b/tests/asyncapi/nats/v2_6_0/test_arguments.py index 98b71bd3e0..d361ef5933 100644 --- a/tests/asyncapi/nats/v2_6_0/test_arguments.py +++ b/tests/asyncapi/nats/v2_6_0/test_arguments.py @@ -1,5 +1,5 @@ from faststream.nats import NatsBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase @@ -12,7 +12,7 @@ def test_subscriber_bindings(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/nats/v2_6_0/test_connection.py b/tests/asyncapi/nats/v2_6_0/test_connection.py index 3a2a4df5c1..6a6b906e87 100644 --- a/tests/asyncapi/nats/v2_6_0/test_connection.py +++ b/tests/asyncapi/nats/v2_6_0/test_connection.py @@ -1,22 +1,19 @@ -from faststream import FastStream from faststream.nats import NatsBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from faststream.specification.schema.tag import Tag def test_base(): - schema = get_app_schema( - FastStream( - NatsBroker( - "nats:9092", - protocol="plaintext", - protocol_version="0.9.0", - description="Test description", - tags=(Tag(name="some-tag", description="experimental"),), - ) + schema = AsyncAPI( + NatsBroker( + "nats:9092", + protocol="plaintext", + protocol_version="0.9.0", + description="Test description", + tags=(Tag(name="some-tag", description="experimental"),), ), - version="2.6.0", - ).to_jsonable() + schema_version="2.6.0", + ).jsonable() assert schema == { "asyncapi": "2.6.0", @@ -37,10 +34,10 @@ def test_base(): def test_multi(): - schema = get_app_schema( - FastStream(NatsBroker(["nats:9092", "nats:9093"])), - version="2.6.0", - ).to_jsonable() + schema = AsyncAPI( + NatsBroker(["nats:9092", "nats:9093"]), + schema_version="2.6.0", + ).jsonable() assert schema == { "asyncapi": "2.6.0", @@ -64,14 +61,12 @@ def test_multi(): def test_custom(): - schema = get_app_schema( - FastStream( - NatsBroker( - ["nats:9092", "nats:9093"], specification_url=["nats:9094", "nats:9095"] - ) + schema = AsyncAPI( + NatsBroker( + ["nats:9092", "nats:9093"], specification_url=["nats:9094", "nats:9095"] ), - version="2.6.0", - ).to_jsonable() + schema_version="2.6.0", + ).jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/nats/v2_6_0/test_fastapi.py b/tests/asyncapi/nats/v2_6_0/test_fastapi.py index 93106116e1..fe1be83a89 100644 --- a/tests/asyncapi/nats/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/nats/v2_6_0/test_fastapi.py @@ -1,4 +1,3 @@ -from typing import Type from faststream.nats import TestNatsBroker from faststream.nats.fastapi import NatsRouter @@ -8,7 +7,8 @@ class TestRouterArguments(FastAPITestCase, FastAPICompatible): - broker_class: Type[NatsRouter] = NatsRouter + broker_class = staticmethod(lambda: NatsRouter().broker) + router_class = NatsRouter broker_wrapper = staticmethod(TestNatsBroker) def build_app(self, router): @@ -16,7 +16,7 @@ def build_app(self, router): class TestRouterPublisher(PublisherTestcase): - broker_class = NatsRouter + broker_class = staticmethod(lambda: NatsRouter().broker) def build_app(self, router): return router diff --git a/tests/asyncapi/nats/v2_6_0/test_kv_schema.py b/tests/asyncapi/nats/v2_6_0/test_kv_schema.py index bbe076dbbb..21aa4c6a1a 100644 --- a/tests/asyncapi/nats/v2_6_0/test_kv_schema.py +++ b/tests/asyncapi/nats/v2_6_0/test_kv_schema.py @@ -1,6 +1,5 @@ -from faststream import FastStream from faststream.nats import NatsBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI def test_kv_schema(): @@ -9,6 +8,6 @@ def test_kv_schema(): @broker.subscriber("test", kv_watch="test") async def handle(): ... - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert schema["channels"] == {} diff --git a/tests/asyncapi/nats/v2_6_0/test_naming.py b/tests/asyncapi/nats/v2_6_0/test_naming.py index cf494e3600..0402b83b90 100644 --- a/tests/asyncapi/nats/v2_6_0/test_naming.py +++ b/tests/asyncapi/nats/v2_6_0/test_naming.py @@ -1,6 +1,5 @@ -from faststream import FastStream from faststream.nats import NatsBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.naming import NamingTestCase @@ -13,7 +12,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/nats/v2_6_0/test_obj_schema.py b/tests/asyncapi/nats/v2_6_0/test_obj_schema.py index 3c63c716b7..599c2d95ed 100644 --- a/tests/asyncapi/nats/v2_6_0/test_obj_schema.py +++ b/tests/asyncapi/nats/v2_6_0/test_obj_schema.py @@ -1,6 +1,5 @@ -from faststream import FastStream from faststream.nats import NatsBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI def test_obj_schema(): @@ -9,6 +8,6 @@ def test_obj_schema(): @broker.subscriber("test", obj_watch=True) async def handle(): ... - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert schema["channels"] == {} diff --git a/tests/asyncapi/nats/v2_6_0/test_publisher.py b/tests/asyncapi/nats/v2_6_0/test_publisher.py index db492f56ad..8a0a935f0e 100644 --- a/tests/asyncapi/nats/v2_6_0/test_publisher.py +++ b/tests/asyncapi/nats/v2_6_0/test_publisher.py @@ -1,5 +1,5 @@ from faststream.nats import NatsBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase @@ -12,7 +12,7 @@ def test_publisher_bindings(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/nats/v2_6_0/test_router.py b/tests/asyncapi/nats/v2_6_0/test_router.py index ccbf703cb5..24920871c2 100644 --- a/tests/asyncapi/nats/v2_6_0/test_router.py +++ b/tests/asyncapi/nats/v2_6_0/test_router.py @@ -1,6 +1,5 @@ -from faststream import FastStream from faststream.nats import NatsBroker, NatsPublisher, NatsRoute, NatsRouter -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v2_6_0.router import RouterTestcase @@ -22,7 +21,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert schema == { "asyncapi": "2.6.0", @@ -73,7 +72,7 @@ class TestRouterArguments(ArgumentsTestcase): def build_app(self, router): broker = NatsBroker() broker.include_router(router) - return FastStream(broker) + return broker class TestRouterPublisher(PublisherTestcase): @@ -82,4 +81,4 @@ class TestRouterPublisher(PublisherTestcase): def build_app(self, router): broker = NatsBroker() broker.include_router(router) - return FastStream(broker) + return broker diff --git a/tests/asyncapi/nats/v3_0_0/test_arguments.py b/tests/asyncapi/nats/v3_0_0/test_arguments.py index 6d594ca613..a007642079 100644 --- a/tests/asyncapi/nats/v3_0_0/test_arguments.py +++ b/tests/asyncapi/nats/v3_0_0/test_arguments.py @@ -1,5 +1,5 @@ from faststream.nats import NatsBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase @@ -12,7 +12,7 @@ def test_subscriber_bindings(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/nats/v3_0_0/test_connection.py b/tests/asyncapi/nats/v3_0_0/test_connection.py index dfd041462d..904fd24e5f 100644 --- a/tests/asyncapi/nats/v3_0_0/test_connection.py +++ b/tests/asyncapi/nats/v3_0_0/test_connection.py @@ -1,22 +1,19 @@ -from faststream import FastStream from faststream.nats import NatsBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from faststream.specification.schema.tag import Tag def test_base(): - schema = get_app_schema( - FastStream( - NatsBroker( - "nats:9092", - protocol="plaintext", - protocol_version="0.9.0", - description="Test description", - tags=(Tag(name="some-tag", description="experimental"),), - ), + schema = AsyncAPI( + NatsBroker( + "nats:9092", + protocol="plaintext", + protocol_version="0.9.0", + description="Test description", + tags=(Tag(name="some-tag", description="experimental"),), ), - version="3.0.0", - ).to_jsonable() + schema_version="3.0.0", + ).jsonable() assert schema == { "asyncapi": "3.0.0", @@ -39,12 +36,10 @@ def test_base(): def test_multi(): - schema = get_app_schema( - FastStream( - NatsBroker(["nats:9092", "nats:9093"]), - ), - version="3.0.0", - ).to_jsonable() + schema = AsyncAPI( + NatsBroker(["nats:9092", "nats:9093"]), + schema_version="3.0.0", + ).jsonable() assert schema == { "asyncapi": "3.0.0", @@ -71,15 +66,13 @@ def test_multi(): def test_custom(): - schema = get_app_schema( - FastStream( - NatsBroker( - ["nats:9092", "nats:9093"], - specification_url=["nats:9094", "nats:9095"], - ), + schema = AsyncAPI( + NatsBroker( + ["nats:9092", "nats:9093"], + specification_url=["nats:9094", "nats:9095"], ), - version="3.0.0", - ).to_jsonable() + schema_version="3.0.0", + ).jsonable() assert schema == { "asyncapi": "3.0.0", diff --git a/tests/asyncapi/nats/v3_0_0/test_fastapi.py b/tests/asyncapi/nats/v3_0_0/test_fastapi.py index ec752ece0f..2bd8cc25c4 100644 --- a/tests/asyncapi/nats/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/nats/v3_0_0/test_fastapi.py @@ -6,7 +6,7 @@ class TestRouterArguments(FastAPITestCase, FastAPICompatible): - broker_factory = staticmethod(lambda: NatsRouter()) + broker_factory = staticmethod(lambda: NatsRouter().broker) router_factory = NatsRouter broker_wrapper = staticmethod(TestNatsBroker) @@ -15,7 +15,7 @@ def build_app(self, router): class TestRouterPublisher(PublisherTestcase): - broker_factory = staticmethod(lambda: NatsRouter()) + broker_factory = staticmethod(lambda: NatsRouter().broker) def build_app(self, router): return router diff --git a/tests/asyncapi/nats/v3_0_0/test_kv_schema.py b/tests/asyncapi/nats/v3_0_0/test_kv_schema.py index e9c3680fb7..1377ddc893 100644 --- a/tests/asyncapi/nats/v3_0_0/test_kv_schema.py +++ b/tests/asyncapi/nats/v3_0_0/test_kv_schema.py @@ -1,6 +1,5 @@ -from faststream import FastStream from faststream.nats import NatsBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI def test_kv_schema(): @@ -9,6 +8,6 @@ def test_kv_schema(): @broker.subscriber("test", kv_watch="test") async def handle(): ... - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert schema["channels"] == {} diff --git a/tests/asyncapi/nats/v3_0_0/test_naming.py b/tests/asyncapi/nats/v3_0_0/test_naming.py index 3c6241432c..e95b370842 100644 --- a/tests/asyncapi/nats/v3_0_0/test_naming.py +++ b/tests/asyncapi/nats/v3_0_0/test_naming.py @@ -1,6 +1,5 @@ -from faststream import FastStream from faststream.nats import NatsBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v3_0_0.naming import NamingTestCase @@ -13,7 +12,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert schema == { "asyncapi": "3.0.0", diff --git a/tests/asyncapi/nats/v3_0_0/test_obj_schema.py b/tests/asyncapi/nats/v3_0_0/test_obj_schema.py index 231ab1fdaa..9ea02b5312 100644 --- a/tests/asyncapi/nats/v3_0_0/test_obj_schema.py +++ b/tests/asyncapi/nats/v3_0_0/test_obj_schema.py @@ -1,6 +1,5 @@ -from faststream import FastStream from faststream.nats import NatsBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI def test_obj_schema(): @@ -9,6 +8,6 @@ def test_obj_schema(): @broker.subscriber("test", obj_watch=True) async def handle(): ... - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert schema["channels"] == {} diff --git a/tests/asyncapi/nats/v3_0_0/test_publisher.py b/tests/asyncapi/nats/v3_0_0/test_publisher.py index f825bbcd43..656fa40c4a 100644 --- a/tests/asyncapi/nats/v3_0_0/test_publisher.py +++ b/tests/asyncapi/nats/v3_0_0/test_publisher.py @@ -1,5 +1,5 @@ from faststream.nats import NatsBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase @@ -12,7 +12,7 @@ def test_publisher_bindings(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/nats/v3_0_0/test_router.py b/tests/asyncapi/nats/v3_0_0/test_router.py index b4436a88f7..55d065dc22 100644 --- a/tests/asyncapi/nats/v3_0_0/test_router.py +++ b/tests/asyncapi/nats/v3_0_0/test_router.py @@ -1,6 +1,5 @@ -from faststream import FastStream from faststream.nats import NatsBroker, NatsPublisher, NatsRoute, NatsRouter -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v3_0_0.router import RouterTestcase @@ -22,7 +21,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert schema == { "info": {"title": "FastStream", "version": "0.1.0", "description": ""}, @@ -86,7 +85,7 @@ class TestRouterArguments(ArgumentsTestcase): def build_app(self, router): broker = NatsBroker() broker.include_router(router) - return FastStream(broker) + return broker class TestRouterPublisher(PublisherTestcase): @@ -95,4 +94,4 @@ class TestRouterPublisher(PublisherTestcase): def build_app(self, router): broker = NatsBroker() broker.include_router(router) - return FastStream(broker) + return broker diff --git a/tests/asyncapi/rabbit/v2_6_0/test_arguments.py b/tests/asyncapi/rabbit/v2_6_0/test_arguments.py index bbb9b4ed30..98e139cc55 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_arguments.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_arguments.py @@ -1,5 +1,5 @@ from faststream.rabbit import ExchangeType, RabbitBroker, RabbitExchange, RabbitQueue -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase @@ -15,7 +15,7 @@ def test_subscriber_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -48,7 +48,7 @@ def test_subscriber_fanout_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -74,7 +74,7 @@ def test_subscriber_headers_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -100,7 +100,7 @@ def test_subscriber_xdelay_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -126,7 +126,7 @@ def test_subscriber_consistent_hash_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -152,7 +152,7 @@ def test_subscriber_modules_hash_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker)).to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/rabbit/v2_6_0/test_connection.py b/tests/asyncapi/rabbit/v2_6_0/test_connection.py index 137bb7b444..7684dcb0d6 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_connection.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_connection.py @@ -1,22 +1,19 @@ -from faststream import FastStream from faststream.rabbit import RabbitBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from faststream.specification.schema.tag import Tag def test_base(): - schema = get_app_schema( - FastStream( - RabbitBroker( - "amqps://localhost", - port=5673, - protocol_version="0.9.0", - description="Test description", - tags=(Tag(name="some-tag", description="experimental"),), - ) + schema = AsyncAPI( + RabbitBroker( + "amqps://localhost", + port=5673, + protocol_version="0.9.0", + description="Test description", + tags=(Tag(name="some-tag", description="experimental"),), ), - version="2.6.0", - ).to_jsonable() + schema_version="2.6.0", + ).jsonable() assert schema == { "asyncapi": "2.6.0", @@ -55,7 +52,7 @@ def test_custom(): ) broker.publisher("test") - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert ( schema diff --git a/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py b/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py index f08b8d6a22..4ce7ec8e93 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py @@ -1,16 +1,16 @@ -from typing import Type from faststream.rabbit.fastapi import RabbitRouter from faststream.rabbit.testing import TestRabbitBroker from faststream.security import SASLPlaintext -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.arguments import FastAPICompatible from tests.asyncapi.base.v2_6_0.fastapi import FastAPITestCase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase class TestRouterArguments(FastAPITestCase, FastAPICompatible): - broker_class: Type[RabbitRouter] = RabbitRouter + broker_class = staticmethod(lambda: RabbitRouter().broker) + router_class = RabbitRouter broker_wrapper = staticmethod(TestRabbitBroker) def build_app(self, router): @@ -18,7 +18,7 @@ def build_app(self, router): class TestRouterPublisher(PublisherTestcase): - broker_class = RabbitRouter + broker_class = staticmethod(lambda: RabbitRouter().broker) def build_app(self, router): return router @@ -27,9 +27,9 @@ def build_app(self, router): def test_fastapi_security_schema(): security = SASLPlaintext(username="user", password="pass", use_ssl=False) - broker = RabbitRouter(security=security) + router = RabbitRouter(security=security) - schema = get_app_schema(broker, version="2.6.0").to_jsonable() + schema = AsyncAPI(router.broker, schema_version="2.6.0").jsonable() assert schema["servers"]["development"] == { "protocol": "amqp", diff --git a/tests/asyncapi/rabbit/v2_6_0/test_naming.py b/tests/asyncapi/rabbit/v2_6_0/test_naming.py index 1aeab52db3..8b659c589c 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_naming.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_naming.py @@ -1,8 +1,7 @@ from typing import Type -from faststream import FastStream from faststream.rabbit import RabbitBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.naming import NamingTestCase @@ -15,7 +14,7 @@ def test_subscriber_with_exchange(self): @broker.subscriber("test", "exchange") async def handle(): ... - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert list(schema["channels"].keys()) == ["test:exchange:Handle"] @@ -29,7 +28,7 @@ def test_publisher_with_exchange(self): @broker.publisher("test", "exchange") async def handle(): ... - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert list(schema["channels"].keys()) == ["test:exchange:Publisher"] @@ -43,7 +42,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert ( schema diff --git a/tests/asyncapi/rabbit/v2_6_0/test_publisher.py b/tests/asyncapi/rabbit/v2_6_0/test_publisher.py index ed503d6ce5..476d479f90 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_publisher.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_publisher.py @@ -1,5 +1,5 @@ from faststream.rabbit import ExchangeType, RabbitBroker, RabbitExchange, RabbitQueue -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase @@ -12,7 +12,7 @@ def test_just_exchange(self): @broker.publisher(exchange="test-ex") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() assert schema["channels"] == { "_:test-ex:Publisher": { @@ -55,7 +55,7 @@ def test_publisher_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -88,7 +88,7 @@ def test_useless_queue_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() assert schema["channels"] == { "_:test-ex:Publisher": { @@ -121,7 +121,7 @@ def test_reusable_exchange(self): @broker.publisher(exchange="test-ex", routing_key="key2", priority=10) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() assert schema["channels"] == { "key1:test-ex:Publisher": { diff --git a/tests/asyncapi/rabbit/v2_6_0/test_router.py b/tests/asyncapi/rabbit/v2_6_0/test_router.py index 9c6b8d3fb6..60693e718f 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_router.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_router.py @@ -1,4 +1,3 @@ -from faststream import FastStream from faststream.rabbit import ( RabbitBroker, RabbitPublisher, @@ -6,7 +5,7 @@ RabbitRoute, RabbitRouter, ) -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v2_6_0.router import RouterTestcase @@ -28,7 +27,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert ( schema @@ -100,7 +99,7 @@ class TestRouterArguments(ArgumentsTestcase): def build_app(self, router): broker = RabbitBroker() broker.include_router(router) - return FastStream(broker) + return broker class TestRouterPublisher(PublisherTestcase): @@ -109,4 +108,4 @@ class TestRouterPublisher(PublisherTestcase): def build_app(self, router): broker = RabbitBroker() broker.include_router(router) - return FastStream(broker) + return broker diff --git a/tests/asyncapi/rabbit/v2_6_0/test_security.py b/tests/asyncapi/rabbit/v2_6_0/test_security.py index d46514cb37..e66c0e95f1 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_security.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_security.py @@ -1,12 +1,11 @@ import ssl -from faststream.app import FastStream from faststream.rabbit import RabbitBroker from faststream.security import ( BaseSecurity, SASLPlaintext, ) -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI def test_base_security_schema(): @@ -20,7 +19,7 @@ def test_base_security_schema(): ) # pragma: allowlist secret assert broker._connection_kwargs.get("ssl_context") is ssl_context - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert schema == { "asyncapi": "2.6.0", @@ -56,7 +55,7 @@ def test_plaintext_security_schema(): ) # pragma: allowlist secret assert broker._connection_kwargs.get("ssl_context") is ssl_context - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert ( schema == { @@ -94,7 +93,7 @@ def test_plaintext_security_schema_without_ssl(): == "amqp://admin:password@localhost:5672/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert ( schema == { diff --git a/tests/asyncapi/rabbit/v3_0_0/test_arguments.py b/tests/asyncapi/rabbit/v3_0_0/test_arguments.py index aa9bb997a4..a997788d82 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_arguments.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_arguments.py @@ -1,5 +1,5 @@ from faststream.rabbit import ExchangeType, RabbitBroker, RabbitExchange, RabbitQueue -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase @@ -15,12 +15,12 @@ def test_subscriber_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { "amqp": { - "bindingVersion": "0.2.0", + "bindingVersion": "0.3.0", "exchange": { "autoDelete": False, "durable": False, @@ -48,12 +48,12 @@ def test_subscriber_fanout_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { "amqp": { - "bindingVersion": "0.2.0", + "bindingVersion": "0.3.0", "exchange": { "autoDelete": False, "durable": False, diff --git a/tests/asyncapi/rabbit/v3_0_0/test_connection.py b/tests/asyncapi/rabbit/v3_0_0/test_connection.py index 9bd67f12e0..870d1337e3 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_connection.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_connection.py @@ -1,22 +1,19 @@ -from faststream import FastStream from faststream.rabbit import RabbitBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from faststream.specification.schema.tag import Tag def test_base(): - schema = get_app_schema( - FastStream( - RabbitBroker( - "amqps://localhost", - port=5673, - protocol_version="0.9.0", - description="Test description", - tags=(Tag(name="some-tag", description="experimental"),), - ), + schema = AsyncAPI( + RabbitBroker( + "amqps://localhost", + port=5673, + protocol_version="0.9.0", + description="Test description", + tags=(Tag(name="some-tag", description="experimental"),), ), - version="3.0.0", - ).to_jsonable() + schema_version="3.0.0", + ).jsonable() assert schema == { "asyncapi": "3.0.0", @@ -57,7 +54,7 @@ def test_custom(): ) broker.publisher("test") - schema = get_app_schema(FastStream(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() assert schema == { "asyncapi": "3.0.0", @@ -66,7 +63,7 @@ def test_custom(): "address": "test:_:Publisher", "bindings": { "amqp": { - "bindingVersion": "0.2.0", + "bindingVersion": "0.3.0", "exchange": {"type": "default", "vhost": "/vh"}, "is": "routingKey", "queue": { @@ -96,8 +93,10 @@ def test_custom(): "bindings": { "amqp": { "ack": True, - "bindingVersion": "0.2.0", - "cc": "test", + "bindingVersion": "0.3.0", + "cc": [ + "test", + ], "deliveryMode": 1, "mandatory": True, }, diff --git a/tests/asyncapi/rabbit/v3_0_0/test_fastapi.py b/tests/asyncapi/rabbit/v3_0_0/test_fastapi.py index 22375186a8..14578beb61 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_fastapi.py @@ -1,14 +1,14 @@ from faststream.rabbit.fastapi import RabbitRouter from faststream.rabbit.testing import TestRabbitBroker from faststream.security import SASLPlaintext -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v3_0_0.arguments import FastAPICompatible from tests.asyncapi.base.v3_0_0.fastapi import FastAPITestCase from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase class TestRouterArguments(FastAPITestCase, FastAPICompatible): - broker_factory = staticmethod(lambda: RabbitRouter()) + broker_factory = staticmethod(lambda: RabbitRouter().broker) router_factory = RabbitRouter broker_wrapper = staticmethod(TestRabbitBroker) @@ -17,7 +17,7 @@ def build_app(self, router): class TestRouterPublisher(PublisherTestcase): - broker_factory = staticmethod(lambda: RabbitRouter()) + broker_factory = staticmethod(lambda: RabbitRouter().broker) def build_app(self, router): return router @@ -28,16 +28,17 @@ def test_fastapi_security_schema(): router = RabbitRouter(security=security) - schema = get_app_schema( - router, - ).to_jsonable() + schema = AsyncAPI( + router.broker, + schema_version="3.0.0" + ).jsonable() assert schema["servers"]["development"] == { "protocol": "amqp", "protocolVersion": "0.9.1", "security": [{"user-password": []}], - "host": "user:pass@localhost:5672", # pragma: allowlist secret - "pathname": "/", # pragma: allowlist secret + "host": "user:pass@localhost:5672", + "pathname": "/", } assert schema["components"]["securitySchemes"] == { "user-password": {"type": "userPassword"} diff --git a/tests/asyncapi/rabbit/v3_0_0/test_naming.py b/tests/asyncapi/rabbit/v3_0_0/test_naming.py index eaf52f25eb..34c0415cf3 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_naming.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_naming.py @@ -1,8 +1,7 @@ from typing import Type -from faststream import FastStream from faststream.rabbit import RabbitBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v3_0_0.naming import NamingTestCase @@ -15,10 +14,10 @@ def test_subscriber_with_exchange(self): @broker.subscriber("test", "exchange") async def handle(): ... - schema = get_app_schema( - FastStream(broker), - version="3.0.0", - ).to_jsonable() + schema = AsyncAPI( + broker, + schema_version="3.0.0", + ).jsonable() assert list(schema["channels"].keys()) == ["test:exchange:Handle"] @@ -32,10 +31,10 @@ def test_publisher_with_exchange(self): @broker.publisher("test", "exchange") async def handle(): ... - schema = get_app_schema( - FastStream(broker), - version="3.0.0", - ).to_jsonable() + schema = AsyncAPI( + broker, + schema_version="3.0.0", + ).jsonable() assert list(schema["channels"].keys()) == ["test:exchange:Publisher"] @@ -49,10 +48,10 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema( - FastStream(broker), - version="3.0.0", - ).to_jsonable() + schema = AsyncAPI( + broker, + schema_version="3.0.0", + ).jsonable() assert schema == { "asyncapi": "3.0.0", @@ -77,7 +76,7 @@ async def handle(): ... "bindings": { "amqp": { "is": "routingKey", - "bindingVersion": "0.2.0", + "bindingVersion": "0.3.0", "queue": { "name": "test", "durable": False, @@ -101,8 +100,10 @@ async def handle(): ... "bindings": { "amqp": { "ack": True, - "bindingVersion": "0.2.0", - "cc": "test", + "bindingVersion": "0.3.0", + "cc": [ + "test", + ], }, }, "channel": { diff --git a/tests/asyncapi/rabbit/v3_0_0/test_publisher.py b/tests/asyncapi/rabbit/v3_0_0/test_publisher.py index cdd33870bf..6cafa4e824 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_publisher.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_publisher.py @@ -1,5 +1,5 @@ from faststream.rabbit import ExchangeType, RabbitBroker, RabbitExchange, RabbitQueue -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase @@ -12,14 +12,14 @@ def test_just_exchange(self): @broker.publisher(exchange="test-ex") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() assert schema["channels"] == { "_:test-ex:Publisher": { "address": "_:test-ex:Publisher", "bindings": { "amqp": { - "bindingVersion": "0.2.0", + "bindingVersion": "0.3.0", "exchange": { "autoDelete": False, "durable": False, @@ -49,7 +49,7 @@ async def handle(msg): ... "bindings": { "amqp": { "ack": True, - "bindingVersion": "0.2.0", + "bindingVersion": "0.3.0", "deliveryMode": 1, "mandatory": True, } @@ -74,12 +74,12 @@ def test_publisher_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { "amqp": { - "bindingVersion": "0.2.0", + "bindingVersion": "0.3.0", "exchange": { "autoDelete": False, "durable": False, @@ -107,14 +107,14 @@ def test_useless_queue_bindings(self): ) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() assert schema["channels"] == { "_:test-ex:Publisher": { "address": "_:test-ex:Publisher", "bindings": { "amqp": { - "bindingVersion": "0.2.0", + "bindingVersion": "0.3.0", "exchange": { "autoDelete": False, "durable": False, @@ -157,14 +157,14 @@ def test_reusable_exchange(self): @broker.publisher(exchange="test-ex", routing_key="key2", priority=10) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() assert schema["channels"] == { "key1:test-ex:Publisher": { "address": "key1:test-ex:Publisher", "bindings": { "amqp": { - "bindingVersion": "0.2.0", + "bindingVersion": "0.3.0", "exchange": { "autoDelete": False, "durable": False, @@ -190,7 +190,7 @@ async def handle(msg): ... "address": "key2:test-ex:Publisher", "bindings": { "amqp": { - "bindingVersion": "0.2.0", + "bindingVersion": "0.3.0", "exchange": { "autoDelete": False, "durable": False, @@ -223,8 +223,10 @@ async def handle(msg): ... "bindings": { "amqp": { "ack": True, - "bindingVersion": "0.2.0", - "cc": "key1", + "bindingVersion": "0.3.0", + "cc": [ + "key1", + ], "deliveryMode": 1, "mandatory": True, } @@ -241,8 +243,10 @@ async def handle(msg): ... "bindings": { "amqp": { "ack": True, - "bindingVersion": "0.2.0", - "cc": "key2", + "bindingVersion": "0.3.0", + "cc": [ + "key2", + ], "deliveryMode": 1, "priority": 10, "mandatory": True, diff --git a/tests/asyncapi/rabbit/v3_0_0/test_router.py b/tests/asyncapi/rabbit/v3_0_0/test_router.py index 18bdeb8a5a..e67a4e72ef 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_router.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_router.py @@ -1,4 +1,3 @@ -from faststream import FastStream from faststream.rabbit import ( RabbitBroker, RabbitPublisher, @@ -6,7 +5,7 @@ RabbitRoute, RabbitRouter, ) -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v3_0_0.router import RouterTestcase @@ -28,10 +27,10 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema( - FastStream(broker), - version="3.0.0", - ).to_jsonable() + schema = AsyncAPI( + broker, + schema_version="3.0.0", + ).jsonable() assert schema == { "info": {"title": "FastStream", "version": "0.1.0", "description": ""}, @@ -57,7 +56,7 @@ async def handle(msg): ... "bindings": { "amqp": { "is": "routingKey", - "bindingVersion": "0.2.0", + "bindingVersion": "0.3.0", "queue": { "name": "test_test", "durable": False, @@ -75,9 +74,11 @@ async def handle(msg): ... "action": "receive", "bindings": { "amqp": { - "cc": "test_key", + "cc": [ + "test_key", + ], "ack": True, - "bindingVersion": "0.2.0", + "bindingVersion": "0.3.0", } }, "messages": [ @@ -113,7 +114,7 @@ class TestRouterArguments(ArgumentsTestcase): def build_app(self, router): broker = RabbitBroker() broker.include_router(router) - return FastStream(broker) + return broker class TestRouterPublisher(PublisherTestcase): @@ -122,4 +123,4 @@ class TestRouterPublisher(PublisherTestcase): def build_app(self, router): broker = RabbitBroker() broker.include_router(router) - return FastStream(broker) + return broker diff --git a/tests/asyncapi/rabbit/v3_0_0/test_security.py b/tests/asyncapi/rabbit/v3_0_0/test_security.py index bfa6354a9e..0064330913 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_security.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_security.py @@ -1,12 +1,11 @@ import ssl -from faststream.app import FastStream from faststream.rabbit import RabbitBroker from faststream.security import ( BaseSecurity, SASLPlaintext, ) -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI def test_base_security_schema(): @@ -20,10 +19,10 @@ def test_base_security_schema(): ) # pragma: allowlist secret assert broker._connection_kwargs.get("ssl_context") is ssl_context - schema = get_app_schema( - FastStream(broker), - version="3.0.0", - ).to_jsonable() + schema = AsyncAPI( + broker, + schema_version="3.0.0", + ).jsonable() assert schema == { "asyncapi": "3.0.0", @@ -61,10 +60,10 @@ def test_plaintext_security_schema(): ) # pragma: allowlist secret assert broker._connection_kwargs.get("ssl_context") is ssl_context - schema = get_app_schema( - FastStream(broker), - version="3.0.0", - ).to_jsonable() + schema = AsyncAPI( + broker, + schema_version="3.0.0", + ).jsonable() assert schema == { "asyncapi": "3.0.0", "channels": {}, @@ -101,10 +100,10 @@ def test_plaintext_security_schema_without_ssl(): == "amqp://admin:password@localhost:5672/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = get_app_schema( - FastStream(broker), - version="3.0.0", - ).to_jsonable() + schema = AsyncAPI( + broker, + schema_version="3.0.0", + ).jsonable() assert schema == { "asyncapi": "3.0.0", "channels": {}, diff --git a/tests/asyncapi/redis/v2_6_0/test_arguments.py b/tests/asyncapi/redis/v2_6_0/test_arguments.py index 8b370dd571..678c5e654a 100644 --- a/tests/asyncapi/redis/v2_6_0/test_arguments.py +++ b/tests/asyncapi/redis/v2_6_0/test_arguments.py @@ -1,5 +1,5 @@ from faststream.redis import RedisBroker, StreamSub -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase @@ -12,7 +12,7 @@ def test_channel_subscriber(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -29,7 +29,7 @@ def test_channel_pattern_subscriber(self): @broker.subscriber("test.{path}") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -46,7 +46,7 @@ def test_list_subscriber(self): @broker.subscriber(list="test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -59,7 +59,7 @@ def test_stream_subscriber(self): @broker.subscriber(stream="test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -72,7 +72,7 @@ def test_stream_group_subscriber(self): @broker.subscriber(stream=StreamSub("test", group="group", consumer="consumer")) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/redis/v2_6_0/test_connection.py b/tests/asyncapi/redis/v2_6_0/test_connection.py index 38bc050ad3..c26cececf3 100644 --- a/tests/asyncapi/redis/v2_6_0/test_connection.py +++ b/tests/asyncapi/redis/v2_6_0/test_connection.py @@ -1,22 +1,19 @@ -from faststream import FastStream from faststream.redis import RedisBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from faststream.specification.schema.tag import Tag def test_base(): - schema = get_app_schema( - FastStream( - RedisBroker( - "redis://localhost:6379", - protocol="plaintext", - protocol_version="0.9.0", - description="Test description", - tags=(Tag(name="some-tag", description="experimental"),), - ) + schema = AsyncAPI( + RedisBroker( + "redis://localhost:6379", + protocol="plaintext", + protocol_version="0.9.0", + description="Test description", + tags=(Tag(name="some-tag", description="experimental"),), ), - version="2.6.0", - ).to_jsonable() + schema_version="2.6.0", + ).jsonable() assert schema == { "asyncapi": "2.6.0", @@ -37,14 +34,12 @@ def test_base(): def test_custom(): - schema = get_app_schema( - FastStream( - RedisBroker( - "redis://localhost:6379", specification_url="rediss://127.0.0.1:8000" - ) + schema = AsyncAPI( + RedisBroker( + "redis://localhost:6379", specification_url="rediss://127.0.0.1:8000" ), - version="2.6.0", - ).to_jsonable() + schema_version="2.6.0", + ).jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/redis/v2_6_0/test_fastapi.py b/tests/asyncapi/redis/v2_6_0/test_fastapi.py index 01e3e208a3..734df89abb 100644 --- a/tests/asyncapi/redis/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/redis/v2_6_0/test_fastapi.py @@ -1,4 +1,3 @@ -from typing import Type from faststream.redis import TestRedisBroker from faststream.redis.fastapi import RedisRouter @@ -8,7 +7,8 @@ class TestRouterArguments(FastAPITestCase, FastAPICompatible): - broker_class: Type[RedisRouter] = RedisRouter + broker_class = staticmethod(lambda: RedisRouter().broker) + router_class = RedisRouter broker_wrapper = staticmethod(TestRedisBroker) def build_app(self, router): @@ -16,7 +16,7 @@ def build_app(self, router): class TestRouterPublisher(PublisherTestcase): - broker_class = RedisRouter + broker_class = staticmethod(lambda: RedisRouter().broker) def build_app(self, router): return router diff --git a/tests/asyncapi/redis/v2_6_0/test_naming.py b/tests/asyncapi/redis/v2_6_0/test_naming.py index 27ab159d5f..0e9bac8c11 100644 --- a/tests/asyncapi/redis/v2_6_0/test_naming.py +++ b/tests/asyncapi/redis/v2_6_0/test_naming.py @@ -1,8 +1,7 @@ import pytest -from faststream import FastStream from faststream.redis import RedisBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.naming import NamingTestCase @@ -15,7 +14,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert schema == { "asyncapi": "2.6.0", @@ -71,8 +70,8 @@ def test_subscribers_variations(self, args): @broker.subscriber(**args) async def handle(): ... - schema = get_app_schema(FastStream(broker)) - assert list(schema.channels.keys()) == ["test:Handle"] + schema = AsyncAPI(broker) + assert list(schema.jsonable()["channels"].keys()) == ["test:Handle"] @pytest.mark.parametrize( "args", @@ -88,5 +87,5 @@ def test_publisher_variations(self, args): @broker.publisher(**args) async def handle(): ... - schema = get_app_schema(FastStream(broker)) - assert list(schema.channels.keys()) == ["test:Publisher"] + schema = AsyncAPI(broker) + assert list(schema.jsonable()["channels"].keys()) == ["test:Publisher"] diff --git a/tests/asyncapi/redis/v2_6_0/test_publisher.py b/tests/asyncapi/redis/v2_6_0/test_publisher.py index aa58433d67..49a9e2bfcf 100644 --- a/tests/asyncapi/redis/v2_6_0/test_publisher.py +++ b/tests/asyncapi/redis/v2_6_0/test_publisher.py @@ -1,5 +1,5 @@ from faststream.redis import RedisBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase @@ -12,7 +12,7 @@ def test_channel_publisher(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -29,7 +29,7 @@ def test_list_publisher(self): @broker.publisher(list="test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -42,7 +42,7 @@ def test_stream_publisher(self): @broker.publisher(stream="test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/redis/v2_6_0/test_router.py b/tests/asyncapi/redis/v2_6_0/test_router.py index 2659495141..118be716c3 100644 --- a/tests/asyncapi/redis/v2_6_0/test_router.py +++ b/tests/asyncapi/redis/v2_6_0/test_router.py @@ -1,6 +1,5 @@ -from faststream import FastStream from faststream.redis import RedisBroker, RedisPublisher, RedisRoute, RedisRouter -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v2_6_0.router import RouterTestcase @@ -22,7 +21,7 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert schema == { "asyncapi": "2.6.0", @@ -77,7 +76,7 @@ class TestRouterArguments(ArgumentsTestcase): def build_app(self, router): broker = RedisBroker() broker.include_router(router) - return FastStream(broker) + return broker class TestRouterPublisher(PublisherTestcase): @@ -86,4 +85,4 @@ class TestRouterPublisher(PublisherTestcase): def build_app(self, router): broker = RedisBroker() broker.include_router(router) - return FastStream(broker) + return broker diff --git a/tests/asyncapi/redis/v2_6_0/test_security.py b/tests/asyncapi/redis/v2_6_0/test_security.py index bab9619160..cfef5f9a58 100644 --- a/tests/asyncapi/redis/v2_6_0/test_security.py +++ b/tests/asyncapi/redis/v2_6_0/test_security.py @@ -1,12 +1,11 @@ import ssl -from faststream.app import FastStream from faststream.redis import RedisBroker from faststream.security import ( BaseSecurity, SASLPlaintext, ) -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI def test_base_security_schema(): @@ -19,7 +18,7 @@ def test_base_security_schema(): broker.url == "rediss://localhost:6379/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert schema == { "asyncapi": "2.6.0", @@ -53,7 +52,7 @@ def test_plaintext_security_schema(): broker.url == "redis://localhost:6379/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert schema == { "asyncapi": "2.6.0", @@ -88,7 +87,7 @@ def test_plaintext_security_schema_without_ssl(): broker.url == "redis://localhost:6379/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = get_app_schema(FastStream(broker), version="2.6.0").to_jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/redis/v3_0_0/test_arguments.py b/tests/asyncapi/redis/v3_0_0/test_arguments.py index 52bb000b72..4d230d259b 100644 --- a/tests/asyncapi/redis/v3_0_0/test_arguments.py +++ b/tests/asyncapi/redis/v3_0_0/test_arguments.py @@ -1,5 +1,5 @@ from faststream.redis import RedisBroker, StreamSub -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v3_0_0.arguments import ArgumentsTestcase @@ -12,7 +12,7 @@ def test_channel_subscriber(self): @broker.subscriber("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -29,7 +29,7 @@ def test_channel_pattern_subscriber(self): @broker.subscriber("test.{path}") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -46,7 +46,7 @@ def test_list_subscriber(self): @broker.subscriber(list="test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -59,7 +59,7 @@ def test_stream_subscriber(self): @broker.subscriber(stream="test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -72,7 +72,7 @@ def test_stream_group_subscriber(self): @broker.subscriber(stream=StreamSub("test", group="group", consumer="consumer")) async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/redis/v3_0_0/test_connection.py b/tests/asyncapi/redis/v3_0_0/test_connection.py index 02a6082808..ec0390d425 100644 --- a/tests/asyncapi/redis/v3_0_0/test_connection.py +++ b/tests/asyncapi/redis/v3_0_0/test_connection.py @@ -1,22 +1,19 @@ -from faststream import FastStream from faststream.redis import RedisBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from faststream.specification.schema.tag import Tag def test_base(): - schema = get_app_schema( - FastStream( - RedisBroker( - "redis://localhost:6379", - protocol="plaintext", - protocol_version="0.9.0", - description="Test description", - tags=(Tag(name="some-tag", description="experimental"),), - ), + schema = AsyncAPI( + RedisBroker( + "redis://localhost:6379", + protocol="plaintext", + protocol_version="0.9.0", + description="Test description", + tags=(Tag(name="some-tag", description="experimental"),), ), - version="3.0.0", - ).to_jsonable() + schema_version="3.0.0", + ).jsonable() assert schema == { "asyncapi": "3.0.0", @@ -39,14 +36,12 @@ def test_base(): def test_custom(): - schema = get_app_schema( - FastStream( - RedisBroker( - "redis://localhost:6379", specification_url="rediss://127.0.0.1:8000" - ), + schema = AsyncAPI( + RedisBroker( + "redis://localhost:6379", specification_url="rediss://127.0.0.1:8000" ), - version="3.0.0", - ).to_jsonable() + schema_version="3.0.0", + ).jsonable() assert schema == { "asyncapi": "3.0.0", diff --git a/tests/asyncapi/redis/v3_0_0/test_fastapi.py b/tests/asyncapi/redis/v3_0_0/test_fastapi.py index d7a4b9bac2..fc75b0f092 100644 --- a/tests/asyncapi/redis/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/redis/v3_0_0/test_fastapi.py @@ -6,7 +6,7 @@ class TestRouterArguments(FastAPITestCase, FastAPICompatible): - broker_factory = staticmethod(lambda: RedisRouter()) + broker_factory = staticmethod(lambda: RedisRouter().broker) router_factory = RedisRouter broker_wrapper = staticmethod(TestRedisBroker) @@ -15,7 +15,7 @@ def build_app(self, router): class TestRouterPublisher(PublisherTestcase): - broker_factory = staticmethod(lambda: RedisRouter()) + broker_factory = staticmethod(lambda: RedisRouter().broker) def build_app(self, router): return router diff --git a/tests/asyncapi/redis/v3_0_0/test_naming.py b/tests/asyncapi/redis/v3_0_0/test_naming.py index 421a9ff194..64d448660c 100644 --- a/tests/asyncapi/redis/v3_0_0/test_naming.py +++ b/tests/asyncapi/redis/v3_0_0/test_naming.py @@ -1,8 +1,7 @@ import pytest -from faststream import FastStream from faststream.redis import RedisBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v3_0_0.naming import NamingTestCase @@ -15,10 +14,10 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = get_app_schema( - FastStream(broker), - version="3.0.0", - ).to_jsonable() + schema = AsyncAPI( + broker, + schema_version="3.0.0", + ).jsonable() assert schema == { "asyncapi": "3.0.0", @@ -89,8 +88,8 @@ def test_subscribers_variations(self, args): @broker.subscriber(**args) async def handle(): ... - schema = get_app_schema(FastStream(broker)) - assert list(schema.channels.keys()) == ["test:Handle"] + schema = AsyncAPI(broker) + assert list(schema.jsonable()["channels"].keys()) == ["test:Handle"] @pytest.mark.parametrize( "args", @@ -106,5 +105,5 @@ def test_publisher_variations(self, args): @broker.publisher(**args) async def handle(): ... - schema = get_app_schema(FastStream(broker)) - assert list(schema.channels.keys()) == ["test:Publisher"] + schema = AsyncAPI(broker) + assert list(schema.jsonable()["channels"].keys()) == ["test:Publisher"] diff --git a/tests/asyncapi/redis/v3_0_0/test_publisher.py b/tests/asyncapi/redis/v3_0_0/test_publisher.py index de00df470f..df8b5783e1 100644 --- a/tests/asyncapi/redis/v3_0_0/test_publisher.py +++ b/tests/asyncapi/redis/v3_0_0/test_publisher.py @@ -1,5 +1,5 @@ from faststream.redis import RedisBroker -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v3_0_0.publisher import PublisherTestcase @@ -12,7 +12,7 @@ def test_channel_publisher(self): @broker.publisher("test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -29,7 +29,7 @@ def test_list_publisher(self): @broker.publisher(list="test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -42,7 +42,7 @@ def test_stream_publisher(self): @broker.publisher(stream="test") async def handle(msg): ... - schema = get_app_schema(self.build_app(broker), version="3.0.0").to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/redis/v3_0_0/test_router.py b/tests/asyncapi/redis/v3_0_0/test_router.py index f060ff537f..8582be3142 100644 --- a/tests/asyncapi/redis/v3_0_0/test_router.py +++ b/tests/asyncapi/redis/v3_0_0/test_router.py @@ -1,6 +1,5 @@ -from faststream import FastStream from faststream.redis import RedisBroker, RedisPublisher, RedisRoute, RedisRouter -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI from tests.asyncapi.base.v2_6_0.arguments import ArgumentsTestcase from tests.asyncapi.base.v2_6_0.publisher import PublisherTestcase from tests.asyncapi.base.v3_0_0.router import RouterTestcase @@ -22,10 +21,10 @@ async def handle(msg): ... broker.include_router(router) - schema = get_app_schema( - FastStream(broker), - version="3.0.0", - ).to_jsonable() + schema = AsyncAPI( + broker, + schema_version="3.0.0", + ).jsonable() assert schema == { "info": {"title": "FastStream", "version": "0.1.0", "description": ""}, @@ -93,7 +92,7 @@ class TestRouterArguments(ArgumentsTestcase): def build_app(self, router): broker = RedisBroker() broker.include_router(router) - return FastStream(broker) + return broker class TestRouterPublisher(PublisherTestcase): @@ -102,4 +101,4 @@ class TestRouterPublisher(PublisherTestcase): def build_app(self, router): broker = RedisBroker() broker.include_router(router) - return FastStream(broker) + return broker diff --git a/tests/asyncapi/redis/v3_0_0/test_security.py b/tests/asyncapi/redis/v3_0_0/test_security.py index 27af74de6c..bb28b5e61c 100644 --- a/tests/asyncapi/redis/v3_0_0/test_security.py +++ b/tests/asyncapi/redis/v3_0_0/test_security.py @@ -1,12 +1,11 @@ import ssl -from faststream.app import FastStream from faststream.redis import RedisBroker from faststream.security import ( BaseSecurity, SASLPlaintext, ) -from faststream.specification.asyncapi.generate import get_app_schema +from faststream.specification.asyncapi import AsyncAPI def test_base_security_schema(): @@ -19,10 +18,10 @@ def test_base_security_schema(): broker.url == "rediss://localhost:6379/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = get_app_schema( - FastStream(broker), - version="3.0.0", - ).to_jsonable() + schema = AsyncAPI( + broker, + schema_version="3.0.0", + ).jsonable() assert schema == { "asyncapi": "3.0.0", @@ -58,10 +57,10 @@ def test_plaintext_security_schema(): broker.url == "redis://localhost:6379/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = get_app_schema( - FastStream(broker), - version="3.0.0", - ).to_jsonable() + schema = AsyncAPI( + broker, + schema_version="3.0.0", + ).jsonable() assert schema == { "asyncapi": "3.0.0", @@ -98,10 +97,10 @@ def test_plaintext_security_schema_without_ssl(): broker.url == "redis://localhost:6379/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = get_app_schema( - FastStream(broker), - version="3.0.0", - ).to_jsonable() + schema = AsyncAPI( + broker, + schema_version="3.0.0", + ).jsonable() assert schema == { "asyncapi": "3.0.0", diff --git a/tests/cli/utils/test_imports.py b/tests/cli/utils/test_imports.py index ebac2be5b5..d2496cee3a 100644 --- a/tests/cli/utils/test_imports.py +++ b/tests/cli/utils/test_imports.py @@ -4,7 +4,7 @@ from typer import BadParameter from faststream._internal.cli.utils.imports import ( - get_app_path, + get_obj_path, import_from_string, import_object, ) @@ -13,7 +13,7 @@ def test_import_wrong(): - dir, app = get_app_path("tests:test_object") + dir, app = get_obj_path("tests:test_object") with pytest.raises(FileNotFoundError): import_object(dir, app) @@ -36,14 +36,14 @@ def test_import_wrong(): ), ) def test_get_app_path(test_input, exp_module, exp_app): - dir, app = get_app_path(test_input) + dir, app = get_obj_path(test_input) assert app == exp_app assert dir == Path.cwd() / exp_module def test_get_app_path_wrong(): - with pytest.raises(ValueError, match="`module.app` is not a FastStream"): - get_app_path("module.app") + with pytest.raises(ValueError, match="`module.app` is not a path to object"): + get_obj_path("module.app") def test_import_from_string_import_wrong(): diff --git a/tests/conftest.py b/tests/conftest.py index 43c39a2cde..a032b1be2d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -61,4 +61,4 @@ def context(): @pytest.fixture def kafka_basic_project(): - return "docs.docs_src.kafka.basic.basic:app" + return "docs.docs_src.kafka.basic.basic:asyncapi" From 199b3f43822d4b63796eb315c65f9c9ce7b794ed Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Tue, 1 Oct 2024 23:51:31 +0300 Subject: [PATCH 173/245] refactor: change AsyncAPI inheritance tree --- faststream/_internal/application.py | 117 +++++++----------- faststream/_internal/cli/docs/app.py | 16 +-- faststream/_internal/fastapi/router.py | 9 +- faststream/_internal/publisher/proto.py | 4 +- faststream/_internal/subscriber/proto.py | 4 +- faststream/_internal/testing/app.py | 16 +-- faststream/asgi/app.py | 5 - faststream/asgi/factories.py | 12 +- faststream/redis/schemas/proto.py | 4 +- faststream/specification/__init__.py | 10 ++ faststream/specification/asyncapi/__init__.py | 2 - .../specification/asyncapi/base/__init__.py | 5 - .../specification/asyncapi/base/asyncapi.py | 18 --- .../asyncapi/base/schema/__init__.py | 7 -- .../asyncapi/base/schema/schema.py | 48 ------- faststream/specification/asyncapi/factory.py | 57 +++++---- faststream/specification/asyncapi/site.py | 12 +- .../specification/asyncapi/v2_6_0/facade.py | 88 +++++-------- .../specification/asyncapi/v2_6_0/generate.py | 24 ++-- .../asyncapi/v2_6_0/schema/bindings/sqs.py | 50 -------- .../asyncapi/v2_6_0/schema/info.py | 3 +- .../asyncapi/v2_6_0/schema/schema.py | 11 +- .../specification/asyncapi/v3_0_0/facade.py | 88 +++++-------- .../specification/asyncapi/v3_0_0/generate.py | 32 +++-- .../v3_0_0/schema/bindings/amqp/channel.py | 2 - .../v3_0_0/schema/bindings/amqp/operation.py | 5 +- .../asyncapi/v3_0_0/schema/info.py | 3 +- .../asyncapi/v3_0_0/schema/schema.py | 11 +- faststream/specification/base/__init__.py | 0 .../{asyncapi/base/schema => base}/info.py | 6 +- faststream/specification/base/proto.py | 48 +++++++ .../specification/{schema => base}/schema.py | 6 +- .../specification/base/specification.py | 17 +++ faststream/specification/proto.py | 84 ------------- faststream/specification/schema/__init__.py | 9 ++ .../specification/schema/bindings/main.py | 2 - faststream/specification/schema/channel.py | 1 - faststream/specification/schema/components.py | 1 - faststream/specification/schema/contact.py | 4 +- faststream/specification/schema/docs.py | 2 - faststream/specification/schema/info.py | 1 - faststream/specification/schema/license.py | 2 - faststream/specification/schema/message.py | 2 - faststream/specification/schema/operation.py | 1 - faststream/specification/schema/security.py | 3 - faststream/specification/schema/servers.py | 6 - .../asyncapi_customization/test_basic.py | 2 +- .../asyncapi_customization/test_broker.py | 2 +- .../asyncapi_customization/test_handler.py | 2 +- .../asyncapi_customization/test_info.py | 2 +- .../asyncapi_customization/test_payload.py | 2 +- tests/a_docs/rabbit/test_security.py | 4 +- tests/a_docs/redis/test_security.py | 4 +- tests/asyncapi/base/v2_6_0/arguments.py | 44 +++---- tests/asyncapi/base/v2_6_0/fastapi.py | 4 +- tests/asyncapi/base/v2_6_0/naming.py | 36 +++--- tests/asyncapi/base/v2_6_0/publisher.py | 16 +-- tests/asyncapi/base/v2_6_0/router.py | 18 +-- tests/asyncapi/base/v3_0_0/arguments.py | 44 +++---- tests/asyncapi/base/v3_0_0/fastapi.py | 8 +- tests/asyncapi/base/v3_0_0/naming.py | 37 +++--- tests/asyncapi/base/v3_0_0/publisher.py | 16 +-- tests/asyncapi/base/v3_0_0/router.py | 18 +-- .../confluent/v2_6_0/test_arguments.py | 2 +- .../confluent/v2_6_0/test_connection.py | 7 +- .../asyncapi/confluent/v2_6_0/test_fastapi.py | 3 +- .../asyncapi/confluent/v2_6_0/test_naming.py | 2 +- .../confluent/v2_6_0/test_publisher.py | 2 +- .../asyncapi/confluent/v2_6_0/test_router.py | 2 +- .../confluent/v2_6_0/test_security.py | 12 +- .../confluent/v3_0_0/test_arguments.py | 2 +- .../confluent/v3_0_0/test_connection.py | 6 +- .../asyncapi/confluent/v3_0_0/test_fastapi.py | 2 +- .../asyncapi/confluent/v3_0_0/test_naming.py | 2 +- .../confluent/v3_0_0/test_publisher.py | 2 +- .../asyncapi/confluent/v3_0_0/test_router.py | 2 +- .../confluent/v3_0_0/test_security.py | 12 +- tests/asyncapi/kafka/v2_6_0/test_app.py | 14 +-- tests/asyncapi/kafka/v2_6_0/test_arguments.py | 2 +- .../asyncapi/kafka/v2_6_0/test_connection.py | 6 +- tests/asyncapi/kafka/v2_6_0/test_fastapi.py | 3 +- tests/asyncapi/kafka/v2_6_0/test_naming.py | 2 +- tests/asyncapi/kafka/v2_6_0/test_publisher.py | 2 +- tests/asyncapi/kafka/v2_6_0/test_router.py | 2 +- tests/asyncapi/kafka/v2_6_0/test_security.py | 12 +- tests/asyncapi/kafka/v3_0_0/test_arguments.py | 2 +- .../asyncapi/kafka/v3_0_0/test_connection.py | 6 +- tests/asyncapi/kafka/v3_0_0/test_fastapi.py | 2 +- tests/asyncapi/kafka/v3_0_0/test_naming.py | 2 +- tests/asyncapi/kafka/v3_0_0/test_publisher.py | 2 +- tests/asyncapi/kafka/v3_0_0/test_router.py | 2 +- tests/asyncapi/kafka/v3_0_0/test_security.py | 12 +- tests/asyncapi/nats/v2_6_0/test_arguments.py | 2 +- tests/asyncapi/nats/v2_6_0/test_connection.py | 6 +- tests/asyncapi/nats/v2_6_0/test_fastapi.py | 1 - tests/asyncapi/nats/v2_6_0/test_kv_schema.py | 2 +- tests/asyncapi/nats/v2_6_0/test_naming.py | 2 +- tests/asyncapi/nats/v2_6_0/test_obj_schema.py | 2 +- tests/asyncapi/nats/v2_6_0/test_publisher.py | 2 +- tests/asyncapi/nats/v2_6_0/test_router.py | 2 +- tests/asyncapi/nats/v3_0_0/test_arguments.py | 2 +- tests/asyncapi/nats/v3_0_0/test_connection.py | 6 +- tests/asyncapi/nats/v3_0_0/test_kv_schema.py | 2 +- tests/asyncapi/nats/v3_0_0/test_naming.py | 2 +- tests/asyncapi/nats/v3_0_0/test_obj_schema.py | 2 +- tests/asyncapi/nats/v3_0_0/test_publisher.py | 2 +- tests/asyncapi/nats/v3_0_0/test_router.py | 2 +- .../asyncapi/rabbit/v2_6_0/test_arguments.py | 12 +- .../asyncapi/rabbit/v2_6_0/test_connection.py | 4 +- tests/asyncapi/rabbit/v2_6_0/test_fastapi.py | 3 +- tests/asyncapi/rabbit/v2_6_0/test_naming.py | 6 +- .../asyncapi/rabbit/v2_6_0/test_publisher.py | 8 +- tests/asyncapi/rabbit/v2_6_0/test_router.py | 2 +- tests/asyncapi/rabbit/v2_6_0/test_security.py | 6 +- .../asyncapi/rabbit/v3_0_0/test_arguments.py | 4 +- .../asyncapi/rabbit/v3_0_0/test_connection.py | 4 +- tests/asyncapi/rabbit/v3_0_0/test_fastapi.py | 5 +- tests/asyncapi/rabbit/v3_0_0/test_naming.py | 6 +- .../asyncapi/rabbit/v3_0_0/test_publisher.py | 8 +- tests/asyncapi/rabbit/v3_0_0/test_router.py | 2 +- tests/asyncapi/rabbit/v3_0_0/test_security.py | 6 +- tests/asyncapi/redis/v2_6_0/test_arguments.py | 10 +- .../asyncapi/redis/v2_6_0/test_connection.py | 4 +- tests/asyncapi/redis/v2_6_0/test_fastapi.py | 1 - tests/asyncapi/redis/v2_6_0/test_naming.py | 6 +- tests/asyncapi/redis/v2_6_0/test_publisher.py | 6 +- tests/asyncapi/redis/v2_6_0/test_router.py | 2 +- tests/asyncapi/redis/v2_6_0/test_security.py | 6 +- tests/asyncapi/redis/v3_0_0/test_arguments.py | 10 +- .../asyncapi/redis/v3_0_0/test_connection.py | 4 +- tests/asyncapi/redis/v3_0_0/test_naming.py | 6 +- tests/asyncapi/redis/v3_0_0/test_publisher.py | 6 +- tests/asyncapi/redis/v3_0_0/test_router.py | 2 +- tests/asyncapi/redis/v3_0_0/test_security.py | 6 +- 134 files changed, 568 insertions(+), 860 deletions(-) delete mode 100644 faststream/specification/asyncapi/base/__init__.py delete mode 100644 faststream/specification/asyncapi/base/asyncapi.py delete mode 100644 faststream/specification/asyncapi/base/schema/__init__.py delete mode 100644 faststream/specification/asyncapi/base/schema/schema.py delete mode 100644 faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs.py create mode 100644 faststream/specification/base/__init__.py rename faststream/specification/{asyncapi/base/schema => base}/info.py (77%) create mode 100644 faststream/specification/base/proto.py rename faststream/specification/{schema => base}/schema.py (91%) create mode 100644 faststream/specification/base/specification.py delete mode 100644 faststream/specification/proto.py diff --git a/faststream/_internal/application.py b/faststream/_internal/application.py index b8ef50433a..ddb7762038 100644 --- a/faststream/_internal/application.py +++ b/faststream/_internal/application.py @@ -1,5 +1,5 @@ import logging -from abc import ABC, abstractmethod +from abc import abstractmethod from contextlib import asynccontextmanager from typing import ( TYPE_CHECKING, @@ -11,7 +11,6 @@ Optional, Sequence, TypeVar, - Union, ) from typing_extensions import ParamSpec @@ -25,29 +24,51 @@ fake_context, to_async, ) -from faststream.specification.proto import SpecApplication - -P_HookParams = ParamSpec("P_HookParams") -T_HookReturn = TypeVar("T_HookReturn") - if TYPE_CHECKING: from faststream._internal.basic_types import ( - AnyDict, - AnyHttpUrl, + AnyCallable, AsyncFunc, Lifespan, LoggerProto, SettingField, ) from faststream._internal.broker.broker import BrokerUsecase - from faststream.specification.schema.contact import Contact, ContactDict - from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict - from faststream.specification.schema.license import License, LicenseDict - from faststream.specification.schema.tag import Tag, TagDict -class StartAbleApplication(ABC, SpecApplication): +try: + from pydantic import ValidationError as PValidation + + from faststream.exceptions import StartupValidationError + + @asynccontextmanager + async def catch_startup_validation_error() -> AsyncIterator[None]: + try: + yield + except PValidation as e: + missed_fields = [] + invalid_fields = [] + for x in e.errors(): + location = str(x["loc"][0]) + if x["type"] == "missing": + missed_fields.append(location) + else: + invalid_fields.append(location) + + raise StartupValidationError( + missed_fields=missed_fields, + invalid_fields=invalid_fields, + ) from e + +except ImportError: + catch_startup_validation_error = fake_context + + +P_HookParams = ParamSpec("P_HookParams") +T_HookReturn = TypeVar("T_HookReturn") + + +class StartAbleApplication: def __init__( self, broker: Optional["BrokerUsecase[Any, Any]"] = None, @@ -70,25 +91,14 @@ async def _start_broker(self) -> None: class Application(StartAbleApplication): def __init__( self, + *, broker: Optional["BrokerUsecase[Any, Any]"] = None, logger: Optional["LoggerProto"] = logger, lifespan: Optional["Lifespan"] = None, - # AsyncAPI args, - title: str = "FastStream", - version: str = "0.1.0", - description: str = "", - terms_of_service: Optional["AnyHttpUrl"] = None, - license: Optional[Union["License", "LicenseDict", "AnyDict"]] = None, - contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] = None, - tags: Optional[Sequence[Union["Tag", "TagDict", "AnyDict"]]] = None, - external_docs: Optional[ - Union["ExternalDocs", "ExternalDocsDict", "AnyDict"] - ] = None, - identifier: Optional[str] = None, - on_startup: Sequence[Callable[P_HookParams, T_HookReturn]] = (), - after_startup: Sequence[Callable[P_HookParams, T_HookReturn]] = (), - on_shutdown: Sequence[Callable[P_HookParams, T_HookReturn]] = (), - after_shutdown: Sequence[Callable[P_HookParams, T_HookReturn]] = (), + on_startup: Sequence["AnyCallable"] = (), + after_startup: Sequence["AnyCallable"] = (), + on_shutdown: Sequence["AnyCallable"] = (), + after_shutdown: Sequence["AnyCallable"] = (), ) -> None: super().__init__(broker) @@ -112,22 +122,12 @@ def __init__( if lifespan is not None: self.lifespan_context = apply_types( - func=lifespan, wrap_model=drop_response_type + func=lifespan, + wrap_model=drop_response_type, ) else: self.lifespan_context = fake_context - # AsyncAPI information - self.title = title - self.version = version - self.description = description - self.terms_of_service = terms_of_service - self.license = license - self.contact = contact - self.identifier = identifier - self.specification_tags = tags - self.external_docs = external_docs - @abstractmethod def exit(self) -> None: """Stop application manually.""" @@ -218,7 +218,10 @@ async def _shutdown_logging( self, log_level: int = logging.INFO ) -> AsyncIterator[None]: """Separated startup logging.""" - self._log(log_level, "FastStream app shutting down...") + self._log( + log_level, + "FastStream app shutting down...", + ) yield @@ -276,31 +279,3 @@ def after_shutdown( """Add hook running AFTER broker disconnected.""" self._after_shutdown_calling.append(apply_types(to_async(func))) return func - - -try: - from pydantic import ValidationError as PValidation - - from faststream.exceptions import StartupValidationError - - @asynccontextmanager - async def catch_startup_validation_error() -> AsyncIterator[None]: - try: - yield - except PValidation as e: - missed_fields = [] - invalid_fields = [] - for x in e.errors(): - location = str(x["loc"][0]) - if x["type"] == "missing": - missed_fields.append(location) - else: - invalid_fields.append(location) - - raise StartupValidationError( - missed_fields=missed_fields, - invalid_fields=invalid_fields, - ) from e - -except ImportError: - catch_startup_validation_error = fake_context diff --git a/faststream/_internal/cli/docs/app.py b/faststream/_internal/cli/docs/app.py index 29f9c3f8f3..0c6cc4e4a4 100644 --- a/faststream/_internal/cli/docs/app.py +++ b/faststream/_internal/cli/docs/app.py @@ -11,10 +11,10 @@ from faststream._internal._compat import json_dumps, model_parse from faststream._internal.cli.utils.imports import import_from_string from faststream.exceptions import INSTALL_WATCHFILES, INSTALL_YAML, SCHEMA_NOT_SUPPORTED -from faststream.specification.asyncapi import AsyncAPIProto from faststream.specification.asyncapi.site import serve_app from faststream.specification.asyncapi.v2_6_0.schema import Schema as SchemaV2_6 from faststream.specification.asyncapi.v3_0_0.schema import Schema as SchemaV3 +from faststream.specification.base.specification import Specification asyncapi_app = typer.Typer(pretty_exceptions_short=True) @@ -23,7 +23,7 @@ def serve( docs: str = typer.Argument( ..., - help="[python_module:AsyncAPIProto] or [asyncapi.yaml/.json] - path to your application or documentation.", + help="[python_module:Specification] or [asyncapi.yaml/.json] - path to your application or documentation.", ), host: str = typer.Option( "localhost", @@ -93,7 +93,7 @@ def serve( def gen( asyncapi: str = typer.Argument( ..., - help="[python_module:AsyncAPIProto] - path to your AsyncAPI object.", + help="[python_module:Specification] - path to your AsyncAPI object.", ), yaml: bool = typer.Option( False, @@ -134,9 +134,9 @@ def gen( if callable(asyncapi_obj) and is_factory: asyncapi_obj = asyncapi_obj() - assert isinstance(asyncapi_obj, AsyncAPIProto) + assert isinstance(asyncapi_obj, Specification) - raw_schema = asyncapi_obj.schema() + raw_schema = asyncapi_obj.schema if yaml: try: @@ -171,9 +171,9 @@ def _parse_and_serve( if callable(docs_obj) and is_factory: docs_obj = docs_obj() - assert isinstance(docs_obj, AsyncAPIProto) + assert isinstance(docs_obj, Specification) - raw_schema = docs_obj.schema() + raw_schema = docs_obj else: schema_filepath = Path.cwd() / docs @@ -195,7 +195,7 @@ def _parse_and_serve( else: raise ValueError( - f"Unknown extension given - {docs}; Please provide app in format [python_module:AsyncAPIProto] or [asyncapi.yaml/.json] - path to your application or documentation" + f"Unknown extension given - {docs}; Please provide app in format [python_module:Specification] or [asyncapi.yaml/.json] - path to your application or documentation" ) for schema in (SchemaV3, SchemaV2_6): diff --git a/faststream/_internal/fastapi/router.py b/faststream/_internal/fastapi/router.py index 3d57432bdc..7790831fe7 100644 --- a/faststream/_internal/fastapi/router.py +++ b/faststream/_internal/fastapi/router.py @@ -62,7 +62,7 @@ from faststream._internal.subscriber.call_wrapper.call import HandlerCallWrapper from faststream._internal.types import BrokerMiddleware from faststream.message import StreamMessage - from faststream.specification.asyncapi.base.schema import BaseSchema + from faststream.specification.base.specification import Specification from faststream.specification.schema.tag import Tag, TagDict @@ -96,7 +96,7 @@ class StreamRouter( docs_router: Optional[APIRouter] _after_startup_hooks: List[Callable[[Any], Awaitable[Optional[Mapping[str, Any]]]]] _on_shutdown_hooks: List[Callable[[Any], Awaitable[None]]] - schema: Optional["BaseSchema"] + schema: Optional["Specification"] title: str description: str @@ -312,8 +312,8 @@ async def start_broker_lifespan( app_version=self.version, contact=self.contact, license=self.license, - schema_version="3.0.0" - ).schema() + schema_version="3.0.0", + ) app.include_router(self.docs_router) @@ -475,7 +475,6 @@ def serve_asyncapi_schema( schemas=schemas, errors=errors, expand_message_examples=expandMessageExamples, - title=self.schema.info.title, ) ) diff --git a/faststream/_internal/publisher/proto.py b/faststream/_internal/publisher/proto.py index 9707fd6c12..26a6633fe2 100644 --- a/faststream/_internal/publisher/proto.py +++ b/faststream/_internal/publisher/proto.py @@ -5,7 +5,7 @@ from faststream._internal.proto import Endpoint from faststream._internal.types import MsgType -from faststream.specification.proto import SpecificationProto +from faststream.specification.base.proto import EndpointProto if TYPE_CHECKING: from faststream._internal.basic_types import SendableMessage @@ -72,7 +72,7 @@ async def request( class PublisherProto( - SpecificationProto, + EndpointProto, Endpoint, BasePublisherProto, Generic[MsgType], diff --git a/faststream/_internal/subscriber/proto.py b/faststream/_internal/subscriber/proto.py index 1fefc25817..c82843b93c 100644 --- a/faststream/_internal/subscriber/proto.py +++ b/faststream/_internal/subscriber/proto.py @@ -6,7 +6,7 @@ from faststream._internal.proto import Endpoint from faststream._internal.subscriber.call_wrapper.proto import WrapperProto from faststream._internal.types import MsgType -from faststream.specification.proto import SpecificationProto +from faststream.specification.base.proto import EndpointProto if TYPE_CHECKING: from fast_depends.dependencies import Depends @@ -28,7 +28,7 @@ class SubscriberProto( - SpecificationProto, + EndpointProto, Endpoint, WrapperProto[MsgType], ): diff --git a/faststream/_internal/testing/app.py b/faststream/_internal/testing/app.py index 629558d13d..47b90d16bf 100644 --- a/faststream/_internal/testing/app.py +++ b/faststream/_internal/testing/app.py @@ -1,18 +1,14 @@ from contextlib import ExitStack from functools import partial -from typing import TYPE_CHECKING, Any, Dict, Optional, Type, TypeVar +from typing import TYPE_CHECKING, Dict, Optional, Type from anyio.from_thread import start_blocking_portal -from faststream._internal.broker.broker import BrokerUsecase - if TYPE_CHECKING: from types import TracebackType + from faststream._internal.application import Application from faststream._internal.basic_types import SettingField - from faststream.app import FastStream - -Broker = TypeVar("Broker", bound=BrokerUsecase[Any, Any]) class TestApp: @@ -20,18 +16,18 @@ class TestApp: __test__ = False - app: "FastStream" + app: "Application" _extra_options: Dict[str, "SettingField"] def __init__( self, - app: "FastStream", + app: "Application", run_extra_options: Optional[Dict[str, "SettingField"]] = None, ) -> None: self.app = app self._extra_options = run_extra_options or {} - def __enter__(self) -> "FastStream": + def __enter__(self) -> "Application": with ExitStack() as stack: portal = stack.enter_context(start_blocking_portal()) @@ -55,7 +51,7 @@ def __exit__( ) -> None: self.exit_stack.close() - async def __aenter__(self) -> "FastStream": + async def __aenter__(self) -> "Application": self.lifespan_scope = self.app.lifespan_context(**self._extra_options) await self.lifespan_scope.__aenter__() await self.app.start(**self._extra_options) diff --git a/faststream/asgi/app.py b/faststream/asgi/app.py index 2c74344d79..7a3c1d3763 100644 --- a/faststream/asgi/app.py +++ b/faststream/asgi/app.py @@ -19,7 +19,6 @@ from faststream._internal._compat import HAS_TYPER, ExceptionGroup from faststream._internal.application import Application from faststream._internal.log import logger -from faststream.asgi.factories import make_asyncapi_asgi from faststream.asgi.response import AsgiResponse from faststream.asgi.websocket import WebSocketClose from faststream.exceptions import StartupValidationError @@ -82,7 +81,6 @@ def __init__( broker: Optional["BrokerUsecase[Any, Any]"] = None, /, asgi_routes: Sequence[Tuple[str, "ASGIApp"]] = (), - asyncapi_path: Optional[str] = None, # regular broker args logger: Optional["LoggerProto"] = logger, lifespan: Optional["Lifespan"] = None, @@ -106,9 +104,6 @@ def __init__( self._server = OuterRunState() - if asyncapi_path: - self.mount(asyncapi_path, make_asyncapi_asgi(self)) - @classmethod def from_app( cls, diff --git a/faststream/asgi/factories.py b/faststream/asgi/factories.py index f86a66e342..3fa238ef1b 100644 --- a/faststream/asgi/factories.py +++ b/faststream/asgi/factories.py @@ -6,7 +6,6 @@ from faststream.asgi.handlers import get from faststream.asgi.response import AsgiResponse -from faststream.specification.asyncapi import AsyncAPI from faststream.specification.asyncapi.site import ( ASYNCAPI_CSS_DEFAULT_URL, ASYNCAPI_JS_DEFAULT_URL, @@ -16,7 +15,7 @@ if TYPE_CHECKING: from faststream._internal.broker.broker import BrokerUsecase from faststream.asgi.types import ASGIApp, Scope - from faststream.specification.proto import SpecApplication + from faststream.specification.base.specification import Specification def make_ping_asgi( @@ -38,7 +37,7 @@ async def ping(scope: "Scope") -> AsgiResponse: def make_asyncapi_asgi( - app: "SpecApplication", + schema: "Specification", sidebar: bool = True, info: bool = True, servers: bool = True, @@ -47,16 +46,12 @@ def make_asyncapi_asgi( schemas: bool = True, errors: bool = True, expand_message_examples: bool = True, - title: str = "FastStream", asyncapi_js_url: str = ASYNCAPI_JS_DEFAULT_URL, asyncapi_css_url: str = ASYNCAPI_CSS_DEFAULT_URL, ) -> "ASGIApp": - if app.broker is None: - raise RuntimeError() - return AsgiResponse( get_asyncapi_html( - AsyncAPI(app.broker, schema_version="2.6.0").schema(), + schema, sidebar=sidebar, info=info, servers=servers, @@ -65,7 +60,6 @@ def make_asyncapi_asgi( schemas=schemas, errors=errors, expand_message_examples=expand_message_examples, - title=title, asyncapi_js_url=asyncapi_js_url, asyncapi_css_url=asyncapi_css_url, ).encode("utf-8"), diff --git a/faststream/redis/schemas/proto.py b/faststream/redis/schemas/proto.py index c130e07a23..0a64d4dd7f 100644 --- a/faststream/redis/schemas/proto.py +++ b/faststream/redis/schemas/proto.py @@ -2,14 +2,14 @@ from typing import TYPE_CHECKING, Any, Union from faststream.exceptions import SetupError -from faststream.specification.proto import SpecificationProto +from faststream.specification.base.proto import EndpointProto if TYPE_CHECKING: from faststream.redis.schemas import ListSub, PubSub, StreamSub from faststream.specification.schema.bindings import redis -class RedisAsyncAPIProtocol(SpecificationProto): +class RedisAsyncAPIProtocol(EndpointProto): @property @abstractmethod def channel_binding(self) -> "redis.ChannelBinding": ... diff --git a/faststream/specification/__init__.py b/faststream/specification/__init__.py index e69de29bb2..6eac804761 100644 --- a/faststream/specification/__init__.py +++ b/faststream/specification/__init__.py @@ -0,0 +1,10 @@ +from .asyncapi.factory import AsyncAPI +from .schema import Contact, ExternalDocs, License, Tag + +__all__ = ( + "AsyncAPI", + "ExternalDocs", + "Contact", + "License", + "Tag", +) diff --git a/faststream/specification/asyncapi/__init__.py b/faststream/specification/asyncapi/__init__.py index 533c3f0784..fe93b5941d 100644 --- a/faststream/specification/asyncapi/__init__.py +++ b/faststream/specification/asyncapi/__init__.py @@ -2,11 +2,9 @@ from faststream.specification.asyncapi.site import get_asyncapi_html -from .base import AsyncAPIProto from .factory import AsyncAPI __all__ = ( - "AsyncAPIProto", "AsyncAPI", "get_asyncapi_html", ) diff --git a/faststream/specification/asyncapi/base/__init__.py b/faststream/specification/asyncapi/base/__init__.py deleted file mode 100644 index 5ca8980715..0000000000 --- a/faststream/specification/asyncapi/base/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from .asyncapi import AsyncAPIProto - -__all__ = ( - "AsyncAPIProto", -) diff --git a/faststream/specification/asyncapi/base/asyncapi.py b/faststream/specification/asyncapi/base/asyncapi.py deleted file mode 100644 index e9ef2a9334..0000000000 --- a/faststream/specification/asyncapi/base/asyncapi.py +++ /dev/null @@ -1,18 +0,0 @@ -from typing import Any, Protocol, runtime_checkable - -from faststream.specification.asyncapi.base.schema import BaseSchema - - -@runtime_checkable -class AsyncAPIProto(Protocol): - def json(self) -> str: - ... - - def jsonable(self) -> Any: - ... - - def yaml(self) -> str: - ... - - def schema(self) -> BaseSchema: - ... diff --git a/faststream/specification/asyncapi/base/schema/__init__.py b/faststream/specification/asyncapi/base/schema/__init__.py deleted file mode 100644 index 99107ebd15..0000000000 --- a/faststream/specification/asyncapi/base/schema/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from .info import BaseInfo -from .schema import BaseSchema - -__all__ = ( - "BaseSchema", - "BaseInfo", -) diff --git a/faststream/specification/asyncapi/base/schema/schema.py b/faststream/specification/asyncapi/base/schema/schema.py deleted file mode 100644 index ed8b51c075..0000000000 --- a/faststream/specification/asyncapi/base/schema/schema.py +++ /dev/null @@ -1,48 +0,0 @@ -from typing import Any - -from pydantic import BaseModel - -from faststream._internal._compat import model_to_json, model_to_jsonable -from faststream.specification.asyncapi.base.schema.info import BaseInfo - - -class BaseSchema(BaseModel): - """A class to represent a schema. - - Attributes: - info : information about the schema - - Methods: - to_jsonable() -> Any: Convert the schema to a JSON-serializable object. - to_json() -> str: Convert the schema to a JSON string. - to_yaml() -> str: Convert the schema to a YAML string. - - """ - - info: BaseInfo - - def to_jsonable(self) -> Any: - """Convert the schema to a JSON-serializable object.""" - return model_to_jsonable( - self, - by_alias=True, - exclude_none=True, - ) - - def to_json(self) -> str: - """Convert the schema to a JSON string.""" - return model_to_json( - self, - by_alias=True, - exclude_none=True, - ) - - def to_yaml(self) -> str: - """Convert the schema to a YAML string.""" - from io import StringIO - - import yaml - - io = StringIO(initial_value="", newline="\n") - yaml.dump(self.to_jsonable(), io, sort_keys=False) - return io.getvalue() diff --git a/faststream/specification/asyncapi/factory.py b/faststream/specification/asyncapi/factory.py index 0d113d6d0c..d563f8327b 100644 --- a/faststream/specification/asyncapi/factory.py +++ b/faststream/specification/asyncapi/factory.py @@ -1,35 +1,37 @@ from typing import TYPE_CHECKING, Any, Literal, Optional, Sequence, Union -from faststream._internal.broker.broker import BrokerUsecase -from faststream.specification.asyncapi.base.asyncapi import AsyncAPIProto -from faststream.specification.asyncapi.base.schema import BaseSchema -from faststream.specification.asyncapi.v2_6_0.facade import AsyncAPI2 -from faststream.specification.asyncapi.v3_0_0.facade import AsyncAPI3 +from faststream.specification.base.specification import Specification + +from .v2_6_0.facade import AsyncAPI2 +from .v3_0_0.facade import AsyncAPI3 if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict, AnyHttpUrl + from faststream._internal.broker.broker import BrokerUsecase from faststream.specification.schema.contact import Contact, ContactDict from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict from faststream.specification.schema.license import License, LicenseDict from faststream.specification.schema.tag import Tag, TagDict -class AsyncAPI(AsyncAPIProto): +class AsyncAPI(Specification): def __new__( # type: ignore[misc] - cls, - broker: BrokerUsecase[Any, Any], - /, - title: str = "FastStream", - app_version: str = "0.1.0", - schema_version: Union[Literal["3.0.0", "2.6.0"], str] = "3.0.0", - description: str = "", - terms_of_service: Optional["AnyHttpUrl"] = None, - license: Optional[Union["License", "LicenseDict", "AnyDict"]] = None, - contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] = None, - tags: Optional[Sequence[Union["Tag", "TagDict", "AnyDict"]]] = None, - external_docs: Optional[Union["ExternalDocs", "ExternalDocsDict", "AnyDict"]] = None, - identifier: Optional[str] = None, - ) -> AsyncAPIProto: + cls, + broker: "BrokerUsecase[Any, Any]", + /, + title: str = "FastStream", + app_version: str = "0.1.0", + schema_version: Union[Literal["3.0.0", "2.6.0"], str] = "3.0.0", + description: str = "", + terms_of_service: Optional["AnyHttpUrl"] = None, + license: Optional[Union["License", "LicenseDict", "AnyDict"]] = None, + contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] = None, + tags: Optional[Sequence[Union["Tag", "TagDict", "AnyDict"]]] = None, + external_docs: Optional[ + Union["ExternalDocs", "ExternalDocsDict", "AnyDict"] + ] = None, + identifier: Optional[str] = None, + ) -> Specification: if schema_version.startswith("3.0."): return AsyncAPI3( broker, @@ -61,14 +63,11 @@ def __new__( # type: ignore[misc] else: raise NotImplementedError(f"Unsupported schema version: {schema_version}") - def json(self) -> str: # type: ignore[empty-body] - pass - - def jsonable(self) -> Any: - pass + def to_json(self) -> str: + raise NotImplementedError - def yaml(self) -> str: # type: ignore[empty-body] - pass + def to_jsonable(self) -> Any: + raise NotImplementedError - def schema(self) -> BaseSchema: # type: ignore[empty-body] - pass + def to_yaml(self) -> str: + raise NotImplementedError diff --git a/faststream/specification/asyncapi/site.py b/faststream/specification/asyncapi/site.py index 92608c3615..43b7c95228 100644 --- a/faststream/specification/asyncapi/site.py +++ b/faststream/specification/asyncapi/site.py @@ -7,7 +7,7 @@ from faststream._internal.log import logger if TYPE_CHECKING: - from faststream.specification.asyncapi.base.schema import BaseSchema + from faststream.specification.base.specification import Specification ASYNCAPI_JS_DEFAULT_URL = "https://unpkg.com/@asyncapi/react-component@1.0.0-next.54/browser/standalone/index.js" @@ -18,7 +18,7 @@ def get_asyncapi_html( - schema: "BaseSchema", + schema: "Specification", sidebar: bool = True, info: bool = True, servers: bool = True, @@ -27,7 +27,6 @@ def get_asyncapi_html( schemas: bool = True, errors: bool = True, expand_message_examples: bool = True, - title: str = "FastStream", asyncapi_js_url: str = ASYNCAPI_JS_DEFAULT_URL, asyncapi_css_url: str = ASYNCAPI_CSS_DEFAULT_URL, ) -> str: @@ -63,7 +62,7 @@ def get_asyncapi_html( """ f""" - {title} AsyncAPI + {schema.schema.info.title} AsyncAPI """ """ @@ -103,7 +102,7 @@ def get_asyncapi_html( def serve_app( - schema: "BaseSchema", + schema: "Specification", host: str, port: int, ) -> None: @@ -121,7 +120,7 @@ class _Handler(server.BaseHTTPRequestHandler): def __init__( self, *args: Any, - schema: "BaseSchema", + schema: "Specification", **kwargs: Any, ) -> None: self.schema = schema @@ -148,7 +147,6 @@ def do_GET(self) -> None: # noqa: N802 schemas=query_dict.get("schemas", True), errors=query_dict.get("errors", True), expand_message_examples=query_dict.get("expandMessageExamples", True), - title=self.schema.info.title, ) body = html.encode(encoding=encoding) diff --git a/faststream/specification/asyncapi/v2_6_0/facade.py b/faststream/specification/asyncapi/v2_6_0/facade.py index 6316fe72a2..daa90684b9 100644 --- a/faststream/specification/asyncapi/v2_6_0/facade.py +++ b/faststream/specification/asyncapi/v2_6_0/facade.py @@ -1,33 +1,36 @@ from typing import TYPE_CHECKING, Any, Optional, Sequence, Union -from faststream._internal.broker.broker import BrokerUsecase -from faststream.specification.asyncapi.base.asyncapi import AsyncAPIProto -from faststream.specification.asyncapi.v2_6_0.generate import get_app_schema -from faststream.specification.asyncapi.v2_6_0.schema import Schema +from faststream.specification.base.specification import Specification + +from .generate import get_app_schema +from .schema import Schema if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict, AnyHttpUrl + from faststream._internal.broker.broker import BrokerUsecase from faststream.specification.schema.contact import Contact, ContactDict from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict from faststream.specification.schema.license import License, LicenseDict from faststream.specification.schema.tag import Tag, TagDict -class AsyncAPI2(AsyncAPIProto): +class AsyncAPI2(Specification): def __init__( - self, - broker: BrokerUsecase[Any, Any], - /, - title: str = "FastStream", - app_version: str = "0.1.0", - schema_version: str = "3.0.0", - description: str = "", - terms_of_service: Optional["AnyHttpUrl"] = None, - contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] = None, - license: Optional[Union["License", "LicenseDict", "AnyDict"]] = None, - identifier: Optional[str] = None, - tags: Optional[Sequence[Union["Tag", "TagDict", "AnyDict"]]] = None, - external_docs: Optional[Union["ExternalDocs", "ExternalDocsDict", "AnyDict"]] = None, + self, + broker: "BrokerUsecase[Any, Any]", + /, + title: str = "FastStream", + app_version: str = "0.1.0", + schema_version: str = "3.0.0", + description: str = "", + terms_of_service: Optional["AnyHttpUrl"] = None, + contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] = None, + license: Optional[Union["License", "LicenseDict", "AnyDict"]] = None, + identifier: Optional[str] = None, + tags: Optional[Sequence[Union["Tag", "TagDict", "AnyDict"]]] = None, + external_docs: Optional[ + Union["ExternalDocs", "ExternalDocsDict", "AnyDict"] + ] = None, ) -> None: self.broker = broker self.title = title @@ -41,51 +44,16 @@ def __init__( self.tags = tags self.external_docs = external_docs - def json(self) -> str: - return get_app_schema( - self.broker, - title=self.title, - app_version=self.app_version, - schema_version=self.schema_version, - description=self.description, - terms_of_service=self.terms_of_service, - contact=self.contact, - license=self.license, - identifier=self.identifier, - tags=self.tags, - external_docs=self.external_docs, - ).to_json() + def to_json(self) -> str: + return self.schema.to_json() - def jsonable(self) -> Any: - return get_app_schema( - self.broker, - title=self.title, - app_version=self.app_version, - schema_version=self.schema_version, - description=self.description, - terms_of_service=self.terms_of_service, - contact=self.contact, - license=self.license, - identifier=self.identifier, - tags=self.tags, - external_docs=self.external_docs, - ).to_jsonable() + def to_jsonable(self) -> Any: + return self.schema.to_jsonable() - def yaml(self) -> str: - return get_app_schema( - self.broker, - title=self.title, - app_version=self.app_version, - schema_version=self.schema_version, - description=self.description, - terms_of_service=self.terms_of_service, - contact=self.contact, - license=self.license, - identifier=self.identifier, - tags=self.tags, - external_docs=self.external_docs, - ).to_yaml() + def to_yaml(self) -> str: + return self.schema.to_yaml() + @property def schema(self) -> Schema: return get_app_schema( self.broker, diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index 9741d1992f..bb6db0c65a 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -35,18 +35,18 @@ def get_app_schema( - broker: "BrokerUsecase[Any, Any]", - /, - title: str, - app_version: str, - schema_version: str, - description: str, - terms_of_service: Optional["AnyHttpUrl"], - contact: Optional[Union["Contact", "ContactDict", "AnyDict"]], - license: Optional[Union["License", "LicenseDict", "AnyDict"]], - identifier: Optional[str], - tags: Optional[Sequence[Union["SpecsTag", "SpecsTagDict", "AnyDict"]]], - external_docs: Optional[Union["ExternalDocs", "ExternalDocsDict", "AnyDict"]], + broker: "BrokerUsecase[Any, Any]", + /, + title: str, + app_version: str, + schema_version: str, + description: str, + terms_of_service: Optional["AnyHttpUrl"], + contact: Optional[Union["Contact", "ContactDict", "AnyDict"]], + license: Optional[Union["License", "LicenseDict", "AnyDict"]], + identifier: Optional[str], + tags: Optional[Sequence[Union["SpecsTag", "SpecsTagDict", "AnyDict"]]], + external_docs: Optional[Union["ExternalDocs", "ExternalDocsDict", "AnyDict"]], ) -> Schema: """Get the application schema.""" broker._setup() diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs.py deleted file mode 100644 index 5eed3c9984..0000000000 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs.py +++ /dev/null @@ -1,50 +0,0 @@ -"""AsyncAPI SQS bindings. - -References: https://github.com/asyncapi/bindings/tree/master/sqs -""" - -from typing import Optional - -from pydantic import BaseModel -from typing_extensions import Self - -from faststream._internal.basic_types import AnyDict -from faststream.specification import schema as spec - - -class ChannelBinding(BaseModel): - """A class to represent channel binding. - - Attributes: - queue : a dictionary representing the queue - bindingVersion : a string representing the binding version (default: "custom") - """ - - queue: AnyDict - bindingVersion: str = "custom" - - @classmethod - def from_spec(cls, binding: spec.bindings.sqs.ChannelBinding) -> Self: - return cls( - queue=binding.queue, - bindingVersion=binding.bindingVersion, - ) - - -class OperationBinding(BaseModel): - """A class to represent an operation binding. - - Attributes: - replyTo : optional dictionary containing reply information - bindingVersion : version of the binding, default is "custom" - """ - - replyTo: Optional[AnyDict] = None - bindingVersion: str = "custom" - - @classmethod - def from_spec(cls, binding: spec.bindings.sqs.OperationBinding) -> Self: - return cls( - replyTo=binding.replyTo, - bindingVersion=binding.bindingVersion, - ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/info.py b/faststream/specification/asyncapi/v2_6_0/schema/info.py index 2afa9a08cd..b4cf3bceec 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/info.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/info.py @@ -6,9 +6,9 @@ from pydantic import AnyHttpUrl from faststream._internal.basic_types import AnyDict -from faststream.specification.asyncapi.base.schema import BaseInfo from faststream.specification.asyncapi.v2_6_0.schema.contact import Contact from faststream.specification.asyncapi.v2_6_0.schema.license import License +from faststream.specification.base.info import BaseInfo class Info(BaseInfo): @@ -21,7 +21,6 @@ class Info(BaseInfo): termsOfService : terms of service for the information (default: None) contact : contact information for the information (default: None) license : license information for the information (default: None) - """ termsOfService: Optional[AnyHttpUrl] = None diff --git a/faststream/specification/asyncapi/v2_6_0/schema/schema.py b/faststream/specification/asyncapi/v2_6_0/schema/schema.py index 81b29d06a2..17d9851e73 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/schema.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/schema.py @@ -1,13 +1,13 @@ from typing import Dict, List, Literal, Optional, Union from faststream._internal.basic_types import AnyDict -from faststream.specification.asyncapi.base.schema import BaseSchema from faststream.specification.asyncapi.v2_6_0.schema.channels import Channel from faststream.specification.asyncapi.v2_6_0.schema.components import Components from faststream.specification.asyncapi.v2_6_0.schema.docs import ExternalDocs from faststream.specification.asyncapi.v2_6_0.schema.info import Info from faststream.specification.asyncapi.v2_6_0.schema.servers import Server from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag +from faststream.specification.base.schema import BaseSchema class Schema(BaseSchema): @@ -23,18 +23,13 @@ class Schema(BaseSchema): components : optional components of the schema tags : optional list of tags externalDocs : optional external documentation - - Methods: - to_jsonable() -> Any: Convert the schema to a JSON-serializable object. - to_json() -> str: Convert the schema to a JSON string. - to_yaml() -> str: Convert the schema to a YAML string. - """ + info: Info + asyncapi: Union[Literal["2.6.0"], str] = "2.6.0" id: Optional[str] = None defaultContentType: Optional[str] = None - info: Info servers: Optional[Dict[str, Server]] = None channels: Dict[str, Channel] components: Optional[Components] = None diff --git a/faststream/specification/asyncapi/v3_0_0/facade.py b/faststream/specification/asyncapi/v3_0_0/facade.py index 5632edbfcf..eda740b74b 100644 --- a/faststream/specification/asyncapi/v3_0_0/facade.py +++ b/faststream/specification/asyncapi/v3_0_0/facade.py @@ -1,33 +1,36 @@ from typing import TYPE_CHECKING, Any, Optional, Sequence, Union -from faststream._internal.broker.broker import BrokerUsecase -from faststream.specification.asyncapi.base.asyncapi import AsyncAPIProto -from faststream.specification.asyncapi.v3_0_0.generate import get_app_schema -from faststream.specification.asyncapi.v3_0_0.schema import Schema +from faststream.specification.base.specification import Specification + +from .generate import get_app_schema +from .schema import Schema if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict, AnyHttpUrl + from faststream._internal.broker.broker import BrokerUsecase from faststream.specification.schema.contact import Contact, ContactDict from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict from faststream.specification.schema.license import License, LicenseDict from faststream.specification.schema.tag import Tag, TagDict -class AsyncAPI3(AsyncAPIProto): +class AsyncAPI3(Specification): def __init__( - self, - broker: BrokerUsecase[Any, Any], - /, - title: str = "FastStream", - app_version: str = "0.1.0", - schema_version: str = "3.0.0", - description: str = "", - terms_of_service: Optional["AnyHttpUrl"] = None, - contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] = None, - license: Optional[Union["License", "LicenseDict", "AnyDict"]] = None, - identifier: Optional[str] = None, - tags: Optional[Sequence[Union["Tag", "TagDict", "AnyDict"]]] = None, - external_docs: Optional[Union["ExternalDocs", "ExternalDocsDict", "AnyDict"]] = None, + self, + broker: "BrokerUsecase[Any, Any]", + /, + title: str = "FastStream", + app_version: str = "0.1.0", + schema_version: str = "3.0.0", + description: str = "", + terms_of_service: Optional["AnyHttpUrl"] = None, + contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] = None, + license: Optional[Union["License", "LicenseDict", "AnyDict"]] = None, + identifier: Optional[str] = None, + tags: Optional[Sequence[Union["Tag", "TagDict", "AnyDict"]]] = None, + external_docs: Optional[ + Union["ExternalDocs", "ExternalDocsDict", "AnyDict"] + ] = None, ) -> None: self.broker = broker self.title = title @@ -41,51 +44,16 @@ def __init__( self.tags = tags self.external_docs = external_docs - def json(self) -> str: - return get_app_schema( - self.broker, - title=self.title, - app_version=self.app_version, - schema_version=self.schema_version, - description=self.description, - terms_of_service=self.terms_of_service, - contact=self.contact, - license=self.license, - identifier=self.identifier, - tags=self.tags, - external_docs=self.external_docs, - ).to_json() + def to_json(self) -> str: + return self.schema.to_json() - def jsonable(self) -> Any: - return get_app_schema( - self.broker, - title=self.title, - app_version=self.app_version, - schema_version=self.schema_version, - description=self.description, - terms_of_service=self.terms_of_service, - contact=self.contact, - license=self.license, - identifier=self.identifier, - tags=self.tags, - external_docs=self.external_docs, - ).to_jsonable() + def to_jsonable(self) -> Any: + return self.schema.to_jsonable() - def yaml(self) -> str: - return get_app_schema( - self.broker, - title=self.title, - app_version=self.app_version, - schema_version=self.schema_version, - description=self.description, - terms_of_service=self.terms_of_service, - contact=self.contact, - license=self.license, - identifier=self.identifier, - tags=self.tags, - external_docs=self.external_docs, - ).to_yaml() + def to_yaml(self) -> str: + return self.schema.to_yaml() + @property def schema(self) -> Schema: return get_app_schema( self.broker, diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index 92d85ae016..122c74c6ec 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -44,18 +44,18 @@ def get_app_schema( - broker: "BrokerUsecase[Any, Any]", - /, - title: str, - app_version: str, - schema_version: str, - description: str, - terms_of_service: Optional["AnyHttpUrl"], - contact: Optional[Union["Contact", "ContactDict", "AnyDict"]], - license: Optional[Union["License", "LicenseDict", "AnyDict"]], - identifier: Optional[str], - tags: Optional[Sequence[Union["SpecsTag", "SpecsTagDict", "AnyDict"]]], - external_docs: Optional[Union["ExternalDocs", "ExternalDocsDict", "AnyDict"]], + broker: "BrokerUsecase[Any, Any]", + /, + title: str, + app_version: str, + schema_version: str, + description: str, + terms_of_service: Optional["AnyHttpUrl"], + contact: Optional[Union["Contact", "ContactDict", "AnyDict"]], + license: Optional[Union["License", "LicenseDict", "AnyDict"]], + identifier: Optional[str], + tags: Optional[Sequence[Union["SpecsTag", "SpecsTagDict", "AnyDict"]]], + external_docs: Optional[Union["ExternalDocs", "ExternalDocsDict", "AnyDict"]], ) -> Schema: """Get the application schema.""" broker._setup() @@ -91,12 +91,8 @@ def get_app_schema( termsOfService=terms_of_service, contact=contact_from_spec(contact) if contact else None, license=license_from_spec(license) if license else None, - tags=[tag_from_spec(tag) for tag in tags] - if tags - else None, - externalDocs=docs_from_spec(external_docs) - if external_docs - else None, + tags=[tag_from_spec(tag) for tag in tags] if tags else None, + externalDocs=docs_from_spec(external_docs) if external_docs else None, ), asyncapi=schema_version, defaultContentType=ContentTypes.json.value, diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel.py index d8d5d24cf4..2e31575e69 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel.py @@ -11,11 +11,9 @@ def from_spec(binding: spec.bindings.amqp.ChannelBinding) -> ChannelBinding: **{ "is": binding.is_, "bindingVersion": "0.3.0", - "queue": Queue.from_spec(binding.queue) if binding.queue is not None else None, - "exchange": Exchange.from_spec(binding.exchange) if binding.exchange is not None else None, diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation.py index daf172f940..5b46f630a0 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation.py @@ -32,10 +32,7 @@ class OperationBinding(BaseModel): @classmethod def from_spec(cls, binding: spec.bindings.amqp.OperationBinding) -> Self: return cls( - cc=[binding.cc] - if binding.cc is not None - else None, - + cc=[binding.cc] if binding.cc is not None else None, ack=binding.ack, replyTo=binding.replyTo, deliveryMode=binding.deliveryMode, diff --git a/faststream/specification/asyncapi/v3_0_0/schema/info.py b/faststream/specification/asyncapi/v3_0_0/schema/info.py index 23759f5b89..eaf081230d 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/info.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/info.py @@ -9,13 +9,13 @@ from faststream._internal.basic_types import ( AnyDict, ) -from faststream.specification.asyncapi.base.schema import BaseInfo from faststream.specification.asyncapi.v2_6_0.schema import ( Contact, ExternalDocs, License, Tag, ) +from faststream.specification.base.info import BaseInfo class Info(BaseInfo): @@ -27,7 +27,6 @@ class Info(BaseInfo): license : license information for the information (default: None) tags : optional list of tags externalDocs : optional external documentation - """ termsOfService: Optional[AnyHttpUrl] = None diff --git a/faststream/specification/asyncapi/v3_0_0/schema/schema.py b/faststream/specification/asyncapi/v3_0_0/schema/schema.py index ddd6413d0a..a8af859127 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/schema.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/schema.py @@ -1,11 +1,11 @@ from typing import Dict, Literal, Optional, Union -from faststream.specification.asyncapi.base.schema import BaseSchema from faststream.specification.asyncapi.v3_0_0.schema.channels import Channel from faststream.specification.asyncapi.v3_0_0.schema.components import Components from faststream.specification.asyncapi.v3_0_0.schema.info import Info from faststream.specification.asyncapi.v3_0_0.schema.operations import Operation from faststream.specification.asyncapi.v3_0_0.schema.servers import Server +from faststream.specification.base.schema import BaseSchema class Schema(BaseSchema): @@ -19,18 +19,13 @@ class Schema(BaseSchema): servers : optional dictionary of servers channels : dictionary of channels components : optional components of the schema - - Methods: - to_jsonable() -> Any: Convert the schema to a JSON-serializable object. - to_json() -> str: Convert the schema to a JSON string. - to_yaml() -> str: Convert the schema to a YAML string. - """ + info: Info + asyncapi: Union[Literal["3.0.0"], str] = "3.0.0" id: Optional[str] = None defaultContentType: Optional[str] = None - info: Info servers: Optional[Dict[str, Server]] = None channels: Dict[str, Channel] operations: Dict[str, Operation] diff --git a/faststream/specification/base/__init__.py b/faststream/specification/base/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/faststream/specification/asyncapi/base/schema/info.py b/faststream/specification/base/info.py similarity index 77% rename from faststream/specification/asyncapi/base/schema/info.py rename to faststream/specification/base/info.py index 428dcb4a86..79e5164de7 100644 --- a/faststream/specification/asyncapi/base/schema/info.py +++ b/faststream/specification/base/info.py @@ -1,12 +1,10 @@ from pydantic import BaseModel -from faststream._internal._compat import ( - PYDANTIC_V2, -) +from faststream._internal._compat import PYDANTIC_V2 class BaseInfo(BaseModel): - """A class to represent AsyncAPI application information. + """A class to represent basic application information. Attributes: title : application title diff --git a/faststream/specification/base/proto.py b/faststream/specification/base/proto.py new file mode 100644 index 0000000000..6334008773 --- /dev/null +++ b/faststream/specification/base/proto.py @@ -0,0 +1,48 @@ +from abc import abstractmethod +from typing import Any, Dict, Optional, Protocol + +from faststream.specification.schema.channel import Channel + + +class EndpointProto(Protocol): + """A class representing an asynchronous API operation.""" + + title_: Optional[str] + description_: Optional[str] + include_in_schema: bool + + @property + def name(self) -> str: + """Returns the name of the API operation.""" + return self.title_ or self.get_name() + + @abstractmethod + def get_name(self) -> str: + """Name property fallback.""" + raise NotImplementedError() + + @property + def description(self) -> Optional[str]: + """Returns the description of the API operation.""" + return self.description_ or self.get_description() + + def get_description(self) -> Optional[str]: + """Description property fallback.""" + return None + + def schema(self) -> Dict[str, Channel]: + """Returns the schema of the API operation as a dictionary of channel names and channel objects.""" + if self.include_in_schema: + return self.get_schema() + else: + return {} + + @abstractmethod + def get_schema(self) -> Dict[str, Channel]: + """Generate AsyncAPI schema.""" + raise NotImplementedError() + + @abstractmethod + def get_payloads(self) -> Any: + """Generate AsyncAPI payloads.""" + raise NotImplementedError() diff --git a/faststream/specification/schema/schema.py b/faststream/specification/base/schema.py similarity index 91% rename from faststream/specification/schema/schema.py rename to faststream/specification/base/schema.py index 6b2f5d4942..914b389bc2 100644 --- a/faststream/specification/schema/schema.py +++ b/faststream/specification/base/schema.py @@ -3,11 +3,12 @@ from pydantic import BaseModel from faststream._internal._compat import model_to_json, model_to_jsonable -from faststream.specification.asyncapi.base.schema import BaseInfo + +from .info import BaseInfo class BaseSchema(BaseModel): - """A class to represent a schema. + """A class to represent a Pydantic-serializable schema. Attributes: info : information about the schema @@ -16,7 +17,6 @@ class BaseSchema(BaseModel): to_jsonable() -> Any: Convert the schema to a JSON-serializable object. to_json() -> str: Convert the schema to a JSON string. to_yaml() -> str: Convert the schema to a YAML string. - """ info: BaseInfo diff --git a/faststream/specification/base/specification.py b/faststream/specification/base/specification.py new file mode 100644 index 0000000000..d9dc0fcf14 --- /dev/null +++ b/faststream/specification/base/specification.py @@ -0,0 +1,17 @@ +from typing import Any, Protocol, runtime_checkable + +from .schema import BaseSchema + + +@runtime_checkable +class Specification(Protocol): + schema: BaseSchema + + def to_json(self) -> str: + return self.schema.to_json() + + def to_jsonable(self) -> Any: + return self.schema.to_jsonable() + + def to_yaml(self) -> str: + return self.schema.to_yaml() diff --git a/faststream/specification/proto.py b/faststream/specification/proto.py deleted file mode 100644 index fee0970af0..0000000000 --- a/faststream/specification/proto.py +++ /dev/null @@ -1,84 +0,0 @@ -from abc import abstractmethod -from typing import TYPE_CHECKING, Any, Dict, Optional, Protocol, Sequence, Union - -from typing_extensions import Annotated, Doc - -from faststream.specification.schema.channel import Channel - -if TYPE_CHECKING: - from faststream._internal.basic_types import ( - AnyDict, - AnyHttpUrl, - ) - from faststream._internal.broker.broker import BrokerUsecase - from faststream.specification.schema.contact import Contact, ContactDict - from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict - from faststream.specification.schema.license import License, LicenseDict - from faststream.specification.schema.tag import Tag, TagDict - - -class SpecApplication(Protocol): - broker: Optional["BrokerUsecase[Any, Any]"] - - title: str - version: str - description: str - terms_of_service: Optional["AnyHttpUrl"] - license: Optional[Union["License", "LicenseDict", "AnyDict"]] - contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] - specification_tags: Optional[Sequence[Union["Tag", "TagDict", "AnyDict"]]] - external_docs: Optional[Union["ExternalDocs", "ExternalDocsDict", "AnyDict"]] - identifier: Optional[str] - - -class SpecificationProto(Protocol): - """A class representing an asynchronous API operation.""" - - title_: Annotated[ - Optional[str], - Doc("AsyncAPI object title."), - ] - description_: Annotated[ - Optional[str], - Doc("AsyncAPI object description."), - ] - include_in_schema: Annotated[ - bool, - Doc("Whatever to include operation in AsyncAPI schema or not."), - ] - - @property - def name(self) -> str: - """Returns the name of the API operation.""" - return self.title_ or self.get_name() - - @abstractmethod - def get_name(self) -> str: - """Name property fallback.""" - raise NotImplementedError() - - @property - def description(self) -> Optional[str]: - """Returns the description of the API operation.""" - return self.description_ or self.get_description() - - def get_description(self) -> Optional[str]: - """Description property fallback.""" - return None - - def schema(self) -> Dict[str, Channel]: - """Returns the schema of the API operation as a dictionary of channel names and channel objects.""" - if self.include_in_schema: - return self.get_schema() - else: - return {} - - @abstractmethod - def get_schema(self) -> Dict[str, Channel]: - """Generate AsyncAPI schema.""" - raise NotImplementedError() - - @abstractmethod - def get_payloads(self) -> Any: - """Generate AsyncAPI payloads.""" - raise NotImplementedError() diff --git a/faststream/specification/schema/__init__.py b/faststream/specification/schema/__init__.py index 4e9a9ee5be..a50f0e2a41 100644 --- a/faststream/specification/schema/__init__.py +++ b/faststream/specification/schema/__init__.py @@ -10,8 +10,17 @@ security, tag, ) +from .contact import Contact +from .docs import ExternalDocs +from .license import License +from .tag import Tag __all__ = ( + "ExternalDocs", + "License", + "Tag", + "Contact", + # module aliases "bindings", "channel", "contact", diff --git a/faststream/specification/schema/bindings/main.py b/faststream/specification/schema/bindings/main.py index 65622aaa76..3fe0e4c62f 100644 --- a/faststream/specification/schema/bindings/main.py +++ b/faststream/specification/schema/bindings/main.py @@ -18,7 +18,6 @@ class ChannelBinding: sqs : SQS channel binding (optional) nats : NATS channel binding (optional)d redis : Redis channel binding (optional) - """ amqp: Optional[amqp_bindings.ChannelBinding] = None @@ -38,7 +37,6 @@ class OperationBinding: sqs : SQS operation binding (optional) nats : NATS operation binding (optional) redis : Redis operation binding (optional) - """ amqp: Optional[amqp_bindings.OperationBinding] = None diff --git a/faststream/specification/schema/channel.py b/faststream/specification/schema/channel.py index d5649a5c36..98166e9e06 100644 --- a/faststream/specification/schema/channel.py +++ b/faststream/specification/schema/channel.py @@ -15,7 +15,6 @@ class Channel: bindings : optional channel binding subscribe : optional operation for subscribing to the channel publish : optional operation for publishing to the channel - """ description: Optional[str] = None diff --git a/faststream/specification/schema/components.py b/faststream/specification/schema/components.py index bcce7129bb..3562fa48b6 100644 --- a/faststream/specification/schema/components.py +++ b/faststream/specification/schema/components.py @@ -25,7 +25,6 @@ class Components(BaseModel): - serverVariables - channels - securitySchemes - """ messages: Optional[Dict[str, Message]] = None diff --git a/faststream/specification/schema/contact.py b/faststream/specification/schema/contact.py index e51f5286d5..275062d60e 100644 --- a/faststream/specification/schema/contact.py +++ b/faststream/specification/schema/contact.py @@ -94,12 +94,11 @@ class ContactDict(TypedDict, total=False): name : required name of the contact (type: str) url : URL of the contact (type: AnyHttpUrl) email : email address of the contact (type: EmailStr) - """ name: Required[str] url: AnyHttpUrl - # email: EmailStr + email: EmailStr class Contact(BaseModel): @@ -109,7 +108,6 @@ class Contact(BaseModel): name : name of the contact (str) url : URL of the contact (Optional[AnyHttpUrl]) email : email of the contact (Optional[EmailStr]) - """ name: str diff --git a/faststream/specification/schema/docs.py b/faststream/specification/schema/docs.py index 2828b8e4b0..d5b69fe7b4 100644 --- a/faststream/specification/schema/docs.py +++ b/faststream/specification/schema/docs.py @@ -10,7 +10,6 @@ class ExternalDocsDict(TypedDict, total=False): Attributes: url : Required URL for the external documentation description : Description of the external documentation - """ url: Required[str] @@ -24,7 +23,6 @@ class ExternalDocs: Attributes: url : URL of the external documentation description : optional description of the external documentation - """ url: str diff --git a/faststream/specification/schema/info.py b/faststream/specification/schema/info.py index 804f46e61c..fb2f0f04e9 100644 --- a/faststream/specification/schema/info.py +++ b/faststream/specification/schema/info.py @@ -21,7 +21,6 @@ class Info(BaseModel): termsOfService : terms of service for the information (default: None) contact : contact information for the information (default: None) license : license information for the information (default: None) - """ termsOfService: Optional[AnyHttpUrl] = None diff --git a/faststream/specification/schema/license.py b/faststream/specification/schema/license.py index bc88795f6f..f95faf3e10 100644 --- a/faststream/specification/schema/license.py +++ b/faststream/specification/schema/license.py @@ -16,7 +16,6 @@ class LicenseDict(TypedDict, total=False): Attributes: name : required name of the license (type: str) url : URL of the license (type: AnyHttpUrl) - """ name: Required[str] @@ -32,7 +31,6 @@ class License(BaseModel): Config: extra : allow additional attributes in the model (PYDANTIC_V2) - """ name: str diff --git a/faststream/specification/schema/message.py b/faststream/specification/schema/message.py index bd3bb98917..9b5868a388 100644 --- a/faststream/specification/schema/message.py +++ b/faststream/specification/schema/message.py @@ -15,7 +15,6 @@ class CorrelationId: Configurations: extra : allows extra fields in the correlation ID model - """ location: str @@ -37,7 +36,6 @@ class Message: payload : dictionary representing the payload of the message tags : list of tags associated with the message externalDocs : external documentation associated with the message - """ payload: Dict[str, Any] diff --git a/faststream/specification/schema/operation.py b/faststream/specification/schema/operation.py index 71b56c5d16..23f3343290 100644 --- a/faststream/specification/schema/operation.py +++ b/faststream/specification/schema/operation.py @@ -18,7 +18,6 @@ class Operation: message : message of the operation security : security details of the operation tags : tags associated with the operation - """ message: Message diff --git a/faststream/specification/schema/security.py b/faststream/specification/schema/security.py index ccb621a4dd..9948a850da 100644 --- a/faststream/specification/schema/security.py +++ b/faststream/specification/schema/security.py @@ -13,7 +13,6 @@ class OauthFlowObj(BaseModel): tokenUrl : Optional[AnyHttpUrl] : The URL for token refreshUrl : Optional[AnyHttpUrl] : The URL for refresh scopes : Dict[str, str] : The scopes for the OAuth flow - """ authorizationUrl: Optional[AnyHttpUrl] = None @@ -38,7 +37,6 @@ class OauthFlows(BaseModel): password : Optional[OauthFlowObj] : Password OAuth flow object clientCredentials : Optional[OauthFlowObj] : Client credentials OAuth flow object authorizationCode : Optional[OauthFlowObj] : Authorization code OAuth flow object - """ implicit: Optional[OauthFlowObj] = None @@ -67,7 +65,6 @@ class SecuritySchemaComponent(BaseModel): bearerFormat : optional bearer format of the security schema component openIdConnectUrl : optional OpenID Connect URL of the security schema component flows : optional OAuth flows of the security schema component - """ type: Literal[ diff --git a/faststream/specification/schema/servers.py b/faststream/specification/schema/servers.py index 619a5fc3c6..8bac32b4f6 100644 --- a/faststream/specification/schema/servers.py +++ b/faststream/specification/schema/servers.py @@ -16,7 +16,6 @@ class ServerVariable(BaseModel): default : default value for the server variable (optional) description : description of the server variable (optional) examples : list of example values for the server variable (optional) - """ enum: Optional[List[str]] = None @@ -47,11 +46,6 @@ class Server(BaseModel): Note: The attributes `description`, `protocolVersion`, `tags`, `security`, `variables`, and `bindings` are all optional. - - Configurations: - If `PYDANTIC_V2` is True, the model configuration is set to allow extra attributes. - Otherwise, the `Config` class is defined with the `extra` attribute set to "allow". - """ url: str diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py index fe246acf96..7c605a3925 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py @@ -3,7 +3,7 @@ def test_basic_customization(): - schema = AsyncAPI(app.broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(app.broker, schema_version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_broker.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_broker.py index 5b0483ba77..08916cb97f 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_broker.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_broker.py @@ -4,7 +4,7 @@ def test_broker_customization(): - schema = docs_obj.jsonable() + schema = docs_obj.to_jsonable() assert schema["servers"] == { "development": { diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py index cc0c895170..a441441dbe 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py @@ -4,7 +4,7 @@ def test_handler_customization(): - schema = docs_obj.jsonable() + schema = docs_obj.to_jsonable() assert schema["channels"] == { "input_data:Consume": { diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_info.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_info.py index 4700abca36..a707a6357f 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_info.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_info.py @@ -4,7 +4,7 @@ def test_info_customization(): - schema = docs_obj.jsonable() + schema = docs_obj.to_jsonable() assert schema["info"] == { "title": "My App", diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_payload.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_payload.py index d94ec9f4ff..e9f3cfce18 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_payload.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_payload.py @@ -4,7 +4,7 @@ def test_payload_customization(): - schema = docs_obj.jsonable() + schema = docs_obj.to_jsonable() assert schema["components"]["schemas"] == { "DataBasic": { diff --git a/tests/a_docs/rabbit/test_security.py b/tests/a_docs/rabbit/test_security.py index aaeebb896c..9a9343d27f 100644 --- a/tests/a_docs/rabbit/test_security.py +++ b/tests/a_docs/rabbit/test_security.py @@ -13,7 +13,7 @@ async def test_base_security(): async with broker: pass - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", "channels": {}, @@ -40,7 +40,7 @@ async def test_plaintext_security(): async with broker: pass - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert ( schema == { diff --git a/tests/a_docs/redis/test_security.py b/tests/a_docs/redis/test_security.py index 70cd3d2949..8fbd3c87a8 100644 --- a/tests/a_docs/redis/test_security.py +++ b/tests/a_docs/redis/test_security.py @@ -38,7 +38,7 @@ async def test_base_security(): assert connection.call_args.kwargs["ssl"] - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", "channels": {}, @@ -68,7 +68,7 @@ async def test_plaintext_security(): assert connection.call_args.kwargs["ssl"] - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", "channels": {}, diff --git a/tests/asyncapi/base/v2_6_0/arguments.py b/tests/asyncapi/base/v2_6_0/arguments.py index 775934ad87..4c0d0c0e17 100644 --- a/tests/asyncapi/base/v2_6_0/arguments.py +++ b/tests/asyncapi/base/v2_6_0/arguments.py @@ -29,7 +29,7 @@ def test_custom_naming(self): @broker.subscriber("test", title="custom_name", description="test description") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert key == "custom_name" @@ -41,7 +41,7 @@ def test_slash_in_title(self): @broker.subscriber("test", title="/") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() assert next(iter(schema["channels"].keys())) == "/" @@ -61,7 +61,7 @@ def test_docstring_description(self): async def handle(msg): """Test description.""" - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert key == "custom_name" @@ -75,7 +75,7 @@ def test_empty(self): @broker.subscriber("test") async def handle(): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -92,7 +92,7 @@ def test_no_type(self): @broker.subscriber("test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -106,7 +106,7 @@ def test_simple_type(self): @broker.subscriber("test") async def handle(msg: int): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] assert next(iter(schema["channels"].values())).get("description") is None @@ -121,7 +121,7 @@ def test_simple_optional_type(self): @broker.subscriber("test") async def handle(msg: Optional[int]): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -145,7 +145,7 @@ def test_simple_type_with_default(self): @broker.subscriber("test") async def handle(msg: int = 1): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -163,7 +163,7 @@ def test_multi_args_no_type(self): @broker.subscriber("test") async def handle(msg, another): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -185,7 +185,7 @@ def test_multi_args_with_type(self): @broker.subscriber("test") async def handle(msg: str, another: int): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -207,7 +207,7 @@ def test_multi_args_with_default(self): @broker.subscriber("test") async def handle(msg: str, another: Optional[int] = None): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -247,7 +247,7 @@ class User: @broker.subscriber("test") async def handle(user: User): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -273,7 +273,7 @@ class User(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: User): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -304,7 +304,7 @@ class User(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: User): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -342,7 +342,7 @@ class User(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: User, description: str = ""): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -398,7 +398,7 @@ class Config: @broker.subscriber("test") async def handle(user: User): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -430,7 +430,7 @@ def dep2(name2: str): @broker.subscriber("test", dependencies=dependencies) async def handle(id: int, message=message): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -464,7 +464,7 @@ class Sub(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: descriminator): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = next(iter(schema["components"]["messages"].keys())) assert key == IsStr(regex=r"test[\w:]*:Handle:Message") @@ -519,7 +519,7 @@ class Model(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: Model): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = next(iter(schema["components"]["messages"].keys())) assert key == IsStr(regex=r"test[\w:]*:Handle:Message") @@ -583,7 +583,7 @@ async def handle(id: int): ... @sub async def handle_default(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() assert ( len( @@ -616,7 +616,7 @@ async def msg( ), ): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -638,7 +638,7 @@ def test_ignores_custom_field(self): @broker.subscriber("test") async def handle(id: int, user: Optional[str] = None, message=Context()): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] diff --git a/tests/asyncapi/base/v2_6_0/fastapi.py b/tests/asyncapi/base/v2_6_0/fastapi.py index 34b694ba79..5c75b87595 100644 --- a/tests/asyncapi/base/v2_6_0/fastapi.py +++ b/tests/asyncapi/base/v2_6_0/fastapi.py @@ -84,10 +84,10 @@ async def handler(): ... schema = AsyncAPI(router.broker, schema_version="2.6.0") response_json = client.get("/asyncapi_schema.json") - assert response_json.json() == schema.jsonable() + assert response_json.json() == schema.to_jsonable() response_yaml = client.get("/asyncapi_schema.yaml") - assert response_yaml.text == schema.yaml() + assert response_yaml.text == schema.to_yaml() response_html = client.get("/asyncapi_schema") assert response_html.status_code == 200 diff --git a/tests/asyncapi/base/v2_6_0/naming.py b/tests/asyncapi/base/v2_6_0/naming.py index e4f3ac7ef4..798a5088ad 100644 --- a/tests/asyncapi/base/v2_6_0/naming.py +++ b/tests/asyncapi/base/v2_6_0/naming.py @@ -18,7 +18,7 @@ def test_subscriber_naming(self): @broker.subscriber("test") async def handle_user_created(msg: str): ... - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -38,7 +38,7 @@ def test_pydantic_subscriber_naming(self): @broker.subscriber("test") async def handle_user_created(msg: create_model("SimpleModel")): ... - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -57,7 +57,7 @@ def test_multi_subscribers_naming(self): @broker.subscriber("test2") async def handle_user_created(msg: str): ... - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated"), @@ -79,7 +79,7 @@ def test_subscriber_naming_manual(self): @broker.subscriber("test", title="custom") async def handle_user_created(msg: str): ... - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -94,7 +94,7 @@ def test_subscriber_naming_default(self): broker.subscriber("test") - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:Subscriber") @@ -113,7 +113,7 @@ def test_subscriber_naming_default_with_title(self): broker.subscriber("test", title="custom") - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -136,7 +136,7 @@ async def handle_user_created(msg: str): ... broker.subscriber("test2") broker.subscriber("test3") - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated"), @@ -172,7 +172,7 @@ async def handle_user_created(msg: str): ... @sub async def handle_user_id(msg: int): ... - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -198,7 +198,7 @@ async def handle_user_created(msg: create_model("SimpleModel")): ... @sub async def handle_user_id(msg: int): ... - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -224,7 +224,7 @@ async def handle_user_created(msg: str): ... @sub async def handle_user_id(msg: int): ... - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -243,7 +243,7 @@ def test_publisher_naming_base(self): @broker.publisher("test") async def handle_user_created() -> str: ... - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] @@ -261,7 +261,7 @@ def test_publisher_naming_pydantic(self): @broker.publisher("test") async def handle_user_created() -> create_model("SimpleModel"): ... - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] @@ -279,7 +279,7 @@ def test_publisher_manual_naming(self): @broker.publisher("test", title="custom") async def handle_user_created() -> str: ... - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -295,7 +295,7 @@ def test_publisher_with_schema_naming(self): @broker.publisher("test", schema=str) async def handle_user_created(): ... - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] @@ -313,7 +313,7 @@ def test_publisher_manual_naming_with_schema(self): @broker.publisher("test", title="custom", schema=str) async def handle_user_created(): ... - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -330,7 +330,7 @@ def test_multi_publishers_naming(self): @broker.publisher("test2") async def handle_user_created() -> str: ... - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() names = list(schema["channels"].keys()) assert names == Contains( @@ -361,7 +361,7 @@ async def handle_user_created() -> str: ... @pub async def handle() -> int: ... - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:Publisher"), @@ -387,7 +387,7 @@ async def handle_user_created() -> str: ... @pub async def handle() -> int: ... - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == ["custom"] diff --git a/tests/asyncapi/base/v2_6_0/publisher.py b/tests/asyncapi/base/v2_6_0/publisher.py index d7e2cd9fba..3ac2fa56c3 100644 --- a/tests/asyncapi/base/v2_6_0/publisher.py +++ b/tests/asyncapi/base/v2_6_0/publisher.py @@ -19,7 +19,7 @@ def test_publisher_with_description(self): @broker.publisher("test", description="test description") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["description"] == "test description" @@ -30,7 +30,7 @@ def test_basic_publisher(self): @broker.publisher("test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key].get("description") is None @@ -46,7 +46,7 @@ def test_none_publisher(self): @broker.publisher("test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -58,7 +58,7 @@ def test_typed_publisher(self): @broker.publisher("test") async def handle(msg) -> int: ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -74,7 +74,7 @@ class User(pydantic.BaseModel): @broker.publisher("test") async def handle(msg) -> User: ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] @@ -97,7 +97,7 @@ def test_delayed(self): @pub async def handle(msg) -> int: ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -108,7 +108,7 @@ def test_with_schema(self): broker.publisher("test", title="Custom", schema=int) - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -124,4 +124,4 @@ async def handler(msg: str): schema = AsyncAPI(self.build_app(broker)) - assert schema.jsonable()["channels"] == {}, schema.jsonable()["channels"] + assert schema.to_jsonable()["channels"] == {}, schema.to_jsonable()["channels"] diff --git a/tests/asyncapi/base/v2_6_0/router.py b/tests/asyncapi/base/v2_6_0/router.py index aa847a8631..2b6078bbde 100644 --- a/tests/asyncapi/base/v2_6_0/router.py +++ b/tests/asyncapi/base/v2_6_0/router.py @@ -28,7 +28,7 @@ async def handle(msg): ... broker.include_router(router) - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] key = list(payload.keys())[0] # noqa: RUF015 @@ -52,7 +52,7 @@ async def handle(msg): ... broker.include_router(router) schema = AsyncAPI(broker, schema_version="2.6.0") - schemas = schema.jsonable()["components"]["schemas"] + schemas = schema.to_jsonable()["components"]["schemas"] del schemas["Handle:Message:Payload"] for i, j in schemas.items(): @@ -72,7 +72,7 @@ async def handle(msg): ... broker.include_router(router) schema = AsyncAPI(broker, schema_version="2.6.0") - assert schema.jsonable()["channels"] == {}, schema.jsonable()["channels"] + assert schema.to_jsonable()["channels"] == {}, schema.to_jsonable()["channels"] def test_not_include_in_method(self): broker = self.broker_class() @@ -85,7 +85,7 @@ async def handle(msg): ... broker.include_router(router, include_in_schema=False) schema = AsyncAPI(broker, schema_version="2.6.0") - assert schema.jsonable()["channels"] == {}, schema.jsonable()["channels"] + assert schema.to_jsonable()["channels"] == {}, schema.to_jsonable()["channels"] def test_respect_subrouter(self): broker = self.broker_class() @@ -101,7 +101,7 @@ async def handle(msg): ... schema = AsyncAPI(broker, schema_version="2.6.0") - assert schema.jsonable()["channels"] == {}, schema.jsonable()["channels"] + assert schema.to_jsonable()["channels"] == {}, schema.to_jsonable()["channels"] def test_not_include_subrouter(self): broker = self.broker_class() @@ -117,7 +117,7 @@ async def handle(msg): ... schema = AsyncAPI(broker, schema_version="2.6.0") - assert schema.jsonable()["channels"] == {} + assert schema.to_jsonable()["channels"] == {} def test_not_include_subrouter_by_method(self): broker = self.broker_class() @@ -133,7 +133,7 @@ async def handle(msg): ... schema = AsyncAPI(broker, schema_version="2.6.0") - assert schema.jsonable()["channels"] == {} + assert schema.to_jsonable()["channels"] == {} def test_all_nested_routers_by_method(self): broker = self.broker_class() @@ -149,7 +149,7 @@ async def handle(msg): ... schema = AsyncAPI(broker, schema_version="2.6.0") - assert schema.jsonable()["channels"] == {} + assert schema.to_jsonable()["channels"] == {} def test_include_subrouter(self): broker = self.broker_class() @@ -165,4 +165,4 @@ async def handle(msg): ... schema = AsyncAPI(broker, schema_version="2.6.0") - assert len(schema.jsonable()["channels"]) == 2 + assert len(schema.to_jsonable()["channels"]) == 2 diff --git a/tests/asyncapi/base/v3_0_0/arguments.py b/tests/asyncapi/base/v3_0_0/arguments.py index 7370b7e009..128f2c0468 100644 --- a/tests/asyncapi/base/v3_0_0/arguments.py +++ b/tests/asyncapi/base/v3_0_0/arguments.py @@ -30,7 +30,7 @@ def test_custom_naming(self): @broker.subscriber("test", title="custom_name", description="test description") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert key == "custom_name" @@ -42,7 +42,7 @@ def test_slash_in_title(self): @broker.subscriber("test", title="/") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() assert next(iter(schema["channels"].keys())) == "." assert schema["channels"]["."]["address"] == "/" @@ -70,7 +70,7 @@ def test_docstring_description(self): async def handle(msg): """Test description.""" - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert key == "custom_name" @@ -84,7 +84,7 @@ def test_empty(self): @broker.subscriber("test") async def handle(): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -101,7 +101,7 @@ def test_no_type(self): @broker.subscriber("test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -115,7 +115,7 @@ def test_simple_type(self): @broker.subscriber("test") async def handle(msg: int): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] assert next(iter(schema["channels"].values())).get("description") is None @@ -130,7 +130,7 @@ def test_simple_optional_type(self): @broker.subscriber("test") async def handle(msg: Optional[int]): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -154,7 +154,7 @@ def test_simple_type_with_default(self): @broker.subscriber("test") async def handle(msg: int = 1): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -172,7 +172,7 @@ def test_multi_args_no_type(self): @broker.subscriber("test") async def handle(msg, another): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -194,7 +194,7 @@ def test_multi_args_with_type(self): @broker.subscriber("test") async def handle(msg: str, another: int): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -216,7 +216,7 @@ def test_multi_args_with_default(self): @broker.subscriber("test") async def handle(msg: str, another: Optional[int] = None): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -256,7 +256,7 @@ class User: @broker.subscriber("test") async def handle(user: User): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -282,7 +282,7 @@ class User(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: User): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -313,7 +313,7 @@ class User(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: User): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -351,7 +351,7 @@ class User(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: User, description: str = ""): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -407,7 +407,7 @@ class Config: @broker.subscriber("test") async def handle(user: User): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -441,7 +441,7 @@ async def handle(id: int): ... @sub async def handle_default(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() assert ( len( @@ -472,7 +472,7 @@ def dep2(name2: str): @broker.subscriber("test", dependencies=dependencies) async def handle(id: int, message=message): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -506,7 +506,7 @@ class Sub(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: descriminator): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() key = next(iter(schema["components"]["messages"].keys())) assert key == IsStr(regex=r"test[\w:]*:Handle:SubscribeMessage") @@ -562,7 +562,7 @@ class Model(pydantic.BaseModel): @broker.subscriber("test") async def handle(user: Model): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() key = next(iter(schema["components"]["messages"].keys())) assert key == IsStr(regex=r"test[\w:]*:Handle:SubscribeMessage") @@ -626,7 +626,7 @@ async def msg( ), ): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -648,7 +648,7 @@ def test_ignores_custom_field(self): @broker.subscriber("test") async def handle(id: int, user: Optional[str] = None, message=Context()): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] diff --git a/tests/asyncapi/base/v3_0_0/fastapi.py b/tests/asyncapi/base/v3_0_0/fastapi.py index 653acf0092..6783803987 100644 --- a/tests/asyncapi/base/v3_0_0/fastapi.py +++ b/tests/asyncapi/base/v3_0_0/fastapi.py @@ -89,14 +89,16 @@ async def handler(): ... app_version=router.version, contact=router.contact, license=router.license, - schema_version="3.0.0" + schema_version="3.0.0", ) response_json = client.get("/asyncapi_schema.json") - assert response_json.json() == schema.jsonable(), schema.jsonable() + assert ( + response_json.json() == schema.to_jsonable() + ), schema.to_jsonable() response_yaml = client.get("/asyncapi_schema.yaml") - assert response_yaml.text == schema.yaml() + assert response_yaml.text == schema.to_yaml() response_html = client.get("/asyncapi_schema") assert response_html.status_code == 200 diff --git a/tests/asyncapi/base/v3_0_0/naming.py b/tests/asyncapi/base/v3_0_0/naming.py index 6852b3945a..1f23839c25 100644 --- a/tests/asyncapi/base/v3_0_0/naming.py +++ b/tests/asyncapi/base/v3_0_0/naming.py @@ -17,7 +17,8 @@ def test_subscriber_naming(self): @broker.subscriber("test") async def handle_user_created(msg: str): ... - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -37,7 +38,7 @@ def test_pydantic_subscriber_naming(self): @broker.subscriber("test") async def handle_user_created(msg: create_model("SimpleModel")): ... - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -56,7 +57,7 @@ def test_multi_subscribers_naming(self): @broker.subscriber("test2") async def handle_user_created(msg: str): ... - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated"), @@ -78,7 +79,7 @@ def test_subscriber_naming_manual(self): @broker.subscriber("test", title="custom") async def handle_user_created(msg: str): ... - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -95,7 +96,7 @@ def test_subscriber_naming_default(self): broker.subscriber("test") - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:Subscriber") @@ -114,7 +115,7 @@ def test_subscriber_naming_default_with_title(self): broker.subscriber("test", title="custom") - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -139,7 +140,7 @@ async def handle_user_created(msg: str): ... broker.subscriber("test2") broker.subscriber("test3") - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated"), @@ -175,7 +176,7 @@ async def handle_user_created(msg: str): ... @sub async def handle_user_id(msg: int): ... - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -201,7 +202,7 @@ async def handle_user_created(msg: create_model("SimpleModel")): ... @sub async def handle_user_id(msg: int): ... - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:HandleUserCreated") @@ -227,7 +228,7 @@ async def handle_user_created(msg: str): ... @sub async def handle_user_id(msg: int): ... - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -248,7 +249,7 @@ def test_publisher_naming_base(self): @broker.publisher("test") async def handle_user_created() -> str: ... - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] @@ -266,7 +267,7 @@ def test_publisher_naming_pydantic(self): @broker.publisher("test") async def handle_user_created() -> create_model("SimpleModel"): ... - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] @@ -284,7 +285,7 @@ def test_publisher_manual_naming(self): @broker.publisher("test", title="custom") async def handle_user_created() -> str: ... - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -300,7 +301,7 @@ def test_publisher_with_schema_naming(self): @broker.publisher("test", schema=str) async def handle_user_created(): ... - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] @@ -318,7 +319,7 @@ def test_publisher_manual_naming_with_schema(self): @broker.publisher("test", title="custom", schema=str) async def handle_user_created(): ... - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == ["custom"] @@ -335,7 +336,7 @@ def test_multi_publishers_naming(self): @broker.publisher("test2") async def handle_user_created() -> str: ... - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() names = list(schema["channels"].keys()) assert names == Contains( @@ -366,7 +367,7 @@ async def handle_user_created() -> str: ... @pub async def handle() -> int: ... - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [ IsStr(regex=r"test[\w:]*:Publisher"), @@ -392,7 +393,7 @@ async def handle_user_created() -> str: ... @pub async def handle() -> int: ... - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == ["custom"] diff --git a/tests/asyncapi/base/v3_0_0/publisher.py b/tests/asyncapi/base/v3_0_0/publisher.py index 5cee8ca6b9..2439d0bbf8 100644 --- a/tests/asyncapi/base/v3_0_0/publisher.py +++ b/tests/asyncapi/base/v3_0_0/publisher.py @@ -20,7 +20,7 @@ def test_publisher_with_description(self): @broker.publisher("test", description="test description") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["description"] == "test description" @@ -31,7 +31,7 @@ def test_basic_publisher(self): @broker.publisher("test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key].get("description") is None @@ -47,7 +47,7 @@ def test_none_publisher(self): @broker.publisher("test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -59,7 +59,7 @@ def test_typed_publisher(self): @broker.publisher("test") async def handle(msg) -> int: ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -75,7 +75,7 @@ class User(pydantic.BaseModel): @broker.publisher("test") async def handle(msg) -> User: ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] @@ -98,7 +98,7 @@ def test_delayed(self): @pub async def handle(msg) -> int: ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -109,7 +109,7 @@ def test_with_schema(self): broker.publisher("test", title="Custom", schema=int) - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] for v in payload.values(): @@ -125,4 +125,4 @@ async def handler(msg: str): schema = AsyncAPI(self.build_app(broker)) - assert schema.jsonable()["channels"] == {}, schema.jsonable()["channels"] + assert schema.to_jsonable()["channels"] == {}, schema.to_jsonable()["channels"] diff --git a/tests/asyncapi/base/v3_0_0/router.py b/tests/asyncapi/base/v3_0_0/router.py index d8242368bd..f19144b13a 100644 --- a/tests/asyncapi/base/v3_0_0/router.py +++ b/tests/asyncapi/base/v3_0_0/router.py @@ -28,7 +28,7 @@ async def handle(msg): ... broker.include_router(router) - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() payload = schema["components"]["schemas"] key = list(payload.keys())[0] # noqa: RUF015 @@ -52,7 +52,7 @@ async def handle(msg): ... broker.include_router(router) schema = AsyncAPI(broker, schema_version="3.0.0") - schemas = schema.jsonable()["components"]["schemas"] + schemas = schema.to_jsonable()["components"]["schemas"] del schemas["Handle:Message:Payload"] for i, j in schemas.items(): @@ -72,7 +72,7 @@ async def handle(msg): ... broker.include_router(router) schema = AsyncAPI(broker, schema_version="3.0.0") - assert schema.jsonable()["channels"] == {}, schema.jsonable()["channels"] + assert schema.to_jsonable()["channels"] == {}, schema.to_jsonable()["channels"] def test_not_include_in_method(self): broker = self.broker_class() @@ -85,7 +85,7 @@ async def handle(msg): ... broker.include_router(router, include_in_schema=False) schema = AsyncAPI(broker, schema_version="3.0.0") - assert schema.jsonable()["channels"] == {}, schema.jsonable()["channels"] + assert schema.to_jsonable()["channels"] == {}, schema.to_jsonable()["channels"] def test_respect_subrouter(self): broker = self.broker_class() @@ -101,7 +101,7 @@ async def handle(msg): ... schema = AsyncAPI(broker, schema_version="3.0.0") - assert schema.jsonable()["channels"] == {}, schema.jsonable()["channels"] + assert schema.to_jsonable()["channels"] == {}, schema.to_jsonable()["channels"] def test_not_include_subrouter(self): broker = self.broker_class() @@ -117,7 +117,7 @@ async def handle(msg): ... schema = AsyncAPI(broker, schema_version="3.0.0") - assert schema.jsonable()["channels"] == {} + assert schema.to_jsonable()["channels"] == {} def test_not_include_subrouter_by_method(self): broker = self.broker_class() @@ -133,7 +133,7 @@ async def handle(msg): ... schema = AsyncAPI(broker, schema_version="3.0.0") - assert schema.jsonable()["channels"] == {} + assert schema.to_jsonable()["channels"] == {} def test_all_nested_routers_by_method(self): broker = self.broker_class() @@ -149,7 +149,7 @@ async def handle(msg): ... schema = AsyncAPI(broker, schema_version="3.0.0") - assert schema.jsonable()["channels"] == {} + assert schema.to_jsonable()["channels"] == {} def test_include_subrouter(self): broker = self.broker_class() @@ -165,4 +165,4 @@ async def handle(msg): ... schema = AsyncAPI(broker, schema_version="3.0.0") - assert len(schema.jsonable()["channels"]) == 2 + assert len(schema.to_jsonable()["channels"]) == 2 diff --git a/tests/asyncapi/confluent/v2_6_0/test_arguments.py b/tests/asyncapi/confluent/v2_6_0/test_arguments.py index 994851d07e..9e10831bd7 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_arguments.py +++ b/tests/asyncapi/confluent/v2_6_0/test_arguments.py @@ -12,7 +12,7 @@ def test_subscriber_bindings(self): @broker.subscriber("test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/confluent/v2_6_0/test_connection.py b/tests/asyncapi/confluent/v2_6_0/test_connection.py index 6a503bc783..04ffb3bb27 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_connection.py +++ b/tests/asyncapi/confluent/v2_6_0/test_connection.py @@ -1,4 +1,3 @@ - from faststream.confluent import KafkaBroker from faststream.specification.asyncapi import AsyncAPI from faststream.specification.schema.tag import Tag @@ -14,7 +13,7 @@ def test_base(): tags=(Tag(name="some-tag", description="experimental"),), ), schema_version="2.6.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "2.6.0", @@ -37,7 +36,7 @@ def test_base(): def test_multi(): schema = AsyncAPI( KafkaBroker(["kafka:9092", "kafka:9093"]), schema_version="2.6.0" - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "2.6.0", @@ -67,7 +66,7 @@ def test_custom(): specification_url=["kafka:9094", "kafka:9095"], ), schema_version="2.6.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/confluent/v2_6_0/test_fastapi.py b/tests/asyncapi/confluent/v2_6_0/test_fastapi.py index 39bc487784..1a68210249 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/confluent/v2_6_0/test_fastapi.py @@ -1,4 +1,3 @@ - from faststream.confluent.fastapi import KafkaRouter from faststream.confluent.testing import TestKafkaBroker from faststream.security import SASLPlaintext @@ -29,7 +28,7 @@ def test_fastapi_security_schema(): router = KafkaRouter("localhost:9092", security=security) - schema = AsyncAPI(router.broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(router.broker, schema_version="2.6.0").to_jsonable() assert schema["servers"]["development"] == { "protocol": "kafka", diff --git a/tests/asyncapi/confluent/v2_6_0/test_naming.py b/tests/asyncapi/confluent/v2_6_0/test_naming.py index 156674cf1c..1bc6ac2ffe 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_naming.py +++ b/tests/asyncapi/confluent/v2_6_0/test_naming.py @@ -12,7 +12,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/confluent/v2_6_0/test_publisher.py b/tests/asyncapi/confluent/v2_6_0/test_publisher.py index e2d7746858..27bbf086b6 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_publisher.py +++ b/tests/asyncapi/confluent/v2_6_0/test_publisher.py @@ -12,7 +12,7 @@ def test_publisher_bindings(self): @broker.publisher("test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/confluent/v2_6_0/test_router.py b/tests/asyncapi/confluent/v2_6_0/test_router.py index 145fc7fe80..bd95965558 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_router.py +++ b/tests/asyncapi/confluent/v2_6_0/test_router.py @@ -21,7 +21,7 @@ async def handle(msg): ... broker.include_router(router) - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/confluent/v2_6_0/test_security.py b/tests/asyncapi/confluent/v2_6_0/test_security.py index f5a1f0a8fb..a11bf60df2 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_security.py +++ b/tests/asyncapi/confluent/v2_6_0/test_security.py @@ -81,7 +81,7 @@ def test_base_security_schema(): async def test_topic(msg: str) -> str: pass - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert schema == basic_schema @@ -101,7 +101,7 @@ def test_plaintext_security_schema(): async def test_topic(msg: str) -> str: pass - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() plaintext_security_schema = deepcopy(basic_schema) plaintext_security_schema["servers"]["development"]["security"] = [ @@ -129,7 +129,7 @@ def test_scram256_security_schema(): async def test_topic(msg: str) -> str: pass - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() sasl256_security_schema = deepcopy(basic_schema) sasl256_security_schema["servers"]["development"]["security"] = [{"scram256": []}] @@ -155,7 +155,7 @@ def test_scram512_security_schema(): async def test_topic(msg: str) -> str: pass - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() sasl512_security_schema = deepcopy(basic_schema) sasl512_security_schema["servers"]["development"]["security"] = [{"scram512": []}] @@ -179,7 +179,7 @@ def test_oauthbearer_security_schema(): async def test_topic(msg: str) -> str: pass - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() sasl_oauthbearer_security_schema = deepcopy(basic_schema) sasl_oauthbearer_security_schema["servers"]["development"]["security"] = [ @@ -203,7 +203,7 @@ def test_gssapi_security_schema(): async def test_topic(msg: str) -> str: pass - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() gssapi_security_schema = deepcopy(basic_schema) gssapi_security_schema["servers"]["development"]["security"] = [{"gssapi": []}] diff --git a/tests/asyncapi/confluent/v3_0_0/test_arguments.py b/tests/asyncapi/confluent/v3_0_0/test_arguments.py index 52c3e39ec7..97e4333888 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_arguments.py +++ b/tests/asyncapi/confluent/v3_0_0/test_arguments.py @@ -12,7 +12,7 @@ def test_subscriber_bindings(self): @broker.subscriber("test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/confluent/v3_0_0/test_connection.py b/tests/asyncapi/confluent/v3_0_0/test_connection.py index df99f96b2e..a277652f5e 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_connection.py +++ b/tests/asyncapi/confluent/v3_0_0/test_connection.py @@ -13,7 +13,7 @@ def test_base(): tags=(Tag(name="some-tag", description="experimental"),), ), schema_version="3.0.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "3.0.0", @@ -39,7 +39,7 @@ def test_multi(): schema = AsyncAPI( KafkaBroker(["kafka:9092", "kafka:9093"]), schema_version="3.0.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "3.0.0", @@ -72,7 +72,7 @@ def test_custom(): specification_url=["kafka:9094", "kafka:9095"], ), schema_version="3.0.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "3.0.0", diff --git a/tests/asyncapi/confluent/v3_0_0/test_fastapi.py b/tests/asyncapi/confluent/v3_0_0/test_fastapi.py index fb3c2275e6..18a4859956 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/confluent/v3_0_0/test_fastapi.py @@ -28,7 +28,7 @@ def test_fastapi_security_schema(): router = KafkaRouter("localhost:9092", security=security) - schema = AsyncAPI(router.broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(router.broker, schema_version="3.0.0").to_jsonable() assert schema["servers"]["development"] == { "protocol": "kafka", diff --git a/tests/asyncapi/confluent/v3_0_0/test_naming.py b/tests/asyncapi/confluent/v3_0_0/test_naming.py index c4b33a1469..b2558ca39e 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_naming.py +++ b/tests/asyncapi/confluent/v3_0_0/test_naming.py @@ -12,7 +12,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert schema == { "asyncapi": "3.0.0", diff --git a/tests/asyncapi/confluent/v3_0_0/test_publisher.py b/tests/asyncapi/confluent/v3_0_0/test_publisher.py index 546050d22a..e7ac72d523 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_publisher.py +++ b/tests/asyncapi/confluent/v3_0_0/test_publisher.py @@ -12,7 +12,7 @@ def test_publisher_bindings(self): @broker.publisher("test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/confluent/v3_0_0/test_router.py b/tests/asyncapi/confluent/v3_0_0/test_router.py index 985543fa22..42efa5bf05 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_router.py +++ b/tests/asyncapi/confluent/v3_0_0/test_router.py @@ -21,7 +21,7 @@ async def handle(msg): ... broker.include_router(router) - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert schema == { "info": {"title": "FastStream", "version": "0.1.0", "description": ""}, diff --git a/tests/asyncapi/confluent/v3_0_0/test_security.py b/tests/asyncapi/confluent/v3_0_0/test_security.py index 1d711487c7..3fff31d194 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_security.py +++ b/tests/asyncapi/confluent/v3_0_0/test_security.py @@ -100,7 +100,7 @@ def test_base_security_schema(): async def test_topic(msg: str) -> str: pass - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert schema == basic_schema @@ -120,7 +120,7 @@ def test_plaintext_security_schema(): async def test_topic(msg: str) -> str: pass - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() plaintext_security_schema = deepcopy(basic_schema) plaintext_security_schema["servers"]["development"]["security"] = [ @@ -148,7 +148,7 @@ def test_scram256_security_schema(): async def test_topic(msg: str) -> str: pass - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() sasl256_security_schema = deepcopy(basic_schema) sasl256_security_schema["servers"]["development"]["security"] = [{"scram256": []}] @@ -174,7 +174,7 @@ def test_scram512_security_schema(): async def test_topic(msg: str) -> str: pass - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() sasl512_security_schema = deepcopy(basic_schema) sasl512_security_schema["servers"]["development"]["security"] = [{"scram512": []}] @@ -198,7 +198,7 @@ def test_oauthbearer_security_schema(): async def test_topic(msg: str) -> str: pass - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() sasl_oauthbearer_security_schema = deepcopy(basic_schema) sasl_oauthbearer_security_schema["servers"]["development"]["security"] = [ @@ -222,7 +222,7 @@ def test_gssapi_security_schema(): async def test_topic(msg: str) -> str: pass - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() gssapi_security_schema = deepcopy(basic_schema) gssapi_security_schema["servers"]["development"]["security"] = [{"gssapi": []}] diff --git a/tests/asyncapi/kafka/v2_6_0/test_app.py b/tests/asyncapi/kafka/v2_6_0/test_app.py index 1b71dc7936..23aa904be8 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_app.py +++ b/tests/asyncapi/kafka/v2_6_0/test_app.py @@ -7,7 +7,7 @@ def test_base(): - schema = AsyncAPI(KafkaBroker(), schema_version="2.6.0").jsonable() + schema = AsyncAPI(KafkaBroker(), schema_version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", @@ -32,7 +32,7 @@ def test_with_name(): app_version="1.0.0", description="Test description", schema_version="2.6.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "2.6.0", @@ -69,7 +69,7 @@ def test_full(): url="https://extra-docs.py/", ), schema_version="2.6.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "2.6.0", @@ -112,7 +112,7 @@ def test_full_dict(): "url": "https://extra-docs.py/", }, schema_version="2.6.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "2.6.0", @@ -149,16 +149,14 @@ def test_extra(): license={"name": "MIT", "url": "https://mit.com/", "x-field": "extra"}, terms_of_service="https://my-terms.com/", contact={"name": "support", "url": "https://help.com/", "x-field": "extra"}, - tags=( - {"name": "some-tag", "description": "experimental", "x-field": "extra"}, - ), + tags=({"name": "some-tag", "description": "experimental", "x-field": "extra"},), identifier="some-unique-uuid", external_docs={ "url": "https://extra-docs.py/", "x-field": "extra", }, schema_version="2.6.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/kafka/v2_6_0/test_arguments.py b/tests/asyncapi/kafka/v2_6_0/test_arguments.py index eee8de3cef..8ef7f6e63f 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_arguments.py +++ b/tests/asyncapi/kafka/v2_6_0/test_arguments.py @@ -12,7 +12,7 @@ def test_subscriber_bindings(self): @broker.subscriber("test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/kafka/v2_6_0/test_connection.py b/tests/asyncapi/kafka/v2_6_0/test_connection.py index eeecdf8230..559ec4a200 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_connection.py +++ b/tests/asyncapi/kafka/v2_6_0/test_connection.py @@ -13,7 +13,7 @@ def test_base(): tags=(Tag(name="some-tag", description="experimental"),), ), schema_version="2.6.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "2.6.0", @@ -37,7 +37,7 @@ def test_multi(): schema = AsyncAPI( KafkaBroker(["kafka:9092", "kafka:9093"]), schema_version="2.6.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "2.6.0", @@ -67,7 +67,7 @@ def test_custom(): specification_url=["kafka:9094", "kafka:9095"], ), schema_version="2.6.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/kafka/v2_6_0/test_fastapi.py b/tests/asyncapi/kafka/v2_6_0/test_fastapi.py index 1d1a803edc..719fb472df 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/kafka/v2_6_0/test_fastapi.py @@ -1,4 +1,3 @@ - from faststream.kafka.fastapi import KafkaRouter from faststream.kafka.testing import TestKafkaBroker from faststream.security import SASLPlaintext @@ -29,7 +28,7 @@ def test_fastapi_security_schema(): router = KafkaRouter("localhost:9092", security=security) - schema = AsyncAPI(router.broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(router.broker, schema_version="2.6.0").to_jsonable() assert schema["servers"]["development"] == { "protocol": "kafka", diff --git a/tests/asyncapi/kafka/v2_6_0/test_naming.py b/tests/asyncapi/kafka/v2_6_0/test_naming.py index aa89287ee0..3108bb5c3e 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_naming.py +++ b/tests/asyncapi/kafka/v2_6_0/test_naming.py @@ -12,7 +12,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/kafka/v2_6_0/test_publisher.py b/tests/asyncapi/kafka/v2_6_0/test_publisher.py index 9b054282e5..65dcbcdb19 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_publisher.py +++ b/tests/asyncapi/kafka/v2_6_0/test_publisher.py @@ -12,7 +12,7 @@ def test_publisher_bindings(self): @broker.publisher("test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/kafka/v2_6_0/test_router.py b/tests/asyncapi/kafka/v2_6_0/test_router.py index 314689ffb6..903726b6be 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_router.py +++ b/tests/asyncapi/kafka/v2_6_0/test_router.py @@ -21,7 +21,7 @@ async def handle(msg): ... broker.include_router(router) - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/kafka/v2_6_0/test_security.py b/tests/asyncapi/kafka/v2_6_0/test_security.py index ddc10d5c37..c7fc972395 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_security.py +++ b/tests/asyncapi/kafka/v2_6_0/test_security.py @@ -81,7 +81,7 @@ def test_base_security_schema(): async def test_topic(msg: str) -> str: pass - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert schema == basic_schema @@ -101,7 +101,7 @@ def test_plaintext_security_schema(): async def test_topic(msg: str) -> str: pass - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() plaintext_security_schema = deepcopy(basic_schema) plaintext_security_schema["servers"]["development"]["security"] = [ @@ -129,7 +129,7 @@ def test_scram256_security_schema(): async def test_topic(msg: str) -> str: pass - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() sasl256_security_schema = deepcopy(basic_schema) sasl256_security_schema["servers"]["development"]["security"] = [{"scram256": []}] @@ -155,7 +155,7 @@ def test_scram512_security_schema(): async def test_topic(msg: str) -> str: pass - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() sasl512_security_schema = deepcopy(basic_schema) sasl512_security_schema["servers"]["development"]["security"] = [{"scram512": []}] @@ -179,7 +179,7 @@ def test_oauthbearer_security_schema(): async def test_topic(msg: str) -> str: pass - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() sasl_oauthbearer_security_schema = deepcopy(basic_schema) sasl_oauthbearer_security_schema["servers"]["development"]["security"] = [ @@ -205,7 +205,7 @@ def test_gssapi_security_schema(): async def test_topic(msg: str) -> str: pass - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() gssapi_security_schema = deepcopy(basic_schema) gssapi_security_schema["servers"]["development"]["security"] = [{"gssapi": []}] diff --git a/tests/asyncapi/kafka/v3_0_0/test_arguments.py b/tests/asyncapi/kafka/v3_0_0/test_arguments.py index 4a95f34a84..03d675fddb 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_arguments.py +++ b/tests/asyncapi/kafka/v3_0_0/test_arguments.py @@ -12,7 +12,7 @@ def test_subscriber_bindings(self): @broker.subscriber("test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/kafka/v3_0_0/test_connection.py b/tests/asyncapi/kafka/v3_0_0/test_connection.py index ceb90a2820..a9dd5ba99e 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_connection.py +++ b/tests/asyncapi/kafka/v3_0_0/test_connection.py @@ -13,7 +13,7 @@ def test_base(): tags=(Tag(name="some-tag", description="experimental"),), ), schema_version="3.0.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "3.0.0", @@ -39,7 +39,7 @@ def test_multi(): schema = AsyncAPI( KafkaBroker(["kafka:9092", "kafka:9093"]), schema_version="3.0.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "3.0.0", @@ -72,7 +72,7 @@ def test_custom(): specification_url=["kafka:9094", "kafka:9095"], ), schema_version="3.0.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "3.0.0", diff --git a/tests/asyncapi/kafka/v3_0_0/test_fastapi.py b/tests/asyncapi/kafka/v3_0_0/test_fastapi.py index 6f58c7b255..86c9cbc8ed 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/kafka/v3_0_0/test_fastapi.py @@ -28,7 +28,7 @@ def test_fastapi_security_schema(): router = KafkaRouter("localhost:9092", security=security) - schema = AsyncAPI(router.broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(router.broker, schema_version="3.0.0").to_jsonable() assert schema["servers"]["development"] == { "protocol": "kafka", diff --git a/tests/asyncapi/kafka/v3_0_0/test_naming.py b/tests/asyncapi/kafka/v3_0_0/test_naming.py index 40c09bd8ad..bba306fcbe 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_naming.py +++ b/tests/asyncapi/kafka/v3_0_0/test_naming.py @@ -12,7 +12,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert schema == { "asyncapi": "3.0.0", diff --git a/tests/asyncapi/kafka/v3_0_0/test_publisher.py b/tests/asyncapi/kafka/v3_0_0/test_publisher.py index 6086630267..c4db9d558e 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_publisher.py +++ b/tests/asyncapi/kafka/v3_0_0/test_publisher.py @@ -12,7 +12,7 @@ def test_publisher_bindings(self): @broker.publisher("test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/kafka/v3_0_0/test_router.py b/tests/asyncapi/kafka/v3_0_0/test_router.py index 195842eb34..ee92b456fc 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_router.py +++ b/tests/asyncapi/kafka/v3_0_0/test_router.py @@ -21,7 +21,7 @@ async def handle(msg): ... broker.include_router(router) - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert schema == { "info": {"title": "FastStream", "version": "0.1.0", "description": ""}, diff --git a/tests/asyncapi/kafka/v3_0_0/test_security.py b/tests/asyncapi/kafka/v3_0_0/test_security.py index 7308677064..4a752552e8 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_security.py +++ b/tests/asyncapi/kafka/v3_0_0/test_security.py @@ -100,7 +100,7 @@ def test_base_security_schema(): async def test_topic(msg: str) -> str: pass - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert schema == basic_schema @@ -120,7 +120,7 @@ def test_plaintext_security_schema(): async def test_topic(msg: str) -> str: pass - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() plaintext_security_schema = deepcopy(basic_schema) plaintext_security_schema["servers"]["development"]["security"] = [ @@ -148,7 +148,7 @@ def test_scram256_security_schema(): async def test_topic(msg: str) -> str: pass - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() sasl256_security_schema = deepcopy(basic_schema) sasl256_security_schema["servers"]["development"]["security"] = [{"scram256": []}] @@ -174,7 +174,7 @@ def test_scram512_security_schema(): async def test_topic(msg: str) -> str: pass - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() sasl512_security_schema = deepcopy(basic_schema) sasl512_security_schema["servers"]["development"]["security"] = [{"scram512": []}] @@ -198,7 +198,7 @@ def test_oauthbearer_security_schema(): async def test_topic(msg: str) -> str: pass - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() sasl_oauthbearer_security_schema = deepcopy(basic_schema) sasl_oauthbearer_security_schema["servers"]["development"]["security"] = [ @@ -224,7 +224,7 @@ def test_gssapi_security_schema(): async def test_topic(msg: str) -> str: pass - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() gssapi_security_schema = deepcopy(basic_schema) gssapi_security_schema["servers"]["development"]["security"] = [{"gssapi": []}] diff --git a/tests/asyncapi/nats/v2_6_0/test_arguments.py b/tests/asyncapi/nats/v2_6_0/test_arguments.py index d361ef5933..70f92e2702 100644 --- a/tests/asyncapi/nats/v2_6_0/test_arguments.py +++ b/tests/asyncapi/nats/v2_6_0/test_arguments.py @@ -12,7 +12,7 @@ def test_subscriber_bindings(self): @broker.subscriber("test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/nats/v2_6_0/test_connection.py b/tests/asyncapi/nats/v2_6_0/test_connection.py index 6a6b906e87..a53367112f 100644 --- a/tests/asyncapi/nats/v2_6_0/test_connection.py +++ b/tests/asyncapi/nats/v2_6_0/test_connection.py @@ -13,7 +13,7 @@ def test_base(): tags=(Tag(name="some-tag", description="experimental"),), ), schema_version="2.6.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "2.6.0", @@ -37,7 +37,7 @@ def test_multi(): schema = AsyncAPI( NatsBroker(["nats:9092", "nats:9093"]), schema_version="2.6.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "2.6.0", @@ -66,7 +66,7 @@ def test_custom(): ["nats:9092", "nats:9093"], specification_url=["nats:9094", "nats:9095"] ), schema_version="2.6.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/nats/v2_6_0/test_fastapi.py b/tests/asyncapi/nats/v2_6_0/test_fastapi.py index fe1be83a89..6f7c8b3eb1 100644 --- a/tests/asyncapi/nats/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/nats/v2_6_0/test_fastapi.py @@ -1,4 +1,3 @@ - from faststream.nats import TestNatsBroker from faststream.nats.fastapi import NatsRouter from tests.asyncapi.base.v2_6_0.arguments import FastAPICompatible diff --git a/tests/asyncapi/nats/v2_6_0/test_kv_schema.py b/tests/asyncapi/nats/v2_6_0/test_kv_schema.py index 21aa4c6a1a..0831d8c6c3 100644 --- a/tests/asyncapi/nats/v2_6_0/test_kv_schema.py +++ b/tests/asyncapi/nats/v2_6_0/test_kv_schema.py @@ -8,6 +8,6 @@ def test_kv_schema(): @broker.subscriber("test", kv_watch="test") async def handle(): ... - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert schema["channels"] == {} diff --git a/tests/asyncapi/nats/v2_6_0/test_naming.py b/tests/asyncapi/nats/v2_6_0/test_naming.py index 0402b83b90..4f998b7633 100644 --- a/tests/asyncapi/nats/v2_6_0/test_naming.py +++ b/tests/asyncapi/nats/v2_6_0/test_naming.py @@ -12,7 +12,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/nats/v2_6_0/test_obj_schema.py b/tests/asyncapi/nats/v2_6_0/test_obj_schema.py index 599c2d95ed..bda3cb8dbc 100644 --- a/tests/asyncapi/nats/v2_6_0/test_obj_schema.py +++ b/tests/asyncapi/nats/v2_6_0/test_obj_schema.py @@ -8,6 +8,6 @@ def test_obj_schema(): @broker.subscriber("test", obj_watch=True) async def handle(): ... - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert schema["channels"] == {} diff --git a/tests/asyncapi/nats/v2_6_0/test_publisher.py b/tests/asyncapi/nats/v2_6_0/test_publisher.py index 8a0a935f0e..2d859f242f 100644 --- a/tests/asyncapi/nats/v2_6_0/test_publisher.py +++ b/tests/asyncapi/nats/v2_6_0/test_publisher.py @@ -12,7 +12,7 @@ def test_publisher_bindings(self): @broker.publisher("test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/nats/v2_6_0/test_router.py b/tests/asyncapi/nats/v2_6_0/test_router.py index 24920871c2..73d8d60e4b 100644 --- a/tests/asyncapi/nats/v2_6_0/test_router.py +++ b/tests/asyncapi/nats/v2_6_0/test_router.py @@ -21,7 +21,7 @@ async def handle(msg): ... broker.include_router(router) - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/nats/v3_0_0/test_arguments.py b/tests/asyncapi/nats/v3_0_0/test_arguments.py index a007642079..bda50e73ea 100644 --- a/tests/asyncapi/nats/v3_0_0/test_arguments.py +++ b/tests/asyncapi/nats/v3_0_0/test_arguments.py @@ -12,7 +12,7 @@ def test_subscriber_bindings(self): @broker.subscriber("test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/nats/v3_0_0/test_connection.py b/tests/asyncapi/nats/v3_0_0/test_connection.py index 904fd24e5f..6d825f9513 100644 --- a/tests/asyncapi/nats/v3_0_0/test_connection.py +++ b/tests/asyncapi/nats/v3_0_0/test_connection.py @@ -13,7 +13,7 @@ def test_base(): tags=(Tag(name="some-tag", description="experimental"),), ), schema_version="3.0.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "3.0.0", @@ -39,7 +39,7 @@ def test_multi(): schema = AsyncAPI( NatsBroker(["nats:9092", "nats:9093"]), schema_version="3.0.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "3.0.0", @@ -72,7 +72,7 @@ def test_custom(): specification_url=["nats:9094", "nats:9095"], ), schema_version="3.0.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "3.0.0", diff --git a/tests/asyncapi/nats/v3_0_0/test_kv_schema.py b/tests/asyncapi/nats/v3_0_0/test_kv_schema.py index 1377ddc893..0600c6c82b 100644 --- a/tests/asyncapi/nats/v3_0_0/test_kv_schema.py +++ b/tests/asyncapi/nats/v3_0_0/test_kv_schema.py @@ -8,6 +8,6 @@ def test_kv_schema(): @broker.subscriber("test", kv_watch="test") async def handle(): ... - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert schema["channels"] == {} diff --git a/tests/asyncapi/nats/v3_0_0/test_naming.py b/tests/asyncapi/nats/v3_0_0/test_naming.py index e95b370842..0f3fda4a2a 100644 --- a/tests/asyncapi/nats/v3_0_0/test_naming.py +++ b/tests/asyncapi/nats/v3_0_0/test_naming.py @@ -12,7 +12,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert schema == { "asyncapi": "3.0.0", diff --git a/tests/asyncapi/nats/v3_0_0/test_obj_schema.py b/tests/asyncapi/nats/v3_0_0/test_obj_schema.py index 9ea02b5312..e3bbefd311 100644 --- a/tests/asyncapi/nats/v3_0_0/test_obj_schema.py +++ b/tests/asyncapi/nats/v3_0_0/test_obj_schema.py @@ -8,6 +8,6 @@ def test_obj_schema(): @broker.subscriber("test", obj_watch=True) async def handle(): ... - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert schema["channels"] == {} diff --git a/tests/asyncapi/nats/v3_0_0/test_publisher.py b/tests/asyncapi/nats/v3_0_0/test_publisher.py index 656fa40c4a..99f14470ff 100644 --- a/tests/asyncapi/nats/v3_0_0/test_publisher.py +++ b/tests/asyncapi/nats/v3_0_0/test_publisher.py @@ -12,7 +12,7 @@ def test_publisher_bindings(self): @broker.publisher("test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/nats/v3_0_0/test_router.py b/tests/asyncapi/nats/v3_0_0/test_router.py index 55d065dc22..697692d947 100644 --- a/tests/asyncapi/nats/v3_0_0/test_router.py +++ b/tests/asyncapi/nats/v3_0_0/test_router.py @@ -21,7 +21,7 @@ async def handle(msg): ... broker.include_router(router) - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert schema == { "info": {"title": "FastStream", "version": "0.1.0", "description": ""}, diff --git a/tests/asyncapi/rabbit/v2_6_0/test_arguments.py b/tests/asyncapi/rabbit/v2_6_0/test_arguments.py index 98e139cc55..7f1782e5f4 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_arguments.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_arguments.py @@ -15,7 +15,7 @@ def test_subscriber_bindings(self): ) async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -48,7 +48,7 @@ def test_subscriber_fanout_bindings(self): ) async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -74,7 +74,7 @@ def test_subscriber_headers_bindings(self): ) async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -100,7 +100,7 @@ def test_subscriber_xdelay_bindings(self): ) async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -126,7 +126,7 @@ def test_subscriber_consistent_hash_bindings(self): ) async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -152,7 +152,7 @@ def test_subscriber_modules_hash_bindings(self): ) async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/rabbit/v2_6_0/test_connection.py b/tests/asyncapi/rabbit/v2_6_0/test_connection.py index 7684dcb0d6..2682bc6b77 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_connection.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_connection.py @@ -13,7 +13,7 @@ def test_base(): tags=(Tag(name="some-tag", description="experimental"),), ), schema_version="2.6.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "2.6.0", @@ -52,7 +52,7 @@ def test_custom(): ) broker.publisher("test") - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert ( schema diff --git a/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py b/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py index 4ce7ec8e93..69465e5b82 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py @@ -1,4 +1,3 @@ - from faststream.rabbit.fastapi import RabbitRouter from faststream.rabbit.testing import TestRabbitBroker from faststream.security import SASLPlaintext @@ -29,7 +28,7 @@ def test_fastapi_security_schema(): router = RabbitRouter(security=security) - schema = AsyncAPI(router.broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(router.broker, schema_version="2.6.0").to_jsonable() assert schema["servers"]["development"] == { "protocol": "amqp", diff --git a/tests/asyncapi/rabbit/v2_6_0/test_naming.py b/tests/asyncapi/rabbit/v2_6_0/test_naming.py index 8b659c589c..4625ddae09 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_naming.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_naming.py @@ -14,7 +14,7 @@ def test_subscriber_with_exchange(self): @broker.subscriber("test", "exchange") async def handle(): ... - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == ["test:exchange:Handle"] @@ -28,7 +28,7 @@ def test_publisher_with_exchange(self): @broker.publisher("test", "exchange") async def handle(): ... - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == ["test:exchange:Publisher"] @@ -42,7 +42,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert ( schema diff --git a/tests/asyncapi/rabbit/v2_6_0/test_publisher.py b/tests/asyncapi/rabbit/v2_6_0/test_publisher.py index 476d479f90..87b8d5d13a 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_publisher.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_publisher.py @@ -12,7 +12,7 @@ def test_just_exchange(self): @broker.publisher(exchange="test-ex") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() assert schema["channels"] == { "_:test-ex:Publisher": { @@ -55,7 +55,7 @@ def test_publisher_bindings(self): ) async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -88,7 +88,7 @@ def test_useless_queue_bindings(self): ) async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() assert schema["channels"] == { "_:test-ex:Publisher": { @@ -121,7 +121,7 @@ def test_reusable_exchange(self): @broker.publisher(exchange="test-ex", routing_key="key2", priority=10) async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() assert schema["channels"] == { "key1:test-ex:Publisher": { diff --git a/tests/asyncapi/rabbit/v2_6_0/test_router.py b/tests/asyncapi/rabbit/v2_6_0/test_router.py index 60693e718f..9ed97f1c4b 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_router.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_router.py @@ -27,7 +27,7 @@ async def handle(msg): ... broker.include_router(router) - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert ( schema diff --git a/tests/asyncapi/rabbit/v2_6_0/test_security.py b/tests/asyncapi/rabbit/v2_6_0/test_security.py index e66c0e95f1..a23ad59cad 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_security.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_security.py @@ -19,7 +19,7 @@ def test_base_security_schema(): ) # pragma: allowlist secret assert broker._connection_kwargs.get("ssl_context") is ssl_context - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", @@ -55,7 +55,7 @@ def test_plaintext_security_schema(): ) # pragma: allowlist secret assert broker._connection_kwargs.get("ssl_context") is ssl_context - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert ( schema == { @@ -93,7 +93,7 @@ def test_plaintext_security_schema_without_ssl(): == "amqp://admin:password@localhost:5672/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert ( schema == { diff --git a/tests/asyncapi/rabbit/v3_0_0/test_arguments.py b/tests/asyncapi/rabbit/v3_0_0/test_arguments.py index a997788d82..1dea5c8635 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_arguments.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_arguments.py @@ -15,7 +15,7 @@ def test_subscriber_bindings(self): ) async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -48,7 +48,7 @@ def test_subscriber_fanout_bindings(self): ) async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/rabbit/v3_0_0/test_connection.py b/tests/asyncapi/rabbit/v3_0_0/test_connection.py index 870d1337e3..1b4b9e0431 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_connection.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_connection.py @@ -13,7 +13,7 @@ def test_base(): tags=(Tag(name="some-tag", description="experimental"),), ), schema_version="3.0.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "3.0.0", @@ -54,7 +54,7 @@ def test_custom(): ) broker.publisher("test") - schema = AsyncAPI(broker, schema_version="3.0.0").jsonable() + schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert schema == { "asyncapi": "3.0.0", diff --git a/tests/asyncapi/rabbit/v3_0_0/test_fastapi.py b/tests/asyncapi/rabbit/v3_0_0/test_fastapi.py index 14578beb61..0e6d707218 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_fastapi.py @@ -28,10 +28,7 @@ def test_fastapi_security_schema(): router = RabbitRouter(security=security) - schema = AsyncAPI( - router.broker, - schema_version="3.0.0" - ).jsonable() + schema = AsyncAPI(router.broker, schema_version="3.0.0").to_jsonable() assert schema["servers"]["development"] == { "protocol": "amqp", diff --git a/tests/asyncapi/rabbit/v3_0_0/test_naming.py b/tests/asyncapi/rabbit/v3_0_0/test_naming.py index 34c0415cf3..ebdf2004aa 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_naming.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_naming.py @@ -17,7 +17,7 @@ async def handle(): ... schema = AsyncAPI( broker, schema_version="3.0.0", - ).jsonable() + ).to_jsonable() assert list(schema["channels"].keys()) == ["test:exchange:Handle"] @@ -34,7 +34,7 @@ async def handle(): ... schema = AsyncAPI( broker, schema_version="3.0.0", - ).jsonable() + ).to_jsonable() assert list(schema["channels"].keys()) == ["test:exchange:Publisher"] @@ -51,7 +51,7 @@ async def handle(): ... schema = AsyncAPI( broker, schema_version="3.0.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "3.0.0", diff --git a/tests/asyncapi/rabbit/v3_0_0/test_publisher.py b/tests/asyncapi/rabbit/v3_0_0/test_publisher.py index 6cafa4e824..1aebc660c6 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_publisher.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_publisher.py @@ -12,7 +12,7 @@ def test_just_exchange(self): @broker.publisher(exchange="test-ex") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() assert schema["channels"] == { "_:test-ex:Publisher": { @@ -74,7 +74,7 @@ def test_publisher_bindings(self): ) async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -107,7 +107,7 @@ def test_useless_queue_bindings(self): ) async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() assert schema["channels"] == { "_:test-ex:Publisher": { @@ -157,7 +157,7 @@ def test_reusable_exchange(self): @broker.publisher(exchange="test-ex", routing_key="key2", priority=10) async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() assert schema["channels"] == { "key1:test-ex:Publisher": { diff --git a/tests/asyncapi/rabbit/v3_0_0/test_router.py b/tests/asyncapi/rabbit/v3_0_0/test_router.py index e67a4e72ef..d0848a2d25 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_router.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_router.py @@ -30,7 +30,7 @@ async def handle(msg): ... schema = AsyncAPI( broker, schema_version="3.0.0", - ).jsonable() + ).to_jsonable() assert schema == { "info": {"title": "FastStream", "version": "0.1.0", "description": ""}, diff --git a/tests/asyncapi/rabbit/v3_0_0/test_security.py b/tests/asyncapi/rabbit/v3_0_0/test_security.py index 0064330913..55e68288b2 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_security.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_security.py @@ -22,7 +22,7 @@ def test_base_security_schema(): schema = AsyncAPI( broker, schema_version="3.0.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "3.0.0", @@ -63,7 +63,7 @@ def test_plaintext_security_schema(): schema = AsyncAPI( broker, schema_version="3.0.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "3.0.0", "channels": {}, @@ -103,7 +103,7 @@ def test_plaintext_security_schema_without_ssl(): schema = AsyncAPI( broker, schema_version="3.0.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "3.0.0", "channels": {}, diff --git a/tests/asyncapi/redis/v2_6_0/test_arguments.py b/tests/asyncapi/redis/v2_6_0/test_arguments.py index 678c5e654a..6989305e85 100644 --- a/tests/asyncapi/redis/v2_6_0/test_arguments.py +++ b/tests/asyncapi/redis/v2_6_0/test_arguments.py @@ -12,7 +12,7 @@ def test_channel_subscriber(self): @broker.subscriber("test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -29,7 +29,7 @@ def test_channel_pattern_subscriber(self): @broker.subscriber("test.{path}") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -46,7 +46,7 @@ def test_list_subscriber(self): @broker.subscriber(list="test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -59,7 +59,7 @@ def test_stream_subscriber(self): @broker.subscriber(stream="test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -72,7 +72,7 @@ def test_stream_group_subscriber(self): @broker.subscriber(stream=StreamSub("test", group="group", consumer="consumer")) async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/redis/v2_6_0/test_connection.py b/tests/asyncapi/redis/v2_6_0/test_connection.py index c26cececf3..7a507e2a2a 100644 --- a/tests/asyncapi/redis/v2_6_0/test_connection.py +++ b/tests/asyncapi/redis/v2_6_0/test_connection.py @@ -13,7 +13,7 @@ def test_base(): tags=(Tag(name="some-tag", description="experimental"),), ), schema_version="2.6.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "2.6.0", @@ -39,7 +39,7 @@ def test_custom(): "redis://localhost:6379", specification_url="rediss://127.0.0.1:8000" ), schema_version="2.6.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/redis/v2_6_0/test_fastapi.py b/tests/asyncapi/redis/v2_6_0/test_fastapi.py index 734df89abb..3ccfff1c8c 100644 --- a/tests/asyncapi/redis/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/redis/v2_6_0/test_fastapi.py @@ -1,4 +1,3 @@ - from faststream.redis import TestRedisBroker from faststream.redis.fastapi import RedisRouter from tests.asyncapi.base.v2_6_0.arguments import FastAPICompatible diff --git a/tests/asyncapi/redis/v2_6_0/test_naming.py b/tests/asyncapi/redis/v2_6_0/test_naming.py index 0e9bac8c11..8371c5986f 100644 --- a/tests/asyncapi/redis/v2_6_0/test_naming.py +++ b/tests/asyncapi/redis/v2_6_0/test_naming.py @@ -14,7 +14,7 @@ def test_base(self): @broker.subscriber("test") async def handle(): ... - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", @@ -71,7 +71,7 @@ def test_subscribers_variations(self, args): async def handle(): ... schema = AsyncAPI(broker) - assert list(schema.jsonable()["channels"].keys()) == ["test:Handle"] + assert list(schema.to_jsonable()["channels"].keys()) == ["test:Handle"] @pytest.mark.parametrize( "args", @@ -88,4 +88,4 @@ def test_publisher_variations(self, args): async def handle(): ... schema = AsyncAPI(broker) - assert list(schema.jsonable()["channels"].keys()) == ["test:Publisher"] + assert list(schema.to_jsonable()["channels"].keys()) == ["test:Publisher"] diff --git a/tests/asyncapi/redis/v2_6_0/test_publisher.py b/tests/asyncapi/redis/v2_6_0/test_publisher.py index 49a9e2bfcf..873116b2cb 100644 --- a/tests/asyncapi/redis/v2_6_0/test_publisher.py +++ b/tests/asyncapi/redis/v2_6_0/test_publisher.py @@ -12,7 +12,7 @@ def test_channel_publisher(self): @broker.publisher("test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -29,7 +29,7 @@ def test_list_publisher(self): @broker.publisher(list="test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -42,7 +42,7 @@ def test_stream_publisher(self): @broker.publisher(stream="test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/redis/v2_6_0/test_router.py b/tests/asyncapi/redis/v2_6_0/test_router.py index 118be716c3..c607713a4f 100644 --- a/tests/asyncapi/redis/v2_6_0/test_router.py +++ b/tests/asyncapi/redis/v2_6_0/test_router.py @@ -21,7 +21,7 @@ async def handle(msg): ... broker.include_router(router) - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/redis/v2_6_0/test_security.py b/tests/asyncapi/redis/v2_6_0/test_security.py index cfef5f9a58..ac981ddfd9 100644 --- a/tests/asyncapi/redis/v2_6_0/test_security.py +++ b/tests/asyncapi/redis/v2_6_0/test_security.py @@ -18,7 +18,7 @@ def test_base_security_schema(): broker.url == "rediss://localhost:6379/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", @@ -52,7 +52,7 @@ def test_plaintext_security_schema(): broker.url == "redis://localhost:6379/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", @@ -87,7 +87,7 @@ def test_plaintext_security_schema_without_ssl(): broker.url == "redis://localhost:6379/" # pragma: allowlist secret ) # pragma: allowlist secret - schema = AsyncAPI(broker, schema_version="2.6.0").jsonable() + schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert schema == { "asyncapi": "2.6.0", diff --git a/tests/asyncapi/redis/v3_0_0/test_arguments.py b/tests/asyncapi/redis/v3_0_0/test_arguments.py index 4d230d259b..546544b1cd 100644 --- a/tests/asyncapi/redis/v3_0_0/test_arguments.py +++ b/tests/asyncapi/redis/v3_0_0/test_arguments.py @@ -12,7 +12,7 @@ def test_channel_subscriber(self): @broker.subscriber("test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -29,7 +29,7 @@ def test_channel_pattern_subscriber(self): @broker.subscriber("test.{path}") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -46,7 +46,7 @@ def test_list_subscriber(self): @broker.subscriber(list="test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -59,7 +59,7 @@ def test_stream_subscriber(self): @broker.subscriber(stream="test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -72,7 +72,7 @@ def test_stream_group_subscriber(self): @broker.subscriber(stream=StreamSub("test", group="group", consumer="consumer")) async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/redis/v3_0_0/test_connection.py b/tests/asyncapi/redis/v3_0_0/test_connection.py index ec0390d425..a14f2eb737 100644 --- a/tests/asyncapi/redis/v3_0_0/test_connection.py +++ b/tests/asyncapi/redis/v3_0_0/test_connection.py @@ -13,7 +13,7 @@ def test_base(): tags=(Tag(name="some-tag", description="experimental"),), ), schema_version="3.0.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "3.0.0", @@ -41,7 +41,7 @@ def test_custom(): "redis://localhost:6379", specification_url="rediss://127.0.0.1:8000" ), schema_version="3.0.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "3.0.0", diff --git a/tests/asyncapi/redis/v3_0_0/test_naming.py b/tests/asyncapi/redis/v3_0_0/test_naming.py index 64d448660c..13088411c2 100644 --- a/tests/asyncapi/redis/v3_0_0/test_naming.py +++ b/tests/asyncapi/redis/v3_0_0/test_naming.py @@ -17,7 +17,7 @@ async def handle(): ... schema = AsyncAPI( broker, schema_version="3.0.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "3.0.0", @@ -89,7 +89,7 @@ def test_subscribers_variations(self, args): async def handle(): ... schema = AsyncAPI(broker) - assert list(schema.jsonable()["channels"].keys()) == ["test:Handle"] + assert list(schema.to_jsonable()["channels"].keys()) == ["test:Handle"] @pytest.mark.parametrize( "args", @@ -106,4 +106,4 @@ def test_publisher_variations(self, args): async def handle(): ... schema = AsyncAPI(broker) - assert list(schema.jsonable()["channels"].keys()) == ["test:Publisher"] + assert list(schema.to_jsonable()["channels"].keys()) == ["test:Publisher"] diff --git a/tests/asyncapi/redis/v3_0_0/test_publisher.py b/tests/asyncapi/redis/v3_0_0/test_publisher.py index df8b5783e1..2ab2e819de 100644 --- a/tests/asyncapi/redis/v3_0_0/test_publisher.py +++ b/tests/asyncapi/redis/v3_0_0/test_publisher.py @@ -12,7 +12,7 @@ def test_channel_publisher(self): @broker.publisher("test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -29,7 +29,7 @@ def test_list_publisher(self): @broker.publisher(list="test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { @@ -42,7 +42,7 @@ def test_stream_publisher(self): @broker.publisher(stream="test") async def handle(msg): ... - schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { diff --git a/tests/asyncapi/redis/v3_0_0/test_router.py b/tests/asyncapi/redis/v3_0_0/test_router.py index 8582be3142..c98e8c6f13 100644 --- a/tests/asyncapi/redis/v3_0_0/test_router.py +++ b/tests/asyncapi/redis/v3_0_0/test_router.py @@ -24,7 +24,7 @@ async def handle(msg): ... schema = AsyncAPI( broker, schema_version="3.0.0", - ).jsonable() + ).to_jsonable() assert schema == { "info": {"title": "FastStream", "version": "0.1.0", "description": ""}, diff --git a/tests/asyncapi/redis/v3_0_0/test_security.py b/tests/asyncapi/redis/v3_0_0/test_security.py index bb28b5e61c..db7b3a131a 100644 --- a/tests/asyncapi/redis/v3_0_0/test_security.py +++ b/tests/asyncapi/redis/v3_0_0/test_security.py @@ -21,7 +21,7 @@ def test_base_security_schema(): schema = AsyncAPI( broker, schema_version="3.0.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "3.0.0", @@ -60,7 +60,7 @@ def test_plaintext_security_schema(): schema = AsyncAPI( broker, schema_version="3.0.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "3.0.0", @@ -100,7 +100,7 @@ def test_plaintext_security_schema_without_ssl(): schema = AsyncAPI( broker, schema_version="3.0.0", - ).jsonable() + ).to_jsonable() assert schema == { "asyncapi": "3.0.0", From 2ed00d7b0dabc73034bcfb04716928efefde95cd Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Wed, 2 Oct 2024 21:57:34 +0300 Subject: [PATCH 174/245] lint: update ruff config, drop python3.8 --- docs/create_api_docs.py | 42 +- docs/docs.py | 13 +- docs/expand_markdown.py | 9 +- docs/update_releases.py | 6 +- faststream/__init__.py | 28 +- faststream/__main__.py | 5 +- faststream/_internal/_compat.py | 147 +++++-- faststream/_internal/application.py | 23 +- faststream/_internal/basic_types.py | 24 +- faststream/_internal/broker/abc_broker.py | 12 +- faststream/_internal/broker/broker.py | 22 +- faststream/_internal/broker/router.py | 2 +- faststream/_internal/cli/docs/app.py | 14 +- faststream/_internal/cli/main.py | 37 +- .../_internal/cli/supervisors/basereload.py | 9 +- .../_internal/cli/supervisors/multiprocess.py | 6 +- .../_internal/cli/supervisors/watchfiles.py | 5 +- faststream/_internal/cli/utils/errors.py | 6 +- faststream/_internal/cli/utils/imports.py | 29 +- faststream/_internal/cli/utils/logs.py | 23 +- faststream/_internal/cli/utils/parser.py | 70 ++- faststream/_internal/context/__init__.py | 2 +- faststream/_internal/context/repository.py | 14 +- faststream/_internal/fastapi/_compat.py | 18 +- faststream/_internal/fastapi/context.py | 3 +- faststream/_internal/fastapi/get_dependant.py | 13 +- faststream/_internal/fastapi/route.py | 17 +- faststream/_internal/fastapi/router.py | 57 ++- faststream/_internal/log/formatter.py | 2 +- faststream/_internal/log/logging.py | 9 +- faststream/_internal/proto.py | 16 +- faststream/_internal/publisher/fake.py | 8 +- faststream/_internal/publisher/proto.py | 3 +- faststream/_internal/publisher/usecase.py | 15 +- faststream/_internal/setup/__init__.py | 10 +- faststream/_internal/setup/fast_depends.py | 3 +- faststream/_internal/setup/logger.py | 13 +- faststream/_internal/setup/state.py | 4 +- .../subscriber/acknowledgement_watcher.py | 26 +- faststream/_internal/subscriber/call_item.py | 27 +- .../_internal/subscriber/call_wrapper/call.py | 27 +- .../subscriber/call_wrapper/proto.py | 2 +- faststream/_internal/subscriber/proto.py | 11 +- faststream/_internal/subscriber/usecase.py | 57 ++- faststream/_internal/subscriber/utils.py | 32 +- faststream/_internal/testing/app.py | 10 +- faststream/_internal/testing/ast.py | 7 +- faststream/_internal/testing/broker.py | 70 +-- faststream/_internal/types.py | 2 +- faststream/_internal/utils/data.py | 8 +- faststream/_internal/utils/functions.py | 17 +- faststream/_internal/utils/nuid.py | 2 +- faststream/_internal/utils/path.py | 8 +- faststream/annotations.py | 4 +- faststream/app.py | 8 +- faststream/asgi/__init__.py | 4 +- faststream/asgi/app.py | 19 +- faststream/asgi/factories.py | 3 +- faststream/asgi/handlers.py | 3 +- faststream/asgi/response.py | 13 +- faststream/asgi/types.py | 3 +- faststream/asgi/websocket.py | 2 +- faststream/confluent/__init__.py | 8 +- faststream/confluent/annotations.py | 8 +- faststream/confluent/broker/broker.py | 53 ++- faststream/confluent/broker/logging.py | 20 +- faststream/confluent/broker/registrator.py | 214 +++++----- faststream/confluent/client.py | 66 +-- faststream/confluent/fastapi/__init__.py | 8 +- faststream/confluent/fastapi/fastapi.py | 329 +++++++------- faststream/confluent/message.py | 6 +- .../confluent/opentelemetry/provider.py | 20 +- faststream/confluent/parser.py | 15 +- faststream/confluent/publisher/producer.py | 9 +- faststream/confluent/publisher/publisher.py | 58 ++- faststream/confluent/publisher/usecase.py | 21 +- faststream/confluent/response.py | 3 +- faststream/confluent/router.py | 59 ++- faststream/confluent/schemas/params.py | 4 +- faststream/confluent/schemas/partition.py | 8 +- faststream/confluent/security.py | 19 +- faststream/confluent/subscriber/factory.py | 43 +- faststream/confluent/subscriber/subscriber.py | 8 +- faststream/confluent/subscriber/usecase.py | 34 +- faststream/confluent/testing.py | 39 +- faststream/exceptions.py | 13 +- faststream/kafka/__init__.py | 8 +- faststream/kafka/annotations.py | 9 +- faststream/kafka/broker/broker.py | 95 ++--- faststream/kafka/broker/logging.py | 20 +- faststream/kafka/broker/registrator.py | 283 ++++++------ faststream/kafka/fastapi/__init__.py | 8 +- faststream/kafka/fastapi/fastapi.py | 401 +++++++++--------- faststream/kafka/message.py | 6 +- faststream/kafka/opentelemetry/provider.py | 20 +- faststream/kafka/parser.py | 19 +- faststream/kafka/publisher/producer.py | 9 +- faststream/kafka/publisher/publisher.py | 58 ++- faststream/kafka/publisher/usecase.py | 54 ++- faststream/kafka/response.py | 3 +- faststream/kafka/router.py | 79 ++-- faststream/kafka/schemas/params.py | 4 +- faststream/kafka/security.py | 16 +- faststream/kafka/subscriber/factory.py | 65 +-- faststream/kafka/subscriber/subscriber.py | 8 +- faststream/kafka/subscriber/usecase.py | 36 +- faststream/kafka/testing.py | 26 +- faststream/message/__init__.py | 4 +- faststream/message/message.py | 5 +- faststream/message/utils.py | 5 +- faststream/middlewares/base.py | 7 +- faststream/middlewares/exception.py | 71 ++-- faststream/middlewares/logging.py | 4 +- faststream/nats/__init__.py | 30 +- faststream/nats/annotations.py | 19 +- faststream/nats/broker/broker.py | 82 ++-- faststream/nats/broker/logging.py | 24 +- faststream/nats/broker/registrator.py | 41 +- faststream/nats/fastapi/__init__.py | 13 +- faststream/nats/fastapi/fastapi.py | 119 +++--- faststream/nats/helpers/__init__.py | 2 +- faststream/nats/helpers/bucket_declarer.py | 6 +- .../nats/helpers/obj_storage_declarer.py | 4 +- faststream/nats/helpers/object_builder.py | 4 +- faststream/nats/message.py | 8 +- faststream/nats/opentelemetry/provider.py | 16 +- faststream/nats/parser.py | 19 +- faststream/nats/publisher/producer.py | 12 +- faststream/nats/publisher/publisher.py | 13 +- faststream/nats/publisher/usecase.py | 19 +- faststream/nats/response.py | 7 +- faststream/nats/router.py | 37 +- faststream/nats/schemas/__init__.py | 2 +- faststream/nats/schemas/js_stream.py | 47 +- faststream/nats/schemas/kv_watch.py | 6 +- faststream/nats/schemas/obj_watch.py | 7 +- faststream/nats/schemas/pull_sub.py | 5 +- faststream/nats/security.py | 8 +- faststream/nats/subscriber/factory.py | 217 +++++----- faststream/nats/subscriber/subscriber.py | 14 +- faststream/nats/subscriber/usecase.py | 45 +- faststream/nats/testing.py | 28 +- faststream/opentelemetry/annotations.py | 3 +- faststream/opentelemetry/baggage.py | 8 +- faststream/opentelemetry/middleware.py | 63 +-- faststream/params/__init__.py | 4 +- faststream/params/no_cast.py | 3 +- faststream/rabbit/__init__.py | 16 +- faststream/rabbit/annotations.py | 18 +- faststream/rabbit/broker/broker.py | 56 ++- faststream/rabbit/broker/registrator.py | 39 +- faststream/rabbit/fastapi/__init__.py | 6 +- faststream/rabbit/fastapi/router.py | 109 +++-- faststream/rabbit/helpers/declarer.py | 6 +- faststream/rabbit/opentelemetry/provider.py | 4 +- faststream/rabbit/parser.py | 41 +- faststream/rabbit/publisher/producer.py | 3 +- faststream/rabbit/publisher/publisher.py | 61 +-- faststream/rabbit/publisher/usecase.py | 24 +- faststream/rabbit/response.py | 3 +- faststream/rabbit/router.py | 31 +- faststream/rabbit/schemas/__init__.py | 6 +- faststream/rabbit/schemas/exchange.py | 26 +- faststream/rabbit/schemas/queue.py | 26 +- faststream/rabbit/security.py | 8 +- faststream/rabbit/subscriber/factory.py | 3 +- faststream/rabbit/subscriber/subscriber.py | 50 +-- faststream/rabbit/subscriber/usecase.py | 11 +- faststream/rabbit/testing.py | 84 ++-- faststream/rabbit/utils.py | 4 +- faststream/redis/__init__.py | 12 +- faststream/redis/annotations.py | 9 +- faststream/redis/broker/broker.py | 41 +- faststream/redis/broker/logging.py | 2 +- faststream/redis/broker/registrator.py | 23 +- faststream/redis/fastapi/__init__.py | 11 +- faststream/redis/fastapi/fastapi.py | 94 ++-- faststream/redis/message.py | 22 +- faststream/redis/opentelemetry/provider.py | 5 +- faststream/redis/parser.py | 42 +- faststream/redis/publisher/producer.py | 8 +- faststream/redis/publisher/publisher.py | 43 +- faststream/redis/publisher/usecase.py | 29 +- faststream/redis/response.py | 3 +- faststream/redis/router.py | 19 +- faststream/redis/schemas/__init__.py | 2 +- faststream/redis/schemas/list_sub.py | 2 +- faststream/redis/schemas/proto.py | 13 +- faststream/redis/schemas/pub_sub.py | 4 +- faststream/redis/schemas/stream_sub.py | 15 +- faststream/redis/security.py | 11 +- faststream/redis/subscriber/factory.py | 64 ++- faststream/redis/subscriber/subscriber.py | 8 +- faststream/redis/subscriber/usecase.py | 79 ++-- faststream/redis/testing.py | 46 +- faststream/response/response.py | 3 +- faststream/security.py | 42 +- faststream/specification/__init__.py | 2 +- faststream/specification/asyncapi/factory.py | 9 +- faststream/specification/asyncapi/message.py | 14 +- faststream/specification/asyncapi/site.py | 6 +- faststream/specification/asyncapi/utils.py | 8 +- .../specification/asyncapi/v2_6_0/facade.py | 5 +- .../specification/asyncapi/v2_6_0/generate.py | 44 +- .../asyncapi/v2_6_0/schema/__init__.py | 75 ++-- .../v2_6_0/schema/bindings/__init__.py | 2 +- .../v2_6_0/schema/bindings/amqp/__init__.py | 6 +- .../v2_6_0/schema/bindings/amqp/channel.py | 2 +- .../v2_6_0/schema/bindings/kafka/__init__.py | 6 +- .../v2_6_0/schema/bindings/main/__init__.py | 6 +- .../v2_6_0/schema/bindings/main/channel.py | 8 +- .../v2_6_0/schema/bindings/main/operation.py | 8 +- .../v2_6_0/schema/bindings/nats/__init__.py | 6 +- .../v2_6_0/schema/bindings/redis/__init__.py | 6 +- .../v2_6_0/schema/bindings/sqs/__init__.py | 6 +- .../asyncapi/v2_6_0/schema/channels.py | 6 +- .../asyncapi/v2_6_0/schema/components.py | 7 +- .../asyncapi/v2_6_0/schema/contact.py | 81 +--- .../asyncapi/v2_6_0/schema/message.py | 6 +- .../asyncapi/v2_6_0/schema/operations.py | 10 +- .../asyncapi/v2_6_0/schema/schema.py | 8 +- .../asyncapi/v2_6_0/schema/servers.py | 12 +- .../asyncapi/v2_6_0/schema/tag.py | 2 - .../asyncapi/v2_6_0/schema/utils.py | 1 - .../specification/asyncapi/v3_0_0/facade.py | 5 +- .../specification/asyncapi/v3_0_0/generate.py | 75 ++-- .../asyncapi/v3_0_0/schema/__init__.py | 20 +- .../v3_0_0/schema/bindings/__init__.py | 2 +- .../v3_0_0/schema/bindings/amqp/__init__.py | 4 +- .../v3_0_0/schema/bindings/amqp/channel.py | 2 +- .../v3_0_0/schema/bindings/amqp/operation.py | 4 +- .../v3_0_0/schema/bindings/main/__init__.py | 4 +- .../v3_0_0/schema/bindings/main/operation.py | 6 +- .../asyncapi/v3_0_0/schema/channels.py | 8 +- .../asyncapi/v3_0_0/schema/components.py | 8 +- .../asyncapi/v3_0_0/schema/info.py | 3 +- .../asyncapi/v3_0_0/schema/operations.py | 21 +- .../asyncapi/v3_0_0/schema/schema.py | 8 +- .../asyncapi/v3_0_0/schema/servers.py | 8 +- faststream/specification/base/proto.py | 15 +- faststream/specification/schema/__init__.py | 2 +- .../specification/schema/bindings/kafka.py | 8 +- .../specification/schema/bindings/main.py | 12 +- .../specification/schema/bindings/nats.py | 4 +- .../specification/schema/bindings/redis.py | 4 +- .../specification/schema/bindings/sqs.py | 6 +- faststream/specification/schema/channel.py | 4 +- faststream/specification/schema/components.py | 7 +- faststream/specification/schema/contact.py | 81 +--- faststream/specification/schema/info.py | 5 +- faststream/specification/schema/message.py | 8 +- faststream/specification/schema/operation.py | 6 +- faststream/specification/schema/security.py | 6 +- faststream/specification/schema/servers.py | 12 +- pyproject.toml | 123 +----- ruff.toml | 148 +++++++ tests/a_docs/confluent/ack/test_errors.py | 4 +- .../batch_consuming_pydantic/test_app.py | 2 +- .../confluent/publish_batch/test_app.py | 4 +- .../asyncapi_customization/test_basic.py | 18 +- .../asyncapi_customization/test_broker.py | 2 +- .../asyncapi_customization/test_handler.py | 6 +- .../asyncapi_customization/test_payload.py | 4 +- .../cli/rabbit/test_rabbit_context.py | 2 +- .../dependencies/test_basic.py | 2 +- .../dependencies/test_class.py | 2 +- .../dependencies/test_global.py | 2 +- .../dependencies/test_global_broker.py | 2 +- .../dependencies/test_sub_dep.py | 2 +- .../getting_started/routers/test_delay.py | 10 +- .../routers/test_delay_equal.py | 10 +- tests/a_docs/index/test_basic.py | 10 +- tests/a_docs/integration/fastapi/test_base.py | 10 +- tests/a_docs/kafka/ack/test_errors.py | 4 +- .../batch_consuming_pydantic/test_app.py | 2 +- tests/a_docs/kafka/publish_batch/test_app.py | 4 +- tests/a_docs/rabbit/test_security.py | 4 +- tests/a_docs/redis/test_security.py | 4 +- tests/asgi/testcase.py | 2 +- tests/asyncapi/base/v2_6_0/arguments.py | 35 +- tests/asyncapi/base/v2_6_0/fastapi.py | 2 +- tests/asyncapi/base/v2_6_0/naming.py | 46 +- tests/asyncapi/base/v3_0_0/arguments.py | 35 +- tests/asyncapi/base/v3_0_0/fastapi.py | 2 +- tests/asyncapi/base/v3_0_0/naming.py | 52 +-- .../confluent/v2_6_0/test_arguments.py | 2 +- .../confluent/v2_6_0/test_connection.py | 5 +- .../asyncapi/confluent/v2_6_0/test_fastapi.py | 2 +- .../asyncapi/confluent/v2_6_0/test_naming.py | 12 +- .../confluent/v2_6_0/test_publisher.py | 2 +- .../asyncapi/confluent/v2_6_0/test_router.py | 18 +- .../confluent/v2_6_0/test_security.py | 22 +- .../confluent/v3_0_0/test_arguments.py | 2 +- .../confluent/v3_0_0/test_connection.py | 2 +- .../asyncapi/confluent/v3_0_0/test_fastapi.py | 2 +- .../asyncapi/confluent/v3_0_0/test_naming.py | 14 +- .../confluent/v3_0_0/test_publisher.py | 2 +- .../asyncapi/confluent/v3_0_0/test_router.py | 24 +- .../confluent/v3_0_0/test_security.py | 26 +- tests/asyncapi/kafka/v2_6_0/test_app.py | 12 +- tests/asyncapi/kafka/v2_6_0/test_arguments.py | 2 +- .../asyncapi/kafka/v2_6_0/test_connection.py | 2 +- tests/asyncapi/kafka/v2_6_0/test_fastapi.py | 2 +- tests/asyncapi/kafka/v2_6_0/test_naming.py | 12 +- tests/asyncapi/kafka/v2_6_0/test_publisher.py | 2 +- tests/asyncapi/kafka/v2_6_0/test_router.py | 18 +- tests/asyncapi/kafka/v2_6_0/test_security.py | 22 +- tests/asyncapi/kafka/v3_0_0/test_arguments.py | 2 +- .../asyncapi/kafka/v3_0_0/test_connection.py | 2 +- tests/asyncapi/kafka/v3_0_0/test_fastapi.py | 2 +- tests/asyncapi/kafka/v3_0_0/test_naming.py | 14 +- tests/asyncapi/kafka/v3_0_0/test_publisher.py | 2 +- tests/asyncapi/kafka/v3_0_0/test_router.py | 24 +- tests/asyncapi/kafka/v3_0_0/test_security.py | 26 +- tests/asyncapi/nats/v2_6_0/test_arguments.py | 2 +- tests/asyncapi/nats/v2_6_0/test_connection.py | 5 +- tests/asyncapi/nats/v2_6_0/test_naming.py | 14 +- tests/asyncapi/nats/v2_6_0/test_publisher.py | 2 +- tests/asyncapi/nats/v2_6_0/test_router.py | 18 +- tests/asyncapi/nats/v3_0_0/test_arguments.py | 2 +- tests/asyncapi/nats/v3_0_0/test_connection.py | 2 +- tests/asyncapi/nats/v3_0_0/test_naming.py | 16 +- tests/asyncapi/nats/v3_0_0/test_publisher.py | 2 +- tests/asyncapi/nats/v3_0_0/test_router.py | 24 +- .../asyncapi/rabbit/v2_6_0/test_arguments.py | 12 +- .../asyncapi/rabbit/v2_6_0/test_connection.py | 18 +- tests/asyncapi/rabbit/v2_6_0/test_fastapi.py | 2 +- tests/asyncapi/rabbit/v2_6_0/test_naming.py | 20 +- .../asyncapi/rabbit/v2_6_0/test_publisher.py | 30 +- tests/asyncapi/rabbit/v2_6_0/test_router.py | 18 +- tests/asyncapi/rabbit/v2_6_0/test_security.py | 6 +- .../asyncapi/rabbit/v3_0_0/test_arguments.py | 4 +- .../asyncapi/rabbit/v3_0_0/test_connection.py | 14 +- tests/asyncapi/rabbit/v3_0_0/test_fastapi.py | 2 +- tests/asyncapi/rabbit/v3_0_0/test_naming.py | 20 +- .../asyncapi/rabbit/v3_0_0/test_publisher.py | 40 +- tests/asyncapi/rabbit/v3_0_0/test_router.py | 26 +- tests/asyncapi/rabbit/v3_0_0/test_security.py | 6 +- tests/asyncapi/redis/v2_6_0/test_arguments.py | 10 +- .../asyncapi/redis/v2_6_0/test_connection.py | 7 +- tests/asyncapi/redis/v2_6_0/test_naming.py | 14 +- tests/asyncapi/redis/v2_6_0/test_publisher.py | 6 +- tests/asyncapi/redis/v2_6_0/test_router.py | 18 +- tests/asyncapi/redis/v2_6_0/test_security.py | 6 +- tests/asyncapi/redis/v3_0_0/test_arguments.py | 10 +- .../asyncapi/redis/v3_0_0/test_connection.py | 7 +- tests/asyncapi/redis/v3_0_0/test_naming.py | 18 +- tests/asyncapi/redis/v3_0_0/test_publisher.py | 6 +- tests/asyncapi/redis/v3_0_0/test_router.py | 24 +- tests/asyncapi/redis/v3_0_0/test_security.py | 6 +- tests/brokers/base/fastapi.py | 10 +- tests/brokers/base/middlewares.py | 16 +- tests/brokers/base/publish.py | 6 +- tests/brokers/base/router.py | 5 +- tests/brokers/base/testclient.py | 5 +- tests/brokers/confluent/basic.py | 4 +- tests/brokers/confluent/test_connect.py | 2 +- tests/brokers/confluent/test_consume.py | 30 +- tests/brokers/confluent/test_security.py | 10 +- tests/brokers/confluent/test_test_client.py | 7 +- .../brokers/confluent/test_test_reentrancy.py | 8 +- tests/brokers/kafka/test_consume.py | 32 +- tests/brokers/kafka/test_test_client.py | 7 +- tests/brokers/kafka/test_test_reentrancy.py | 2 +- tests/brokers/nats/test_consume.py | 6 +- tests/brokers/nats/test_fastapi.py | 2 +- tests/brokers/nats/test_router.py | 3 +- tests/brokers/nats/test_test_client.py | 3 +- .../rabbit/specific/test_nested_exchange.py | 7 +- tests/brokers/rabbit/test_consume.py | 80 ++-- tests/brokers/rabbit/test_fastapi.py | 2 +- tests/brokers/rabbit/test_publish.py | 2 +- tests/brokers/rabbit/test_router.py | 11 +- tests/brokers/rabbit/test_schemas.py | 4 +- tests/brokers/rabbit/test_test_client.py | 21 +- tests/brokers/rabbit/test_test_reentrancy.py | 2 +- tests/brokers/redis/test_consume.py | 38 +- tests/brokers/redis/test_fastapi.py | 3 +- tests/brokers/redis/test_test_client.py | 3 +- tests/cli/rabbit/test_app.py | 130 ++++-- tests/cli/test_asyncapi_docs.py | 3 +- tests/cli/test_publish.py | 2 +- tests/cli/test_run.py | 15 +- tests/mocks.py | 3 +- tests/mypy/kafka.py | 8 +- tests/mypy/nats.py | 8 +- tests/mypy/rabbit.py | 5 +- tests/mypy/redis.py | 8 +- tests/opentelemetry/basic.py | 20 +- .../opentelemetry/confluent/test_confluent.py | 31 +- tests/opentelemetry/kafka/test_kafka.py | 31 +- tests/opentelemetry/nats/test_nats.py | 3 +- tests/opentelemetry/redis/test_redis.py | 24 +- tests/tools.py | 1 + tests/utils/context/test_main.py | 9 +- tests/utils/test_ast.py | 2 +- 396 files changed, 4205 insertions(+), 4124 deletions(-) create mode 100644 ruff.toml diff --git a/docs/create_api_docs.py b/docs/create_api_docs.py index 64dafda5ff..fe21b9b4fd 100644 --- a/docs/create_api_docs.py +++ b/docs/create_api_docs.py @@ -63,7 +63,8 @@ def _get_submodules(package_name: str) -> List[str]: def _import_submodules( - module_name: str, include_public_api_only: bool = False + module_name: str, + include_public_api_only: bool = False, ) -> Optional[List[ModuleType]]: def _import_module(name: str) -> Optional[ModuleType]: try: @@ -89,7 +90,8 @@ def _import_module(name: str) -> Optional[ModuleType]: def _import_functions_and_classes( - m: ModuleType, include_public_api_only: bool = False + m: ModuleType, + include_public_api_only: bool = False, ) -> List[Tuple[str, Union[FunctionType, Type[Any]]]]: funcs_and_classes = [] if not include_public_api_only: @@ -112,20 +114,23 @@ def _is_private(name: str) -> bool: def _import_all_members( - module_name: str, include_public_api_only: bool = False + module_name: str, + include_public_api_only: bool = False, ) -> List[str]: submodules = _import_submodules( - module_name, include_public_api_only=include_public_api_only + module_name, + include_public_api_only=include_public_api_only, ) members: List[Tuple[str, Union[FunctionType, Type[Any]]]] = list( itertools.chain( *[ _import_functions_and_classes( - m, include_public_api_only=include_public_api_only + m, + include_public_api_only=include_public_api_only, ) for m in submodules - ] - ) + ], + ), ) names = [ @@ -168,9 +173,8 @@ def _get_api_summary_item(x: str) -> str: if x.endswith("."): indent = " " * (4 * (len(xs) - 1 + 1)) return f"{indent}- {xs[-2]}" - else: - indent = " " * (4 * (len(xs) + 1)) - return f"{indent}- [{xs[-1]}](api/{'/'.join(xs)}.md)" + indent = " " * (4 * (len(xs) + 1)) + return f"{indent}- [{xs[-1]}](api/{'/'.join(xs)}.md)" def _get_api_summary(members: List[str]) -> str: @@ -236,7 +240,9 @@ def _load_submodules( def _update_single_api_doc( - symbol: Union[FunctionType, Type[Any]], docs_path: Path, module_name: str + symbol: Union[FunctionType, Type[Any]], + docs_path: Path, + module_name: str, ) -> None: en_docs_path = docs_path / "docs" / "en" @@ -263,11 +269,15 @@ def _update_single_api_doc( def _update_api_docs( - symbols: List[Union[FunctionType, Type[Any]]], docs_path: Path, module_name: str + symbols: List[Union[FunctionType, Type[Any]]], + docs_path: Path, + module_name: str, ) -> None: for symbol in symbols: _update_single_api_doc( - symbol=symbol, docs_path=docs_path, module_name=module_name + symbol=symbol, + docs_path=docs_path, + module_name=module_name, ) @@ -284,8 +294,8 @@ def _generate_api_docs_for_module(root_path: Path, module_name: str) -> Tuple[st """ public_api_summary = _get_api_summary( _add_all_submodules( - _import_all_members(module_name, include_public_api_only=True) - ) + _import_all_members(module_name, include_public_api_only=True), + ), ) # Using public_api/ symlink pointing to api/ because of the issue # https://github.com/mkdocs/mkdocs/issues/1974 @@ -308,7 +318,7 @@ def _generate_api_docs_for_module(root_path: Path, module_name: str) -> Tuple[st _update_api_docs(symbols, root_path, module_name) - # todo: fix the problem and remove this + # TODO: fix the problem and remove this src = """ - [ContactDict](api/faststream/asyncapi/schema/info/ContactDict.md) """ dst = """ - [ContactDict](api/faststream/asyncapi/schema/info/ContactDict.md) diff --git a/docs/docs.py b/docs/docs.py index f5a9f0e7a9..045c665068 100644 --- a/docs/docs.py +++ b/docs/docs.py @@ -22,7 +22,7 @@ CONFIG = BASE_DIR / "mkdocs.yml" DOCS_DIR = BASE_DIR / "docs" LANGUAGES_DIRS = tuple( - filter(lambda f: f.is_dir() and f.name not in IGNORE_DIRS, DOCS_DIR.iterdir()) + filter(lambda f: f.is_dir() and f.name not in IGNORE_DIRS, DOCS_DIR.iterdir()), ) BUILD_DIR = BASE_DIR / "site" @@ -125,7 +125,7 @@ def add(path=typer.Argument(...)): not_exists.append(i) file.write_text( f"# {title or get_default_title(file)} \n" - "{! " + get_in_progress(i.name) + " !}" + "{! " + get_in_progress(i.name) + " !}", ) typer.echo(f"{file} - write `in progress`") @@ -134,7 +134,7 @@ def add(path=typer.Argument(...)): file = i / path file.write_text( f"# {title or get_default_title(file)} \n" - "{! " + get_missing_translation(i.name) + " !}" + "{! " + get_missing_translation(i.name) + " !}", ) typer.echo(f"{file} - write `missing translation`") @@ -172,9 +172,8 @@ def mv(path: str = typer.Argument(...), new_path: str = typer.Argument(...)): @app.command() def update_readme() -> None: """Update README.md by expanding embeddings in docs/docs/en/index.md.""" - # todo: fix this function + # TODO: fix this function typer.echo("Skipping updating README.md for now") - return None # typer.echo(f"Updating README.md") # expand_markdown(input_markdown_path=EN_INDEX_PATH, output_markdown_path=README_PATH) @@ -208,9 +207,9 @@ def update_contributing(): ( f"> **_NOTE:_** This is an auto-generated file. Please edit {relative_path} instead.", *content, - ) + ), ) - + "\n" + + "\n", ) diff --git a/docs/expand_markdown.py b/docs/expand_markdown.py index 4cc40e83c0..1d06c6fb06 100644 --- a/docs/expand_markdown.py +++ b/docs/expand_markdown.py @@ -68,9 +68,12 @@ def expand_markdown( input_markdown_path: Path = typer.Argument(...), output_markdown_path: Path = typer.Argument(...), ): - with input_markdown_path.open() as input_file, output_markdown_path.open( - "w" - ) as output_file: + with ( + input_markdown_path.open() as input_file, + output_markdown_path.open( + "w", + ) as output_file, + ): for line in input_file: # Check if the line does not contain the "{!>" pattern if "{!>" not in line: diff --git a/docs/update_releases.py b/docs/update_releases.py index 79a6ca0d6b..7e7e82ac41 100644 --- a/docs/update_releases.py +++ b/docs/update_releases.py @@ -35,7 +35,9 @@ def convert_links_and_usernames(text): if "](" not in text: # Convert HTTP/HTTPS links text = re.sub( - r"(https?://.*\/(.*))", r'[#\2](\1){.external-link target="_blank"}', text + r"(https?://.*\/(.*))", + r'[#\2](\1){.external-link target="_blank"}', + text, ) # Convert GitHub usernames to links @@ -83,7 +85,7 @@ def update_release_notes(realease_notes_path: Path): + "\n" # adding an addition newline after the header results in one empty file being added every time we run the script + changelog + "\n" - ).replace("\r", "") + ).replace("\r", ""), ) diff --git a/faststream/__init__.py b/faststream/__init__.py index cc3c8a159b..b4241ff458 100644 --- a/faststream/__init__.py +++ b/faststream/__init__.py @@ -16,25 +16,25 @@ from faststream.response import Response __all__ = ( - # app - "FastStream", - "TestApp", - # utils - "apply_types", - # context - "context", + # middlewares + "BaseMiddleware", # params "Context", - "Header", - "Path", + "ContextRepo", "Depends", - "NoCast", + "ExceptionMiddleware", + # app + "FastStream", + "Header", # annotations "Logger", - "ContextRepo", - # middlewares - "BaseMiddleware", - "ExceptionMiddleware", + "NoCast", + "Path", # basic "Response", + "TestApp", + # utils + "apply_types", + # context + "context", ) diff --git a/faststream/__main__.py b/faststream/__main__.py index 5165f8e528..1b1a44657f 100644 --- a/faststream/__main__.py +++ b/faststream/__main__.py @@ -5,12 +5,15 @@ from faststream._internal._compat import HAS_TYPER if not HAS_TYPER: - raise ImportError( + msg = ( "\n\nYou're trying to use the FastStream CLI, " "\nbut you haven't installed the required dependencies." "\nPlease install them using the following command: " '\npip install "faststream[cli]"' ) + raise ImportError( + msg, + ) from faststream._internal.cli.main import cli diff --git a/faststream/_internal/_compat.py b/faststream/_internal/_compat.py index 6ec078d1ec..e96bfbf46c 100644 --- a/faststream/_internal/_compat.py +++ b/faststream/_internal/_compat.py @@ -1,14 +1,23 @@ import json import os import sys +import warnings +from collections.abc import Iterable, Mapping from importlib.metadata import version as get_version -from typing import Any, Callable, Dict, Mapping, Optional, Type, TypeVar, Union +from importlib.util import find_spec +from typing import ( + Any, + Callable, + Optional, + TypeVar, + Union, +) -from fast_depends._compat import PYDANTIC_V2 as PYDANTIC_V2 from fast_depends._compat import ( # type: ignore[attr-defined] - PYDANTIC_VERSION as PYDANTIC_VERSION, + PYDANTIC_V2, + PYDANTIC_VERSION, ) -from pydantic import BaseModel as BaseModel +from pydantic import BaseModel from faststream._internal.basic_types import AnyDict @@ -28,17 +37,25 @@ def is_test_env() -> bool: orjson: Any ujson: Any +__all__ = ( + "HAS_TYPER", + "PYDANTIC_V2", + "CoreSchema", + "EmailStr", + "GetJsonSchemaHandler", + "json_dumps", + "json_loads", + "with_info_plain_validator_function", +) try: - import typer as typer - - HAS_TYPER = True + HAS_TYPER = find_spec("typer") is not None except ImportError: HAS_TYPER = False try: - import orjson # type: ignore[no-redef] + import orjson except ImportError: orjson = None @@ -55,7 +72,7 @@ def is_test_env() -> bool: json_loads = ujson.loads def json_dumps(*a: Any, **kw: Any) -> bytes: - return ujson.dumps(*a, **kw).encode() # type: ignore + return ujson.dumps(*a, **kw).encode() # type: ignore[no-any-return] else: json_loads = json.loads @@ -69,23 +86,20 @@ def json_dumps(*a: Any, **kw: Any) -> bytes: if PYDANTIC_V2: if PYDANTIC_VERSION >= "2.4.0": from pydantic.annotated_handlers import ( - GetJsonSchemaHandler as GetJsonSchemaHandler, + GetJsonSchemaHandler, ) from pydantic_core.core_schema import ( - with_info_plain_validator_function as with_info_plain_validator_function, + with_info_plain_validator_function, ) else: from pydantic._internal._annotated_handlers import ( # type: ignore[no-redef] - GetJsonSchemaHandler as GetJsonSchemaHandler, + GetJsonSchemaHandler, ) from pydantic_core.core_schema import ( general_plain_validator_function as with_info_plain_validator_function, ) - from pydantic.fields import FieldInfo as FieldInfo - from pydantic_core import CoreSchema as CoreSchema - from pydantic_core import PydanticUndefined as PydanticUndefined - from pydantic_core import to_jsonable_python + from pydantic_core import CoreSchema, PydanticUndefined, to_jsonable_python SCHEMA_FIELD = "json_schema_extra" DEF_KEY = "$defs" @@ -99,22 +113,23 @@ def model_to_jsonable( def dump_json(data: Any) -> bytes: return json_dumps(model_to_jsonable(data)) - def get_model_fields(model: Type[BaseModel]) -> Dict[str, Any]: + def get_model_fields(model: type[BaseModel]) -> dict[str, Any]: return model.model_fields def model_to_json(model: BaseModel, **kwargs: Any) -> str: return model.model_dump_json(**kwargs) def model_parse( - model: Type[ModelVar], data: Union[str, bytes], **kwargs: Any + model: type[ModelVar], + data: Union[str, bytes], + **kwargs: Any, ) -> ModelVar: return model.model_validate_json(data, **kwargs) - def model_schema(model: Type[BaseModel], **kwargs: Any) -> AnyDict: + def model_schema(model: type[BaseModel], **kwargs: Any) -> AnyDict: return model.model_json_schema(**kwargs) else: - from pydantic.fields import FieldInfo as FieldInfo from pydantic.json import pydantic_encoder GetJsonSchemaHandler = Any # type: ignore[assignment,misc] @@ -128,18 +143,20 @@ def model_schema(model: Type[BaseModel], **kwargs: Any) -> AnyDict: def dump_json(data: Any) -> bytes: return json_dumps(data, default=pydantic_encoder) - def get_model_fields(model: Type[BaseModel]) -> Dict[str, Any]: + def get_model_fields(model: type[BaseModel]) -> dict[str, Any]: return model.__fields__ # type: ignore[return-value] def model_to_json(model: BaseModel, **kwargs: Any) -> str: return model.json(**kwargs) def model_parse( - model: Type[ModelVar], data: Union[str, bytes], **kwargs: Any + model: type[ModelVar], + data: Union[str, bytes], + **kwargs: Any, ) -> ModelVar: return model.parse_raw(data, **kwargs) - def model_schema(model: Type[BaseModel], **kwargs: Any) -> AnyDict: + def model_schema(model: type[BaseModel], **kwargs: Any) -> AnyDict: return model.schema(**kwargs) def model_to_jsonable( @@ -164,11 +181,81 @@ def with_info_plain_validator_function( # type: ignore[misc] if ANYIO_V3: - from anyio import ExceptionGroup as ExceptionGroup # type: ignore[attr-defined] + from anyio import ExceptionGroup # type: ignore[attr-defined] +elif sys.version_info < (3, 11): + from exceptiongroup import ( + ExceptionGroup, + ) else: - if sys.version_info < (3, 11): - from exceptiongroup import ( - ExceptionGroup as ExceptionGroup, - ) - else: - ExceptionGroup = ExceptionGroup + ExceptionGroup = ExceptionGroup # noqa: PLW0127 + + +try: + import email_validator + + if email_validator is None: + raise ImportError + from pydantic import EmailStr +except ImportError: # pragma: no cover + # NOTE: EmailStr mock was copied from the FastAPI + # https://github.com/tiangolo/fastapi/blob/master/fastapi/openapi/models.py#24 + class EmailStr(str): # type: ignore[no-redef] + """EmailStr is a string that should be an email. + + Note: EmailStr mock was copied from the FastAPI: + https://github.com/tiangolo/fastapi/blob/master/fastapi/openapi/models.py#24 + """ + + @classmethod + def __get_validators__(cls) -> Iterable[Callable[..., Any]]: + """Returns the validators for the EmailStr class.""" + yield cls.validate + + @classmethod + def validate(cls, v: Any) -> str: + """Validates the EmailStr class.""" + warnings.warn( + "email-validator bot installed, email fields will be treated as str.\n" + "To install, run: pip install email-validator", + category=RuntimeWarning, + stacklevel=1, + ) + return str(v) + + @classmethod + def _validate(cls, __input_value: Any, _: Any) -> str: + warnings.warn( + "email-validator bot installed, email fields will be treated as str.\n" + "To install, run: pip install email-validator", + category=RuntimeWarning, + stacklevel=1, + ) + return str(__input_value) + + @classmethod + def __get_pydantic_json_schema__( + cls, + core_schema: CoreSchema, + handler: GetJsonSchemaHandler, + ) -> JsonSchemaValue: + """Returns the JSON schema for the EmailStr class. + + Args: + core_schema : the core schema + handler : the handler + """ + return {"type": "string", "format": "email"} + + @classmethod + def __get_pydantic_core_schema__( + cls, + source: type[Any], + handler: Callable[[Any], CoreSchema], + ) -> JsonSchemaValue: + """Returns the core schema for the EmailStr class. + + Args: + source : the source + handler : the handler + """ + return with_info_plain_validator_function(cls._validate) diff --git a/faststream/_internal/application.py b/faststream/_internal/application.py index ddb7762038..15c389b6e8 100644 --- a/faststream/_internal/application.py +++ b/faststream/_internal/application.py @@ -1,15 +1,12 @@ import logging from abc import abstractmethod +from collections.abc import AsyncIterator, Sequence from contextlib import asynccontextmanager from typing import ( TYPE_CHECKING, Any, - AsyncIterator, Callable, - Dict, - List, Optional, - Sequence, TypeVar, ) @@ -107,16 +104,16 @@ def __init__( self.logger = logger self.context = context - self._on_startup_calling: List[AsyncFunc] = [ + self._on_startup_calling: list[AsyncFunc] = [ apply_types(to_async(x)) for x in on_startup ] - self._after_startup_calling: List[AsyncFunc] = [ + self._after_startup_calling: list[AsyncFunc] = [ apply_types(to_async(x)) for x in after_startup ] - self._on_shutdown_calling: List[AsyncFunc] = [ + self._on_shutdown_calling: list[AsyncFunc] = [ apply_types(to_async(x)) for x in on_shutdown ] - self._after_shutdown_calling: List[AsyncFunc] = [ + self._after_shutdown_calling: list[AsyncFunc] = [ apply_types(to_async(x)) for x in after_shutdown ] @@ -137,7 +134,7 @@ def exit(self) -> None: async def run( self, log_level: int, - run_extra_options: Optional[Dict[str, "SettingField"]] = None, + run_extra_options: Optional[dict[str, "SettingField"]] = None, ) -> None: ... # Startup @@ -145,7 +142,7 @@ async def run( async def _startup( self, log_level: int = logging.INFO, - run_extra_options: Optional[Dict[str, "SettingField"]] = None, + run_extra_options: Optional[dict[str, "SettingField"]] = None, ) -> None: """Private method calls `start` with logging.""" async with self._startup_logging(log_level=log_level): @@ -175,7 +172,8 @@ async def _start_hooks_context( @asynccontextmanager async def _startup_logging( - self, log_level: int = logging.INFO + self, + log_level: int = logging.INFO, ) -> AsyncIterator[None]: """Separated startup logging.""" self._log( @@ -215,7 +213,8 @@ async def _shutdown_hooks_context(self) -> AsyncIterator[None]: @asynccontextmanager async def _shutdown_logging( - self, log_level: int = logging.INFO + self, + log_level: int = logging.INFO, ) -> AsyncIterator[None]: """Separated startup logging.""" self._log( diff --git a/faststream/_internal/basic_types.py b/faststream/_internal/basic_types.py index 8a44384081..f781df146e 100644 --- a/faststream/_internal/basic_types.py +++ b/faststream/_internal/basic_types.py @@ -1,24 +1,20 @@ +from collections.abc import Awaitable, Mapping, Sequence +from contextlib import AbstractAsyncContextManager from datetime import datetime from decimal import Decimal from typing import ( Any, - AsyncContextManager, - Awaitable, Callable, ClassVar, - Dict, - List, - Mapping, Optional, Protocol, - Sequence, TypeVar, Union, ) from typing_extensions import ParamSpec, TypeAlias -AnyDict: TypeAlias = Dict[str, Any] +AnyDict: TypeAlias = dict[str, Any] AnyHttpUrl: TypeAlias = str F_Return = TypeVar("F_Return") @@ -36,7 +32,7 @@ JsonArray: TypeAlias = Sequence["DecodedMessage"] -JsonTable: TypeAlias = Dict[str, "DecodedMessage"] +JsonTable: TypeAlias = dict[str, "DecodedMessage"] JsonDecodable: TypeAlias = Union[ bool, @@ -56,13 +52,13 @@ SendableArray: TypeAlias = Sequence["BaseSendableMessage"] -SendableTable: TypeAlias = Dict[str, "BaseSendableMessage"] +SendableTable: TypeAlias = dict[str, "BaseSendableMessage"] class StandardDataclass(Protocol): """Protocol to check type is dataclass.""" - __dataclass_fields__: ClassVar[Dict[str, Any]] + __dataclass_fields__: ClassVar[dict[str, Any]] BaseSendableMessage: TypeAlias = Union[ @@ -89,12 +85,12 @@ class StandardDataclass(Protocol): SettingField: TypeAlias = Union[ bool, str, - List[Union[bool, str]], - List[str], - List[bool], + list[Union[bool, str]], + list[str], + list[bool], ] -Lifespan: TypeAlias = Callable[..., AsyncContextManager[None]] +Lifespan: TypeAlias = Callable[..., AbstractAsyncContextManager[None]] class LoggerProto(Protocol): diff --git a/faststream/_internal/broker/abc_broker.py b/faststream/_internal/broker/abc_broker.py index 861cfa6299..20aae90d1a 100644 --- a/faststream/_internal/broker/abc_broker.py +++ b/faststream/_internal/broker/abc_broker.py @@ -1,10 +1,9 @@ from abc import abstractmethod +from collections.abc import Iterable from typing import ( TYPE_CHECKING, Any, Generic, - Iterable, - List, Optional, ) @@ -18,8 +17,8 @@ class ABCBroker(Generic[MsgType]): - _subscribers: List["SubscriberProto[MsgType]"] - _publishers: List["PublisherProto[MsgType]"] + _subscribers: list["SubscriberProto[MsgType]"] + _publishers: list["PublisherProto[MsgType]"] def __init__( self, @@ -84,7 +83,7 @@ def include_router( ) -> None: """Includes a router in the current object.""" for h in router._subscribers: - h.add_prefix("".join((self.prefix, prefix))) + h.add_prefix(f"{self.prefix}{prefix}") if include_in_schema is None: h.include_in_schema = self._solve_include_in_schema(h.include_in_schema) @@ -129,5 +128,4 @@ def include_routers( def _solve_include_in_schema(self, include_in_schema: bool) -> bool: if self.include_in_schema is None or self.include_in_schema: return include_in_schema - else: - return self.include_in_schema + return self.include_in_schema diff --git a/faststream/_internal/broker/broker.py b/faststream/_internal/broker/broker.py index e7a7fe63cf..e48dfabd36 100644 --- a/faststream/_internal/broker/broker.py +++ b/faststream/_internal/broker/broker.py @@ -1,20 +1,18 @@ from abc import abstractmethod +from collections.abc import Iterable, Sequence from functools import partial from typing import ( TYPE_CHECKING, + Annotated, Any, Callable, Generic, - Iterable, - List, Optional, - Sequence, - Type, Union, cast, ) -from typing_extensions import Annotated, Doc, Self +from typing_extensions import Doc, Self from faststream._internal._compat import is_test_env from faststream._internal.setup import ( @@ -88,7 +86,7 @@ def __init__( graceful_timeout: Annotated[ Optional[float], Doc( - "Graceful shutdown timeout. Broker waits for all running subscribers completion before shut down." + "Graceful shutdown timeout. Broker waits for all running subscribers completion before shut down.", ), ], # Logging args @@ -128,13 +126,13 @@ def __init__( Doc("AsyncAPI server tags."), ], specification_url: Annotated[ - Union[str, List[str]], + Union[str, list[str]], Doc("AsyncAPI hardcoded server addresses."), ], security: Annotated[ Optional["BaseSecurity"], Doc( - "Security options to connect broker and generate AsyncAPI server security." + "Security options to connect broker and generate AsyncAPI server security.", ), ], **connection_kwargs: Any, @@ -193,7 +191,7 @@ async def __aenter__(self) -> "Self": async def __aexit__( self, - exc_type: Optional[Type[BaseException]], + exc_type: Optional[type[BaseException]], exc_val: Optional[BaseException], exc_tb: Optional["TracebackType"], ) -> None: @@ -222,7 +220,7 @@ async def connect(self, **kwargs: Any) -> ConnectionType: @abstractmethod async def _connect(self) -> ConnectionType: """Connect to a resource.""" - raise NotImplementedError() + raise NotImplementedError def _setup(self, state: Optional[BaseState] = None) -> None: """Prepare all Broker entities to startup.""" @@ -308,7 +306,7 @@ def publisher(self, *args: Any, **kwargs: Any) -> "PublisherProto[MsgType]": async def close( self, - exc_type: Optional[Type[BaseException]] = None, + exc_type: Optional[type[BaseException]] = None, exc_val: Optional[BaseException] = None, exc_tb: Optional["TracebackType"] = None, ) -> None: @@ -368,4 +366,4 @@ async def request( @abstractmethod async def ping(self, timeout: Optional[float]) -> bool: """Check connection alive.""" - raise NotImplementedError() + raise NotImplementedError diff --git a/faststream/_internal/broker/router.py b/faststream/_internal/broker/router.py index 0661ac4bd6..35d2b2779a 100644 --- a/faststream/_internal/broker/router.py +++ b/faststream/_internal/broker/router.py @@ -1,8 +1,8 @@ +from collections.abc import Iterable from typing import ( TYPE_CHECKING, Any, Callable, - Iterable, Optional, ) diff --git a/faststream/_internal/cli/docs/app.py b/faststream/_internal/cli/docs/app.py index 0c6cc4e4a4..49e4411bed 100644 --- a/faststream/_internal/cli/docs/app.py +++ b/faststream/_internal/cli/docs/app.py @@ -3,7 +3,7 @@ import warnings from contextlib import suppress from pathlib import Path -from typing import Optional, Sequence +from typing import TYPE_CHECKING, Optional import typer from pydantic import ValidationError @@ -16,6 +16,9 @@ from faststream.specification.asyncapi.v3_0_0.schema import Schema as SchemaV3 from faststream.specification.base.specification import Specification +if TYPE_CHECKING: + from collections.abc import Sequence + asyncapi_app = typer.Typer(pretty_exceptions_short=True) @@ -147,14 +150,14 @@ def gen( name = out or "asyncapi.yaml" - with Path(name).open("w") as f: + with Path(name).open("w", encoding="utf-8") as f: f.write(schema) else: schema = raw_schema.to_jsonable() name = out or "asyncapi.json" - with Path(name).open("w") as f: + with Path(name).open("w", encoding="utf-8") as f: json.dump(schema, f, indent=2) typer.echo(f"Your project AsyncAPI scheme was placed to `{name}`") @@ -181,7 +184,7 @@ def _parse_and_serve( if schema_filepath.suffix == ".json": data = schema_filepath.read_bytes() - elif schema_filepath.suffix == ".yaml" or schema_filepath.suffix == ".yml": + elif schema_filepath.suffix in {".yaml", ".yml"}: try: import yaml except ImportError as e: # pragma: no cover @@ -194,8 +197,9 @@ def _parse_and_serve( data = json_dumps(schema) else: + msg = f"Unknown extension given - {docs}; Please provide app in format [python_module:Specification] or [asyncapi.yaml/.json] - path to your application or documentation" raise ValueError( - f"Unknown extension given - {docs}; Please provide app in format [python_module:Specification] or [asyncapi.yaml/.json] - path to your application or documentation" + msg, ) for schema in (SchemaV3, SchemaV2_6): diff --git a/faststream/_internal/cli/main.py b/faststream/_internal/cli/main.py index c406c63365..043dc27785 100644 --- a/faststream/_internal/cli/main.py +++ b/faststream/_internal/cli/main.py @@ -2,7 +2,7 @@ import sys import warnings from contextlib import suppress -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import TYPE_CHECKING, Any, Optional import anyio import typer @@ -31,10 +31,10 @@ def version_callback(version: bool) -> None: typer.echo( f"Running FastStream {__version__} with {platform.python_implementation()} " - f"{platform.python_version()} on {platform.system()}" + f"{platform.python_version()} on {platform.system()}", ) - raise typer.Exit() + raise typer.Exit @cli.callback() @@ -52,7 +52,7 @@ def main( @cli.command( - context_settings={"allow_extra_args": True, "ignore_unknown_options": True} + context_settings={"allow_extra_args": True, "ignore_unknown_options": True}, ) def run( ctx: typer.Context, @@ -76,7 +76,7 @@ def run( is_flag=True, help="Restart app at directory files changes.", ), - watch_extensions: List[str] = typer.Option( + watch_extensions: list[str] = typer.Option( (), "--extension", "--ext", @@ -103,7 +103,7 @@ def run( if watch_extensions and not reload: typer.echo( "Extra reload extensions has no effect without `--reload` flag." - "\nProbably, you forgot it?" + "\nProbably, you forgot it?", ) app, extra = parse_cli_args(app, *ctx.args) @@ -116,7 +116,8 @@ def run( args = (app, extra, is_factory, casted_log_level) if reload and workers > 1: - raise SetupError("You can't use reload option with multiprocessing") + msg = "You can't use reload option with multiprocessing" + raise SetupError(msg) if reload: try: @@ -157,7 +158,7 @@ def run( def _run( # NOTE: we should pass `str` due FastStream is not picklable app: str, - extra_options: Dict[str, "SettingField"], + extra_options: dict[str, "SettingField"], is_factory: bool, log_level: int = logging.NOTSET, app_level: int = logging.INFO, @@ -168,14 +169,15 @@ def _run( app_obj = app_obj() if not isinstance(app_obj, Application): + msg = f'Imported object "{app_obj}" must be "Application" type.' raise typer.BadParameter( - f'Imported object "{app_obj}" must be "Application" type.', + msg, ) if log_level > 0: set_log_level(log_level, app_obj) - if sys.platform not in ("win32", "cygwin", "cli"): # pragma: no cover + if sys.platform not in {"win32", "cygwin", "cli"}: # pragma: no cover with suppress(ImportError): import uvloop @@ -196,7 +198,7 @@ def _run( @cli.command( - context_settings={"allow_extra_args": True, "ignore_unknown_options": True} + context_settings={"allow_extra_args": True, "ignore_unknown_options": True}, ) def publish( ctx: typer.Context, @@ -241,7 +243,8 @@ def publish( assert isinstance(app_obj, FastStream), app_obj if not app_obj.broker: - raise ValueError("Broker instance not found in the app.") + msg = "Broker instance not found in the app." + raise ValueError(msg) app_obj._setup() result = anyio.run(publish_message, app_obj.broker, rpc, extra) @@ -255,15 +258,15 @@ def publish( async def publish_message( - broker: "BrokerUsecase[Any, Any]", rpc: bool, extra: "AnyDict" + broker: "BrokerUsecase[Any, Any]", + rpc: bool, + extra: "AnyDict", ) -> Any: try: async with broker: if rpc: - msg = await broker.request(**extra) - return msg - else: - return await broker.publish(**extra) + return await broker.request(**extra) + return await broker.publish(**extra) except Exception as e: typer.echo(f"Error when broker was publishing: {e}") sys.exit(1) diff --git a/faststream/_internal/cli/supervisors/basereload.py b/faststream/_internal/cli/supervisors/basereload.py index ffc76e80da..0b9f788897 100644 --- a/faststream/_internal/cli/supervisors/basereload.py +++ b/faststream/_internal/cli/supervisors/basereload.py @@ -1,7 +1,7 @@ import os import threading from multiprocessing.context import SpawnProcess -from typing import TYPE_CHECKING, Any, Optional, Tuple +from typing import TYPE_CHECKING, Any, Optional from faststream._internal.cli.supervisors.utils import get_subprocess, set_exit from faststream._internal.log import logger @@ -15,7 +15,7 @@ class BaseReload: _process: SpawnProcess _target: "DecoratedCallable" - _args: Tuple[Any, ...] + _args: tuple[Any, ...] reload_delay: Optional[float] should_exit: threading.Event @@ -25,7 +25,7 @@ class BaseReload: def __init__( self, target: "DecoratedCallable", - args: Tuple[Any, ...], + args: tuple[Any, ...], reload_delay: Optional[float] = 0.5, ) -> None: self._target = target @@ -67,4 +67,5 @@ def _start_process(self) -> SpawnProcess: return process def should_restart(self) -> bool: - raise NotImplementedError("Reload strategies should override should_restart()") + msg = "Reload strategies should override should_restart()" + raise NotImplementedError(msg) diff --git a/faststream/_internal/cli/supervisors/multiprocess.py b/faststream/_internal/cli/supervisors/multiprocess.py index 1ebcb1c772..e84f98cf7a 100644 --- a/faststream/_internal/cli/supervisors/multiprocess.py +++ b/faststream/_internal/cli/supervisors/multiprocess.py @@ -1,5 +1,5 @@ import signal -from typing import TYPE_CHECKING, Any, List, Tuple +from typing import TYPE_CHECKING, Any from faststream._internal.cli.supervisors.basereload import BaseReload from faststream._internal.log import logger @@ -16,14 +16,14 @@ class Multiprocess(BaseReload): def __init__( self, target: "DecoratedCallable", - args: Tuple[Any, ...], + args: tuple[Any, ...], workers: int, reload_delay: float = 0.5, ) -> None: super().__init__(target, args, reload_delay) self.workers = workers - self.processes: List[SpawnProcess] = [] + self.processes: list[SpawnProcess] = [] def startup(self) -> None: logger.info(f"Started parent process [{self.pid}]") diff --git a/faststream/_internal/cli/supervisors/watchfiles.py b/faststream/_internal/cli/supervisors/watchfiles.py index dbd3be23ab..d83e670fb3 100644 --- a/faststream/_internal/cli/supervisors/watchfiles.py +++ b/faststream/_internal/cli/supervisors/watchfiles.py @@ -1,5 +1,6 @@ +from collections.abc import Sequence from pathlib import Path -from typing import TYPE_CHECKING, Any, Optional, Sequence, Tuple, Union +from typing import TYPE_CHECKING, Any, Optional, Union import watchfiles @@ -38,7 +39,7 @@ class WatchReloader(BaseReload): def __init__( self, target: "DecoratedCallable", - args: Tuple[Any, ...], + args: tuple[Any, ...], reload_dirs: Sequence[Union[Path, str]], reload_delay: float = 0.3, extra_extensions: Sequence[str] = (), diff --git a/faststream/_internal/cli/utils/errors.py b/faststream/_internal/cli/utils/errors.py index 708db46f94..c9d1eb0721 100644 --- a/faststream/_internal/cli/utils/errors.py +++ b/faststream/_internal/cli/utils/errors.py @@ -21,7 +21,7 @@ def draw_error(click_exc: BadParameter) -> None: "`lifespan/on_startup` hook has a wrong type." ), param=TyperOption(param_decls=[f"--{field}"]), - ) + ), ) if startup_exc.missed_fields: @@ -32,7 +32,7 @@ def draw_error(click_exc: BadParameter) -> None: "`lifespan/on_startup` hook, but does not set in CLI." ), param=TyperOption( - param_decls=[f"--{x}" for x in startup_exc.missed_fields] + param_decls=[f"--{x}" for x in startup_exc.missed_fields], ), - ) + ), ) diff --git a/faststream/_internal/cli/utils/imports.py b/faststream/_internal/cli/utils/imports.py index e977a693dd..87b02d12fd 100644 --- a/faststream/_internal/cli/utils/imports.py +++ b/faststream/_internal/cli/utils/imports.py @@ -1,7 +1,6 @@ import importlib from importlib.util import module_from_spec, spec_from_file_location from pathlib import Path -from typing import Tuple import typer @@ -15,8 +14,11 @@ def try_import_app(module: Path, app: str) -> object: except FileNotFoundError as e: typer.echo(e, err=True) - raise typer.BadParameter( + msg = ( "Please, input module like [python_file:docs_object] or [module:attribute]" + ) + raise typer.BadParameter( + msg, ) from e else: @@ -38,7 +40,8 @@ def import_object(module: Path, app: str) -> object: loader = spec.loader if loader is None: # pragma: no cover - raise SetupError(f"{spec} has no loader") + msg = f"{spec} has no loader" + raise SetupError(msg) loader.exec_module(mod) @@ -50,34 +53,37 @@ def import_object(module: Path, app: str) -> object: return obj -def get_obj_path(obj_path: str) -> Tuple[Path, str]: +def get_obj_path(obj_path: str) -> tuple[Path, str]: """Get the application path.""" if ":" not in obj_path: - raise SetupError(f"`{obj_path}` is not a path to object") + msg = f"`{obj_path}` is not a path to object" + raise SetupError(msg) module, app_name = obj_path.split(":", 2) mod_path = Path.cwd() for i in module.split("."): - mod_path = mod_path / i + mod_path /= i return mod_path, app_name -def import_from_string(import_str: str) -> Tuple[Path, object]: +def import_from_string(import_str: str) -> tuple[Path, object]: """Import FastStream application from module specified by a string.""" if not isinstance(import_str, str): - raise typer.BadParameter("Given value is not of type string") + msg = "Given value is not of type string" + raise typer.BadParameter(msg) module_str, _, attrs_str = import_str.partition(":") if not module_str or not attrs_str: + msg = f'Import string "{import_str}" must be in format ":"' raise typer.BadParameter( - f'Import string "{import_str}" must be in format ":"' + msg, ) try: module = importlib.import_module( # nosemgrep: python.lang.security.audit.non-literal-import.non-literal-import - module_str + module_str, ) except ModuleNotFoundError: @@ -93,8 +99,9 @@ def import_from_string(import_str: str) -> Tuple[Path, object]: except AttributeError as e: typer.echo(e, err=True) + msg = f'Attribute "{attrs_str}" not found in module "{module_str}".' raise typer.BadParameter( - f'Attribute "{attrs_str}" not found in module "{module_str}".' + msg, ) from e if module.__file__: diff --git a/faststream/_internal/cli/utils/logs.py b/faststream/_internal/cli/utils/logs.py index 4330f9cdb9..ce11aa732c 100644 --- a/faststream/_internal/cli/utils/logs.py +++ b/faststream/_internal/cli/utils/logs.py @@ -1,7 +1,7 @@ import logging from collections import defaultdict from enum import Enum -from typing import TYPE_CHECKING, DefaultDict, Optional, Union +from typing import TYPE_CHECKING, Optional, Union if TYPE_CHECKING: from faststream._internal.basic_types import LoggerProto @@ -29,18 +29,16 @@ class LogLevels(str, Enum): notset = "notset" -LOG_LEVELS: DefaultDict[str, int] = defaultdict( +LOG_LEVELS: defaultdict[str, int] = defaultdict( lambda: logging.INFO, - **{ - "critical": logging.CRITICAL, - "fatal": logging.FATAL, - "error": logging.ERROR, - "warning": logging.WARNING, - "warn": logging.WARN, - "info": logging.INFO, - "debug": logging.DEBUG, - "notset": logging.NOTSET, - }, + critical=logging.CRITICAL, + fatal=logging.FATAL, + error=logging.ERROR, + warning=logging.WARNING, + warn=logging.WARNING, + info=logging.INFO, + debug=logging.DEBUG, + notset=logging.NOTSET, ) @@ -62,6 +60,7 @@ def get_log_level(level: Union[LogLevels, str, int]) -> int: if isinstance(level, str): # pragma: no branch return LOG_LEVELS[level.lower()] + return None def set_log_level(level: int, app: "FastStream") -> None: diff --git a/faststream/_internal/cli/utils/parser.py b/faststream/_internal/cli/utils/parser.py index 1310e115ec..693052b912 100644 --- a/faststream/_internal/cli/utils/parser.py +++ b/faststream/_internal/cli/utils/parser.py @@ -1,72 +1,54 @@ from functools import reduce -from typing import TYPE_CHECKING, Dict, List, Tuple +from typing import TYPE_CHECKING, cast if TYPE_CHECKING: from faststream._internal.basic_types import SettingField -def parse_cli_args(*args: str) -> Tuple[str, Dict[str, "SettingField"]]: +def parse_cli_args(*args: str) -> tuple[str, dict[str, "SettingField"]]: """Parses command line arguments.""" - extra_kwargs: Dict[str, SettingField] = {} + extra_kwargs: dict[str, SettingField] = {} k: str = "" v: SettingField - field_args: List[str] = [] + field_args: list[str] = [] app = "" for item in [ *reduce( - lambda acc, x: acc + x.split("="), # type: ignore + lambda acc, x: acc + x.split("="), args, - [], + cast(list[str], []), ), "-", ]: if ":" in item: app = item - else: - if "-" in item: - if k: - k = k.strip().lstrip("-").replace("-", "_") + elif "-" in item: + if k: + k = k.strip().lstrip("-").replace("-", "_") - if len(field_args) == 0: - v = not k.startswith("no_") - elif len(field_args) == 1: - v = field_args[0] - else: - v = field_args + if len(field_args) == 0: + v = not k.startswith("no_") + elif len(field_args) == 1: + v = field_args[0] + else: + v = field_args - key = remove_prefix(k, "no_") - if (exists := extra_kwargs.get(key)) is not None: - v = [ - *(exists if isinstance(exists, list) else [exists]), - *(v if isinstance(v, list) else [v]), - ] + key = k.removeprefix("no_") + if (exists := extra_kwargs.get(key)) is not None: + v = [ + *(exists if isinstance(exists, list) else [exists]), + *(v if isinstance(v, list) else [v]), + ] - extra_kwargs[key] = v - field_args = [] + extra_kwargs[key] = v + field_args = [] - k = item + k = item - else: - field_args.append(item) + else: + field_args.append(item) return app, extra_kwargs - - -def remove_prefix(text: str, prefix: str) -> str: - """Removes a prefix from a given text. - - Python 3.8 compatibility function - - Args: - text (str): The text from which the prefix will be removed. - prefix (str): The prefix to be removed from the text. - - Returns: - str: The text with the prefix removed. If the text does not start with the prefix, the original text is returned. - """ - if text.startswith(prefix): - return text[len(prefix) :] - return text diff --git a/faststream/_internal/context/__init__.py b/faststream/_internal/context/__init__.py index 202ba06363..89152e682f 100644 --- a/faststream/_internal/context/__init__.py +++ b/faststream/_internal/context/__init__.py @@ -2,7 +2,7 @@ from .repository import ContextRepo, context __all__ = ( - "context", "Context", "ContextRepo", + "context", ) diff --git a/faststream/_internal/context/repository.py b/faststream/_internal/context/repository.py index 24654844b7..9990ad9bd0 100644 --- a/faststream/_internal/context/repository.py +++ b/faststream/_internal/context/repository.py @@ -1,6 +1,7 @@ +from collections.abc import Iterator, Mapping from contextlib import contextmanager from contextvars import ContextVar, Token -from typing import Any, Dict, Iterator, Mapping +from typing import Any from faststream._internal.basic_types import AnyDict from faststream._internal.constants import EMPTY @@ -13,7 +14,7 @@ class ContextRepo: """A class to represent a context repository.""" _global_context: AnyDict - _scope_context: Dict[str, ContextVar[Any]] + _scope_context: dict[str, ContextVar[Any]] def __init__(self) -> None: """Initialize the class. @@ -132,19 +133,18 @@ def get(self, key: str, default: Any = None) -> Any: """ if (glob := self._global_context.get(key, EMPTY)) is EMPTY: return self.get_local(key, default) - else: - return glob + return glob - def __getattr__(self, __name: str) -> Any: + def __getattr__(self, name: str, /) -> Any: """This is a function that is part of a class. It is used to get an attribute value using the `__getattr__` method. Args: - __name: The name of the attribute to get. + name: The name of the attribute to get. Returns: The value of the attribute. """ - return self.get(__name) + return self.get(name) def resolve(self, argument: str) -> Any: """Resolve the context of an argument. diff --git a/faststream/_internal/fastapi/_compat.py b/faststream/_internal/fastapi/_compat.py index b673c0d110..0393b62489 100644 --- a/faststream/_internal/fastapi/_compat.py +++ b/faststream/_internal/fastapi/_compat.py @@ -1,5 +1,5 @@ from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, List, Optional +from typing import TYPE_CHECKING, Any, Optional from fastapi import __version__ as FASTAPI_VERSION # noqa: N812 from fastapi.dependencies.utils import solve_dependencies @@ -19,17 +19,17 @@ FASTAPI_v102_4 = major > 0 or minor > 112 or (minor == 112 and patch > 3) __all__ = ( + "RequestValidationError", "create_response_field", - "solve_faststream_dependency", "raise_fastapi_validation_error", - "RequestValidationError", + "solve_faststream_dependency", ) @dataclass class SolvedDependency: values: AnyDict - errors: List[Any] + errors: list[Any] background_tasks: Optional[BackgroundTasks] @@ -37,18 +37,18 @@ class SolvedDependency: from fastapi._compat import _normalize_errors from fastapi.exceptions import RequestValidationError - def raise_fastapi_validation_error(errors: List[Any], body: AnyDict) -> Never: + def raise_fastapi_validation_error(errors: list[Any], body: AnyDict) -> Never: raise RequestValidationError(_normalize_errors(errors), body=body) else: from pydantic import ( # type: ignore[assignment] ValidationError as RequestValidationError, + create_model, ) - from pydantic import create_model ROUTER_VALIDATION_ERROR_MODEL = create_model("StreamRoute") - def raise_fastapi_validation_error(errors: List[Any], body: AnyDict) -> Never: + def raise_fastapi_validation_error(errors: list[Any], body: AnyDict) -> Never: raise RequestValidationError(errors, ROUTER_VALIDATION_ERROR_MODEL) # type: ignore[misc] @@ -74,7 +74,7 @@ async def solve_faststream_dependency( **kwargs, ) values, errors, background = ( - solved_result.values, + solved_result.values, # noqa: PD011 solved_result.errors, solved_result.background_tasks, ) @@ -87,7 +87,7 @@ async def solve_faststream_dependency( else: from fastapi.utils import ( # type: ignore[attr-defined,no-redef] - create_response_field as create_response_field, + create_response_field, ) async def solve_faststream_dependency( diff --git a/faststream/_internal/fastapi/context.py b/faststream/_internal/fastapi/context.py index 1422448b4f..0a76e31a19 100644 --- a/faststream/_internal/fastapi/context.py +++ b/faststream/_internal/fastapi/context.py @@ -1,8 +1,7 @@ import logging -from typing import Any, Callable, Optional +from typing import Annotated, Any, Callable, Optional from fastapi import params -from typing_extensions import Annotated from faststream._internal.constants import EMPTY from faststream._internal.context import ContextRepo as CR diff --git a/faststream/_internal/fastapi/get_dependant.py b/faststream/_internal/fastapi/get_dependant.py index ca40aae455..e21a62954a 100644 --- a/faststream/_internal/fastapi/get_dependant.py +++ b/faststream/_internal/fastapi/get_dependant.py @@ -1,4 +1,5 @@ -from typing import TYPE_CHECKING, Any, Callable, Iterable, cast +from collections.abc import Iterable +from typing import TYPE_CHECKING, Any, Callable, cast from fastapi.dependencies.utils import get_dependant, get_parameterless_sub_dependant @@ -19,9 +20,7 @@ def get_fastapi_dependant( dependencies=dependencies, ) - dependent = _patch_fastapi_dependent(dependent) - - return dependent + return _patch_fastapi_dependent(dependent) def get_fastapi_native_dependant( @@ -81,7 +80,7 @@ def _patch_fastapi_dependent(dependant: "Dependant") -> "Dependant": "examples": info.examples, "exclude": info.exclude, "json_schema_extra": info.json_schema_extra, - } + }, ) f = next( @@ -107,7 +106,7 @@ def _patch_fastapi_dependent(dependant: "Dependant") -> "Dependant": "ge": info.field_info.ge, "lt": info.field_info.lt, "le": info.field_info.le, - } + }, ) f = Field(**field_data) # type: ignore[pydantic-field] @@ -117,7 +116,7 @@ def _patch_fastapi_dependent(dependant: "Dependant") -> "Dependant": ) dependant.model = create_model( # type: ignore[attr-defined] - getattr(dependant.call, "__name__", type(dependant.call).__name__) + getattr(dependant.call, "__name__", type(dependant.call).__name__), ) dependant.custom_fields = {} # type: ignore[attr-defined] diff --git a/faststream/_internal/fastapi/route.py b/faststream/_internal/fastapi/route.py index 413ad3929e..dffe9517aa 100644 --- a/faststream/_internal/fastapi/route.py +++ b/faststream/_internal/fastapi/route.py @@ -1,15 +1,13 @@ import asyncio import inspect +from collections.abc import Awaitable, Iterable from contextlib import AsyncExitStack from functools import wraps from itertools import dropwhile from typing import ( TYPE_CHECKING, Any, - Awaitable, Callable, - Iterable, - List, Optional, Union, ) @@ -45,14 +43,14 @@ class StreamMessage(Request): scope: "AnyDict" _cookies: "AnyDict" - _headers: "AnyDict" # type: ignore - _body: Union["AnyDict", List[Any]] # type: ignore - _query_params: "AnyDict" # type: ignore + _headers: "AnyDict" # type: ignore[assignment] + _body: Union["AnyDict", list[Any]] # type: ignore[assignment] + _query_params: "AnyDict" # type: ignore[assignment] def __init__( self, *, - body: Union["AnyDict", List[Any]], + body: Union["AnyDict", list[Any]], headers: "AnyDict", path: "AnyDict", ) -> None: @@ -149,7 +147,7 @@ async def parsed_consumer(message: "NativeMessage[Any]") -> Any: """Wrapper, that parser FastStream message to FastAPI compatible one.""" body = await message.decode() - fastapi_body: Union[AnyDict, List[Any]] + fastapi_body: Union[AnyDict, list[Any]] if first_arg is not None: if isinstance(body, dict): path = fastapi_body = body or {} @@ -240,6 +238,7 @@ async def app( return response - raise AssertionError("unreachable") + msg = "unreachable" + raise AssertionError(msg) return app diff --git a/faststream/_internal/fastapi/router.py b/faststream/_internal/fastapi/router.py index 7790831fe7..fec1207744 100644 --- a/faststream/_internal/fastapi/router.py +++ b/faststream/_internal/fastapi/router.py @@ -1,21 +1,14 @@ import json from abc import abstractmethod +from collections.abc import AsyncIterator, Awaitable, Iterable, Mapping, Sequence from contextlib import asynccontextmanager from enum import Enum from typing import ( TYPE_CHECKING, Any, - AsyncIterator, - Awaitable, Callable, - Dict, Generic, - Iterable, - List, - Mapping, Optional, - Sequence, - Type, Union, cast, overload, @@ -69,7 +62,7 @@ class _BackgroundMiddleware(BaseMiddleware): async def __aexit__( self, - exc_type: Optional[Type[BaseException]] = None, + exc_type: Optional[type[BaseException]] = None, exc_val: Optional[BaseException] = None, exc_tb: Optional["TracebackType"] = None, ) -> Optional[bool]: @@ -91,11 +84,11 @@ class StreamRouter( ): """A class to route streams.""" - broker_class: Type["BrokerUsecase[MsgType, Any]"] + broker_class: type["BrokerUsecase[MsgType, Any]"] broker: "BrokerUsecase[MsgType, Any]" docs_router: Optional[APIRouter] - _after_startup_hooks: List[Callable[[Any], Awaitable[Optional[Mapping[str, Any]]]]] - _on_shutdown_hooks: List[Callable[[Any], Awaitable[None]]] + _after_startup_hooks: list[Callable[[Any], Awaitable[Optional[Mapping[str, Any]]]]] + _on_shutdown_hooks: list[Callable[[Any], Awaitable[None]]] schema: Optional["Specification"] title: str @@ -109,16 +102,16 @@ def __init__( *connection_args: Any, middlewares: Iterable["BrokerMiddleware[MsgType]"] = (), prefix: str = "", - tags: Optional[List[Union[str, Enum]]] = None, + tags: Optional[list[Union[str, Enum]]] = None, dependencies: Optional[Sequence["params.Depends"]] = None, - default_response_class: Type["Response"] = Default(JSONResponse), - responses: Optional[Dict[Union[int, str], "AnyDict"]] = None, - callbacks: Optional[List["routing.BaseRoute"]] = None, - routes: Optional[List["routing.BaseRoute"]] = None, + default_response_class: type["Response"] = Default(JSONResponse), + responses: Optional[dict[Union[int, str], "AnyDict"]] = None, + callbacks: Optional[list["routing.BaseRoute"]] = None, + routes: Optional[list["routing.BaseRoute"]] = None, redirect_slashes: bool = True, default: Optional["ASGIApp"] = None, dependency_overrides_provider: Optional[Any] = None, - route_class: Type["APIRoute"] = APIRoute, + route_class: type["APIRoute"] = APIRoute, on_startup: Optional[Sequence[Callable[[], Any]]] = None, on_shutdown: Optional[Sequence[Callable[[], Any]]] = None, deprecated: Optional[bool] = None, @@ -126,7 +119,7 @@ def __init__( setup_state: bool = True, lifespan: Optional["Lifespan[Any]"] = None, generate_unique_id_function: Callable[["APIRoute"], str] = Default( - generate_unique_id + generate_unique_id, ), # Specification information specification_tags: Optional[Iterable[Union["Tag", "TagDict"]]] = None, @@ -205,8 +198,7 @@ def _get_dependencies_overides_provider(self) -> Optional[Any]: """Dependency provider WeakRef resolver.""" if self.dependency_overrides_provider is not None: return self.dependency_overrides_provider - else: - return next(iter(self.weak_dependencies_provider), None) + return next(iter(self.weak_dependencies_provider), None) def _add_api_mq_route( self, @@ -284,14 +276,15 @@ def subscriber( return sub def _wrap_lifespan( - self, lifespan: Optional["Lifespan[Any]"] = None + self, + lifespan: Optional["Lifespan[Any]"] = None, ) -> "Lifespan[Any]": lifespan_context = lifespan if lifespan is not None else _DefaultLifespan(self) @asynccontextmanager async def start_broker_lifespan( app: "FastAPI", - ) -> AsyncIterator[Mapping[str, Any]]: + ) -> AsyncIterator[Optional[Mapping[str, Any]]]: """Starts the lifespan of a broker.""" if not len(self.weak_dependencies_provider): self.weak_dependencies_provider.add(app) @@ -339,7 +332,7 @@ async def start_broker_lifespan( yield context else: # NOTE: old asgi compatibility - yield # type: ignore + yield None for h in self._on_shutdown_hooks: await h(app) @@ -347,7 +340,7 @@ async def start_broker_lifespan( finally: await self.broker.close() - return start_broker_lifespan + return start_broker_lifespan # type: ignore[return-value] @overload def after_startup( @@ -420,7 +413,7 @@ def on_broker_shutdown( @abstractmethod def publisher(self) -> "PublisherProto[MsgType]": """Create Publisher object.""" - raise NotImplementedError() + raise NotImplementedError def _asyncapi_router(self, schema_url: Optional[str]) -> Optional[APIRouter]: """Creates an API router for serving AsyncAPI documentation.""" @@ -475,7 +468,7 @@ def serve_asyncapi_schema( schemas=schemas, errors=errors, expand_message_examples=expandMessageExamples, - ) + ), ) docs_router = APIRouter( @@ -495,15 +488,15 @@ def include_router( # type: ignore[override] router: Union["StreamRouter[MsgType]", "BrokerRouter[MsgType]"], *, prefix: str = "", - tags: Optional[List[Union[str, Enum]]] = None, + tags: Optional[list[Union[str, Enum]]] = None, dependencies: Optional[Sequence["params.Depends"]] = None, - default_response_class: Type[Response] = Default(JSONResponse), - responses: Optional[Dict[Union[int, str], "AnyDict"]] = None, - callbacks: Optional[List["BaseRoute"]] = None, + default_response_class: type[Response] = Default(JSONResponse), + responses: Optional[dict[Union[int, str], "AnyDict"]] = None, + callbacks: Optional[list["BaseRoute"]] = None, deprecated: Optional[bool] = None, include_in_schema: bool = True, generate_unique_id_function: Callable[["APIRoute"], str] = Default( - generate_unique_id + generate_unique_id, ), ) -> None: """Includes a router in the API.""" diff --git a/faststream/_internal/log/formatter.py b/faststream/_internal/log/formatter.py index fe1aa3a267..0e8608051c 100644 --- a/faststream/_internal/log/formatter.py +++ b/faststream/_internal/log/formatter.py @@ -37,7 +37,7 @@ def __init__( use one of %-formatting, :meth:`str.format` (``{}``) formatting or :class:`string.Template` formatting in your format string. """ - if use_colors in (True, False): + if use_colors in {True, False}: self.use_colors = use_colors else: self.use_colors = sys.stdout.isatty() diff --git a/faststream/_internal/log/logging.py b/faststream/_internal/log/logging.py index 56c5a6d31b..4156b24270 100644 --- a/faststream/_internal/log/logging.py +++ b/faststream/_internal/log/logging.py @@ -1,7 +1,7 @@ import logging import sys +from collections.abc import Mapping from logging import LogRecord -from typing import Mapping from faststream._internal.context.repository import context from faststream._internal.log.formatter import ColourizedFormatter @@ -14,7 +14,7 @@ ColourizedFormatter( fmt="%(asctime)s %(levelname)8s - %(message)s", use_colors=True, - ) + ), ) logger.addHandler(main_handler) @@ -33,7 +33,8 @@ def __init__( def filter(self, record: LogRecord) -> bool: if is_suitable := super().filter(record): log_context: Mapping[str, str] = context.get_local( - "log_context", self.default_context + "log_context", + self.default_context, ) for k, v in log_context.items(): @@ -60,7 +61,7 @@ def get_broker_logger( ColourizedFormatter( fmt=fmt, use_colors=True, - ) + ), ) logger.addHandler(handler) return logger diff --git a/faststream/_internal/proto.py b/faststream/_internal/proto.py index 2ee3cb5106..b75266d087 100644 --- a/faststream/_internal/proto.py +++ b/faststream/_internal/proto.py @@ -1,5 +1,5 @@ from abc import abstractmethod -from typing import Any, Optional, Protocol, Type, TypeVar, Union, overload +from typing import Any, Optional, Protocol, TypeVar, Union, overload from .setup import SetupAble @@ -15,15 +15,15 @@ def add_prefix(self, prefix: str) -> None: ... class NameRequired: """Required name option object.""" - def __eq__(self, __value: object) -> bool: + def __eq__(self, value: object, /) -> bool: """Compares the current object with another object for equality.""" - if __value is None: + if value is None: return False - if not isinstance(__value, NameRequired): + if not isinstance(value, NameRequired): return NotImplemented - return self.name == __value.name + return self.name == value.name def __init__(self, name: str) -> None: self.name = name @@ -31,7 +31,7 @@ def __init__(self, name: str) -> None: @overload @classmethod def validate( - cls: Type[NameRequiredCls], + cls: type[NameRequiredCls], value: Union[str, NameRequiredCls], **kwargs: Any, ) -> NameRequiredCls: ... @@ -39,14 +39,14 @@ def validate( @overload @classmethod def validate( - cls: Type[NameRequiredCls], + cls: type[NameRequiredCls], value: None, **kwargs: Any, ) -> None: ... @classmethod def validate( - cls: Type[NameRequiredCls], + cls: type[NameRequiredCls], value: Union[str, NameRequiredCls, None], **kwargs: Any, ) -> Optional[NameRequiredCls]: diff --git a/faststream/_internal/publisher/fake.py b/faststream/_internal/publisher/fake.py index 89f87ed4c2..3fb3b1e074 100644 --- a/faststream/_internal/publisher/fake.py +++ b/faststream/_internal/publisher/fake.py @@ -1,6 +1,7 @@ +from collections.abc import Iterable from functools import partial from itertools import chain -from typing import TYPE_CHECKING, Any, Iterable, Optional +from typing import TYPE_CHECKING, Any, Optional from faststream._internal.publisher.proto import BasePublisherProto @@ -53,7 +54,10 @@ async def request( correlation_id: Optional[str] = None, _extra_middlewares: Iterable["PublisherMiddleware"] = (), ) -> Any: - raise NotImplementedError( + msg = ( "`FakePublisher` can be used only to publish " "a response for `reply-to` or `RPC` messages." ) + raise NotImplementedError( + msg, + ) diff --git a/faststream/_internal/publisher/proto.py b/faststream/_internal/publisher/proto.py index 26a6633fe2..074fe97d97 100644 --- a/faststream/_internal/publisher/proto.py +++ b/faststream/_internal/publisher/proto.py @@ -1,5 +1,6 @@ from abc import abstractmethod -from typing import TYPE_CHECKING, Any, Callable, Generic, Iterable, Optional, Protocol +from collections.abc import Iterable +from typing import TYPE_CHECKING, Any, Callable, Generic, Optional, Protocol from typing_extensions import override diff --git a/faststream/_internal/publisher/usecase.py b/faststream/_internal/publisher/usecase.py index 584d6b6ff4..dbff727a29 100644 --- a/faststream/_internal/publisher/usecase.py +++ b/faststream/_internal/publisher/usecase.py @@ -1,18 +1,17 @@ +from collections.abc import Iterable from inspect import unwrap from typing import ( TYPE_CHECKING, + Annotated, Any, Callable, - Iterable, - List, Optional, - Tuple, ) from unittest.mock import MagicMock from fast_depends._compat import create_model, get_config_base from fast_depends.core import CallModel, build_call_model -from typing_extensions import Annotated, Doc, override +from typing_extensions import Doc, override from faststream._internal.publisher.proto import PublisherProto from faststream._internal.subscriber.call_wrapper.call import HandlerCallWrapper @@ -39,7 +38,7 @@ class PublisherUsecase( """A base class for publishers in an asynchronous API.""" mock: Optional[MagicMock] - calls: List[Callable[..., Any]] + calls: list[Callable[..., Any]] def __init__( self, @@ -57,7 +56,7 @@ def __init__( Optional[Any], Doc( "AsyncAPI publishing message type" - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ], title_: Annotated[ @@ -133,8 +132,8 @@ def __call__( self.calls.append(handler_call._original_call) return handler_call - def get_payloads(self) -> List[Tuple["AnyDict", str]]: - payloads: List[Tuple[AnyDict, str]] = [] + def get_payloads(self) -> list[tuple["AnyDict", str]]: + payloads: list[tuple[AnyDict, str]] = [] if self.schema_: params = {"response__": (self.schema_, ...)} diff --git a/faststream/_internal/setup/__init__.py b/faststream/_internal/setup/__init__.py index 7462d2c586..bd5d749560 100644 --- a/faststream/_internal/setup/__init__.py +++ b/faststream/_internal/setup/__init__.py @@ -4,14 +4,14 @@ from .state import EmptyState, SetupState __all__ = ( - # state - "SetupState", "EmptyState", - # proto - "SetupAble", # FastDepend "FastDependsData", + "LoggerParamsStorage", # logging "LoggerState", - "LoggerParamsStorage", + # proto + "SetupAble", + # state + "SetupState", ) diff --git a/faststream/_internal/setup/fast_depends.py b/faststream/_internal/setup/fast_depends.py index 9122492539..aa3a664540 100644 --- a/faststream/_internal/setup/fast_depends.py +++ b/faststream/_internal/setup/fast_depends.py @@ -1,5 +1,6 @@ +from collections.abc import Sequence from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Callable, Optional, Sequence +from typing import TYPE_CHECKING, Any, Callable, Optional if TYPE_CHECKING: from faststream._internal.basic_types import Decorator diff --git a/faststream/_internal/setup/logger.py b/faststream/_internal/setup/logger.py index 216ddc1267..45d660c687 100644 --- a/faststream/_internal/setup/logger.py +++ b/faststream/_internal/setup/logger.py @@ -1,6 +1,6 @@ import warnings from dataclasses import dataclass, field -from typing import Optional, Protocol, Type +from typing import Optional, Protocol from faststream._internal.basic_types import AnyDict, LoggerProto from faststream._internal.constants import EMPTY @@ -9,10 +9,10 @@ from .proto import SetupAble __all__ = ( - "make_logger_state", - "LoggerState", - "LoggerParamsStorage", "DefaultLoggerStorage", + "LoggerParamsStorage", + "LoggerState", + "make_logger_state", ) @@ -20,7 +20,7 @@ def make_logger_state( logger: Optional["LoggerProto"], log_level: int, log_fmt: Optional[str], - default_storag_cls: Type["DefaultLoggerStorage"], + default_storag_cls: type["DefaultLoggerStorage"], ) -> "LoggerState": if logger is not EMPTY and log_fmt: warnings.warn( @@ -65,7 +65,8 @@ def log( extra: Optional["AnyDict"] = None, exc_info: Optional[Exception] = None, ) -> None: - raise IncorrectState("Logger object was not set up.") + msg = "Logger object was not set up." + raise IncorrectState(msg) class _EmptyLoggerObject(_LoggerObject): diff --git a/faststream/_internal/setup/state.py b/faststream/_internal/setup/state.py index a2c33d5a3c..907d8a3b56 100644 --- a/faststream/_internal/setup/state.py +++ b/faststream/_internal/setup/state.py @@ -1,5 +1,5 @@ from abc import abstractmethod, abstractproperty -from typing import Optional, Type +from typing import Optional from faststream.exceptions import IncorrectState @@ -38,7 +38,7 @@ def copy_with_params( depends_params=depends_params or self._depends_params, ) - def copy_to_state(self, state_cls: Type["SetupState"]) -> "SetupState": + def copy_to_state(self, state_cls: type["SetupState"]) -> "SetupState": return state_cls( depends_params=self._depends_params, logger_state=self._logger_params, diff --git a/faststream/_internal/subscriber/acknowledgement_watcher.py b/faststream/_internal/subscriber/acknowledgement_watcher.py index 04d7e03cde..c86e59baf6 100644 --- a/faststream/_internal/subscriber/acknowledgement_watcher.py +++ b/faststream/_internal/subscriber/acknowledgement_watcher.py @@ -1,8 +1,10 @@ import logging from abc import ABC, abstractmethod -from collections import Counter -from typing import TYPE_CHECKING, Any, Optional, Type, Union -from typing import Counter as CounterType +from collections import ( + Counter, + Counter as CounterType, +) +from typing import TYPE_CHECKING, Any, Optional, Union from faststream.exceptions import ( AckMessage, @@ -36,17 +38,17 @@ def __init__( @abstractmethod def add(self, message_id: str) -> None: """Add a message.""" - raise NotImplementedError() + raise NotImplementedError @abstractmethod def is_max(self, message_id: str) -> bool: """Check if the given message ID is the maximum attempt.""" - raise NotImplementedError() + raise NotImplementedError @abstractmethod def remove(self, message_id: str) -> None: """Remove a message.""" - raise NotImplementedError() + raise NotImplementedError class EndlessWatcher(BaseWatcher): @@ -54,7 +56,6 @@ class EndlessWatcher(BaseWatcher): def add(self, message_id: str) -> None: """Add a message to the list.""" - pass def is_max(self, message_id: str) -> bool: """Check if the given message ID is the maximum attempt.""" @@ -62,7 +63,6 @@ def is_max(self, message_id: str) -> bool: def remove(self, message_id: str) -> None: """Remove a message.""" - pass class OneTryWatcher(BaseWatcher): @@ -70,7 +70,6 @@ class OneTryWatcher(BaseWatcher): def add(self, message_id: str) -> None: """Add a message.""" - pass def is_max(self, message_id: str) -> bool: """Check if the given message ID is the maximum attempt.""" @@ -78,7 +77,6 @@ def is_max(self, message_id: str) -> bool: def remove(self, message_id: str) -> None: """Remove a message.""" - pass class CounterWatcher(BaseWatcher): @@ -104,11 +102,13 @@ def is_max(self, message_id: str) -> bool: if self.logger is not None: if is_max: self.logger.log( - logging.ERROR, f"Already retried {self.max_tries} times. Skipped." + logging.ERROR, + f"Already retried {self.max_tries} times. Skipped.", ) else: self.logger.log( - logging.ERROR, "Error is occurred. Pushing back to queue." + logging.ERROR, + "Error is occurred. Pushing back to queue.", ) return is_max @@ -138,7 +138,7 @@ async def __aenter__(self) -> None: async def __aexit__( self, - exc_type: Optional[Type[BaseException]], + exc_type: Optional[type[BaseException]], exc_val: Optional[BaseException], exc_tb: Optional["TracebackType"], ) -> bool: diff --git a/faststream/_internal/subscriber/call_item.py b/faststream/_internal/subscriber/call_item.py index 264a5cf68b..6a20e3ac7c 100644 --- a/faststream/_internal/subscriber/call_item.py +++ b/faststream/_internal/subscriber/call_item.py @@ -1,3 +1,4 @@ +from collections.abc import Iterable from functools import partial from inspect import unwrap from itertools import chain @@ -5,9 +6,7 @@ TYPE_CHECKING, Any, Callable, - Dict, Generic, - Iterable, Optional, cast, ) @@ -36,13 +35,13 @@ class HandlerItem(SetupAble, Generic[MsgType]): """A class representing handler overloaded item.""" __slots__ = ( - "handler", - "filter", "dependant", "dependencies", - "item_parser", + "filter", + "handler", "item_decoder", "item_middlewares", + "item_parser", ) dependant: Optional[Any] @@ -111,8 +110,7 @@ def call_name(self) -> str: return "" caller = unwrap(self.handler._original_call) - name = getattr(caller, "__name__", str(caller)) - return name + return getattr(caller, "__name__", str(caller)) @property def description(self) -> Optional[str]: @@ -121,26 +119,27 @@ def description(self) -> Optional[str]: return None caller = unwrap(self.handler._original_call) - description = getattr(caller, "__doc__", None) - return description + return getattr(caller, "__doc__", None) async def is_suitable( self, msg: MsgType, - cache: Dict[Any, Any], + cache: dict[Any, Any], ) -> Optional["StreamMessage[MsgType]"]: """Check is message suite for current filter.""" if not (parser := cast(Optional["AsyncCallable"], self.item_parser)) or not ( decoder := cast(Optional["AsyncCallable"], self.item_decoder) ): - raise SetupError("You should setup `HandlerItem` at first.") + msg = "You should setup `HandlerItem` at first." + raise SetupError(msg) message = cache[parser] = cast( - "StreamMessage[MsgType]", cache.get(parser) or await parser(msg) + "StreamMessage[MsgType]", + cache.get(parser) or await parser(msg), ) message._decoded_body = cache[decoder] = cache.get(decoder) or await decoder( - message + message, ) if await self.filter(message): @@ -169,7 +168,7 @@ async def call( except Exception as e: self.handler.trigger(error=e) - raise e + raise else: self.handler.trigger(result=result) diff --git a/faststream/_internal/subscriber/call_wrapper/call.py b/faststream/_internal/subscriber/call_wrapper/call.py index ba0ef40daa..208821ad38 100644 --- a/faststream/_internal/subscriber/call_wrapper/call.py +++ b/faststream/_internal/subscriber/call_wrapper/call.py @@ -1,15 +1,11 @@ import asyncio +from collections.abc import Awaitable, Iterable, Mapping, Sequence from typing import ( TYPE_CHECKING, Any, - Awaitable, Callable, Generic, - Iterable, - List, - Mapping, Optional, - Sequence, Union, ) from unittest.mock import MagicMock @@ -43,15 +39,15 @@ class HandlerCallWrapper(Generic[MsgType, P_HandlerParams, T_HandlerReturn]): _wrapped_call: Optional[Callable[..., Awaitable[Any]]] _original_call: Callable[P_HandlerParams, T_HandlerReturn] - _publishers: List["PublisherProto[MsgType]"] + _publishers: list["PublisherProto[MsgType]"] __slots__ = ( - "mock", - "future", - "is_test", - "_wrapped_call", "_original_call", "_publishers", + "_wrapped_call", + "future", + "is_test", + "mock", ) def __new__( @@ -64,8 +60,7 @@ def __new__( """Create a new instance of the class.""" if isinstance(call, cls): return call - else: - return super().__new__(cls) + return super().__new__(cls) def __init__( self, @@ -128,7 +123,8 @@ def trigger( return if self.future is None: - raise SetupError("You can use this method only with TestClient") + msg = "You can use this method only with TestClient" + raise SetupError(msg) if self.future.done(): self.future = asyncio.Future() @@ -195,11 +191,12 @@ async def decode_wrapper(message: "StreamMessage[MsgType]") -> T_HandlerReturn: if params_ln > 1: if isinstance(msg, Mapping): return await func(**msg) - elif isinstance(msg, Sequence): + if isinstance(msg, Sequence): return await func(*msg) else: return await func(msg) - raise AssertionError("unreachable") + msg = "unreachable" + raise AssertionError(msg) return decode_wrapper diff --git a/faststream/_internal/subscriber/call_wrapper/proto.py b/faststream/_internal/subscriber/call_wrapper/proto.py index 2fb8591497..161905351a 100644 --- a/faststream/_internal/subscriber/call_wrapper/proto.py +++ b/faststream/_internal/subscriber/call_wrapper/proto.py @@ -1,8 +1,8 @@ +from collections.abc import Iterable from typing import ( TYPE_CHECKING, Any, Callable, - Iterable, Optional, Protocol, Union, diff --git a/faststream/_internal/subscriber/proto.py b/faststream/_internal/subscriber/proto.py index c82843b93c..e376a497f9 100644 --- a/faststream/_internal/subscriber/proto.py +++ b/faststream/_internal/subscriber/proto.py @@ -1,5 +1,6 @@ from abc import abstractmethod -from typing import TYPE_CHECKING, Any, Callable, Dict, Iterable, List, Optional +from collections.abc import Iterable +from typing import TYPE_CHECKING, Any, Callable, Optional from typing_extensions import Self, override @@ -32,7 +33,7 @@ class SubscriberProto( Endpoint, WrapperProto[MsgType], ): - calls: List["HandlerItem[MsgType]"] + calls: list["HandlerItem[MsgType]"] running: bool _broker_dependencies: Iterable["Depends"] @@ -47,7 +48,7 @@ def get_log_context( self, msg: Optional["StreamMessage[MsgType]"], /, - ) -> Dict[str, str]: ... + ) -> dict[str, str]: ... @override @abstractmethod @@ -91,7 +92,9 @@ async def process_message(self, msg: MsgType) -> "Response": ... @abstractmethod async def get_one( - self, *, timeout: float = 5.0 + self, + *, + timeout: float = 5.0, ) -> "Optional[StreamMessage[MsgType]]": ... @abstractmethod diff --git a/faststream/_internal/subscriber/usecase.py b/faststream/_internal/subscriber/usecase.py index 7e9aba6f4c..54d5a9250c 100644 --- a/faststream/_internal/subscriber/usecase.py +++ b/faststream/_internal/subscriber/usecase.py @@ -1,16 +1,12 @@ from abc import abstractmethod -from contextlib import AsyncExitStack +from collections.abc import Iterable +from contextlib import AbstractContextManager, AsyncExitStack from itertools import chain from typing import ( TYPE_CHECKING, Any, Callable, - ContextManager, - Dict, - Iterable, - List, Optional, - Tuple, Union, overload, ) @@ -61,10 +57,10 @@ class _CallOptions: __slots__ = ( - "parser", "decoder", - "middlewares", "dependencies", + "middlewares", + "parser", ) def __init__( @@ -84,7 +80,7 @@ def __init__( class SubscriberUsecase(SubscriberProto[MsgType]): """A class representing an asynchronous handler.""" - lock: ContextManager[Any] + lock: "AbstractContextManager[Any]" extra_watcher_options: "AnyDict" extra_context: "AnyDict" graceful_timeout: Optional[float] @@ -261,9 +257,12 @@ def __call__( dependencies: Iterable["Depends"] = (), ) -> Any: if (options := self._call_options) is None: - raise SetupError( + msg = ( "You can't create subscriber directly. Please, use `add_call` at first." ) + raise SetupError( + msg, + ) total_deps = (*options.dependencies, *dependencies) total_middlewares = (*options.middlewares, *middlewares) @@ -273,7 +272,7 @@ def real_wrapper( func: Callable[P_HandlerParams, T_HandlerReturn], ) -> "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]": handler = HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]( - func + func, ) self.calls.append( HandlerItem[MsgType]( @@ -283,7 +282,7 @@ def real_wrapper( item_decoder=decoder or options.decoder, item_middlewares=total_middlewares, dependencies=total_deps, - ) + ), ) return handler @@ -291,8 +290,7 @@ def real_wrapper( if func is None: return real_wrapper - else: - return real_wrapper(func) + return real_wrapper(func) async def consume(self, msg: MsgType) -> Any: """Consume a message asynchronously.""" @@ -329,13 +327,13 @@ async def process_message(self, msg: MsgType) -> "Response": stack.enter_context(context.scope("handler_", self)) # enter all middlewares - middlewares: List[BaseMiddleware] = [] + middlewares: list[BaseMiddleware] = [] for base_m in self._broker_middlewares: middleware = base_m(msg) middlewares.append(middleware) await middleware.__aenter__() - cache: Dict[Any, Any] = {} + cache: dict[Any, Any] = {} parsing_error: Optional[Exception] = None for h in self.calls: try: @@ -351,11 +349,11 @@ async def process_message(self, msg: MsgType) -> "Response": self.watcher( message, **self.extra_watcher_options, - ) + ), ) stack.enter_context( - context.scope("log_context", self.get_log_context(message)) + context.scope("log_context", self.get_log_context(message)), ) stack.enter_context(context.scope("message", message)) @@ -368,7 +366,7 @@ async def process_message(self, msg: MsgType) -> "Response": message=message, # consumer middlewares _extra_middlewares=(m.consume_scope for m in middlewares), - ) + ), ) if not result_msg.correlation_id: @@ -396,8 +394,8 @@ async def process_message(self, msg: MsgType) -> "Response": if parsing_error: raise parsing_error - else: - raise SubscriberNotFound(f"There is no suitable handler for {msg=}") + msg = f"There is no suitable handler for {msg=}" + raise SubscriberNotFound(msg) # An error was raised and processed by some middleware return ensure_response(None) @@ -409,13 +407,12 @@ def __get_response_publisher( if not message.reply_to or self._no_reply: return () - else: - return self._make_response_publisher(message) + return self._make_response_publisher(message) def get_log_context( self, message: Optional["StreamMessage[MsgType]"], - ) -> Dict[str, str]: + ) -> dict[str, str]: """Generate log context.""" return { "message_id": getattr(message, "message_id", ""), @@ -436,16 +433,16 @@ def get_description(self) -> Optional[str]: if not self.calls: # pragma: no cover return None - else: - return self.calls[0].description + return self.calls[0].description - def get_payloads(self) -> List[Tuple["AnyDict", str]]: + def get_payloads(self) -> list[tuple["AnyDict", str]]: """Get the payloads of the handler.""" - payloads: List[Tuple[AnyDict, str]] = [] + payloads: list[tuple[AnyDict, str]] = [] for h in self.calls: if h.dependant is None: - raise SetupError("You should setup `Handler` at first.") + msg = "You should setup `Handler` at first." + raise SetupError(msg) body = parse_handler_params( h.dependant, @@ -461,7 +458,7 @@ def get_payloads(self) -> List[Tuple["AnyDict", str]]: "title": f"{self.title_ or self.call_name}:Message:Payload", }, to_camelcase(self.call_name), - ) + ), ) return payloads diff --git a/faststream/_internal/subscriber/utils.py b/faststream/_internal/subscriber/utils.py index 174139848d..f3099b6490 100644 --- a/faststream/_internal/subscriber/utils.py +++ b/faststream/_internal/subscriber/utils.py @@ -1,16 +1,13 @@ import asyncio import inspect -from contextlib import AsyncExitStack, suppress +from collections.abc import Awaitable, Iterable +from contextlib import AbstractAsyncContextManager, AsyncExitStack, suppress from functools import partial from typing import ( TYPE_CHECKING, Any, - AsyncContextManager, - Awaitable, Callable, - Iterable, Optional, - Type, Union, cast, ) @@ -80,7 +77,8 @@ async def process_msg( parsed_msg._decoded_body = await decoder(parsed_msg) return await return_msg(parsed_msg) - raise AssertionError("unreachable") + msg = "unreachable" + raise AssertionError(msg) async def default_filter(msg: "StreamMessage[Any]") -> bool: @@ -93,18 +91,17 @@ def get_watcher_context( no_ack: bool, retry: Union[bool, int], **extra_options: Any, -) -> Callable[..., AsyncContextManager[None]]: +) -> Callable[..., "AbstractAsyncContextManager[None]"]: """Create Acknowledgement scope.""" if no_ack: return fake_context - else: - return partial( - WatcherContext, - watcher=get_watcher(logger, retry), - logger=logger, - **extra_options, - ) + return partial( + WatcherContext, + watcher=get_watcher(logger, retry), + logger=logger, + **extra_options, + ) class MultiLock: @@ -121,7 +118,7 @@ def __enter__(self) -> Self: def __exit__( self, - exc_type: Optional[Type[BaseException]], + exc_type: Optional[type[BaseException]], exc_val: Optional[BaseException], exc_tb: Optional["TracebackType"], ) -> None: @@ -171,6 +168,5 @@ def resolve_custom_func( if len(original_params) == 1: return to_async(cast(Union["SyncCallable", "AsyncCallable"], custom_func)) - else: - name = tuple(original_params.items())[1][0] - return partial(to_async(custom_func), **{name: default_func}) + name = tuple(original_params.items())[1][0] + return partial(to_async(custom_func), **{name: default_func}) diff --git a/faststream/_internal/testing/app.py b/faststream/_internal/testing/app.py index 47b90d16bf..325ebc194a 100644 --- a/faststream/_internal/testing/app.py +++ b/faststream/_internal/testing/app.py @@ -1,6 +1,6 @@ from contextlib import ExitStack from functools import partial -from typing import TYPE_CHECKING, Dict, Optional, Type +from typing import TYPE_CHECKING, Optional from anyio.from_thread import start_blocking_portal @@ -17,12 +17,12 @@ class TestApp: __test__ = False app: "Application" - _extra_options: Dict[str, "SettingField"] + _extra_options: dict[str, "SettingField"] def __init__( self, app: "Application", - run_extra_options: Optional[Dict[str, "SettingField"]] = None, + run_extra_options: Optional[dict[str, "SettingField"]] = None, ) -> None: self.app = app self._extra_options = run_extra_options or {} @@ -45,7 +45,7 @@ def wait_shutdown() -> None: def __exit__( self, - exc_type: Optional[Type[BaseException]] = None, + exc_type: Optional[type[BaseException]] = None, exc_val: Optional[BaseException] = None, exc_tb: Optional["TracebackType"] = None, ) -> None: @@ -59,7 +59,7 @@ async def __aenter__(self) -> "Application": async def __aexit__( self, - exc_type: Optional[Type[BaseException]] = None, + exc_type: Optional[type[BaseException]] = None, exc_val: Optional[BaseException] = None, exc_tb: Optional["TracebackType"] = None, ) -> None: diff --git a/faststream/_internal/testing/ast.py b/faststream/_internal/testing/ast.py index 6120681df8..495819fc38 100644 --- a/faststream/_internal/testing/ast.py +++ b/faststream/_internal/testing/ast.py @@ -1,8 +1,9 @@ import ast import traceback +from collections.abc import Iterator from functools import lru_cache from pathlib import Path -from typing import Iterator, List, Optional, Union, cast +from typing import Optional, Union, cast def is_contains_context_name(scip_name: str, name: str) -> bool: @@ -21,7 +22,7 @@ def is_contains_context_name(scip_name: str, name: str) -> bool: @lru_cache def _read_source_ast(filename: str) -> ast.Module: - return ast.parse(Path(filename).read_text()) + return ast.parse(Path(filename).read_text(encoding="utf-8")) def _find_ast_node(module: ast.Module, lineno: Optional[int]) -> Optional[ast.AST]: @@ -45,7 +46,7 @@ def _find_withitems(node: Union[ast.With, ast.AsyncWith]) -> Iterator[ast.withit yield from _find_withitems(i) -def _get_withitem_calls(node: Union[ast.With, ast.AsyncWith]) -> List[str]: +def _get_withitem_calls(node: Union[ast.With, ast.AsyncWith]) -> list[str]: return [ id for i in _find_withitems(node) diff --git a/faststream/_internal/testing/broker.py b/faststream/_internal/testing/broker.py index 5dda704c55..7e33fd6ab5 100644 --- a/faststream/_internal/testing/broker.py +++ b/faststream/_internal/testing/broker.py @@ -1,17 +1,13 @@ import warnings from abc import abstractmethod +from collections.abc import AsyncGenerator, Generator from contextlib import asynccontextmanager, contextmanager from functools import partial from typing import ( TYPE_CHECKING, Any, - AsyncGenerator, - Generator, Generic, - List, Optional, - Tuple, - Type, TypeVar, ) from unittest import mock @@ -65,13 +61,13 @@ def __init__( connect_only = False self.connect_only = connect_only - self._fake_subscribers: List[SubscriberProto[Any]] = [] + self._fake_subscribers: list[SubscriberProto[Any]] = [] async def __aenter__(self) -> Broker: self._ctx = self._create_ctx() return await self._ctx.__aenter__() - async def __aexit__(self, *args: Any) -> None: + async def __aexit__(self, *args: object) -> None: await self._ctx.__aexit__(*args) @asynccontextmanager @@ -93,29 +89,36 @@ async def _create_ctx(self) -> AsyncGenerator[Broker, None]: @contextmanager def _patch_broker(self, broker: Broker) -> Generator[None, None, None]: - with mock.patch.object( - broker, - "start", - wraps=partial(self._fake_start, broker), - ), mock.patch.object( - broker, - "_connect", - wraps=partial(self._fake_connect, broker), - ), mock.patch.object( - broker, - "close", - ), mock.patch.object( - broker, - "_connection", - new=None, - ), mock.patch.object( - broker, - "_producer", - new=None, - ), mock.patch.object( - broker, - "ping", - return_value=True, + with ( + mock.patch.object( + broker, + "start", + wraps=partial(self._fake_start, broker), + ), + mock.patch.object( + broker, + "_connect", + wraps=partial(self._fake_connect, broker), + ), + mock.patch.object( + broker, + "close", + ), + mock.patch.object( + broker, + "_connection", + new=None, + ), + mock.patch.object( + broker, + "_producer", + new=None, + ), + mock.patch.object( + broker, + "ping", + return_value=True, + ), ): broker._setup() yield @@ -160,7 +163,7 @@ async def publisher_response_subscriber(msg: Any) -> None: def _fake_close( self, broker: Broker, - exc_type: Optional[Type[BaseException]] = None, + exc_type: Optional[type[BaseException]] = None, exc_val: Optional[BaseException] = None, exc_tb: Optional["TracebackType"] = None, ) -> None: @@ -181,8 +184,9 @@ def _fake_close( @staticmethod @abstractmethod def create_publisher_fake_subscriber( - broker: Broker, publisher: Any - ) -> Tuple["SubscriberProto[Any]", bool]: + broker: Broker, + publisher: Any, + ) -> tuple["SubscriberProto[Any]", bool]: raise NotImplementedError @staticmethod diff --git a/faststream/_internal/types.py b/faststream/_internal/types.py index 11179bb503..f7c47c9461 100644 --- a/faststream/_internal/types.py +++ b/faststream/_internal/types.py @@ -1,6 +1,6 @@ +from collections.abc import Awaitable from typing import ( Any, - Awaitable, Callable, Optional, Protocol, diff --git a/faststream/_internal/utils/data.py b/faststream/_internal/utils/data.py index 305648bb73..cc12c4cec2 100644 --- a/faststream/_internal/utils/data.py +++ b/faststream/_internal/utils/data.py @@ -1,12 +1,12 @@ -from typing import Type, TypeVar +from typing import TypeVar from faststream._internal.basic_types import AnyDict TypedDictCls = TypeVar("TypedDictCls") -def filter_by_dict(typed_dict: Type[TypedDictCls], data: AnyDict) -> TypedDictCls: +def filter_by_dict(typed_dict: type[TypedDictCls], data: AnyDict) -> TypedDictCls: annotations = typed_dict.__annotations__ - return typed_dict( # type: ignore - {k: v for k, v in data.items() if k in annotations} + return typed_dict( # type: ignore[call-arg] + {k: v for k, v in data.items() if k in annotations}, ) diff --git a/faststream/_internal/utils/functions.py b/faststream/_internal/utils/functions.py index ebfb349444..6f24aad0b6 100644 --- a/faststream/_internal/utils/functions.py +++ b/faststream/_internal/utils/functions.py @@ -1,12 +1,9 @@ -from contextlib import asynccontextmanager, contextmanager +from collections.abc import AsyncIterator, Awaitable, Iterator +from contextlib import AbstractContextManager, asynccontextmanager, contextmanager from functools import wraps from typing import ( Any, - AsyncIterator, - Awaitable, Callable, - ContextManager, - Iterator, Optional, Union, overload, @@ -20,10 +17,10 @@ __all__ = ( "call_or_await", - "to_async", - "timeout_scope", - "fake_context", "drop_response_type", + "fake_context", + "timeout_scope", + "to_async", ) @@ -58,8 +55,8 @@ async def to_async_wrapper(*args: F_Spec.args, **kwargs: F_Spec.kwargs) -> F_Ret def timeout_scope( timeout: Optional[float] = 30, raise_timeout: bool = False, -) -> ContextManager[anyio.CancelScope]: - scope: Callable[[Optional[float]], ContextManager[anyio.CancelScope]] +) -> AbstractContextManager[anyio.CancelScope]: + scope: Callable[[Optional[float]], AbstractContextManager[anyio.CancelScope]] scope = anyio.fail_after if raise_timeout else anyio.move_on_after # type: ignore[assignment] return scope(timeout) diff --git a/faststream/_internal/utils/nuid.py b/faststream/_internal/utils/nuid.py index a61aa08a8f..b15dc92ac1 100644 --- a/faststream/_internal/utils/nuid.py +++ b/faststream/_internal/utils/nuid.py @@ -36,7 +36,7 @@ class NUID: """ def __init__(self) -> None: - self._prand = Random(randbelow(max_int)) # nosec B311 + self._prand = Random(randbelow(max_int)) # nosec B311 # noqa: S311 self._seq = self._prand.randint(0, MAX_SEQ) self._inc = MIN_INC + self._prand.randint(BASE + 1, INC) self._prefix = bytearray() diff --git a/faststream/_internal/utils/path.py b/faststream/_internal/utils/path.py index c3c059bf71..d55d19da32 100644 --- a/faststream/_internal/utils/path.py +++ b/faststream/_internal/utils/path.py @@ -1,5 +1,6 @@ import re -from typing import Callable, Optional, Pattern, Tuple +from re import Pattern +from typing import Callable, Optional from faststream.exceptions import SetupError @@ -10,7 +11,7 @@ def compile_path( path: str, replace_symbol: str, patch_regex: Callable[[str], str] = lambda x: x, -) -> Tuple[Optional[Pattern[str]], str]: +) -> tuple[Optional[Pattern[str]], str]: path_regex = "^.*?" original_path = "" @@ -36,7 +37,8 @@ def compile_path( if duplicated_params: names = ", ".join(sorted(duplicated_params)) ending = "s" if len(duplicated_params) > 1 else "" - raise SetupError(f"Duplicated param name{ending} {names} at path {path}") + msg = f"Duplicated param name{ending} {names} at path {path}" + raise SetupError(msg) if idx == 0: regex = None diff --git a/faststream/annotations.py b/faststream/annotations.py index 55f3cbac98..a845df0471 100644 --- a/faststream/annotations.py +++ b/faststream/annotations.py @@ -1,11 +1,9 @@ import logging - -from typing_extensions import Annotated +from typing import Annotated from faststream._internal.context import ContextRepo as CR from faststream.app import FastStream as FS from faststream.params import Context -from faststream.params import NoCast as NoCast Logger = Annotated[logging.Logger, Context("logger")] ContextRepo = Annotated[CR, Context("context")] diff --git a/faststream/app.py b/faststream/app.py index 8565e847ba..427437f250 100644 --- a/faststream/app.py +++ b/faststream/app.py @@ -1,11 +1,9 @@ import logging +from collections.abc import Sequence from typing import ( TYPE_CHECKING, Any, - Dict, Optional, - Sequence, - Tuple, TypeVar, ) @@ -64,7 +62,7 @@ def __init__( async def run( self, log_level: int = logging.INFO, - run_extra_options: Optional[Dict[str, "SettingField"]] = None, + run_extra_options: Optional[dict[str, "SettingField"]] = None, ) -> None: """Run FastStream Application.""" assert self.broker, "You should setup a broker" # nosec B101 @@ -88,7 +86,7 @@ def exit(self) -> None: def as_asgi( self, - asgi_routes: Sequence[Tuple[str, "ASGIApp"]] = (), + asgi_routes: Sequence[tuple[str, "ASGIApp"]] = (), asyncapi_path: Optional[str] = None, ) -> AsgiFastStream: return AsgiFastStream.from_app(self, asgi_routes, asyncapi_path) diff --git a/faststream/asgi/__init__.py b/faststream/asgi/__init__.py index d9006a2207..ef994978d8 100644 --- a/faststream/asgi/__init__.py +++ b/faststream/asgi/__init__.py @@ -5,8 +5,8 @@ __all__ = ( "AsgiFastStream", - "make_ping_asgi", - "make_asyncapi_asgi", "AsgiResponse", "get", + "make_asyncapi_asgi", + "make_ping_asgi", ) diff --git a/faststream/asgi/app.py b/faststream/asgi/app.py index 7a3c1d3763..7d2e91e53e 100644 --- a/faststream/asgi/app.py +++ b/faststream/asgi/app.py @@ -2,16 +2,13 @@ import logging import traceback from abc import abstractmethod +from collections.abc import AsyncIterator, Sequence from contextlib import asynccontextmanager from typing import ( TYPE_CHECKING, Any, - AsyncIterator, - Dict, Optional, Protocol, - Sequence, - Tuple, ) import anyio @@ -45,7 +42,7 @@ def handle_exit(self, sig: int, frame: Optional[FrameType]) -> None: ... class ServerState(Protocol): - extra_options: Dict[str, "SettingField"] + extra_options: dict[str, "SettingField"] @abstractmethod def stop(self) -> None: ... @@ -64,7 +61,7 @@ class CliRunState(ServerState): def __init__( self, server: "UvicornServerProtocol", - extra_options: Dict[str, "SettingField"], + extra_options: dict[str, "SettingField"], ) -> None: self.server = server self.extra_options = extra_options @@ -80,7 +77,7 @@ def __init__( self, broker: Optional["BrokerUsecase[Any, Any]"] = None, /, - asgi_routes: Sequence[Tuple[str, "ASGIApp"]] = (), + asgi_routes: Sequence[tuple[str, "ASGIApp"]] = (), # regular broker args logger: Optional["LoggerProto"] = logger, lifespan: Optional["Lifespan"] = None, @@ -108,7 +105,7 @@ def __init__( def from_app( cls, app: Application, - asgi_routes: Sequence[Tuple[str, "ASGIApp"]], + asgi_routes: Sequence[tuple[str, "ASGIApp"]], asyncapi_path: Optional[str] = None, ) -> "AsgiFastStream": asgi_app = cls( @@ -151,7 +148,7 @@ async def __call__( async def run( self, log_level: int = logging.INFO, - run_extra_options: Optional[Dict[str, "SettingField"]] = None, + run_extra_options: Optional[dict[str, "SettingField"]] = None, ) -> None: """Method to be compatible with FastStream CLI.""" import uvicorn @@ -186,7 +183,7 @@ def exit(self) -> None: @asynccontextmanager async def start_lifespan_context( self, - run_extra_options: Optional[Dict[str, "SettingField"]] = None, + run_extra_options: Optional[dict[str, "SettingField"]] = None, ) -> AsyncIterator[None]: run_extra_options = run_extra_options or self._server.extra_options @@ -208,7 +205,7 @@ async def start_lifespan_context( async def __start( self, log_level: int, - run_extra_options: Dict[str, "SettingField"], + run_extra_options: dict[str, "SettingField"], *, task_status: "TaskStatus[None]" = anyio.TASK_STATUS_IGNORED, ) -> None: diff --git a/faststream/asgi/factories.py b/faststream/asgi/factories.py index 3fa238ef1b..171bc4a414 100644 --- a/faststream/asgi/factories.py +++ b/faststream/asgi/factories.py @@ -30,8 +30,7 @@ def make_ping_asgi( async def ping(scope: "Scope") -> AsgiResponse: if await broker.ping(timeout): return healthy_response - else: - return unhealthy_response + return unhealthy_response return ping diff --git a/faststream/asgi/handlers.py b/faststream/asgi/handlers.py index e14234cdf6..0fb681e853 100644 --- a/faststream/asgi/handlers.py +++ b/faststream/asgi/handlers.py @@ -1,7 +1,7 @@ +from collections.abc import Sequence from functools import wraps from typing import ( TYPE_CHECKING, - Sequence, ) from faststream.asgi.response import AsgiResponse @@ -32,7 +32,6 @@ async def asgi_wrapper( response = error_response await response(scope, receive, send) - return return asgi_wrapper diff --git a/faststream/asgi/response.py b/faststream/asgi/response.py index cfc9d37d59..48e19598ff 100644 --- a/faststream/asgi/response.py +++ b/faststream/asgi/response.py @@ -1,4 +1,5 @@ -from typing import TYPE_CHECKING, List, Mapping, Optional, Tuple +from collections.abc import Mapping +from typing import TYPE_CHECKING, Optional if TYPE_CHECKING: from faststream.asgi.types import Receive, Scope, Send @@ -22,13 +23,13 @@ async def __call__(self, scope: "Scope", receive: "Receive", send: "Send") -> No "type": f"{prefix}http.response.start", "status": self.status_code, "headers": self.raw_headers, - } + }, ) await send( { "type": f"{prefix}http.response.body", "body": self.body, - } + }, ) @@ -36,9 +37,9 @@ def _get_response_headers( body: bytes, headers: Optional[Mapping[str, str]], status_code: int, -) -> List[Tuple[bytes, bytes]]: +) -> list[tuple[bytes, bytes]]: if headers is None: - raw_headers: List[Tuple[bytes, bytes]] = [] + raw_headers: list[tuple[bytes, bytes]] = [] populate_content_length = True else: @@ -52,7 +53,7 @@ def _get_response_headers( if ( body and populate_content_length - and not (status_code < 200 or status_code in (204, 304)) + and not (status_code < 200 or status_code in {204, 304}) ): content_length = str(len(body)) raw_headers.append((b"content-length", content_length.encode("latin-1"))) diff --git a/faststream/asgi/types.py b/faststream/asgi/types.py index df9d96b098..62910a1a2c 100644 --- a/faststream/asgi/types.py +++ b/faststream/asgi/types.py @@ -1,4 +1,5 @@ -from typing import Any, Awaitable, Callable, MutableMapping +from collections.abc import Awaitable, MutableMapping +from typing import Any, Callable Scope = MutableMapping[str, Any] Message = MutableMapping[str, Any] diff --git a/faststream/asgi/websocket.py b/faststream/asgi/websocket.py index 4a7fdf45de..e28397e2d4 100644 --- a/faststream/asgi/websocket.py +++ b/faststream/asgi/websocket.py @@ -15,5 +15,5 @@ def __init__( async def __call__(self, scope: "Scope", receive: "Receive", send: "Send") -> None: await send( - {"type": "websocket.close", "code": self.code, "reason": self.reason} + {"type": "websocket.close", "code": self.code, "reason": self.reason}, ) diff --git a/faststream/confluent/__init__.py b/faststream/confluent/__init__.py index 77c1b20280..8cd702ba5f 100644 --- a/faststream/confluent/__init__.py +++ b/faststream/confluent/__init__.py @@ -9,11 +9,11 @@ __all__ = ( "KafkaBroker", "KafkaMessage", - "KafkaRouter", - "KafkaRoute", "KafkaPublisher", "KafkaResponse", - "TopicPartition", - "TestKafkaBroker", + "KafkaRoute", + "KafkaRouter", "TestApp", + "TestKafkaBroker", + "TopicPartition", ) diff --git a/faststream/confluent/annotations.py b/faststream/confluent/annotations.py index 1d7739445a..e3c1f82af9 100644 --- a/faststream/confluent/annotations.py +++ b/faststream/confluent/annotations.py @@ -1,4 +1,4 @@ -from typing_extensions import Annotated +from typing import Annotated from faststream._internal.context import Context from faststream.annotations import ContextRepo, Logger @@ -8,12 +8,12 @@ from faststream.params import NoCast __all__ = ( - "Logger", "ContextRepo", - "NoCast", - "KafkaMessage", "KafkaBroker", + "KafkaMessage", "KafkaProducer", + "Logger", + "NoCast", ) KafkaMessage = Annotated[KM, Context("message")] diff --git a/faststream/confluent/broker/broker.py b/faststream/confluent/broker/broker.py index 65d6ed24cc..a2e28a0670 100644 --- a/faststream/confluent/broker/broker.py +++ b/faststream/confluent/broker/broker.py @@ -1,23 +1,20 @@ import logging +from collections.abc import Iterable from functools import partial from typing import ( TYPE_CHECKING, + Annotated, Any, Callable, - Dict, - Iterable, - List, Literal, Optional, - Tuple, - Type, TypeVar, Union, ) import anyio import confluent_kafka -from typing_extensions import Annotated, Doc, override +from typing_extensions import Doc, override from faststream.__about__ import SERVICE_NAME from faststream._internal.broker.broker import BrokerUsecase @@ -63,12 +60,12 @@ class KafkaBroker( BrokerUsecase[ Union[ confluent_kafka.Message, - Tuple[confluent_kafka.Message, ...], + tuple[confluent_kafka.Message, ...], ], Callable[..., AsyncConfluentConsumer], ], ): - url: List[str] + url: list[str] _producer: Optional[AsyncConfluentFastProducer] def __init__( @@ -83,7 +80,7 @@ def __init__( This does not have to be the full node list. It just needs to have at least one broker that will respond to a Metadata API Request. Default port is 9092. - """ + """, ), ] = "localhost", *, @@ -104,7 +101,7 @@ def __init__( which we force a refresh of metadata even if we haven't seen any partition leadership changes to proactively discover any new brokers or partitions. - """ + """, ), ] = 5 * 60 * 1000, connections_max_idle_ms: Annotated[ @@ -114,7 +111,7 @@ def __init__( Close idle connections after the number of milliseconds specified by this config. Specifying `None` will disable idle checks. - """ + """, ), ] = 9 * 60 * 1000, client_id: Annotated[ @@ -126,7 +123,7 @@ def __init__( server-side log entries that correspond to this client. Also submitted to :class:`~.consumer.group_coordinator.GroupCoordinator` for logging with respect to consumer group administration. - """ + """, ), ] = SERVICE_NAME, allow_auto_create_topics: Annotated[ @@ -134,7 +131,7 @@ def __init__( Doc( """ Allow automatic topic creation on the broker when subscribing to or assigning non-existent topics. - """ + """, ), ] = True, config: Annotated[ @@ -143,7 +140,7 @@ def __init__( """ Extra configuration for the confluent-kafka-python producer/consumer. See `confluent_kafka.Config `_. - """ + """, ), ] = None, # publisher args @@ -175,7 +172,7 @@ def __init__( If unset, defaults to ``acks=1``. If `enable_idempotence` is :data:`True` defaults to ``acks=all``. - """ + """, ), ] = EMPTY, compression_type: Annotated[ @@ -186,14 +183,14 @@ def __init__( Compression is of full batches of data, so the efficacy of batching will also impact the compression ratio (more batching means better compression). - """ + """, ), ] = None, partitioner: Annotated[ Union[ str, Callable[ - [bytes, List[Partition], List[Partition]], + [bytes, list[Partition], list[Partition]], Partition, ], ], @@ -207,7 +204,7 @@ def __init__( messages with the same key are assigned to the same partition. When a key is :data:`None`, the message is delivered to a random partition (filtered to partitions with available leaders only, if possible). - """ + """, ), ] = "consistent_random", max_request_size: Annotated[ @@ -219,7 +216,7 @@ def __init__( has its own cap on record size which may be different from this. This setting will limit the number of record batches the producer will send in a single request to avoid sending huge requests. - """ + """, ), ] = 1024 * 1024, linger_ms: Annotated[ @@ -234,7 +231,7 @@ def __init__( This setting accomplishes this by adding a small amount of artificial delay; that is, if first request is processed faster, than `linger_ms`, producer will wait ``linger_ms - process_time``. - """ + """, ), ] = 0, enable_idempotence: Annotated[ @@ -247,7 +244,7 @@ def __init__( etc., may write duplicates of the retried message in the stream. Note that enabling idempotence acks to set to ``all``. If it is not explicitly set by the user it will be chosen. - """ + """, ), ] = False, transactional_id: Optional[str] = None, @@ -256,7 +253,7 @@ def __init__( graceful_timeout: Annotated[ Optional[float], Doc( - "Graceful shutdown timeout. Broker waits for all running subscribers completion before shut down." + "Graceful shutdown timeout. Broker waits for all running subscribers completion before shut down.", ), ] = 15.0, decoder: Annotated[ @@ -275,7 +272,7 @@ def __init__( Iterable[ Union[ "BrokerMiddleware[Message]", - "BrokerMiddleware[Tuple[Message, ...]]", + "BrokerMiddleware[tuple[Message, ...]]", ] ], Doc("Middlewares to apply to all broker publishers/subscribers."), @@ -284,7 +281,7 @@ def __init__( security: Annotated[ Optional["BaseSecurity"], Doc( - "Security options to connect broker and generate AsyncAPI server security information." + "Security options to connect broker and generate AsyncAPI server security information.", ), ] = None, specification_url: Annotated[ @@ -407,7 +404,7 @@ def __init__( async def close( self, - exc_type: Optional[Type[BaseException]] = None, + exc_type: Optional[type[BaseException]] = None, exc_val: Optional[BaseException] = None, exc_tb: Optional["TracebackType"] = None, ) -> None: @@ -482,7 +479,7 @@ async def publish( # type: ignore[override] key: Optional[bytes] = None, partition: Optional[int] = None, timestamp_ms: Optional[int] = None, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, correlation_id: Optional[str] = None, *, reply_to: str = "", @@ -514,7 +511,7 @@ async def request( # type: ignore[override] key: Optional[bytes] = None, partition: Optional[int] = None, timestamp_ms: Optional[int] = None, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, correlation_id: Optional[str] = None, timeout: float = 0.5, ) -> Optional[Any]: @@ -538,7 +535,7 @@ async def publish_batch( topic: str, partition: Optional[int] = None, timestamp_ms: Optional[int] = None, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, reply_to: str = "", correlation_id: Optional[str] = None, no_confirm: bool = False, diff --git a/faststream/confluent/broker/logging.py b/faststream/confluent/broker/logging.py index ec17abb215..276c571373 100644 --- a/faststream/confluent/broker/logging.py +++ b/faststream/confluent/broker/logging.py @@ -26,13 +26,13 @@ def setup_log_contest(self, params: "AnyDict") -> None: ( self._max_topic_len, len(params.get("topic", "")), - ) + ), ) self._max_group_len = max( ( self._max_group_len, len(params.get("group_id", "")), - ) + ), ) def get_logger(self) -> Optional["LoggerProto"]: @@ -47,17 +47,17 @@ def get_logger(self) -> Optional["LoggerProto"]: }, message_id_ln=message_id_ln, fmt=self._log_fmt - or ( - "%(asctime)s %(levelname)-8s - " - + f"%(topic)-{self._max_topic_len}s | " - + ( + or "".join(( + "%(asctime)s %(levelname)-8s - ", + f"%(topic)-{self._max_topic_len}s | ", + ( f"%(group_id)-{self._max_group_len}s | " if self._max_group_len else "" - ) - + f"%(message_id)-{message_id_ln}s " - + "- %(message)s" - ), + ), + f"%(message_id)-{message_id_ln}s ", + "- %(message)s", + )), ) diff --git a/faststream/confluent/broker/registrator.py b/faststream/confluent/broker/registrator.py index 10232d060a..823238e587 100644 --- a/faststream/confluent/broker/registrator.py +++ b/faststream/confluent/broker/registrator.py @@ -1,19 +1,16 @@ +from collections.abc import Iterable, Sequence from typing import ( TYPE_CHECKING, + Annotated, Any, - Dict, - Iterable, - List, Literal, Optional, - Sequence, - Tuple, Union, cast, overload, ) -from typing_extensions import Annotated, Doc, override +from typing_extensions import Doc, override from faststream._internal.broker.abc_broker import ABCBroker from faststream.confluent.publisher.publisher import SpecificationPublisher @@ -45,16 +42,16 @@ class KafkaRegistrator( ABCBroker[ Union[ "Message", - Tuple["Message", ...], + tuple["Message", ...], ] - ] + ], ): """Includable to KafkaBroker router.""" - _subscribers: List[ + _subscribers: list[ Union["SpecificationBatchSubscriber", "SpecificationDefaultSubscriber"] ] - _publishers: List[ + _publishers: list[ Union["SpecificationBatchPublisher", "SpecificationDefaultPublisher"] ] @@ -75,7 +72,7 @@ def subscriber( partition assignment (if enabled), and to use for fetching and committing offsets. If `None`, auto-partition assignment (via group coordinator) and offset commits are disabled. - """ + """, ), ] = None, group_instance_id: Annotated[ @@ -88,7 +85,7 @@ def subscriber( partition assignment, rebalances). This can be used to assign partitions to specific consumers, rather than letting the group assign partitions based on consumer metadata. - """ + """, ), ] = None, fetch_max_wait_ms: Annotated[ @@ -99,7 +96,7 @@ def subscriber( the server will block before answering the fetch request if there isn't sufficient data to immediately satisfy the requirement given by `fetch_min_bytes`. - """ + """, ), ] = 500, fetch_max_bytes: Annotated[ @@ -114,7 +111,7 @@ def subscriber( performs fetches to multiple brokers in parallel so memory usage will depend on the number of brokers containing partitions for the topic. - """ + """, ), ] = 50 * 1024 * 1024, fetch_min_bytes: Annotated[ @@ -124,7 +121,7 @@ def subscriber( Minimum amount of data the server should return for a fetch request, otherwise wait up to `fetch_max_wait_ms` for more data to accumulate. - """ + """, ), ] = 1, max_partition_fetch_bytes: Annotated[ @@ -139,7 +136,7 @@ def subscriber( send messages larger than the consumer can fetch. If that happens, the consumer can get stuck trying to fetch a large message on a certain partition. - """ + """, ), ] = 1 * 1024 * 1024, auto_offset_reset: Annotated[ @@ -151,7 +148,7 @@ def subscriber( * `earliest` will move to the oldest available message * `latest` will move to the most recent * `none` will raise an exception so you can handle this case - """ + """, ), ] = "latest", auto_commit: Annotated[ @@ -160,7 +157,7 @@ def subscriber( """ If `True` the consumer's offset will be periodically committed in the background. - """ + """, ), ] = True, auto_commit_interval_ms: Annotated[ @@ -168,7 +165,7 @@ def subscriber( Doc( """ Milliseconds between automatic - offset commits, if `auto_commit` is `True`.""" + offset commits, if `auto_commit` is `True`.""", ), ] = 5 * 1000, check_crcs: Annotated[ @@ -179,7 +176,7 @@ def subscriber( consumed. This ensures no on-the-wire or on-disk corruption to the messages occurred. This check adds some overhead, so it may be disabled in cases seeking extreme performance. - """ + """, ), ] = True, partition_assignment_strategy: Annotated[ @@ -195,7 +192,7 @@ def subscriber( one. The coordinator will choose the old assignment strategy until all members have been updated. Then it will choose the new strategy. - """ + """, ), ] = ("roundrobin",), max_poll_interval_ms: Annotated[ @@ -208,7 +205,7 @@ def subscriber( rebalance in order to reassign the partitions to another consumer group member. If API methods block waiting for messages, that time does not count against this timeout. - """ + """, ), ] = 5 * 60 * 1000, session_timeout_ms: Annotated[ @@ -223,7 +220,7 @@ def subscriber( group and trigger a rebalance. The allowed range is configured with the **broker** configuration properties `group.min.session.timeout.ms` and `group.max.session.timeout.ms`. - """ + """, ), ] = 10 * 1000, heartbeat_interval_ms: Annotated[ @@ -239,7 +236,7 @@ def subscriber( should be set no higher than 1/3 of that value. It can be adjusted even lower to control the expected time for normal rebalances. - """ + """, ), ] = 3 * 1000, isolation_level: Annotated[ @@ -269,7 +266,7 @@ def subscriber( to the high watermark when there are in flight transactions. Further, when in `read_committed` the seek_to_end method will return the LSO. See method docs below. - """ + """, ), ] = "read_uncommitted", batch: Annotated[ @@ -308,7 +305,7 @@ def subscriber( no_reply: Annotated[ bool, Doc( - "Whether to disable **FastStream** RPC and Reply To auto responses or not." + "Whether to disable **FastStream** RPC and Reply To auto responses or not.", ), ] = False, # Specification args @@ -320,7 +317,7 @@ def subscriber( Optional[str], Doc( "Specification subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -346,7 +343,7 @@ def subscriber( partition assignment (if enabled), and to use for fetching and committing offsets. If `None`, auto-partition assignment (via group coordinator) and offset commits are disabled. - """ + """, ), ] = None, group_instance_id: Annotated[ @@ -359,7 +356,7 @@ def subscriber( partition assignment, rebalances). This can be used to assign partitions to specific consumers, rather than letting the group assign partitions based on consumer metadata. - """ + """, ), ] = None, fetch_max_wait_ms: Annotated[ @@ -370,7 +367,7 @@ def subscriber( the server will block before answering the fetch request if there isn't sufficient data to immediately satisfy the requirement given by `fetch_min_bytes`. - """ + """, ), ] = 500, fetch_max_bytes: Annotated[ @@ -385,7 +382,7 @@ def subscriber( performs fetches to multiple brokers in parallel so memory usage will depend on the number of brokers containing partitions for the topic. - """ + """, ), ] = 50 * 1024 * 1024, fetch_min_bytes: Annotated[ @@ -395,7 +392,7 @@ def subscriber( Minimum amount of data the server should return for a fetch request, otherwise wait up to `fetch_max_wait_ms` for more data to accumulate. - """ + """, ), ] = 1, max_partition_fetch_bytes: Annotated[ @@ -410,7 +407,7 @@ def subscriber( send messages larger than the consumer can fetch. If that happens, the consumer can get stuck trying to fetch a large message on a certain partition. - """ + """, ), ] = 1 * 1024 * 1024, auto_offset_reset: Annotated[ @@ -422,7 +419,7 @@ def subscriber( * `earliest` will move to the oldest available message * `latest` will move to the most recent * `none` will raise an exception so you can handle this case - """ + """, ), ] = "latest", auto_commit: Annotated[ @@ -431,7 +428,7 @@ def subscriber( """ If `True` the consumer's offset will be periodically committed in the background. - """ + """, ), ] = True, auto_commit_interval_ms: Annotated[ @@ -439,7 +436,7 @@ def subscriber( Doc( """ Milliseconds between automatic - offset commits, if `auto_commit` is `True`.""" + offset commits, if `auto_commit` is `True`.""", ), ] = 5 * 1000, check_crcs: Annotated[ @@ -450,7 +447,7 @@ def subscriber( consumed. This ensures no on-the-wire or on-disk corruption to the messages occurred. This check adds some overhead, so it may be disabled in cases seeking extreme performance. - """ + """, ), ] = True, partition_assignment_strategy: Annotated[ @@ -466,7 +463,7 @@ def subscriber( one. The coordinator will choose the old assignment strategy until all members have been updated. Then it will choose the new strategy. - """ + """, ), ] = ("roundrobin",), max_poll_interval_ms: Annotated[ @@ -479,7 +476,7 @@ def subscriber( rebalance in order to reassign the partitions to another consumer group member. If API methods block waiting for messages, that time does not count against this timeout. - """ + """, ), ] = 5 * 60 * 1000, session_timeout_ms: Annotated[ @@ -494,7 +491,7 @@ def subscriber( group and trigger a rebalance. The allowed range is configured with the **broker** configuration properties `group.min.session.timeout.ms` and `group.max.session.timeout.ms`. - """ + """, ), ] = 10 * 1000, heartbeat_interval_ms: Annotated[ @@ -510,7 +507,7 @@ def subscriber( should be set no higher than 1/3 of that value. It can be adjusted even lower to control the expected time for normal rebalances. - """ + """, ), ] = 3 * 1000, isolation_level: Annotated[ @@ -540,7 +537,7 @@ def subscriber( to the high watermark when there are in flight transactions. Further, when in `read_committed` the seek_to_end method will return the LSO. See method docs below. - """ + """, ), ] = "read_uncommitted", batch: Annotated[ @@ -579,7 +576,7 @@ def subscriber( no_reply: Annotated[ bool, Doc( - "Whether to disable **FastStream** RPC and Reply To auto responses or not." + "Whether to disable **FastStream** RPC and Reply To auto responses or not.", ), ] = False, # Specification args @@ -591,7 +588,7 @@ def subscriber( Optional[str], Doc( "Specification subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -617,7 +614,7 @@ def subscriber( partition assignment (if enabled), and to use for fetching and committing offsets. If `None`, auto-partition assignment (via group coordinator) and offset commits are disabled. - """ + """, ), ] = None, group_instance_id: Annotated[ @@ -630,7 +627,7 @@ def subscriber( partition assignment, rebalances). This can be used to assign partitions to specific consumers, rather than letting the group assign partitions based on consumer metadata. - """ + """, ), ] = None, fetch_max_wait_ms: Annotated[ @@ -641,7 +638,7 @@ def subscriber( the server will block before answering the fetch request if there isn't sufficient data to immediately satisfy the requirement given by `fetch_min_bytes`. - """ + """, ), ] = 500, fetch_max_bytes: Annotated[ @@ -656,7 +653,7 @@ def subscriber( performs fetches to multiple brokers in parallel so memory usage will depend on the number of brokers containing partitions for the topic. - """ + """, ), ] = 50 * 1024 * 1024, fetch_min_bytes: Annotated[ @@ -666,7 +663,7 @@ def subscriber( Minimum amount of data the server should return for a fetch request, otherwise wait up to `fetch_max_wait_ms` for more data to accumulate. - """ + """, ), ] = 1, max_partition_fetch_bytes: Annotated[ @@ -681,7 +678,7 @@ def subscriber( send messages larger than the consumer can fetch. If that happens, the consumer can get stuck trying to fetch a large message on a certain partition. - """ + """, ), ] = 1 * 1024 * 1024, auto_offset_reset: Annotated[ @@ -693,7 +690,7 @@ def subscriber( * `earliest` will move to the oldest available message * `latest` will move to the most recent * `none` will raise an exception so you can handle this case - """ + """, ), ] = "latest", auto_commit: Annotated[ @@ -702,7 +699,7 @@ def subscriber( """ If `True` the consumer's offset will be periodically committed in the background. - """ + """, ), ] = True, auto_commit_interval_ms: Annotated[ @@ -710,7 +707,7 @@ def subscriber( Doc( """ Milliseconds between automatic - offset commits, if `auto_commit` is `True`.""" + offset commits, if `auto_commit` is `True`.""", ), ] = 5 * 1000, check_crcs: Annotated[ @@ -721,7 +718,7 @@ def subscriber( consumed. This ensures no on-the-wire or on-disk corruption to the messages occurred. This check adds some overhead, so it may be disabled in cases seeking extreme performance. - """ + """, ), ] = True, partition_assignment_strategy: Annotated[ @@ -737,7 +734,7 @@ def subscriber( one. The coordinator will choose the old assignment strategy until all members have been updated. Then it will choose the new strategy. - """ + """, ), ] = ("roundrobin",), max_poll_interval_ms: Annotated[ @@ -750,7 +747,7 @@ def subscriber( rebalance in order to reassign the partitions to another consumer group member. If API methods block waiting for messages, that time does not count against this timeout. - """ + """, ), ] = 5 * 60 * 1000, session_timeout_ms: Annotated[ @@ -765,7 +762,7 @@ def subscriber( group and trigger a rebalance. The allowed range is configured with the **broker** configuration properties `group.min.session.timeout.ms` and `group.max.session.timeout.ms`. - """ + """, ), ] = 10 * 1000, heartbeat_interval_ms: Annotated[ @@ -781,7 +778,7 @@ def subscriber( should be set no higher than 1/3 of that value. It can be adjusted even lower to control the expected time for normal rebalances. - """ + """, ), ] = 3 * 1000, isolation_level: Annotated[ @@ -811,7 +808,7 @@ def subscriber( to the high watermark when there are in flight transactions. Further, when in `read_committed` the seek_to_end method will return the LSO. See method docs below. - """ + """, ), ] = "read_uncommitted", batch: Annotated[ @@ -850,7 +847,7 @@ def subscriber( no_reply: Annotated[ bool, Doc( - "Whether to disable **FastStream** RPC and Reply To auto responses or not." + "Whether to disable **FastStream** RPC and Reply To auto responses or not.", ), ] = False, # Specification args @@ -862,7 +859,7 @@ def subscriber( Optional[str], Doc( "Specification subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -891,7 +888,7 @@ def subscriber( partition assignment (if enabled), and to use for fetching and committing offsets. If `None`, auto-partition assignment (via group coordinator) and offset commits are disabled. - """ + """, ), ] = None, group_instance_id: Annotated[ @@ -904,7 +901,7 @@ def subscriber( partition assignment, rebalances). This can be used to assign partitions to specific consumers, rather than letting the group assign partitions based on consumer metadata. - """ + """, ), ] = None, fetch_max_wait_ms: Annotated[ @@ -915,7 +912,7 @@ def subscriber( the server will block before answering the fetch request if there isn't sufficient data to immediately satisfy the requirement given by `fetch_min_bytes`. - """ + """, ), ] = 500, fetch_max_bytes: Annotated[ @@ -930,7 +927,7 @@ def subscriber( performs fetches to multiple brokers in parallel so memory usage will depend on the number of brokers containing partitions for the topic. - """ + """, ), ] = 50 * 1024 * 1024, fetch_min_bytes: Annotated[ @@ -940,7 +937,7 @@ def subscriber( Minimum amount of data the server should return for a fetch request, otherwise wait up to `fetch_max_wait_ms` for more data to accumulate. - """ + """, ), ] = 1, max_partition_fetch_bytes: Annotated[ @@ -955,7 +952,7 @@ def subscriber( send messages larger than the consumer can fetch. If that happens, the consumer can get stuck trying to fetch a large message on a certain partition. - """ + """, ), ] = 1 * 1024 * 1024, auto_offset_reset: Annotated[ @@ -967,7 +964,7 @@ def subscriber( * `earliest` will move to the oldest available message * `latest` will move to the most recent * `none` will raise an exception so you can handle this case - """ + """, ), ] = "latest", auto_commit: Annotated[ @@ -976,7 +973,7 @@ def subscriber( """ If `True` the consumer's offset will be periodically committed in the background. - """ + """, ), ] = True, auto_commit_interval_ms: Annotated[ @@ -984,7 +981,7 @@ def subscriber( Doc( """ Milliseconds between automatic - offset commits, if `auto_commit` is `True`.""" + offset commits, if `auto_commit` is `True`.""", ), ] = 5 * 1000, check_crcs: Annotated[ @@ -995,7 +992,7 @@ def subscriber( consumed. This ensures no on-the-wire or on-disk corruption to the messages occurred. This check adds some overhead, so it may be disabled in cases seeking extreme performance. - """ + """, ), ] = True, partition_assignment_strategy: Annotated[ @@ -1011,7 +1008,7 @@ def subscriber( one. The coordinator will choose the old assignment strategy until all members have been updated. Then it will choose the new strategy. - """ + """, ), ] = ("roundrobin",), max_poll_interval_ms: Annotated[ @@ -1024,7 +1021,7 @@ def subscriber( rebalance in order to reassign the partitions to another consumer group member. If API methods block waiting for messages, that time does not count against this timeout. - """ + """, ), ] = 5 * 60 * 1000, session_timeout_ms: Annotated[ @@ -1039,7 +1036,7 @@ def subscriber( group and trigger a rebalance. The allowed range is configured with the **broker** configuration properties `group.min.session.timeout.ms` and `group.max.session.timeout.ms`. - """ + """, ), ] = 10 * 1000, heartbeat_interval_ms: Annotated[ @@ -1055,7 +1052,7 @@ def subscriber( should be set no higher than 1/3 of that value. It can be adjusted even lower to control the expected time for normal rebalances. - """ + """, ), ] = 3 * 1000, isolation_level: Annotated[ @@ -1085,7 +1082,7 @@ def subscriber( to the high watermark when there are in flight transactions. Further, when in `read_committed` the seek_to_end method will return the LSO. See method docs below. - """ + """, ), ] = "read_uncommitted", batch: Annotated[ @@ -1124,7 +1121,7 @@ def subscriber( no_reply: Annotated[ bool, Doc( - "Whether to disable **FastStream** RPC and Reply To auto responses or not." + "Whether to disable **FastStream** RPC and Reply To auto responses or not.", ), ] = False, # Specification args @@ -1136,7 +1133,7 @@ def subscriber( Optional[str], Doc( "Specification subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -1148,7 +1145,8 @@ def subscriber( "SpecificationBatchSubscriber", ]: if not auto_commit and not group_id: - raise SetupError("You should install `group_id` with manual commit mode") + msg = "You should install `group_id` with manual commit mode" + raise SetupError(msg) subscriber = super().subscriber( create_subscriber( @@ -1185,7 +1183,7 @@ def subscriber( title_=title, description_=description, include_in_schema=self._solve_include_in_schema(include_in_schema), - ) + ), ) if batch: @@ -1195,13 +1193,12 @@ def subscriber( dependencies_=dependencies, middlewares_=middlewares, ) - else: - return cast("SpecificationDefaultSubscriber", subscriber).add_call( - parser_=parser or self._parser, - decoder_=decoder or self._decoder, - dependencies_=dependencies, - middlewares_=middlewares, - ) + return cast("SpecificationDefaultSubscriber", subscriber).add_call( + parser_=parser or self._parser, + decoder_=decoder or self._decoder, + dependencies_=dependencies, + middlewares_=middlewares, + ) @overload # type: ignore[override] def publisher( @@ -1222,7 +1219,7 @@ def publisher( partition (but if key is `None`, partition is chosen randomly). Must be type `bytes`, or be serializable to bytes via configured `key_serializer`. - """ + """, ), ] = None, partition: Annotated[ @@ -1231,15 +1228,15 @@ def publisher( """ Specify a partition. If not set, the partition will be selected using the configured `partitioner`. - """ + """, ), ] = None, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc( "Message headers to store metainformation. " "**content-type** and **correlation_id** will be set automatically by framework anyway. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, reply_to: Annotated[ @@ -1268,7 +1265,7 @@ def publisher( Optional[Any], Doc( "Specification publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ @@ -1296,7 +1293,7 @@ def publisher( partition (but if key is `None`, partition is chosen randomly). Must be type `bytes`, or be serializable to bytes via configured `key_serializer`. - """ + """, ), ] = None, partition: Annotated[ @@ -1305,15 +1302,15 @@ def publisher( """ Specify a partition. If not set, the partition will be selected using the configured `partitioner`. - """ + """, ), ] = None, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc( "Message headers to store metainformation. " "**content-type** and **correlation_id** will be set automatically by framework anyway. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, reply_to: Annotated[ @@ -1342,7 +1339,7 @@ def publisher( Optional[Any], Doc( "Specification publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ @@ -1370,7 +1367,7 @@ def publisher( partition (but if key is `None`, partition is chosen randomly). Must be type `bytes`, or be serializable to bytes via configured `key_serializer`. - """ + """, ), ] = None, partition: Annotated[ @@ -1379,15 +1376,15 @@ def publisher( """ Specify a partition. If not set, the partition will be selected using the configured `partitioner`. - """ + """, ), ] = None, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc( "Message headers to store metainformation. " "**content-type** and **correlation_id** will be set automatically by framework anyway. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, reply_to: Annotated[ @@ -1416,7 +1413,7 @@ def publisher( Optional[Any], Doc( "Specification publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ @@ -1447,7 +1444,7 @@ def publisher( partition (but if key is `None`, partition is chosen randomly). Must be type `bytes`, or be serializable to bytes via configured `key_serializer`. - """ + """, ), ] = None, partition: Annotated[ @@ -1456,15 +1453,15 @@ def publisher( """ Specify a partition. If not set, the partition will be selected using the configured `partitioner`. - """ + """, ), ] = None, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc( "Message headers to store metainformation. " "**content-type** and **correlation_id** will be set automatically by framework anyway. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, reply_to: Annotated[ @@ -1493,7 +1490,7 @@ def publisher( Optional[Any], Doc( "Specification publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ @@ -1533,5 +1530,4 @@ def publisher( if batch: return cast("SpecificationBatchPublisher", super().publisher(publisher)) - else: - return cast("SpecificationDefaultPublisher", super().publisher(publisher)) + return cast("SpecificationDefaultPublisher", super().publisher(publisher)) diff --git a/faststream/confluent/client.py b/faststream/confluent/client.py index bd30ef2a56..74a3bed571 100644 --- a/faststream/confluent/client.py +++ b/faststream/confluent/client.py @@ -1,17 +1,13 @@ import asyncio import logging +from collections.abc import Iterable, Sequence from contextlib import suppress from time import time from typing import ( TYPE_CHECKING, Any, Callable, - Dict, - Iterable, - List, Optional, - Sequence, - Tuple, Union, ) @@ -35,7 +31,7 @@ class _SendKwargs(TypedDict): value: Optional[Union[str, bytes]] key: Optional[Union[str, bytes]] - headers: Optional[List[Tuple[str, Union[str, bytes]]]] + headers: Optional[list[tuple[str, Union[str, bytes]]]] partition: NotRequired[int] timestamp: NotRequired[int] on_delivery: NotRequired[Callable[..., None]] @@ -48,7 +44,7 @@ def __init__( self, *, config: config_module.ConfluentFastConfig, - bootstrap_servers: Union[str, List[str]] = "localhost", + bootstrap_servers: Union[str, list[str]] = "localhost", client_id: Optional[str] = None, metadata_max_age_ms: int = 300000, request_timeout_ms: int = 40000, @@ -69,7 +65,8 @@ def __init__( sasl_plain_username: Optional[str] = None, ) -> None: if isinstance(bootstrap_servers, Iterable) and not isinstance( - bootstrap_servers, str + bootstrap_servers, + str, ): bootstrap_servers = ",".join(bootstrap_servers) @@ -101,13 +98,13 @@ def __init__( final_config = {**config.as_config_dict(), **config_from_params} - if sasl_mechanism in ["PLAIN", "SCRAM-SHA-256", "SCRAM-SHA-512"]: + if sasl_mechanism in {"PLAIN", "SCRAM-SHA-256", "SCRAM-SHA-512"}: final_config.update( { "sasl.mechanism": sasl_mechanism, "sasl.username": sasl_plain_username, "sasl.password": sasl_plain_password, - } + }, ) self.producer = Producer(final_config) @@ -135,7 +132,7 @@ async def send( key: Optional[Union[str, bytes]] = None, partition: Optional[int] = None, timestamp_ms: Optional[int] = None, - headers: Optional[List[Tuple[str, Union[str, bytes]]]] = None, + headers: Optional[list[tuple[str, Union[str, bytes]]]] = None, no_confirm: bool = False, ) -> None: """Sends a single message to a Kafka topic.""" @@ -223,7 +220,7 @@ def __init__( partitions: Sequence["TopicPartition"], logger: "LoggerState", config: config_module.ConfluentFastConfig, - bootstrap_servers: Union[str, List[str]] = "localhost", + bootstrap_servers: Union[str, list[str]] = "localhost", client_id: Optional[str] = "confluent-kafka-consumer", group_id: Optional[str] = None, group_instance_id: Optional[str] = None, @@ -237,7 +234,7 @@ def __init__( auto_commit_interval_ms: int = 5000, check_crcs: bool = True, metadata_max_age_ms: int = 5 * 60 * 1000, - partition_assignment_strategy: Union[str, List[Any]] = "roundrobin", + partition_assignment_strategy: Union[str, list[Any]] = "roundrobin", max_poll_interval_ms: int = 300000, session_timeout_ms: int = 10000, heartbeat_interval_ms: int = 3000, @@ -252,7 +249,8 @@ def __init__( self.logger_state = logger if isinstance(bootstrap_servers, Iterable) and not isinstance( - bootstrap_servers, str + bootstrap_servers, + str, ): bootstrap_servers = ",".join(bootstrap_servers) @@ -264,7 +262,7 @@ def __init__( [ x if isinstance(x, str) else x().name for x in partition_assignment_strategy - ] + ], ) final_config = config.as_config_dict() @@ -300,20 +298,20 @@ def __init__( self.allow_auto_create_topics = allow_auto_create_topics final_config.update(config_from_params) - if sasl_mechanism in ["PLAIN", "SCRAM-SHA-256", "SCRAM-SHA-512"]: + if sasl_mechanism in {"PLAIN", "SCRAM-SHA-256", "SCRAM-SHA-512"}: final_config.update( { "sasl.mechanism": sasl_mechanism, "sasl.username": sasl_plain_username, "sasl.password": sasl_plain_password, - } + }, ) self.config = final_config self.consumer = Consumer(final_config) @property - def topics_to_create(self) -> List[str]: + def topics_to_create(self) -> list[str]: return list({*self.topics, *(p.topic for p in self.partitions)}) async def start(self) -> None: @@ -337,11 +335,13 @@ async def start(self) -> None: elif self.partitions: await call_or_await( - self.consumer.assign, [p.to_confluent() for p in self.partitions] + self.consumer.assign, + [p.to_confluent() for p in self.partitions], ) else: - raise SetupError("You must provide either `topics` or `partitions` option.") + msg = "You must provide either `topics` or `partitions` option." + raise SetupError(msg) async def commit(self, asynchronous: bool = True) -> None: """Commits the offsets of all messages returned by the last poll operation.""" @@ -379,9 +379,9 @@ async def getmany( self, timeout: float = 0.1, max_records: Optional[int] = 10, - ) -> Tuple[Message, ...]: + ) -> tuple[Message, ...]: """Consumes a batch of messages from Kafka and groups them by topic and partition.""" - raw_messages: List[Optional[Message]] = await call_or_await( + raw_messages: list[Optional[Message]] = await call_or_await( self.consumer.consume, num_messages=max_records or 10, timeout=timeout, @@ -392,7 +392,9 @@ async def getmany( async def seek(self, topic: str, partition: int, offset: int) -> None: """Seeks to the specified offset in the specified topic and partition.""" topic_partition = TopicPartition( - topic=topic, partition=partition, offset=offset + topic=topic, + partition=partition, + offset=offset, ) await call_or_await(self.consumer.seek, topic_partition.to_confluent()) @@ -410,7 +412,7 @@ class BatchBuilder: def __init__(self) -> None: """Initializes a new BatchBuilder instance.""" - self._builder: List[AnyDict] = [] + self._builder: list[AnyDict] = [] def append( self, @@ -418,12 +420,12 @@ def append( timestamp: Optional[int] = None, key: Optional[Union[str, bytes]] = None, value: Optional[Union[str, bytes]] = None, - headers: Optional[List[Tuple[str, bytes]]] = None, + headers: Optional[list[tuple[str, bytes]]] = None, ) -> None: """Appends a message to the batch with optional timestamp, key, value, and headers.""" if key is None and value is None: raise KafkaException( - KafkaError(40, reason="Both key and value can't be None") + KafkaError(40, reason="Both key and value can't be None"), ) self._builder.append( @@ -432,24 +434,24 @@ def append( "key": key, "value": value, "headers": headers or [], - } + }, ) def create_topics( - topics: List[str], - config: Dict[str, Optional[Union[str, int, float, bool, Any]]], + topics: list[str], + config: dict[str, Optional[Union[str, int, float, bool, Any]]], logger_: Optional["LoggerProto"] = None, ) -> None: logger_ = logger_ or faststream_logger """Creates Kafka topics using the provided configuration.""" admin_client = AdminClient( - {x: config[x] for x in ADMINCLIENT_CONFIG_PARAMS if x in config} + {x: config[x] for x in ADMINCLIENT_CONFIG_PARAMS if x in config}, ) fs = admin_client.create_topics( - [NewTopic(topic, num_partitions=1, replication_factor=1) for topic in topics] + [NewTopic(topic, num_partitions=1, replication_factor=1) for topic in topics], ) for topic, f in fs.items(): @@ -457,7 +459,7 @@ def create_topics( f.result() # The result itself is None except Exception as e: # noqa: PERF203 if "TOPIC_ALREADY_EXISTS" not in str(e): - logger_.log(logging.WARN, f"Failed to create topic {topic}: {e}") + logger_.log(logging.WARNING, f"Failed to create topic {topic}: {e}") else: logger_.log(logging.INFO, f"Topic `{topic}` created.") diff --git a/faststream/confluent/fastapi/__init__.py b/faststream/confluent/fastapi/__init__.py index d29709ebb8..dc7cb73000 100644 --- a/faststream/confluent/fastapi/__init__.py +++ b/faststream/confluent/fastapi/__init__.py @@ -1,4 +1,4 @@ -from typing_extensions import Annotated +from typing import Annotated from faststream._internal.fastapi.context import Context, ContextRepo, Logger from faststream.confluent.broker import KafkaBroker as KB @@ -8,12 +8,12 @@ __all__ = ( "Context", - "Logger", "ContextRepo", - "KafkaRouter", - "KafkaMessage", "KafkaBroker", + "KafkaMessage", "KafkaProducer", + "KafkaRouter", + "Logger", ) KafkaMessage = Annotated[KM, Context("message")] diff --git a/faststream/confluent/fastapi/fastapi.py b/faststream/confluent/fastapi/fastapi.py index b792c63a5d..7ebc3a6b77 100644 --- a/faststream/confluent/fastapi/fastapi.py +++ b/faststream/confluent/fastapi/fastapi.py @@ -1,16 +1,12 @@ import logging +from collections.abc import Iterable, Sequence from typing import ( TYPE_CHECKING, + Annotated, Any, Callable, - Dict, - Iterable, - List, Literal, Optional, - Sequence, - Tuple, - Type, TypeVar, Union, cast, @@ -23,7 +19,7 @@ from fastapi.utils import generate_unique_id from starlette.responses import JSONResponse, Response from starlette.routing import BaseRoute -from typing_extensions import Annotated, Doc, deprecated, override +from typing_extensions import Doc, deprecated, override from faststream.__about__ import SERVICE_NAME from faststream._internal.constants import EMPTY @@ -62,7 +58,7 @@ Partition = TypeVar("Partition") -class KafkaRouter(StreamRouter[Union[Message, Tuple[Message, ...]]]): +class KafkaRouter(StreamRouter[Union[Message, tuple[Message, ...]]]): """A class to represent a Kafka router.""" broker_class = KB @@ -80,7 +76,7 @@ def __init__( This does not have to be the full node list. It just needs to have at least one broker that will respond to a Metadata API Request. Default port is 9092. - """ + """, ), ] = "localhost", *, @@ -101,7 +97,7 @@ def __init__( which we force a refresh of metadata even if we haven't seen any partition leadership changes to proactively discover any new brokers or partitions. - """ + """, ), ] = 5 * 60 * 1000, connections_max_idle_ms: Annotated[ @@ -111,7 +107,7 @@ def __init__( Close idle connections after the number of milliseconds specified by this config. Specifying `None` will disable idle checks. - """ + """, ), ] = 9 * 60 * 1000, client_id: Annotated[ @@ -123,7 +119,7 @@ def __init__( server-side log entries that correspond to this client. Also submitted to :class:`~.consumer.group_coordinator.GroupCoordinator` for logging with respect to consumer group administration. - """ + """, ), ] = SERVICE_NAME, allow_auto_create_topics: Annotated[ @@ -131,7 +127,7 @@ def __init__( Doc( """ Allow automatic topic creation on the broker when subscribing to or assigning non-existent topics. - """ + """, ), ] = True, config: Annotated[ @@ -140,7 +136,7 @@ def __init__( """ Extra configuration for the confluent-kafka-python producer/consumer. See `confluent_kafka.Config `_. - """ + """, ), ] = None, # publisher args @@ -172,7 +168,7 @@ def __init__( If unset, defaults to ``acks=1``. If `enable_idempotence` is :data:`True` defaults to ``acks=all``. - """ + """, ), ] = EMPTY, compression_type: Annotated[ @@ -183,14 +179,14 @@ def __init__( Compression is of full batches of data, so the efficacy of batching will also impact the compression ratio (more batching means better compression). - """ + """, ), ] = None, partitioner: Annotated[ Union[ str, Callable[ - [bytes, List[Partition], List[Partition]], + [bytes, list[Partition], list[Partition]], Partition, ], ], @@ -204,7 +200,7 @@ def __init__( messages with the same key are assigned to the same partition. When a key is :data:`None`, the message is delivered to a random partition (filtered to partitions with available leaders only, if possible). - """ + """, ), ] = "consistent_random", max_request_size: Annotated[ @@ -216,7 +212,7 @@ def __init__( has its own cap on record size which may be different from this. This setting will limit the number of record batches the producer will send in a single request to avoid sending huge requests. - """ + """, ), ] = 1024 * 1024, linger_ms: Annotated[ @@ -231,7 +227,7 @@ def __init__( This setting accomplishes this by adding a small amount of artificial delay; that is, if first request is processed faster, than `linger_ms`, producer will wait ``linger_ms - process_time``. - """ + """, ), ] = 0, enable_idempotence: Annotated[ @@ -244,7 +240,7 @@ def __init__( etc., may write duplicates of the retried message in the stream. Note that enabling idempotence acks to set to ``all``. If it is not explicitly set by the user it will be chosen. - """ + """, ), ] = False, transactional_id: Optional[str] = None, @@ -253,7 +249,7 @@ def __init__( graceful_timeout: Annotated[ Optional[float], Doc( - "Graceful shutdown timeout. Broker waits for all running subscribers completion before shut down." + "Graceful shutdown timeout. Broker waits for all running subscribers completion before shut down.", ), ] = 15.0, decoder: Annotated[ @@ -268,7 +264,7 @@ def __init__( Iterable[ Union[ "BrokerMiddleware[Message]", - "BrokerMiddleware[Tuple[Message, ...]]", + "BrokerMiddleware[tuple[Message, ...]]", ] ], Doc("Middlewares to apply to all broker publishers/subscribers."), @@ -277,13 +273,13 @@ def __init__( security: Annotated[ Optional["BaseSecurity"], Doc( - "Security options to connect broker and generate Specification server security information." + "Security options to connect broker and generate Specification server security information.", ), ] = None, specification_url: Annotated[ Optional[str], Doc( - "Specification hardcoded server addresses. Use `servers` if not specified." + "Specification hardcoded server addresses. Use `servers` if not specified.", ), ] = None, protocol: Annotated[ @@ -320,13 +316,13 @@ def __init__( bool, Doc( "Whether to add broker to app scope in lifespan. " - "You should disable this option at old ASGI servers." + "You should disable this option at old ASGI servers.", ), ] = True, schema_url: Annotated[ Optional[str], Doc( - "Specification schema url. You should set this option to `None` to disable Specification routes at all." + "Specification schema url. You should set this option to `None` to disable Specification routes at all.", ), ] = "/asyncapi", # FastAPI args @@ -335,7 +331,7 @@ def __init__( Doc("An optional path prefix for the router."), ] = "", tags: Annotated[ - Optional[List[Union[str, "Enum"]]], + Optional[list[Union[str, "Enum"]]], Doc( """ A list of tags to be applied to all the *path operations* in this @@ -345,7 +341,7 @@ def __init__( Read more about it in the [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ + """, ), ] = None, dependencies: Annotated[ @@ -357,22 +353,22 @@ def __init__( Read more about it in the [FastAPI docs for Bigger Applications - Multiple Files](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies). - """ + """, ), ] = None, default_response_class: Annotated[ - Type["Response"], + type["Response"], Doc( """ The default response class to be used. Read more in the [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#default-response-class). - """ + """, ), ] = Default(JSONResponse), responses: Annotated[ - Optional[Dict[Union[int, str], "AnyDict"]], + Optional[dict[Union[int, str], "AnyDict"]], Doc( """ Additional responses to be shown in OpenAPI. @@ -384,11 +380,11 @@ def __init__( And in the [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies). - """ + """, ), ] = None, callbacks: Annotated[ - Optional[List[BaseRoute]], + Optional[list[BaseRoute]], Doc( """ OpenAPI callbacks that should apply to all *path operations* in this @@ -398,11 +394,11 @@ def __init__( Read more about it in the [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). - """ + """, ), ] = None, routes: Annotated[ - Optional[List[BaseRoute]], + Optional[list[BaseRoute]], Doc( """ **Note**: you probably shouldn't use this parameter, it is inherited @@ -411,7 +407,7 @@ def __init__( --- A list of routes to serve incoming HTTP and WebSocket requests. - """ + """, ), deprecated( """ @@ -420,7 +416,7 @@ def __init__( In FastAPI, you normally would use the *path operation methods*, like `router.get()`, `router.post()`, etc. - """ + """, ), ] = None, redirect_slashes: Annotated[ @@ -429,7 +425,7 @@ def __init__( """ Whether to detect and redirect slashes in URLs when the client doesn't use the same format. - """ + """, ), ] = True, default: Annotated[ @@ -438,7 +434,7 @@ def __init__( """ Default function handler for this router. Used to handle 404 Not Found errors. - """ + """, ), ] = None, dependency_overrides_provider: Annotated[ @@ -449,18 +445,18 @@ def __init__( You shouldn't need to use it. It normally points to the `FastAPI` app object. - """ + """, ), ] = None, route_class: Annotated[ - Type["APIRoute"], + type["APIRoute"], Doc( """ Custom route (*path operation*) class to be used by this router. Read more about it in the [FastAPI docs for Custom Request and APIRoute class](https://fastapi.tiangolo.com/how-to/custom-request-and-route/#custom-apiroute-class-in-a-router). - """ + """, ), ] = APIRoute, on_startup: Annotated[ @@ -472,7 +468,7 @@ def __init__( You should instead use the `lifespan` handlers. Read more in the [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/). - """ + """, ), ] = None, on_shutdown: Annotated[ @@ -485,7 +481,7 @@ def __init__( Read more in the [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/). - """ + """, ), ] = None, lifespan: Annotated[ @@ -497,7 +493,7 @@ def __init__( Read more in the [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/). - """ + """, ), ] = None, deprecated: Annotated[ @@ -510,7 +506,7 @@ def __init__( Read more about it in the [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ + """, ), ] = None, include_in_schema: Annotated[ @@ -524,7 +520,7 @@ def __init__( Read more about it in the [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi). - """ + """, ), ] = True, generate_unique_id_function: Annotated[ @@ -539,7 +535,7 @@ def __init__( Read more about it in the [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). - """ + """, ), ] = Default(generate_unique_id), ) -> None: @@ -615,7 +611,7 @@ def subscriber( partition assignment (if enabled), and to use for fetching and committing offsets. If `None`, auto-partition assignment (via group coordinator) and offset commits are disabled. - """ + """, ), ] = None, group_instance_id: Annotated[ @@ -628,7 +624,7 @@ def subscriber( partition assignment, rebalances). This can be used to assign partitions to specific consumers, rather than letting the group assign partitions based on consumer metadata. - """ + """, ), ] = None, fetch_max_wait_ms: Annotated[ @@ -639,7 +635,7 @@ def subscriber( the server will block before answering the fetch request if there isn't sufficient data to immediately satisfy the requirement given by `fetch_min_bytes`. - """ + """, ), ] = 500, fetch_max_bytes: Annotated[ @@ -654,7 +650,7 @@ def subscriber( performs fetches to multiple brokers in parallel so memory usage will depend on the number of brokers containing partitions for the topic. - """ + """, ), ] = 50 * 1024 * 1024, fetch_min_bytes: Annotated[ @@ -664,7 +660,7 @@ def subscriber( Minimum amount of data the server should return for a fetch request, otherwise wait up to `fetch_max_wait_ms` for more data to accumulate. - """ + """, ), ] = 1, max_partition_fetch_bytes: Annotated[ @@ -679,7 +675,7 @@ def subscriber( send messages larger than the consumer can fetch. If that happens, the consumer can get stuck trying to fetch a large message on a certain partition. - """ + """, ), ] = 1 * 1024 * 1024, auto_offset_reset: Annotated[ @@ -691,7 +687,7 @@ def subscriber( * `earliest` will move to the oldest available message * `latest` will move to the most recent * `none` will raise an exception so you can handle this case - """ + """, ), ] = "latest", auto_commit: Annotated[ @@ -700,7 +696,7 @@ def subscriber( """ If `True` the consumer's offset will be periodically committed in the background. - """ + """, ), ] = True, auto_commit_interval_ms: Annotated[ @@ -708,7 +704,7 @@ def subscriber( Doc( """ Milliseconds between automatic - offset commits, if `auto_commit` is `True`.""" + offset commits, if `auto_commit` is `True`.""", ), ] = 5 * 1000, check_crcs: Annotated[ @@ -719,7 +715,7 @@ def subscriber( consumed. This ensures no on-the-wire or on-disk corruption to the messages occurred. This check adds some overhead, so it may be disabled in cases seeking extreme performance. - """ + """, ), ] = True, partition_assignment_strategy: Annotated[ @@ -735,7 +731,7 @@ def subscriber( one. The coordinator will choose the old assignment strategy until all members have been updated. Then it will choose the new strategy. - """ + """, ), ] = ("roundrobin",), max_poll_interval_ms: Annotated[ @@ -748,7 +744,7 @@ def subscriber( rebalance in order to reassign the partitions to another consumer group member. If API methods block waiting for messages, that time does not count against this timeout. - """ + """, ), ] = 5 * 60 * 1000, session_timeout_ms: Annotated[ @@ -763,7 +759,7 @@ def subscriber( group and trigger a rebalance. The allowed range is configured with the **broker** configuration properties `group.min.session.timeout.ms` and `group.max.session.timeout.ms`. - """ + """, ), ] = 10 * 1000, heartbeat_interval_ms: Annotated[ @@ -779,7 +775,7 @@ def subscriber( should be set no higher than 1/3 of that value. It can be adjusted even lower to control the expected time for normal rebalances. - """ + """, ), ] = 3 * 1000, isolation_level: Annotated[ @@ -809,7 +805,7 @@ def subscriber( to the high watermark when there are in flight transactions. Further, when in `read_committed` the seek_to_end method will return the LSO. See method docs below. - """ + """, ), ] = "read_uncommitted", batch: Annotated[ @@ -848,7 +844,7 @@ def subscriber( no_reply: Annotated[ bool, Doc( - "Whether to disable **FastStream** RPC and Reply To auto responses or not." + "Whether to disable **FastStream** RPC and Reply To auto responses or not.", ), ] = False, # Specification args @@ -860,7 +856,7 @@ def subscriber( Optional[str], Doc( "Specification subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -899,7 +895,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). - """ + """, ), ] = Default(None), response_model_include: Annotated[ @@ -911,7 +907,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = None, response_model_exclude: Annotated[ @@ -923,7 +919,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = None, response_model_by_alias: Annotated[ @@ -935,7 +931,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = True, response_model_exclude_unset: Annotated[ @@ -953,7 +949,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ + """, ), ] = False, response_model_exclude_defaults: Annotated[ @@ -970,7 +966,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ + """, ), ] = False, response_model_exclude_none: Annotated[ @@ -987,7 +983,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). - """ + """, ), ] = False, ) -> "SpecificationDefaultSubscriber": ... @@ -1009,7 +1005,7 @@ def subscriber( partition assignment (if enabled), and to use for fetching and committing offsets. If `None`, auto-partition assignment (via group coordinator) and offset commits are disabled. - """ + """, ), ] = None, group_instance_id: Annotated[ @@ -1022,7 +1018,7 @@ def subscriber( partition assignment, rebalances). This can be used to assign partitions to specific consumers, rather than letting the group assign partitions based on consumer metadata. - """ + """, ), ] = None, fetch_max_wait_ms: Annotated[ @@ -1033,7 +1029,7 @@ def subscriber( the server will block before answering the fetch request if there isn't sufficient data to immediately satisfy the requirement given by `fetch_min_bytes`. - """ + """, ), ] = 500, fetch_max_bytes: Annotated[ @@ -1048,7 +1044,7 @@ def subscriber( performs fetches to multiple brokers in parallel so memory usage will depend on the number of brokers containing partitions for the topic. - """ + """, ), ] = 50 * 1024 * 1024, fetch_min_bytes: Annotated[ @@ -1058,7 +1054,7 @@ def subscriber( Minimum amount of data the server should return for a fetch request, otherwise wait up to `fetch_max_wait_ms` for more data to accumulate. - """ + """, ), ] = 1, max_partition_fetch_bytes: Annotated[ @@ -1073,7 +1069,7 @@ def subscriber( send messages larger than the consumer can fetch. If that happens, the consumer can get stuck trying to fetch a large message on a certain partition. - """ + """, ), ] = 1 * 1024 * 1024, auto_offset_reset: Annotated[ @@ -1085,7 +1081,7 @@ def subscriber( * `earliest` will move to the oldest available message * `latest` will move to the most recent * `none` will raise an exception so you can handle this case - """ + """, ), ] = "latest", auto_commit: Annotated[ @@ -1094,7 +1090,7 @@ def subscriber( """ If `True` the consumer's offset will be periodically committed in the background. - """ + """, ), ] = True, auto_commit_interval_ms: Annotated[ @@ -1102,7 +1098,7 @@ def subscriber( Doc( """ Milliseconds between automatic - offset commits, if `auto_commit` is `True`.""" + offset commits, if `auto_commit` is `True`.""", ), ] = 5 * 1000, check_crcs: Annotated[ @@ -1113,7 +1109,7 @@ def subscriber( consumed. This ensures no on-the-wire or on-disk corruption to the messages occurred. This check adds some overhead, so it may be disabled in cases seeking extreme performance. - """ + """, ), ] = True, partition_assignment_strategy: Annotated[ @@ -1129,7 +1125,7 @@ def subscriber( one. The coordinator will choose the old assignment strategy until all members have been updated. Then it will choose the new strategy. - """ + """, ), ] = ("roundrobin",), max_poll_interval_ms: Annotated[ @@ -1142,7 +1138,7 @@ def subscriber( rebalance in order to reassign the partitions to another consumer group member. If API methods block waiting for messages, that time does not count against this timeout. - """ + """, ), ] = 5 * 60 * 1000, session_timeout_ms: Annotated[ @@ -1157,7 +1153,7 @@ def subscriber( group and trigger a rebalance. The allowed range is configured with the **broker** configuration properties `group.min.session.timeout.ms` and `group.max.session.timeout.ms`. - """ + """, ), ] = 10 * 1000, heartbeat_interval_ms: Annotated[ @@ -1173,7 +1169,7 @@ def subscriber( should be set no higher than 1/3 of that value. It can be adjusted even lower to control the expected time for normal rebalances. - """ + """, ), ] = 3 * 1000, isolation_level: Annotated[ @@ -1203,7 +1199,7 @@ def subscriber( to the high watermark when there are in flight transactions. Further, when in `read_committed` the seek_to_end method will return the LSO. See method docs below. - """ + """, ), ] = "read_uncommitted", batch: Annotated[ @@ -1240,7 +1236,7 @@ def subscriber( Optional[str], Doc( "Specification subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -1279,7 +1275,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). - """ + """, ), ] = Default(None), response_model_include: Annotated[ @@ -1291,7 +1287,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = None, response_model_exclude: Annotated[ @@ -1303,7 +1299,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = None, response_model_by_alias: Annotated[ @@ -1315,7 +1311,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = True, response_model_exclude_unset: Annotated[ @@ -1333,7 +1329,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ + """, ), ] = False, response_model_exclude_defaults: Annotated[ @@ -1350,7 +1346,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ + """, ), ] = False, response_model_exclude_none: Annotated[ @@ -1367,7 +1363,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). - """ + """, ), ] = False, ) -> "SpecificationBatchSubscriber": ... @@ -1389,7 +1385,7 @@ def subscriber( partition assignment (if enabled), and to use for fetching and committing offsets. If `None`, auto-partition assignment (via group coordinator) and offset commits are disabled. - """ + """, ), ] = None, group_instance_id: Annotated[ @@ -1402,7 +1398,7 @@ def subscriber( partition assignment, rebalances). This can be used to assign partitions to specific consumers, rather than letting the group assign partitions based on consumer metadata. - """ + """, ), ] = None, fetch_max_wait_ms: Annotated[ @@ -1413,7 +1409,7 @@ def subscriber( the server will block before answering the fetch request if there isn't sufficient data to immediately satisfy the requirement given by `fetch_min_bytes`. - """ + """, ), ] = 500, fetch_max_bytes: Annotated[ @@ -1428,7 +1424,7 @@ def subscriber( performs fetches to multiple brokers in parallel so memory usage will depend on the number of brokers containing partitions for the topic. - """ + """, ), ] = 50 * 1024 * 1024, fetch_min_bytes: Annotated[ @@ -1438,7 +1434,7 @@ def subscriber( Minimum amount of data the server should return for a fetch request, otherwise wait up to `fetch_max_wait_ms` for more data to accumulate. - """ + """, ), ] = 1, max_partition_fetch_bytes: Annotated[ @@ -1453,7 +1449,7 @@ def subscriber( send messages larger than the consumer can fetch. If that happens, the consumer can get stuck trying to fetch a large message on a certain partition. - """ + """, ), ] = 1 * 1024 * 1024, auto_offset_reset: Annotated[ @@ -1465,7 +1461,7 @@ def subscriber( * `earliest` will move to the oldest available message * `latest` will move to the most recent * `none` will raise an exception so you can handle this case - """ + """, ), ] = "latest", auto_commit: Annotated[ @@ -1474,7 +1470,7 @@ def subscriber( """ If `True` the consumer's offset will be periodically committed in the background. - """ + """, ), ] = True, auto_commit_interval_ms: Annotated[ @@ -1482,7 +1478,7 @@ def subscriber( Doc( """ Milliseconds between automatic - offset commits, if `auto_commit` is `True`.""" + offset commits, if `auto_commit` is `True`.""", ), ] = 5 * 1000, check_crcs: Annotated[ @@ -1493,7 +1489,7 @@ def subscriber( consumed. This ensures no on-the-wire or on-disk corruption to the messages occurred. This check adds some overhead, so it may be disabled in cases seeking extreme performance. - """ + """, ), ] = True, partition_assignment_strategy: Annotated[ @@ -1509,7 +1505,7 @@ def subscriber( one. The coordinator will choose the old assignment strategy until all members have been updated. Then it will choose the new strategy. - """ + """, ), ] = ("roundrobin",), max_poll_interval_ms: Annotated[ @@ -1522,7 +1518,7 @@ def subscriber( rebalance in order to reassign the partitions to another consumer group member. If API methods block waiting for messages, that time does not count against this timeout. - """ + """, ), ] = 5 * 60 * 1000, session_timeout_ms: Annotated[ @@ -1537,7 +1533,7 @@ def subscriber( group and trigger a rebalance. The allowed range is configured with the **broker** configuration properties `group.min.session.timeout.ms` and `group.max.session.timeout.ms`. - """ + """, ), ] = 10 * 1000, heartbeat_interval_ms: Annotated[ @@ -1553,7 +1549,7 @@ def subscriber( should be set no higher than 1/3 of that value. It can be adjusted even lower to control the expected time for normal rebalances. - """ + """, ), ] = 3 * 1000, isolation_level: Annotated[ @@ -1583,7 +1579,7 @@ def subscriber( to the high watermark when there are in flight transactions. Further, when in `read_committed` the seek_to_end method will return the LSO. See method docs below. - """ + """, ), ] = "read_uncommitted", batch: Annotated[ @@ -1622,7 +1618,7 @@ def subscriber( no_reply: Annotated[ bool, Doc( - "Whether to disable **FastStream** RPC and Reply To auto responses or not." + "Whether to disable **FastStream** RPC and Reply To auto responses or not.", ), ] = False, # Specification args @@ -1634,7 +1630,7 @@ def subscriber( Optional[str], Doc( "Specification subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -1673,7 +1669,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). - """ + """, ), ] = Default(None), response_model_include: Annotated[ @@ -1685,7 +1681,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = None, response_model_exclude: Annotated[ @@ -1697,7 +1693,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = None, response_model_by_alias: Annotated[ @@ -1709,7 +1705,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = True, response_model_exclude_unset: Annotated[ @@ -1727,7 +1723,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ + """, ), ] = False, response_model_exclude_defaults: Annotated[ @@ -1744,7 +1740,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ + """, ), ] = False, response_model_exclude_none: Annotated[ @@ -1761,7 +1757,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). - """ + """, ), ] = False, ) -> Union[ @@ -1786,7 +1782,7 @@ def subscriber( partition assignment (if enabled), and to use for fetching and committing offsets. If `None`, auto-partition assignment (via group coordinator) and offset commits are disabled. - """ + """, ), ] = None, group_instance_id: Annotated[ @@ -1799,7 +1795,7 @@ def subscriber( partition assignment, rebalances). This can be used to assign partitions to specific consumers, rather than letting the group assign partitions based on consumer metadata. - """ + """, ), ] = None, fetch_max_wait_ms: Annotated[ @@ -1810,7 +1806,7 @@ def subscriber( the server will block before answering the fetch request if there isn't sufficient data to immediately satisfy the requirement given by `fetch_min_bytes`. - """ + """, ), ] = 500, fetch_max_bytes: Annotated[ @@ -1825,7 +1821,7 @@ def subscriber( performs fetches to multiple brokers in parallel so memory usage will depend on the number of brokers containing partitions for the topic. - """ + """, ), ] = 50 * 1024 * 1024, fetch_min_bytes: Annotated[ @@ -1835,7 +1831,7 @@ def subscriber( Minimum amount of data the server should return for a fetch request, otherwise wait up to `fetch_max_wait_ms` for more data to accumulate. - """ + """, ), ] = 1, max_partition_fetch_bytes: Annotated[ @@ -1850,7 +1846,7 @@ def subscriber( send messages larger than the consumer can fetch. If that happens, the consumer can get stuck trying to fetch a large message on a certain partition. - """ + """, ), ] = 1 * 1024 * 1024, auto_offset_reset: Annotated[ @@ -1862,7 +1858,7 @@ def subscriber( * `earliest` will move to the oldest available message * `latest` will move to the most recent * `none` will raise an exception so you can handle this case - """ + """, ), ] = "latest", auto_commit: Annotated[ @@ -1871,7 +1867,7 @@ def subscriber( """ If `True` the consumer's offset will be periodically committed in the background. - """ + """, ), ] = True, auto_commit_interval_ms: Annotated[ @@ -1879,7 +1875,7 @@ def subscriber( Doc( """ Milliseconds between automatic - offset commits, if `auto_commit` is `True`.""" + offset commits, if `auto_commit` is `True`.""", ), ] = 5 * 1000, check_crcs: Annotated[ @@ -1890,7 +1886,7 @@ def subscriber( consumed. This ensures no on-the-wire or on-disk corruption to the messages occurred. This check adds some overhead, so it may be disabled in cases seeking extreme performance. - """ + """, ), ] = True, partition_assignment_strategy: Annotated[ @@ -1906,7 +1902,7 @@ def subscriber( one. The coordinator will choose the old assignment strategy until all members have been updated. Then it will choose the new strategy. - """ + """, ), ] = ("roundrobin",), max_poll_interval_ms: Annotated[ @@ -1919,7 +1915,7 @@ def subscriber( rebalance in order to reassign the partitions to another consumer group member. If API methods block waiting for messages, that time does not count against this timeout. - """ + """, ), ] = 5 * 60 * 1000, session_timeout_ms: Annotated[ @@ -1934,7 +1930,7 @@ def subscriber( group and trigger a rebalance. The allowed range is configured with the **broker** configuration properties `group.min.session.timeout.ms` and `group.max.session.timeout.ms`. - """ + """, ), ] = 10 * 1000, heartbeat_interval_ms: Annotated[ @@ -1950,7 +1946,7 @@ def subscriber( should be set no higher than 1/3 of that value. It can be adjusted even lower to control the expected time for normal rebalances. - """ + """, ), ] = 3 * 1000, isolation_level: Annotated[ @@ -1980,7 +1976,7 @@ def subscriber( to the high watermark when there are in flight transactions. Further, when in `read_committed` the seek_to_end method will return the LSO. See method docs below. - """ + """, ), ] = "read_uncommitted", batch: Annotated[ @@ -2019,7 +2015,7 @@ def subscriber( no_reply: Annotated[ bool, Doc( - "Whether to disable **FastStream** RPC and Reply To auto responses or not." + "Whether to disable **FastStream** RPC and Reply To auto responses or not.", ), ] = False, # Specification args @@ -2031,7 +2027,7 @@ def subscriber( Optional[str], Doc( "Specification subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -2070,7 +2066,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). - """ + """, ), ] = Default(None), response_model_include: Annotated[ @@ -2082,7 +2078,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = None, response_model_exclude: Annotated[ @@ -2094,7 +2090,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = None, response_model_by_alias: Annotated[ @@ -2106,7 +2102,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = True, response_model_exclude_unset: Annotated[ @@ -2124,7 +2120,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ + """, ), ] = False, response_model_exclude_defaults: Annotated[ @@ -2141,7 +2137,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ + """, ), ] = False, response_model_exclude_none: Annotated[ @@ -2158,7 +2154,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). - """ + """, ), ] = False, ) -> Union[ @@ -2209,8 +2205,7 @@ def subscriber( if batch: return cast("SpecificationBatchSubscriber", subscriber) - else: - return cast("SpecificationDefaultSubscriber", subscriber) + return cast("SpecificationDefaultSubscriber", subscriber) @overload # type: ignore[override] def publisher( @@ -2231,7 +2226,7 @@ def publisher( partition (but if key is `None`, partition is chosen randomly). Must be type `bytes`, or be serializable to bytes via configured `key_serializer`. - """ + """, ), ] = None, partition: Annotated[ @@ -2240,15 +2235,15 @@ def publisher( """ Specify a partition. If not set, the partition will be selected using the configured `partitioner`. - """ + """, ), ] = None, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc( "Message headers to store metainformation. " "**content-type** and **correlation_id** will be set automatically by framework anyway. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, reply_to: Annotated[ @@ -2277,7 +2272,7 @@ def publisher( Optional[Any], Doc( "Specification publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ @@ -2305,7 +2300,7 @@ def publisher( partition (but if key is `None`, partition is chosen randomly). Must be type `bytes`, or be serializable to bytes via configured `key_serializer`. - """ + """, ), ] = None, partition: Annotated[ @@ -2314,15 +2309,15 @@ def publisher( """ Specify a partition. If not set, the partition will be selected using the configured `partitioner`. - """ + """, ), ] = None, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc( "Message headers to store metainformation. " "**content-type** and **correlation_id** will be set automatically by framework anyway. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, reply_to: Annotated[ @@ -2351,7 +2346,7 @@ def publisher( Optional[Any], Doc( "Specification publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ @@ -2379,7 +2374,7 @@ def publisher( partition (but if key is `None`, partition is chosen randomly). Must be type `bytes`, or be serializable to bytes via configured `key_serializer`. - """ + """, ), ] = None, partition: Annotated[ @@ -2388,15 +2383,15 @@ def publisher( """ Specify a partition. If not set, the partition will be selected using the configured `partitioner`. - """ + """, ), ] = None, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc( "Message headers to store metainformation. " "**content-type** and **correlation_id** will be set automatically by framework anyway. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, reply_to: Annotated[ @@ -2425,7 +2420,7 @@ def publisher( Optional[Any], Doc( "Specification publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ @@ -2456,7 +2451,7 @@ def publisher( partition (but if key is `None`, partition is chosen randomly). Must be type `bytes`, or be serializable to bytes via configured `key_serializer`. - """ + """, ), ] = None, partition: Annotated[ @@ -2465,15 +2460,15 @@ def publisher( """ Specify a partition. If not set, the partition will be selected using the configured `partitioner`. - """ + """, ), ] = None, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc( "Message headers to store metainformation. " "**content-type** and **correlation_id** will be set automatically by framework anyway. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, reply_to: Annotated[ @@ -2502,7 +2497,7 @@ def publisher( Optional[Any], Doc( "Specification publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ diff --git a/faststream/confluent/message.py b/faststream/confluent/message.py index 6365932ff4..bdf0d5cb13 100644 --- a/faststream/confluent/message.py +++ b/faststream/confluent/message.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Any, Optional, Protocol, Tuple, Union +from typing import TYPE_CHECKING, Any, Optional, Protocol, Union from faststream.message import StreamMessage @@ -41,9 +41,9 @@ class KafkaMessage( StreamMessage[ Union[ "Message", - Tuple["Message", ...], + tuple["Message", ...], ] - ] + ], ): """Represents a Kafka message in the FastStream framework. diff --git a/faststream/confluent/opentelemetry/provider.py b/faststream/confluent/opentelemetry/provider.py index ea1d96cac7..8ebeea51d7 100644 --- a/faststream/confluent/opentelemetry/provider.py +++ b/faststream/confluent/opentelemetry/provider.py @@ -1,4 +1,5 @@ -from typing import TYPE_CHECKING, Sequence, Tuple, Union, cast +from collections.abc import Sequence +from typing import TYPE_CHECKING, Union, cast from opentelemetry.semconv.trace import SpanAttributes @@ -45,7 +46,7 @@ def get_publish_destination_name( class ConfluentTelemetrySettingsProvider( - BaseConfluentTelemetrySettingsProvider["Message"] + BaseConfluentTelemetrySettingsProvider["Message"], ): def get_consume_attrs_from_message( self, @@ -74,30 +75,28 @@ def get_consume_destination_name( class BatchConfluentTelemetrySettingsProvider( - BaseConfluentTelemetrySettingsProvider[Tuple["Message", ...]] + BaseConfluentTelemetrySettingsProvider[tuple["Message", ...]], ): def get_consume_attrs_from_message( self, - msg: "StreamMessage[Tuple[Message, ...]]", + msg: "StreamMessage[tuple[Message, ...]]", ) -> "AnyDict": raw_message = msg.raw_message[0] - attrs = { + return { SpanAttributes.MESSAGING_SYSTEM: self.messaging_system, SpanAttributes.MESSAGING_MESSAGE_ID: msg.message_id, SpanAttributes.MESSAGING_MESSAGE_CONVERSATION_ID: msg.correlation_id, SpanAttributes.MESSAGING_BATCH_MESSAGE_COUNT: len(msg.raw_message), SpanAttributes.MESSAGING_MESSAGE_PAYLOAD_SIZE_BYTES: len( - bytearray().join(cast(Sequence[bytes], msg.body)) + bytearray().join(cast(Sequence[bytes], msg.body)), ), SpanAttributes.MESSAGING_KAFKA_DESTINATION_PARTITION: raw_message.partition(), MESSAGING_DESTINATION_PUBLISH_NAME: raw_message.topic(), } - return attrs - def get_consume_destination_name( self, - msg: "StreamMessage[Tuple[Message, ...]]", + msg: "StreamMessage[tuple[Message, ...]]", ) -> str: return cast(str, msg.raw_message[0].topic()) @@ -110,5 +109,4 @@ def telemetry_attributes_provider_factory( ]: if isinstance(msg, Sequence): return BatchConfluentTelemetrySettingsProvider() - else: - return ConfluentTelemetrySettingsProvider() + return ConfluentTelemetrySettingsProvider() diff --git a/faststream/confluent/parser.py b/faststream/confluent/parser.py index f868cab0b1..85063b53b2 100644 --- a/faststream/confluent/parser.py +++ b/faststream/confluent/parser.py @@ -1,4 +1,5 @@ -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Sequence, Tuple, Union +from collections.abc import Sequence +from typing import TYPE_CHECKING, Any, Optional, Union from faststream._internal.context.repository import context from faststream.confluent.message import FAKE_CONSUMER, KafkaMessage @@ -42,11 +43,11 @@ async def parse_message( @staticmethod async def parse_message_batch( - message: Tuple["Message", ...], + message: tuple["Message", ...], ) -> KafkaMessage: """Parses a batch of messages from a Kafka consumer.""" - body: List[Any] = [] - batch_headers: List[Dict[str, str]] = [] + body: list[Any] = [] + batch_headers: list[dict[str, str]] = [] first = message[0] last = message[-1] @@ -84,13 +85,13 @@ async def decode_message( @classmethod async def decode_message_batch( cls, - msg: "StreamMessage[Tuple[Message, ...]]", + msg: "StreamMessage[tuple[Message, ...]]", ) -> "DecodedMessage": """Decode a batch of messages.""" return [decode_message(await cls.parse_message(m)) for m in msg.raw_message] def _parse_msg_headers( - headers: Sequence[Tuple[str, Union[bytes, str]]], -) -> Dict[str, str]: + headers: Sequence[tuple[str, Union[bytes, str]]], +) -> dict[str, str]: return {i: j if isinstance(j, str) else j.decode() for i, j in headers} diff --git a/faststream/confluent/publisher/producer.py b/faststream/confluent/publisher/producer.py index bb162d720f..a4d9d9cf29 100644 --- a/faststream/confluent/publisher/producer.py +++ b/faststream/confluent/publisher/producer.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Any, Dict, Optional +from typing import TYPE_CHECKING, Any, Optional from typing_extensions import override @@ -39,7 +39,7 @@ async def publish( # type: ignore[override] key: Optional[bytes] = None, partition: Optional[int] = None, timestamp_ms: Optional[int] = None, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, correlation_id: str = "", reply_to: str = "", no_confirm: bool = False, @@ -78,7 +78,7 @@ async def publish_batch( topic: str, partition: Optional[int] = None, timestamp_ms: Optional[int] = None, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, reply_to: str = "", correlation_id: str = "", no_confirm: bool = False, @@ -121,6 +121,7 @@ async def publish_batch( @override async def request(self, *args: Any, **kwargs: Any) -> Optional[Any]: + msg = "Kafka doesn't support `request` method without test client." raise OperationForbiddenError( - "Kafka doesn't support `request` method without test client." + msg, ) diff --git a/faststream/confluent/publisher/publisher.py b/faststream/confluent/publisher/publisher.py index f66dc21c26..39ed1ac865 100644 --- a/faststream/confluent/publisher/publisher.py +++ b/faststream/confluent/publisher/publisher.py @@ -1,11 +1,9 @@ +from collections.abc import Iterable from typing import ( TYPE_CHECKING, Any, - Dict, - Iterable, Literal, Optional, - Tuple, Union, overload, ) @@ -37,7 +35,7 @@ class SpecificationPublisher(LogicPublisher[MsgType]): def get_name(self) -> str: return f"{self.topic}:Publisher" - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> dict[str, Channel]: payloads = self.get_payloads() return { @@ -48,12 +46,12 @@ def get_schema(self) -> Dict[str, Channel]: title=f"{self.name}:Message", payload=resolve_payloads(payloads, "Publisher"), correlationId=CorrelationId( - location="$message.header#/correlation_id" + location="$message.header#/correlation_id", ), ), ), bindings=ChannelBinding(kafka=kafka.ChannelBinding(topic=self.topic)), - ) + ), } @overload # type: ignore[override] @@ -64,10 +62,10 @@ def create( key: Optional[bytes], topic: str, partition: Optional[int], - headers: Optional[Dict[str, str]], + headers: Optional[dict[str, str]], reply_to: str, # Publisher args - broker_middlewares: Iterable["BrokerMiddleware[Tuple[ConfluentMsg, ...]]"], + broker_middlewares: Iterable["BrokerMiddleware[tuple[ConfluentMsg, ...]]"], middlewares: Iterable["PublisherMiddleware"], # Specification args schema_: Optional[Any], @@ -84,7 +82,7 @@ def create( key: Optional[bytes], topic: str, partition: Optional[int], - headers: Optional[Dict[str, str]], + headers: Optional[dict[str, str]], reply_to: str, # Publisher args broker_middlewares: Iterable["BrokerMiddleware[ConfluentMsg]"], @@ -104,11 +102,11 @@ def create( key: Optional[bytes], topic: str, partition: Optional[int], - headers: Optional[Dict[str, str]], + headers: Optional[dict[str, str]], reply_to: str, # Publisher args broker_middlewares: Iterable[ - "BrokerMiddleware[Union[Tuple[ConfluentMsg, ...], ConfluentMsg]]" + "BrokerMiddleware[Union[tuple[ConfluentMsg, ...], ConfluentMsg]]" ], middlewares: Iterable["PublisherMiddleware"], # Specification args @@ -129,11 +127,11 @@ def create( key: Optional[bytes], topic: str, partition: Optional[int], - headers: Optional[Dict[str, str]], + headers: Optional[dict[str, str]], reply_to: str, # Publisher args broker_middlewares: Iterable[ - "BrokerMiddleware[Union[Tuple[ConfluentMsg, ...], ConfluentMsg]]" + "BrokerMiddleware[Union[tuple[ConfluentMsg, ...], ConfluentMsg]]" ], middlewares: Iterable["PublisherMiddleware"], # Specification args @@ -147,7 +145,8 @@ def create( ]: if batch: if key: - raise SetupError("You can't setup `key` with batch publisher") + msg = "You can't setup `key` with batch publisher" + raise SetupError(msg) return SpecificationBatchPublisher( topic=topic, @@ -161,26 +160,25 @@ def create( description_=description_, include_in_schema=include_in_schema, ) - else: - return SpecificationDefaultPublisher( - key=key, - # basic args - topic=topic, - partition=partition, - headers=headers, - reply_to=reply_to, - broker_middlewares=broker_middlewares, - middlewares=middlewares, - schema_=schema_, - title_=title_, - description_=description_, - include_in_schema=include_in_schema, - ) + return SpecificationDefaultPublisher( + key=key, + # basic args + topic=topic, + partition=partition, + headers=headers, + reply_to=reply_to, + broker_middlewares=broker_middlewares, + middlewares=middlewares, + schema_=schema_, + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + ) class SpecificationBatchPublisher( BatchPublisher, - SpecificationPublisher[Tuple["ConfluentMsg", ...]], + SpecificationPublisher[tuple["ConfluentMsg", ...]], ): pass diff --git a/faststream/confluent/publisher/usecase.py b/faststream/confluent/publisher/usecase.py index 766c870fb6..6b7fcf101c 100644 --- a/faststream/confluent/publisher/usecase.py +++ b/faststream/confluent/publisher/usecase.py @@ -1,14 +1,11 @@ +from collections.abc import Awaitable, Iterable from functools import partial from itertools import chain from typing import ( TYPE_CHECKING, Any, - Awaitable, Callable, - Dict, - Iterable, Optional, - Tuple, Union, cast, ) @@ -39,7 +36,7 @@ def __init__( *, topic: str, partition: Optional[int], - headers: Optional[Dict[str, str]], + headers: Optional[dict[str, str]], reply_to: Optional[str], # Publisher args broker_middlewares: Iterable["BrokerMiddleware[MsgType]"], @@ -68,7 +65,7 @@ def __init__( self._producer = None def add_prefix(self, prefix: str) -> None: - self.topic = "".join((prefix, self.topic)) + self.topic = f"{prefix}{self.topic}" @override async def request( @@ -79,7 +76,7 @@ async def request( key: Optional[bytes] = None, partition: Optional[int] = None, timestamp_ms: Optional[int] = None, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, correlation_id: Optional[str] = None, timeout: float = 0.5, # publisher specific @@ -127,7 +124,7 @@ def __init__( key: Optional[bytes], topic: str, partition: Optional[int], - headers: Optional[Dict[str, str]], + headers: Optional[dict[str, str]], reply_to: Optional[str], # Publisher args broker_middlewares: Iterable["BrokerMiddleware[Message]"], @@ -164,7 +161,7 @@ async def publish( key: Optional[bytes] = None, partition: Optional[int] = None, timestamp_ms: Optional[int] = None, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, correlation_id: Optional[str] = None, reply_to: str = "", no_confirm: bool = False, @@ -207,7 +204,7 @@ async def request( key: Optional[bytes] = None, partition: Optional[int] = None, timestamp_ms: Optional[int] = None, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, correlation_id: Optional[str] = None, timeout: float = 0.5, # publisher specific @@ -226,7 +223,7 @@ async def request( ) -class BatchPublisher(LogicPublisher[Tuple[Message, ...]]): +class BatchPublisher(LogicPublisher[tuple[Message, ...]]): @override async def publish( self, @@ -235,7 +232,7 @@ async def publish( topic: str = "", partition: Optional[int] = None, timestamp_ms: Optional[int] = None, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, correlation_id: Optional[str] = None, reply_to: str = "", no_confirm: bool = False, diff --git a/faststream/confluent/response.py b/faststream/confluent/response.py index 353ac8251a..3d04d6ab35 100644 --- a/faststream/confluent/response.py +++ b/faststream/confluent/response.py @@ -29,9 +29,8 @@ def __init__( @override def as_publish_kwargs(self) -> "AnyDict": - publish_options = { + return { **super().as_publish_kwargs(), "timestamp_ms": self.timestamp_ms, "key": self.key, } - return publish_options diff --git a/faststream/confluent/router.py b/faststream/confluent/router.py index c7b89bf226..2d7f599d18 100644 --- a/faststream/confluent/router.py +++ b/faststream/confluent/router.py @@ -1,18 +1,15 @@ +from collections.abc import Awaitable, Iterable, Sequence from typing import ( TYPE_CHECKING, + Annotated, Any, - Awaitable, Callable, - Dict, - Iterable, Literal, Optional, - Sequence, - Tuple, Union, ) -from typing_extensions import Annotated, Doc +from typing_extensions import Doc from faststream._internal.broker.router import ( ArgsContainer, @@ -60,7 +57,7 @@ def __init__( partition (but if key is `None`, partition is chosen randomly). Must be type `bytes`, or be serializable to bytes via configured `key_serializer`. - """ + """, ), ] = None, partition: Annotated[ @@ -69,15 +66,15 @@ def __init__( """ Specify a partition. If not set, the partition will be selected using the configured `partitioner`. - """ + """, ), ] = None, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc( "Message headers to store metainformation. " "**content-type** and **correlation_id** will be set automatically by framework anyway. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, reply_to: Annotated[ @@ -106,7 +103,7 @@ def __init__( Optional[Any], Doc( "AsyncAPI publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ @@ -161,7 +158,7 @@ def __init__( partition assignment (if enabled), and to use for fetching and committing offsets. If `None`, auto-partition assignment (via group coordinator) and offset commits are disabled. - """ + """, ), ] = None, group_instance_id: Annotated[ @@ -174,7 +171,7 @@ def __init__( partition assignment, rebalances). This can be used to assign partitions to specific consumers, rather than letting the group assign partitions based on consumer metadata. - """ + """, ), ] = None, fetch_max_wait_ms: Annotated[ @@ -185,7 +182,7 @@ def __init__( the server will block before answering the fetch request if there isn't sufficient data to immediately satisfy the requirement given by `fetch_min_bytes`. - """ + """, ), ] = 500, fetch_max_bytes: Annotated[ @@ -200,7 +197,7 @@ def __init__( performs fetches to multiple brokers in parallel so memory usage will depend on the number of brokers containing partitions for the topic. - """ + """, ), ] = 50 * 1024 * 1024, fetch_min_bytes: Annotated[ @@ -210,7 +207,7 @@ def __init__( Minimum amount of data the server should return for a fetch request, otherwise wait up to `fetch_max_wait_ms` for more data to accumulate. - """ + """, ), ] = 1, max_partition_fetch_bytes: Annotated[ @@ -225,7 +222,7 @@ def __init__( send messages larger than the consumer can fetch. If that happens, the consumer can get stuck trying to fetch a large message on a certain partition. - """ + """, ), ] = 1 * 1024 * 1024, auto_offset_reset: Annotated[ @@ -237,7 +234,7 @@ def __init__( * `earliest` will move to the oldest available message * `latest` will move to the most recent * `none` will raise an exception so you can handle this case - """ + """, ), ] = "latest", auto_commit: Annotated[ @@ -246,7 +243,7 @@ def __init__( """ If `True` the consumer's offset will be periodically committed in the background. - """ + """, ), ] = True, auto_commit_interval_ms: Annotated[ @@ -254,7 +251,7 @@ def __init__( Doc( """ Milliseconds between automatic - offset commits, if `auto_commit` is `True`.""" + offset commits, if `auto_commit` is `True`.""", ), ] = 5 * 1000, check_crcs: Annotated[ @@ -265,7 +262,7 @@ def __init__( consumed. This ensures no on-the-wire or on-disk corruption to the messages occurred. This check adds some overhead, so it may be disabled in cases seeking extreme performance. - """ + """, ), ] = True, partition_assignment_strategy: Annotated[ @@ -281,7 +278,7 @@ def __init__( one. The coordinator will choose the old assignment strategy until all members have been updated. Then it will choose the new strategy. - """ + """, ), ] = ("roundrobin",), max_poll_interval_ms: Annotated[ @@ -294,7 +291,7 @@ def __init__( rebalance in order to reassign the partitions to another consumer group member. If API methods block waiting for messages, that time does not count against this timeout. - """ + """, ), ] = 5 * 60 * 1000, session_timeout_ms: Annotated[ @@ -309,7 +306,7 @@ def __init__( group and trigger a rebalance. The allowed range is configured with the **broker** configuration properties `group.min.session.timeout.ms` and `group.max.session.timeout.ms`. - """ + """, ), ] = 10 * 1000, heartbeat_interval_ms: Annotated[ @@ -325,7 +322,7 @@ def __init__( should be set no higher than 1/3 of that value. It can be adjusted even lower to control the expected time for normal rebalances. - """ + """, ), ] = 3 * 1000, isolation_level: Annotated[ @@ -355,7 +352,7 @@ def __init__( to the high watermark when there are in flight transactions. Further, when in `read_committed` the seek_to_end method will return the LSO. See method docs below. - """ + """, ), ] = "read_uncommitted", batch: Annotated[ @@ -394,7 +391,7 @@ def __init__( no_reply: Annotated[ bool, Doc( - "Whether to disable **FastStream** RPC and Reply To auto responses or not." + "Whether to disable **FastStream** RPC and Reply To auto responses or not.", ), ] = False, # AsyncAPI args @@ -406,7 +403,7 @@ def __init__( Optional[str], Doc( "AsyncAPI subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -458,7 +455,7 @@ class KafkaRouter( BrokerRouter[ Union[ "Message", - Tuple["Message", ...], + tuple["Message", ...], ] ], ): @@ -478,14 +475,14 @@ def __init__( dependencies: Annotated[ Iterable["Depends"], Doc( - "Dependencies list (`[Depends(),]`) to apply to all routers' publishers/subscribers." + "Dependencies list (`[Depends(),]`) to apply to all routers' publishers/subscribers.", ), ] = (), middlewares: Annotated[ Iterable[ Union[ "BrokerMiddleware[Message]", - "BrokerMiddleware[Tuple[Message, ...]]", + "BrokerMiddleware[tuple[Message, ...]]", ] ], Doc("Router middlewares to apply to all routers' publishers/subscribers."), diff --git a/faststream/confluent/schemas/params.py b/faststream/confluent/schemas/params.py index 91cb83591a..f7b4c2bcdb 100644 --- a/faststream/confluent/schemas/params.py +++ b/faststream/confluent/schemas/params.py @@ -1,4 +1,4 @@ -from typing import List, Literal, Union +from typing import Literal, Union from typing_extensions import TypedDict @@ -6,7 +6,7 @@ class ConsumerConnectionParams(TypedDict, total=False): """A class to represent the connection parameters for a consumer.""" - bootstrap_servers: Union[str, List[str]] + bootstrap_servers: Union[str, list[str]] client_id: str retry_backoff_ms: int metadata_max_age_ms: int diff --git a/faststream/confluent/schemas/partition.py b/faststream/confluent/schemas/partition.py index 97387fc9d3..ace5c78ca3 100644 --- a/faststream/confluent/schemas/partition.py +++ b/faststream/confluent/schemas/partition.py @@ -15,11 +15,11 @@ class _TopicKwargs(TypedDict): class TopicPartition: __slots__ = ( - "topic", - "partition", - "offset", - "metadata", "leader_epoch", + "metadata", + "offset", + "partition", + "topic", ) def __init__( diff --git a/faststream/confluent/security.py b/faststream/confluent/security.py index 7648acc6a4..044402bb24 100644 --- a/faststream/confluent/security.py +++ b/faststream/confluent/security.py @@ -17,26 +17,27 @@ def parse_security(security: Optional[BaseSecurity]) -> "AnyDict": if security and isinstance(security.ssl_context, ssl.SSLContext): + msg = "ssl_context in not supported by confluent-kafka-python, please use config instead." raise SetupError( - "ssl_context in not supported by confluent-kafka-python, please use config instead." + msg, ) if security is None: return {} - elif isinstance(security, SASLPlaintext): + if isinstance(security, SASLPlaintext): return _parse_sasl_plaintext(security) - elif isinstance(security, SASLScram256): + if isinstance(security, SASLScram256): return _parse_sasl_scram256(security) - elif isinstance(security, SASLScram512): + if isinstance(security, SASLScram512): return _parse_sasl_scram512(security) - elif isinstance(security, SASLOAuthBearer): + if isinstance(security, SASLOAuthBearer): return _parse_sasl_oauthbearer(security) - elif isinstance(security, SASLGSSAPI): + if isinstance(security, SASLGSSAPI): return _parse_sasl_gssapi(security) - elif isinstance(security, BaseSecurity): + if isinstance(security, BaseSecurity): return _parse_base_security(security) - else: - raise NotImplementedError(f"KafkaBroker does not support `{type(security)}`.") + msg = f"KafkaBroker does not support `{type(security)}`." + raise NotImplementedError(msg) def _parse_base_security(security: BaseSecurity) -> "AnyDict": diff --git a/faststream/confluent/subscriber/factory.py b/faststream/confluent/subscriber/factory.py index b6c0068c3d..336e02c159 100644 --- a/faststream/confluent/subscriber/factory.py +++ b/faststream/confluent/subscriber/factory.py @@ -1,10 +1,8 @@ +from collections.abc import Iterable, Sequence from typing import ( TYPE_CHECKING, - Iterable, Literal, Optional, - Sequence, - Tuple, Union, overload, ) @@ -39,7 +37,7 @@ def create_subscriber( no_reply: bool, retry: bool, broker_dependencies: Iterable["Depends"], - broker_middlewares: Iterable["BrokerMiddleware[Tuple[ConfluentMsg, ...]]"], + broker_middlewares: Iterable["BrokerMiddleware[tuple[ConfluentMsg, ...]]"], # Specification args title_: Optional[str], description_: Optional[str], @@ -88,7 +86,7 @@ def create_subscriber( retry: bool, broker_dependencies: Iterable["Depends"], broker_middlewares: Iterable[ - "BrokerMiddleware[Union[ConfluentMsg, Tuple[ConfluentMsg, ...]]]" + "BrokerMiddleware[Union[ConfluentMsg, tuple[ConfluentMsg, ...]]]" ], # Specification args title_: Optional[str], @@ -116,7 +114,7 @@ def create_subscriber( retry: bool, broker_dependencies: Iterable["Depends"], broker_middlewares: Iterable[ - "BrokerMiddleware[Union[ConfluentMsg, Tuple[ConfluentMsg, ...]]]" + "BrokerMiddleware[Union[ConfluentMsg, tuple[ConfluentMsg, ...]]]" ], # Specification args title_: Optional[str], @@ -144,20 +142,19 @@ def create_subscriber( description_=description_, include_in_schema=include_in_schema, ) - else: - return SpecificationDefaultSubscriber( - *topics, - partitions=partitions, - polling_interval=polling_interval, - group_id=group_id, - connection_data=connection_data, - is_manual=is_manual, - no_ack=no_ack, - no_reply=no_reply, - retry=retry, - broker_dependencies=broker_dependencies, - broker_middlewares=broker_middlewares, - title_=title_, - description_=description_, - include_in_schema=include_in_schema, - ) + return SpecificationDefaultSubscriber( + *topics, + partitions=partitions, + polling_interval=polling_interval, + group_id=group_id, + connection_data=connection_data, + is_manual=is_manual, + no_ack=no_ack, + no_reply=no_reply, + retry=retry, + broker_dependencies=broker_dependencies, + broker_middlewares=broker_middlewares, + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + ) diff --git a/faststream/confluent/subscriber/subscriber.py b/faststream/confluent/subscriber/subscriber.py index 281f222a12..3d93e83e2a 100644 --- a/faststream/confluent/subscriber/subscriber.py +++ b/faststream/confluent/subscriber/subscriber.py @@ -1,7 +1,5 @@ from typing import ( TYPE_CHECKING, - Dict, - Tuple, ) from faststream._internal.types import MsgType @@ -26,7 +24,7 @@ class SpecificationSubscriber(LogicSubscriber[MsgType]): def get_name(self) -> str: return f'{",".join(self.topics)}:{self.call_name}' - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> dict[str, Channel]: channels = {} payloads = self.get_payloads() @@ -40,7 +38,7 @@ def get_schema(self) -> Dict[str, Channel]: title=f"{handler_name}:Message", payload=resolve_payloads(payloads), correlationId=CorrelationId( - location="$message.header#/correlation_id" + location="$message.header#/correlation_id", ), ), ), @@ -61,6 +59,6 @@ class SpecificationDefaultSubscriber( class SpecificationBatchSubscriber( BatchSubscriber, - SpecificationSubscriber[Tuple["ConfluentMsg", ...]], + SpecificationSubscriber[tuple["ConfluentMsg", ...]], ): pass diff --git a/faststream/confluent/subscriber/usecase.py b/faststream/confluent/subscriber/usecase.py index 54c05ce4ba..1f88912fdc 100644 --- a/faststream/confluent/subscriber/usecase.py +++ b/faststream/confluent/subscriber/usecase.py @@ -1,15 +1,11 @@ import asyncio from abc import ABC, abstractmethod +from collections.abc import Iterable, Sequence from typing import ( TYPE_CHECKING, Any, Callable, - Dict, - Iterable, - List, Optional, - Sequence, - Tuple, ) import anyio @@ -176,13 +172,12 @@ async def get_one( raw_message = await self.consumer.getone(timeout=timeout) - msg = await process_msg( + return await process_msg( msg=raw_message, middlewares=self._broker_middlewares, parser=self._parser, decoder=self._decoder, ) - return msg def _make_response_publisher( self, @@ -202,7 +197,7 @@ def _make_response_publisher( @abstractmethod async def get_msg(self) -> Optional[MsgType]: - raise NotImplementedError() + raise NotImplementedError async def _consume(self) -> None: assert self.consumer, "You should start subscriber at first." # nosec B101 @@ -224,18 +219,17 @@ async def _consume(self) -> None: await self.consume(msg) @property - def topic_names(self) -> List[str]: + def topic_names(self) -> list[str]: if self.topics: return list(self.topics) - else: - return [f"{p.topic}-{p.partition}" for p in self.partitions] + return [f"{p.topic}-{p.partition}" for p in self.partitions] @staticmethod def build_log_context( message: Optional["StreamMessage[Any]"], topic: str, group_id: Optional[str] = None, - ) -> Dict[str, str]: + ) -> dict[str, str]: return { "topic": topic, "group_id": group_id or "", @@ -243,11 +237,11 @@ def build_log_context( } def add_prefix(self, prefix: str) -> None: - self.topics = tuple("".join((prefix, t)) for t in self.topics) + self.topics = tuple(f"{prefix}{t}" for t in self.topics) self.partitions = [ TopicPartition( - topic="".join((prefix, p.topic)), + topic=f"{prefix}{p.topic}", partition=p.partition, offset=p.offset, metadata=p.metadata, @@ -307,7 +301,7 @@ async def get_msg(self) -> Optional["Message"]: def get_log_context( self, message: Optional["StreamMessage[Message]"], - ) -> Dict[str, str]: + ) -> dict[str, str]: if message is None: topic = ",".join(self.topic_names) else: @@ -320,7 +314,7 @@ def get_log_context( ) -class BatchSubscriber(LogicSubscriber[Tuple[Message, ...]]): +class BatchSubscriber(LogicSubscriber[tuple[Message, ...]]): def __init__( self, *topics: str, @@ -336,7 +330,7 @@ def __init__( no_reply: bool, retry: bool, broker_dependencies: Iterable["Depends"], - broker_middlewares: Iterable["BrokerMiddleware[Tuple[Message, ...]]"], + broker_middlewares: Iterable["BrokerMiddleware[tuple[Message, ...]]"], # AsyncAPI args title_: Optional[str], description_: Optional[str], @@ -366,7 +360,7 @@ def __init__( include_in_schema=include_in_schema, ) - async def get_msg(self) -> Optional[Tuple["Message", ...]]: + async def get_msg(self) -> Optional[tuple["Message", ...]]: assert self.consumer, "You should setup subscriber at first." # nosec B101 messages = await self.consumer.getmany( @@ -382,8 +376,8 @@ async def get_msg(self) -> Optional[Tuple["Message", ...]]: def get_log_context( self, - message: Optional["StreamMessage[Tuple[Message, ...]]"], - ) -> Dict[str, str]: + message: Optional["StreamMessage[tuple[Message, ...]]"], + ) -> dict[str, str]: if message is None: topic = ",".join(self.topic_names) else: diff --git a/faststream/confluent/testing.py b/faststream/confluent/testing.py index fbf77555b3..d9c5026298 100644 --- a/faststream/confluent/testing.py +++ b/faststream/confluent/testing.py @@ -1,14 +1,10 @@ -from datetime import datetime +from collections.abc import Generator, Iterable +from datetime import datetime, timezone from typing import ( TYPE_CHECKING, Any, Callable, - Dict, - Generator, - Iterable, - List, Optional, - Tuple, ) from unittest.mock import AsyncMock, MagicMock @@ -51,11 +47,13 @@ async def _fake_connect( # type: ignore[override] def create_publisher_fake_subscriber( broker: KafkaBroker, publisher: "SpecificationPublisher[Any]", - ) -> Tuple["LogicSubscriber[Any]", bool]: + ) -> tuple["LogicSubscriber[Any]", bool]: sub: Optional[LogicSubscriber[Any]] = None for handler in broker._subscribers: if _is_handler_matches( - handler, topic=publisher.topic, partition=publisher.partition + handler, + topic=publisher.topic, + partition=publisher.partition, ): sub = handler break @@ -65,7 +63,8 @@ def create_publisher_fake_subscriber( if publisher.partition: tp = TopicPartition( - topic=publisher.topic, partition=publisher.partition + topic=publisher.topic, + partition=publisher.partition, ) sub = broker.subscriber( partitions=[tp], @@ -110,7 +109,7 @@ async def publish( # type: ignore[override] key: Optional[bytes] = None, partition: Optional[int] = None, timestamp_ms: Optional[int] = None, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, correlation_id: Optional[str] = None, *, no_confirm: bool = False, @@ -147,7 +146,7 @@ async def publish_batch( topic: str, partition: Optional[int] = None, timestamp_ms: Optional[int] = None, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, reply_to: str = "", correlation_id: Optional[str] = None, no_confirm: bool = False, @@ -178,8 +177,6 @@ async def publish_batch( for m in messages: await self._execute_handler(m, topic, handler) - return None - @override async def request( # type: ignore[override] self, @@ -188,7 +185,7 @@ async def request( # type: ignore[override] key: Optional[bytes] = None, partition: Optional[int] = None, timestamp_ms: Optional[int] = None, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, correlation_id: Optional[str] = None, *, timeout: Optional[float] = 0.5, @@ -241,13 +238,13 @@ def __init__( raw_msg: bytes, topic: str, key: bytes, - headers: List[Tuple[str, bytes]], + headers: list[tuple[str, bytes]], offset: int, partition: int, timestamp_type: int, timestamp_ms: int, error: Optional[str] = None, - ): + ) -> None: self._raw_msg = raw_msg self._topic = topic self._key = key @@ -263,7 +260,7 @@ def len(self) -> int: def error(self) -> Optional[str]: return self._error - def headers(self) -> List[Tuple[str, bytes]]: + def headers(self) -> list[tuple[str, bytes]]: return self._headers def key(self) -> bytes: @@ -275,7 +272,7 @@ def offset(self) -> int: def partition(self) -> int: return self._partition - def timestamp(self) -> Tuple[int, int]: + def timestamp(self) -> tuple[int, int]: return self._timestamp def topic(self) -> str: @@ -293,7 +290,7 @@ def build_message( partition: Optional[int] = None, timestamp_ms: Optional[int] = None, key: Optional[bytes] = None, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, reply_to: str = "", ) -> MockConfluentMessage: """Build a mock confluent_kafka.Message for a sendable message.""" @@ -315,7 +312,7 @@ def build_message( offset=0, partition=partition or 0, timestamp_type=0 + 1, - timestamp_ms=timestamp_ms or int(datetime.now().timestamp()), + timestamp_ms=timestamp_ms or int(datetime.now(timezone.utc).timestamp()), ) @@ -352,5 +349,5 @@ def _is_handler_matches( p.topic == topic and (partition is None or p.partition == partition) for p in handler.partitions ) - or topic in handler.topics + or topic in handler.topics, ) diff --git a/faststream/exceptions.py b/faststream/exceptions.py index a692841f69..4b009adde2 100644 --- a/faststream/exceptions.py +++ b/faststream/exceptions.py @@ -1,5 +1,6 @@ +from collections.abc import Iterable from pprint import pformat -from typing import Any, Iterable +from typing import Any class FastStreamException(Exception): # noqa: N818 @@ -46,7 +47,7 @@ class AckMessage(HandlerException): extra_options (Any): Additional parameters that will be passed to `message.ack(**extra_options)` method. """ - def __init__(self, **extra_options: Any): + def __init__(self, **extra_options: Any) -> None: self.extra_options = extra_options super().__init__() @@ -65,7 +66,7 @@ class NackMessage(HandlerException): extra_options (Any): Additional parameters that will be passed to `message.nack(**extra_options)` method. """ - def __init__(self, **kwargs: Any): + def __init__(self, **kwargs: Any) -> None: self.extra_options = kwargs super().__init__() @@ -84,7 +85,7 @@ class RejectMessage(HandlerException): extra_options (Any): Additional parameters that will be passed to `message.reject(**extra_options)` method. """ - def __init__(self, **kwargs: Any): + def __init__(self, **kwargs: Any) -> None: self.extra_options = kwargs super().__init__() @@ -138,13 +139,13 @@ def __str__(self) -> str: ( f"\n Key `{self.field}` not found in the context\n ", pformat(self.context), - ) + ), ) WRONG_PUBLISH_ARGS = SetupError( "You should use `reply_to` to send response to long-living queue " - "and `rpc` to get response in sync mode." + "and `rpc` to get response in sync mode.", ) diff --git a/faststream/kafka/__init__.py b/faststream/kafka/__init__.py index 8d84e4b374..c52fa57508 100644 --- a/faststream/kafka/__init__.py +++ b/faststream/kafka/__init__.py @@ -10,11 +10,11 @@ __all__ = ( "KafkaBroker", "KafkaMessage", - "KafkaRouter", - "KafkaRoute", - "KafkaResponse", "KafkaPublisher", - "TestKafkaBroker", + "KafkaResponse", + "KafkaRoute", + "KafkaRouter", "TestApp", + "TestKafkaBroker", "TopicPartition", ) diff --git a/faststream/kafka/annotations.py b/faststream/kafka/annotations.py index 6f38b5f5cc..1f5c70d524 100644 --- a/faststream/kafka/annotations.py +++ b/faststream/kafka/annotations.py @@ -1,5 +1,6 @@ +from typing import Annotated + from aiokafka import AIOKafkaConsumer -from typing_extensions import Annotated from faststream._internal.context import Context from faststream.annotations import ContextRepo, Logger @@ -9,12 +10,12 @@ from faststream.params import NoCast __all__ = ( - "Logger", "ContextRepo", - "NoCast", - "KafkaMessage", "KafkaBroker", + "KafkaMessage", "KafkaProducer", + "Logger", + "NoCast", ) Consumer = Annotated[AIOKafkaConsumer, Context("handler_.consumer")] diff --git a/faststream/kafka/broker/broker.py b/faststream/kafka/broker/broker.py index be297c40c3..aa77e9c408 100644 --- a/faststream/kafka/broker/broker.py +++ b/faststream/kafka/broker/broker.py @@ -1,16 +1,13 @@ import logging +from collections.abc import Iterable from functools import partial from typing import ( TYPE_CHECKING, + Annotated, Any, Callable, - Dict, - Iterable, - List, Literal, Optional, - Tuple, - Type, TypeVar, Union, ) @@ -19,7 +16,7 @@ import anyio from aiokafka.partitioner import DefaultPartitioner from aiokafka.producer.producer import _missing -from typing_extensions import Annotated, Doc, override +from typing_extensions import Doc, override from faststream.__about__ import SERVICE_NAME from faststream._internal.broker.broker import BrokerUsecase @@ -76,7 +73,7 @@ class KafkaInitKwargs(TypedDict, total=False): which we force a refresh of metadata even if we haven't seen any partition leadership changes to proactively discover any new brokers or partitions. - """ + """, ), ] connections_max_idle_ms: Annotated[ @@ -86,7 +83,7 @@ class KafkaInitKwargs(TypedDict, total=False): Close idle connections after the number of milliseconds specified by this config. Specifying `None` will disable idle checks. - """ + """, ), ] sasl_kerberos_service_name: str @@ -105,7 +102,7 @@ class KafkaInitKwargs(TypedDict, total=False): server-side log entries that correspond to this client. Also submitted to :class:`~.consumer.group_coordinator.GroupCoordinator` for logging with respect to consumer group administration. - """ + """, ), ] # publisher args @@ -137,7 +134,7 @@ class KafkaInitKwargs(TypedDict, total=False): If unset, defaults to ``acks=1``. If `enable_idempotence` is :data:`True` defaults to ``acks=all``. - """ + """, ), ] key_serializer: Annotated[ @@ -156,7 +153,7 @@ class KafkaInitKwargs(TypedDict, total=False): Compression is of full batches of data, so the efficacy of batching will also impact the compression ratio (more batching means better compression). - """ + """, ), ] max_batch_size: Annotated[ @@ -165,12 +162,12 @@ class KafkaInitKwargs(TypedDict, total=False): """ Maximum size of buffered data per partition. After this amount `send` coroutine will block until batch is drained. - """ + """, ), ] partitioner: Annotated[ Callable[ - [bytes, List[Partition], List[Partition]], + [bytes, list[Partition], list[Partition]], Partition, ], Doc( @@ -183,7 +180,7 @@ class KafkaInitKwargs(TypedDict, total=False): messages with the same key are assigned to the same partition. When a key is :data:`None`, the message is delivered to a random partition (filtered to partitions with available leaders only, if possible). - """ + """, ), ] max_request_size: Annotated[ @@ -195,7 +192,7 @@ class KafkaInitKwargs(TypedDict, total=False): has its own cap on record size which may be different from this. This setting will limit the number of record batches the producer will send in a single request to avoid sending huge requests. - """ + """, ), ] linger_ms: Annotated[ @@ -210,7 +207,7 @@ class KafkaInitKwargs(TypedDict, total=False): This setting accomplishes this by adding a small amount of artificial delay; that is, if first request is processed faster, than `linger_ms`, producer will wait ``linger_ms - process_time``. - """ + """, ), ] enable_idempotence: Annotated[ @@ -223,7 +220,7 @@ class KafkaInitKwargs(TypedDict, total=False): etc., may write duplicates of the retried message in the stream. Note that enabling idempotence acks to set to ``all``. If it is not explicitly set by the user it will be chosen. - """ + """, ), ] transactional_id: Optional[str] @@ -233,11 +230,11 @@ class KafkaInitKwargs(TypedDict, total=False): class KafkaBroker( KafkaRegistrator, BrokerUsecase[ - Union[aiokafka.ConsumerRecord, Tuple[aiokafka.ConsumerRecord, ...]], + Union[aiokafka.ConsumerRecord, tuple[aiokafka.ConsumerRecord, ...]], Callable[..., aiokafka.AIOKafkaConsumer], ], ): - url: List[str] + url: list[str] _producer: Optional["AioKafkaFastProducer"] def __init__( @@ -252,7 +249,7 @@ def __init__( This does not have to be the full node list. It just needs to have at least one broker that will respond to a Metadata API Request. Default port is 9092. - """ + """, ), ] = "localhost", *, @@ -273,7 +270,7 @@ def __init__( which we force a refresh of metadata even if we haven't seen any partition leadership changes to proactively discover any new brokers or partitions. - """ + """, ), ] = 5 * 60 * 1000, connections_max_idle_ms: Annotated[ @@ -283,7 +280,7 @@ def __init__( Close idle connections after the number of milliseconds specified by this config. Specifying `None` will disable idle checks. - """ + """, ), ] = 9 * 60 * 1000, sasl_kerberos_service_name: str = "kafka", @@ -302,7 +299,7 @@ def __init__( server-side log entries that correspond to this client. Also submitted to :class:`~.consumer.group_coordinator.GroupCoordinator` for logging with respect to consumer group administration. - """ + """, ), ] = SERVICE_NAME, # publisher args @@ -334,7 +331,7 @@ def __init__( If unset, defaults to ``acks=1``. If `enable_idempotence` is :data:`True` defaults to ``acks=all``. - """ + """, ), ] = _missing, key_serializer: Annotated[ @@ -353,7 +350,7 @@ def __init__( Compression is of full batches of data, so the efficacy of batching will also impact the compression ratio (more batching means better compression). - """ + """, ), ] = None, max_batch_size: Annotated[ @@ -362,12 +359,12 @@ def __init__( """ Maximum size of buffered data per partition. After this amount `send` coroutine will block until batch is drained. - """ + """, ), ] = 16 * 1024, partitioner: Annotated[ Callable[ - [bytes, List[Partition], List[Partition]], + [bytes, list[Partition], list[Partition]], Partition, ], Doc( @@ -380,7 +377,7 @@ def __init__( messages with the same key are assigned to the same partition. When a key is :data:`None`, the message is delivered to a random partition (filtered to partitions with available leaders only, if possible). - """ + """, ), ] = DefaultPartitioner(), max_request_size: Annotated[ @@ -392,7 +389,7 @@ def __init__( has its own cap on record size which may be different from this. This setting will limit the number of record batches the producer will send in a single request to avoid sending huge requests. - """ + """, ), ] = 1024 * 1024, linger_ms: Annotated[ @@ -407,7 +404,7 @@ def __init__( This setting accomplishes this by adding a small amount of artificial delay; that is, if first request is processed faster, than `linger_ms`, producer will wait ``linger_ms - process_time``. - """ + """, ), ] = 0, enable_idempotence: Annotated[ @@ -420,7 +417,7 @@ def __init__( etc., may write duplicates of the retried message in the stream. Note that enabling idempotence acks to set to ``all``. If it is not explicitly set by the user it will be chosen. - """ + """, ), ] = False, transactional_id: Optional[str] = None, @@ -429,7 +426,7 @@ def __init__( graceful_timeout: Annotated[ Optional[float], Doc( - "Graceful shutdown timeout. Broker waits for all running subscribers completion before shut down." + "Graceful shutdown timeout. Broker waits for all running subscribers completion before shut down.", ), ] = 15.0, decoder: Annotated[ @@ -448,7 +445,7 @@ def __init__( Iterable[ Union[ "BrokerMiddleware[ConsumerRecord]", - "BrokerMiddleware[Tuple[ConsumerRecord, ...]]", + "BrokerMiddleware[tuple[ConsumerRecord, ...]]", ] ], Doc("Middlewares to apply to all broker publishers/subscribers."), @@ -457,7 +454,7 @@ def __init__( security: Annotated[ Optional["BaseSecurity"], Doc( - "Security options to connect broker and generate AsyncAPI server security information." + "Security options to connect broker and generate AsyncAPI server security information.", ), ] = None, specification_url: Annotated[ @@ -587,7 +584,7 @@ def __init__( async def close( self, - exc_type: Optional[Type[BaseException]] = None, + exc_type: Optional[type[BaseException]] = None, exc_val: Optional[BaseException] = None, exc_tb: Optional["TracebackType"] = None, ) -> None: @@ -687,7 +684,7 @@ async def publish( # type: ignore[override] partition (but if key is `None`, partition is chosen randomly). Must be type `bytes`, or be serializable to bytes via configured `key_serializer`. - """ + """, ), ] = None, partition: Annotated[ @@ -696,7 +693,7 @@ async def publish( # type: ignore[override] """ Specify a partition. If not set, the partition will be selected using the configured `partitioner`. - """ + """, ), ] = None, timestamp_ms: Annotated[ @@ -705,18 +702,18 @@ async def publish( # type: ignore[override] """ Epoch milliseconds (from Jan 1 1970 UTC) to use as the message timestamp. Defaults to current time. - """ + """, ), ] = None, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc("Message headers to store metainformation."), ] = None, correlation_id: Annotated[ Optional[str], Doc( "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages." + "**correlation_id** is a useful option to trace messages.", ), ] = None, reply_to: Annotated[ @@ -776,7 +773,7 @@ async def request( # type: ignore[override] partition (but if key is `None`, partition is chosen randomly). Must be type `bytes`, or be serializable to bytes via configured `key_serializer`. - """ + """, ), ] = None, partition: Annotated[ @@ -785,7 +782,7 @@ async def request( # type: ignore[override] """ Specify a partition. If not set, the partition will be selected using the configured `partitioner`. - """ + """, ), ] = None, timestamp_ms: Annotated[ @@ -794,18 +791,18 @@ async def request( # type: ignore[override] """ Epoch milliseconds (from Jan 1 1970 UTC) to use as the message timestamp. Defaults to current time. - """ + """, ), ] = None, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc("Message headers to store metainformation."), ] = None, correlation_id: Annotated[ Optional[str], Doc( "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages." + "**correlation_id** is a useful option to trace messages.", ), ] = None, timeout: Annotated[ @@ -843,7 +840,7 @@ async def publish_batch( """ Specify a partition. If not set, the partition will be selected using the configured `partitioner`. - """ + """, ), ] = None, timestamp_ms: Annotated[ @@ -852,11 +849,11 @@ async def publish_batch( """ Epoch milliseconds (from Jan 1 1970 UTC) to use as the message timestamp. Defaults to current time. - """ + """, ), ] = None, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc("Messages headers to store metainformation."), ] = None, reply_to: Annotated[ @@ -867,7 +864,7 @@ async def publish_batch( Optional[str], Doc( "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages." + "**correlation_id** is a useful option to trace messages.", ), ] = None, no_confirm: Annotated[ diff --git a/faststream/kafka/broker/logging.py b/faststream/kafka/broker/logging.py index 5334f4a70d..c39b71a604 100644 --- a/faststream/kafka/broker/logging.py +++ b/faststream/kafka/broker/logging.py @@ -26,13 +26,13 @@ def setup_log_contest(self, params: "AnyDict") -> None: ( self._max_topic_len, len(params.get("topic", "")), - ) + ), ) self._max_group_len = max( ( self._max_group_len, len(params.get("group_id", "")), - ) + ), ) def get_logger(self) -> Optional["LoggerProto"]: @@ -47,17 +47,17 @@ def get_logger(self) -> Optional["LoggerProto"]: }, message_id_ln=message_id_ln, fmt=self._log_fmt - or ( - "%(asctime)s %(levelname)-8s - " - + f"%(topic)-{self._max_topic_len}s | " - + ( + or "".join(( + "%(asctime)s %(levelname)-8s - ", + f"%(topic)-{self._max_topic_len}s | ", + ( f"%(group_id)-{self._max_group_len}s | " if self._max_group_len else "" - ) - + f"%(message_id)-{message_id_ln}s " - + "- %(message)s" - ), + ), + f"%(message_id)-{message_id_ln}s ", + "- %(message)s", + )), ) diff --git a/faststream/kafka/broker/registrator.py b/faststream/kafka/broker/registrator.py index 10be770874..ce805e6066 100644 --- a/faststream/kafka/broker/registrator.py +++ b/faststream/kafka/broker/registrator.py @@ -1,14 +1,11 @@ +from collections.abc import Iterable, Sequence from typing import ( TYPE_CHECKING, + Annotated, Any, Callable, - Dict, - Iterable, - List, Literal, Optional, - Sequence, - Tuple, Union, cast, overload, @@ -16,7 +13,7 @@ from aiokafka import ConsumerRecord from aiokafka.coordinator.assignors.roundrobin import RoundRobinPartitionAssignor -from typing_extensions import Annotated, Doc, override +from typing_extensions import Doc, override from faststream._internal.broker.abc_broker import ABCBroker from faststream.kafka.publisher.publisher import SpecificationPublisher @@ -48,16 +45,16 @@ class KafkaRegistrator( ABCBroker[ Union[ ConsumerRecord, - Tuple[ConsumerRecord, ...], + tuple[ConsumerRecord, ...], ] - ] + ], ): """Includable to KafkaBroker router.""" - _subscribers: List[ + _subscribers: list[ Union["SpecificationBatchSubscriber", "SpecificationDefaultSubscriber"], ] - _publishers: List[ + _publishers: list[ Union["SpecificationBatchPublisher", "SpecificationDefaultPublisher"], ] @@ -80,21 +77,21 @@ def subscriber( partition assignment (if enabled), and to use for fetching and committing offsets. If `None`, auto-partition assignment (via group coordinator) and offset commits are disabled. - """ + """, ), ] = None, key_deserializer: Annotated[ Optional[Callable[[bytes], Any]], Doc( "Any callable that takes a raw message `bytes` " - "key and returns a deserialized one." + "key and returns a deserialized one.", ), ] = None, value_deserializer: Annotated[ Optional[Callable[[bytes], Any]], Doc( "Any callable that takes a raw message `bytes` " - "value and returns a deserialized value." + "value and returns a deserialized value.", ), ] = None, fetch_max_bytes: Annotated[ @@ -109,7 +106,7 @@ def subscriber( performs fetches to multiple brokers in parallel so memory usage will depend on the number of brokers containing partitions for the topic. - """ + """, ), ] = 50 * 1024 * 1024, fetch_min_bytes: Annotated[ @@ -119,7 +116,7 @@ def subscriber( Minimum amount of data the server should return for a fetch request, otherwise wait up to `fetch_max_wait_ms` for more data to accumulate. - """ + """, ), ] = 1, fetch_max_wait_ms: Annotated[ @@ -130,7 +127,7 @@ def subscriber( the server will block before answering the fetch request if there isn't sufficient data to immediately satisfy the requirement given by `fetch_min_bytes`. - """ + """, ), ] = 500, max_partition_fetch_bytes: Annotated[ @@ -145,7 +142,7 @@ def subscriber( send messages larger than the consumer can fetch. If that happens, the consumer can get stuck trying to fetch a large message on a certain partition. - """ + """, ), ] = 1 * 1024 * 1024, auto_offset_reset: Annotated[ @@ -157,7 +154,7 @@ def subscriber( * `earliest` will move to the oldest available message * `latest` will move to the most recent * `none` will raise an exception so you can handle this case - """ + """, ), ] = "latest", auto_commit: Annotated[ @@ -166,7 +163,7 @@ def subscriber( """ If `True` the consumer's offset will be periodically committed in the background. - """ + """, ), ] = True, auto_commit_interval_ms: Annotated[ @@ -174,7 +171,7 @@ def subscriber( Doc( """ Milliseconds between automatic - offset commits, if `auto_commit` is `True`.""" + offset commits, if `auto_commit` is `True`.""", ), ] = 5 * 1000, check_crcs: Annotated[ @@ -185,7 +182,7 @@ def subscriber( consumed. This ensures no on-the-wire or on-disk corruption to the messages occurred. This check adds some overhead, so it may be disabled in cases seeking extreme performance. - """ + """, ), ] = True, partition_assignment_strategy: Annotated[ @@ -201,7 +198,7 @@ def subscriber( one. The coordinator will choose the old assignment strategy until all members have been updated. Then it will choose the new strategy. - """ + """, ), ] = (RoundRobinPartitionAssignor,), max_poll_interval_ms: Annotated[ @@ -214,7 +211,7 @@ def subscriber( rebalance in order to reassign the partitions to another consumer group member. If API methods block waiting for messages, that time does not count against this timeout. - """ + """, ), ] = 5 * 60 * 1000, rebalance_timeout_ms: Annotated[ @@ -228,7 +225,7 @@ def subscriber( decouple this setting to allow finer tuning by users that use `ConsumerRebalanceListener` to delay rebalacing. Defaults to ``session_timeout_ms`` - """ + """, ), ] = None, session_timeout_ms: Annotated[ @@ -243,7 +240,7 @@ def subscriber( group and trigger a rebalance. The allowed range is configured with the **broker** configuration properties `group.min.session.timeout.ms` and `group.max.session.timeout.ms`. - """ + """, ), ] = 10 * 1000, heartbeat_interval_ms: Annotated[ @@ -259,7 +256,7 @@ def subscriber( should be set no higher than 1/3 of that value. It can be adjusted even lower to control the expected time for normal rebalances. - """ + """, ), ] = 3 * 1000, consumer_timeout_ms: Annotated[ @@ -269,7 +266,7 @@ def subscriber( Maximum wait timeout for background fetching routine. Mostly defines how fast the system will see rebalance and request new data for new partitions. - """ + """, ), ] = 200, max_poll_records: Annotated[ @@ -278,7 +275,7 @@ def subscriber( """ The maximum number of records returned in a single call by batch consumer. Has no limit by default. - """ + """, ), ] = None, exclude_internal_topics: Annotated[ @@ -289,7 +286,7 @@ def subscriber( (such as offsets) should be exposed to the consumer. If set to True the only way to receive records from an internal topic is subscribing to it. - """ + """, ), ] = True, isolation_level: Annotated[ @@ -319,7 +316,7 @@ def subscriber( to the high watermark when there are in flight transactions. Further, when in `read_committed` the seek_to_end method will return the LSO. See method docs below. - """ + """, ), ] = "read_uncommitted", batch_timeout_ms: Annotated[ @@ -330,7 +327,7 @@ def subscriber( data is not available in the buffer. If 0, returns immediately with any records that are available currently in the buffer, else returns empty. - """ + """, ), ] = 200, max_records: Annotated[ @@ -362,7 +359,7 @@ def subscriber( to subscribe. It is guaranteed, however, that the partitions revoked/assigned through this interface are from topics subscribed in this call. - """ + """, ), ] = None, pattern: Annotated[ @@ -370,7 +367,7 @@ def subscriber( Doc( """ Pattern to match available topics. You must provide either topics or pattern, but not both. - """ + """, ), ] = None, partitions: Annotated[ @@ -379,7 +376,7 @@ def subscriber( """ An explicit partitions list to assign. You can't use 'topics' and 'partitions' in the same time. - """ + """, ), ] = (), # broker args @@ -410,7 +407,7 @@ def subscriber( no_reply: Annotated[ bool, Doc( - "Whether to disable **FastStream** RPC and Reply To auto responses or not." + "Whether to disable **FastStream** RPC and Reply To auto responses or not.", ), ] = False, # Specification args @@ -422,7 +419,7 @@ def subscriber( Optional[str], Doc( "Specification subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -450,21 +447,21 @@ def subscriber( partition assignment (if enabled), and to use for fetching and committing offsets. If `None`, auto-partition assignment (via group coordinator) and offset commits are disabled. - """ + """, ), ] = None, key_deserializer: Annotated[ Optional[Callable[[bytes], Any]], Doc( "Any callable that takes a raw message `bytes` " - "key and returns a deserialized one." + "key and returns a deserialized one.", ), ] = None, value_deserializer: Annotated[ Optional[Callable[[bytes], Any]], Doc( "Any callable that takes a raw message `bytes` " - "value and returns a deserialized value." + "value and returns a deserialized value.", ), ] = None, fetch_max_bytes: Annotated[ @@ -479,7 +476,7 @@ def subscriber( performs fetches to multiple brokers in parallel so memory usage will depend on the number of brokers containing partitions for the topic. - """ + """, ), ] = 50 * 1024 * 1024, fetch_min_bytes: Annotated[ @@ -489,7 +486,7 @@ def subscriber( Minimum amount of data the server should return for a fetch request, otherwise wait up to `fetch_max_wait_ms` for more data to accumulate. - """ + """, ), ] = 1, fetch_max_wait_ms: Annotated[ @@ -500,7 +497,7 @@ def subscriber( the server will block before answering the fetch request if there isn't sufficient data to immediately satisfy the requirement given by `fetch_min_bytes`. - """ + """, ), ] = 500, max_partition_fetch_bytes: Annotated[ @@ -515,7 +512,7 @@ def subscriber( send messages larger than the consumer can fetch. If that happens, the consumer can get stuck trying to fetch a large message on a certain partition. - """ + """, ), ] = 1 * 1024 * 1024, auto_offset_reset: Annotated[ @@ -527,7 +524,7 @@ def subscriber( * `earliest` will move to the oldest available message * `latest` will move to the most recent * `none` will raise an exception so you can handle this case - """ + """, ), ] = "latest", auto_commit: Annotated[ @@ -536,7 +533,7 @@ def subscriber( """ If `True` the consumer's offset will be periodically committed in the background. - """ + """, ), ] = True, auto_commit_interval_ms: Annotated[ @@ -544,7 +541,7 @@ def subscriber( Doc( """ Milliseconds between automatic - offset commits, if `auto_commit` is `True`.""" + offset commits, if `auto_commit` is `True`.""", ), ] = 5 * 1000, check_crcs: Annotated[ @@ -555,7 +552,7 @@ def subscriber( consumed. This ensures no on-the-wire or on-disk corruption to the messages occurred. This check adds some overhead, so it may be disabled in cases seeking extreme performance. - """ + """, ), ] = True, partition_assignment_strategy: Annotated[ @@ -571,7 +568,7 @@ def subscriber( one. The coordinator will choose the old assignment strategy until all members have been updated. Then it will choose the new strategy. - """ + """, ), ] = (RoundRobinPartitionAssignor,), max_poll_interval_ms: Annotated[ @@ -584,7 +581,7 @@ def subscriber( rebalance in order to reassign the partitions to another consumer group member. If API methods block waiting for messages, that time does not count against this timeout. - """ + """, ), ] = 5 * 60 * 1000, rebalance_timeout_ms: Annotated[ @@ -598,7 +595,7 @@ def subscriber( decouple this setting to allow finer tuning by users that use `ConsumerRebalanceListener` to delay rebalacing. Defaults to ``session_timeout_ms`` - """ + """, ), ] = None, session_timeout_ms: Annotated[ @@ -613,7 +610,7 @@ def subscriber( group and trigger a rebalance. The allowed range is configured with the **broker** configuration properties `group.min.session.timeout.ms` and `group.max.session.timeout.ms`. - """ + """, ), ] = 10 * 1000, heartbeat_interval_ms: Annotated[ @@ -629,7 +626,7 @@ def subscriber( should be set no higher than 1/3 of that value. It can be adjusted even lower to control the expected time for normal rebalances. - """ + """, ), ] = 3 * 1000, consumer_timeout_ms: Annotated[ @@ -639,7 +636,7 @@ def subscriber( Maximum wait timeout for background fetching routine. Mostly defines how fast the system will see rebalance and request new data for new partitions. - """ + """, ), ] = 200, max_poll_records: Annotated[ @@ -648,7 +645,7 @@ def subscriber( """ The maximum number of records returned in a single call by batch consumer. Has no limit by default. - """ + """, ), ] = None, exclude_internal_topics: Annotated[ @@ -659,7 +656,7 @@ def subscriber( (such as offsets) should be exposed to the consumer. If set to True the only way to receive records from an internal topic is subscribing to it. - """ + """, ), ] = True, isolation_level: Annotated[ @@ -689,7 +686,7 @@ def subscriber( to the high watermark when there are in flight transactions. Further, when in `read_committed` the seek_to_end method will return the LSO. See method docs below. - """ + """, ), ] = "read_uncommitted", batch_timeout_ms: Annotated[ @@ -700,7 +697,7 @@ def subscriber( data is not available in the buffer. If 0, returns immediately with any records that are available currently in the buffer, else returns empty. - """ + """, ), ] = 200, max_records: Annotated[ @@ -732,7 +729,7 @@ def subscriber( to subscribe. It is guaranteed, however, that the partitions revoked/assigned through this interface are from topics subscribed in this call. - """ + """, ), ] = None, pattern: Annotated[ @@ -740,7 +737,7 @@ def subscriber( Doc( """ Pattern to match available topics. You must provide either topics or pattern, but not both. - """ + """, ), ] = None, partitions: Annotated[ @@ -749,7 +746,7 @@ def subscriber( """ An explicit partitions list to assign. You can't use 'topics' and 'partitions' in the same time. - """ + """, ), ] = (), # broker args @@ -780,7 +777,7 @@ def subscriber( no_reply: Annotated[ bool, Doc( - "Whether to disable **FastStream** RPC and Reply To auto responses or not." + "Whether to disable **FastStream** RPC and Reply To auto responses or not.", ), ] = False, # Specification args @@ -792,7 +789,7 @@ def subscriber( Optional[str], Doc( "Specification subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -820,21 +817,21 @@ def subscriber( partition assignment (if enabled), and to use for fetching and committing offsets. If `None`, auto-partition assignment (via group coordinator) and offset commits are disabled. - """ + """, ), ] = None, key_deserializer: Annotated[ Optional[Callable[[bytes], Any]], Doc( "Any callable that takes a raw message `bytes` " - "key and returns a deserialized one." + "key and returns a deserialized one.", ), ] = None, value_deserializer: Annotated[ Optional[Callable[[bytes], Any]], Doc( "Any callable that takes a raw message `bytes` " - "value and returns a deserialized value." + "value and returns a deserialized value.", ), ] = None, fetch_max_bytes: Annotated[ @@ -849,7 +846,7 @@ def subscriber( performs fetches to multiple brokers in parallel so memory usage will depend on the number of brokers containing partitions for the topic. - """ + """, ), ] = 50 * 1024 * 1024, fetch_min_bytes: Annotated[ @@ -859,7 +856,7 @@ def subscriber( Minimum amount of data the server should return for a fetch request, otherwise wait up to `fetch_max_wait_ms` for more data to accumulate. - """ + """, ), ] = 1, fetch_max_wait_ms: Annotated[ @@ -870,7 +867,7 @@ def subscriber( the server will block before answering the fetch request if there isn't sufficient data to immediately satisfy the requirement given by `fetch_min_bytes`. - """ + """, ), ] = 500, max_partition_fetch_bytes: Annotated[ @@ -885,7 +882,7 @@ def subscriber( send messages larger than the consumer can fetch. If that happens, the consumer can get stuck trying to fetch a large message on a certain partition. - """ + """, ), ] = 1 * 1024 * 1024, auto_offset_reset: Annotated[ @@ -897,7 +894,7 @@ def subscriber( * `earliest` will move to the oldest available message * `latest` will move to the most recent * `none` will raise an exception so you can handle this case - """ + """, ), ] = "latest", auto_commit: Annotated[ @@ -906,7 +903,7 @@ def subscriber( """ If `True` the consumer's offset will be periodically committed in the background. - """ + """, ), ] = True, auto_commit_interval_ms: Annotated[ @@ -914,7 +911,7 @@ def subscriber( Doc( """ Milliseconds between automatic - offset commits, if `auto_commit` is `True`.""" + offset commits, if `auto_commit` is `True`.""", ), ] = 5 * 1000, check_crcs: Annotated[ @@ -925,7 +922,7 @@ def subscriber( consumed. This ensures no on-the-wire or on-disk corruption to the messages occurred. This check adds some overhead, so it may be disabled in cases seeking extreme performance. - """ + """, ), ] = True, partition_assignment_strategy: Annotated[ @@ -941,7 +938,7 @@ def subscriber( one. The coordinator will choose the old assignment strategy until all members have been updated. Then it will choose the new strategy. - """ + """, ), ] = (RoundRobinPartitionAssignor,), max_poll_interval_ms: Annotated[ @@ -954,7 +951,7 @@ def subscriber( rebalance in order to reassign the partitions to another consumer group member. If API methods block waiting for messages, that time does not count against this timeout. - """ + """, ), ] = 5 * 60 * 1000, rebalance_timeout_ms: Annotated[ @@ -968,7 +965,7 @@ def subscriber( decouple this setting to allow finer tuning by users that use `ConsumerRebalanceListener` to delay rebalacing. Defaults to ``session_timeout_ms`` - """ + """, ), ] = None, session_timeout_ms: Annotated[ @@ -983,7 +980,7 @@ def subscriber( group and trigger a rebalance. The allowed range is configured with the **broker** configuration properties `group.min.session.timeout.ms` and `group.max.session.timeout.ms`. - """ + """, ), ] = 10 * 1000, heartbeat_interval_ms: Annotated[ @@ -999,7 +996,7 @@ def subscriber( should be set no higher than 1/3 of that value. It can be adjusted even lower to control the expected time for normal rebalances. - """ + """, ), ] = 3 * 1000, consumer_timeout_ms: Annotated[ @@ -1009,7 +1006,7 @@ def subscriber( Maximum wait timeout for background fetching routine. Mostly defines how fast the system will see rebalance and request new data for new partitions. - """ + """, ), ] = 200, max_poll_records: Annotated[ @@ -1018,7 +1015,7 @@ def subscriber( """ The maximum number of records returned in a single call by batch consumer. Has no limit by default. - """ + """, ), ] = None, exclude_internal_topics: Annotated[ @@ -1029,7 +1026,7 @@ def subscriber( (such as offsets) should be exposed to the consumer. If set to True the only way to receive records from an internal topic is subscribing to it. - """ + """, ), ] = True, isolation_level: Annotated[ @@ -1059,7 +1056,7 @@ def subscriber( to the high watermark when there are in flight transactions. Further, when in `read_committed` the seek_to_end method will return the LSO. See method docs below. - """ + """, ), ] = "read_uncommitted", batch_timeout_ms: Annotated[ @@ -1070,7 +1067,7 @@ def subscriber( data is not available in the buffer. If 0, returns immediately with any records that are available currently in the buffer, else returns empty. - """ + """, ), ] = 200, max_records: Annotated[ @@ -1102,7 +1099,7 @@ def subscriber( to subscribe. It is guaranteed, however, that the partitions revoked/assigned through this interface are from topics subscribed in this call. - """ + """, ), ] = None, pattern: Annotated[ @@ -1110,7 +1107,7 @@ def subscriber( Doc( """ Pattern to match available topics. You must provide either topics or pattern, but not both. - """ + """, ), ] = None, partitions: Annotated[ @@ -1119,7 +1116,7 @@ def subscriber( """ An explicit partitions list to assign. You can't use 'topics' and 'partitions' in the same time. - """ + """, ), ] = (), # broker args @@ -1150,7 +1147,7 @@ def subscriber( no_reply: Annotated[ bool, Doc( - "Whether to disable **FastStream** RPC and Reply To auto responses or not." + "Whether to disable **FastStream** RPC and Reply To auto responses or not.", ), ] = False, # Specification args @@ -1162,7 +1159,7 @@ def subscriber( Optional[str], Doc( "Specification subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -1193,21 +1190,21 @@ def subscriber( partition assignment (if enabled), and to use for fetching and committing offsets. If `None`, auto-partition assignment (via group coordinator) and offset commits are disabled. - """ + """, ), ] = None, key_deserializer: Annotated[ Optional[Callable[[bytes], Any]], Doc( "Any callable that takes a raw message `bytes` " - "key and returns a deserialized one." + "key and returns a deserialized one.", ), ] = None, value_deserializer: Annotated[ Optional[Callable[[bytes], Any]], Doc( "Any callable that takes a raw message `bytes` " - "value and returns a deserialized value." + "value and returns a deserialized value.", ), ] = None, fetch_max_bytes: Annotated[ @@ -1222,7 +1219,7 @@ def subscriber( performs fetches to multiple brokers in parallel so memory usage will depend on the number of brokers containing partitions for the topic. - """ + """, ), ] = 50 * 1024 * 1024, fetch_min_bytes: Annotated[ @@ -1232,7 +1229,7 @@ def subscriber( Minimum amount of data the server should return for a fetch request, otherwise wait up to `fetch_max_wait_ms` for more data to accumulate. - """ + """, ), ] = 1, fetch_max_wait_ms: Annotated[ @@ -1243,7 +1240,7 @@ def subscriber( the server will block before answering the fetch request if there isn't sufficient data to immediately satisfy the requirement given by `fetch_min_bytes`. - """ + """, ), ] = 500, max_partition_fetch_bytes: Annotated[ @@ -1258,7 +1255,7 @@ def subscriber( send messages larger than the consumer can fetch. If that happens, the consumer can get stuck trying to fetch a large message on a certain partition. - """ + """, ), ] = 1 * 1024 * 1024, auto_offset_reset: Annotated[ @@ -1270,7 +1267,7 @@ def subscriber( * `earliest` will move to the oldest available message * `latest` will move to the most recent * `none` will raise an exception so you can handle this case - """ + """, ), ] = "latest", auto_commit: Annotated[ @@ -1279,7 +1276,7 @@ def subscriber( """ If `True` the consumer's offset will be periodically committed in the background. - """ + """, ), ] = True, auto_commit_interval_ms: Annotated[ @@ -1287,7 +1284,7 @@ def subscriber( Doc( """ Milliseconds between automatic - offset commits, if `auto_commit` is `True`.""" + offset commits, if `auto_commit` is `True`.""", ), ] = 5 * 1000, check_crcs: Annotated[ @@ -1298,7 +1295,7 @@ def subscriber( consumed. This ensures no on-the-wire or on-disk corruption to the messages occurred. This check adds some overhead, so it may be disabled in cases seeking extreme performance. - """ + """, ), ] = True, partition_assignment_strategy: Annotated[ @@ -1314,7 +1311,7 @@ def subscriber( one. The coordinator will choose the old assignment strategy until all members have been updated. Then it will choose the new strategy. - """ + """, ), ] = (RoundRobinPartitionAssignor,), max_poll_interval_ms: Annotated[ @@ -1327,7 +1324,7 @@ def subscriber( rebalance in order to reassign the partitions to another consumer group member. If API methods block waiting for messages, that time does not count against this timeout. - """ + """, ), ] = 5 * 60 * 1000, rebalance_timeout_ms: Annotated[ @@ -1341,7 +1338,7 @@ def subscriber( decouple this setting to allow finer tuning by users that use `ConsumerRebalanceListener` to delay rebalacing. Defaults to ``session_timeout_ms`` - """ + """, ), ] = None, session_timeout_ms: Annotated[ @@ -1356,7 +1353,7 @@ def subscriber( group and trigger a rebalance. The allowed range is configured with the **broker** configuration properties `group.min.session.timeout.ms` and `group.max.session.timeout.ms`. - """ + """, ), ] = 10 * 1000, heartbeat_interval_ms: Annotated[ @@ -1372,7 +1369,7 @@ def subscriber( should be set no higher than 1/3 of that value. It can be adjusted even lower to control the expected time for normal rebalances. - """ + """, ), ] = 3 * 1000, consumer_timeout_ms: Annotated[ @@ -1382,7 +1379,7 @@ def subscriber( Maximum wait timeout for background fetching routine. Mostly defines how fast the system will see rebalance and request new data for new partitions. - """ + """, ), ] = 200, max_poll_records: Annotated[ @@ -1391,7 +1388,7 @@ def subscriber( """ The maximum number of records returned in a single call by batch consumer. Has no limit by default. - """ + """, ), ] = None, exclude_internal_topics: Annotated[ @@ -1402,7 +1399,7 @@ def subscriber( (such as offsets) should be exposed to the consumer. If set to True the only way to receive records from an internal topic is subscribing to it. - """ + """, ), ] = True, isolation_level: Annotated[ @@ -1432,7 +1429,7 @@ def subscriber( to the high watermark when there are in flight transactions. Further, when in `read_committed` the seek_to_end method will return the LSO. See method docs below. - """ + """, ), ] = "read_uncommitted", batch_timeout_ms: Annotated[ @@ -1443,7 +1440,7 @@ def subscriber( data is not available in the buffer. If 0, returns immediately with any records that are available currently in the buffer, else returns empty. - """ + """, ), ] = 200, max_records: Annotated[ @@ -1475,7 +1472,7 @@ def subscriber( to subscribe. It is guaranteed, however, that the partitions revoked/assigned through this interface are from topics subscribed in this call. - """ + """, ), ] = None, pattern: Annotated[ @@ -1483,7 +1480,7 @@ def subscriber( Doc( """ Pattern to match available topics. You must provide either topics or pattern, but not both. - """ + """, ), ] = None, partitions: Annotated[ @@ -1492,7 +1489,7 @@ def subscriber( """ An explicit partitions list to assign. You can't use 'topics' and 'partitions' in the same time. - """ + """, ), ] = (), # broker args @@ -1523,7 +1520,7 @@ def subscriber( no_reply: Annotated[ bool, Doc( - "Whether to disable **FastStream** RPC and Reply To auto responses or not." + "Whether to disable **FastStream** RPC and Reply To auto responses or not.", ), ] = False, # Specification args @@ -1535,7 +1532,7 @@ def subscriber( Optional[str], Doc( "Specification subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -1588,7 +1585,7 @@ def subscriber( title_=title, description_=description, include_in_schema=self._solve_include_in_schema(include_in_schema), - ) + ), ) if batch: @@ -1599,13 +1596,12 @@ def subscriber( middlewares_=middlewares, ) - else: - return cast("SpecificationDefaultSubscriber", subscriber).add_call( - parser_=parser or self._parser, - decoder_=decoder or self._decoder, - dependencies_=dependencies, - middlewares_=middlewares, - ) + return cast("SpecificationDefaultSubscriber", subscriber).add_call( + parser_=parser or self._parser, + decoder_=decoder or self._decoder, + dependencies_=dependencies, + middlewares_=middlewares, + ) @overload # type: ignore[override] def publisher( @@ -1626,7 +1622,7 @@ def publisher( partition (but if key is `None`, partition is chosen randomly). Must be type `bytes`, or be serializable to bytes via configured `key_serializer`. - """ + """, ), ] = None, partition: Annotated[ @@ -1635,15 +1631,15 @@ def publisher( """ Specify a partition. If not set, the partition will be selected using the configured `partitioner`. - """ + """, ), ] = None, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc( "Message headers to store metainformation. " "**content-type** and **correlation_id** will be set automatically by framework anyway. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, reply_to: Annotated[ @@ -1672,7 +1668,7 @@ def publisher( Optional[Any], Doc( "Specification publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ @@ -1700,7 +1696,7 @@ def publisher( partition (but if key is `None`, partition is chosen randomly). Must be type `bytes`, or be serializable to bytes via configured `key_serializer`. - """ + """, ), ] = None, partition: Annotated[ @@ -1709,15 +1705,15 @@ def publisher( """ Specify a partition. If not set, the partition will be selected using the configured `partitioner`. - """ + """, ), ] = None, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc( "Message headers to store metainformation. " "**content-type** and **correlation_id** will be set automatically by framework anyway. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, reply_to: Annotated[ @@ -1746,7 +1742,7 @@ def publisher( Optional[Any], Doc( "Specification publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ @@ -1774,7 +1770,7 @@ def publisher( partition (but if key is `None`, partition is chosen randomly). Must be type `bytes`, or be serializable to bytes via configured `key_serializer`. - """ + """, ), ] = None, partition: Annotated[ @@ -1783,15 +1779,15 @@ def publisher( """ Specify a partition. If not set, the partition will be selected using the configured `partitioner`. - """ + """, ), ] = None, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc( "Message headers to store metainformation. " "**content-type** and **correlation_id** will be set automatically by framework anyway. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, reply_to: Annotated[ @@ -1820,7 +1816,7 @@ def publisher( Optional[Any], Doc( "Specification publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ @@ -1851,7 +1847,7 @@ def publisher( partition (but if key is `None`, partition is chosen randomly). Must be type `bytes`, or be serializable to bytes via configured `key_serializer`. - """ + """, ), ] = None, partition: Annotated[ @@ -1860,15 +1856,15 @@ def publisher( """ Specify a partition. If not set, the partition will be selected using the configured `partitioner`. - """ + """, ), ] = None, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc( "Message headers to store metainformation. " "**content-type** and **correlation_id** will be set automatically by framework anyway. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, reply_to: Annotated[ @@ -1897,7 +1893,7 @@ def publisher( Optional[Any], Doc( "Specification publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ @@ -1937,5 +1933,4 @@ def publisher( if batch: return cast("SpecificationBatchPublisher", super().publisher(publisher)) - else: - return cast("SpecificationDefaultPublisher", super().publisher(publisher)) + return cast("SpecificationDefaultPublisher", super().publisher(publisher)) diff --git a/faststream/kafka/fastapi/__init__.py b/faststream/kafka/fastapi/__init__.py index 07c82c6ccf..e2a8447ef7 100644 --- a/faststream/kafka/fastapi/__init__.py +++ b/faststream/kafka/fastapi/__init__.py @@ -1,4 +1,4 @@ -from typing_extensions import Annotated +from typing import Annotated from faststream._internal.fastapi.context import Context, ContextRepo, Logger from faststream.kafka.broker import KafkaBroker as KB @@ -8,12 +8,12 @@ __all__ = ( "Context", - "Logger", "ContextRepo", - "KafkaRouter", - "KafkaMessage", "KafkaBroker", + "KafkaMessage", "KafkaProducer", + "KafkaRouter", + "Logger", ) KafkaMessage = Annotated[KM, Context("message")] diff --git a/faststream/kafka/fastapi/fastapi.py b/faststream/kafka/fastapi/fastapi.py index d98ed0cc1c..0c805aa2dc 100644 --- a/faststream/kafka/fastapi/fastapi.py +++ b/faststream/kafka/fastapi/fastapi.py @@ -1,16 +1,12 @@ import logging +from collections.abc import Iterable, Sequence from typing import ( TYPE_CHECKING, + Annotated, Any, Callable, - Dict, - Iterable, - List, Literal, Optional, - Sequence, - Tuple, - Type, TypeVar, Union, cast, @@ -26,7 +22,7 @@ from fastapi.utils import generate_unique_id from starlette.responses import JSONResponse, Response from starlette.routing import BaseRoute -from typing_extensions import Annotated, Doc, deprecated, override +from typing_extensions import Doc, deprecated, override from faststream.__about__ import SERVICE_NAME from faststream._internal.constants import EMPTY @@ -66,7 +62,7 @@ Partition = TypeVar("Partition") -class KafkaRouter(StreamRouter[Union[ConsumerRecord, Tuple[ConsumerRecord, ...]]]): +class KafkaRouter(StreamRouter[Union[ConsumerRecord, tuple[ConsumerRecord, ...]]]): """A class to represent a Kafka router.""" broker_class = KB @@ -84,7 +80,7 @@ def __init__( This does not have to be the full node list. It just needs to have at least one broker that will respond to a Metadata API Request. Default port is 9092. - """ + """, ), ] = "localhost", *, @@ -105,7 +101,7 @@ def __init__( which we force a refresh of metadata even if we haven't seen any partition leadership changes to proactively discover any new brokers or partitions. - """ + """, ), ] = 5 * 60 * 1000, connections_max_idle_ms: Annotated[ @@ -115,7 +111,7 @@ def __init__( Close idle connections after the number of milliseconds specified by this config. Specifying `None` will disable idle checks. - """ + """, ), ] = 9 * 60 * 1000, sasl_kerberos_service_name: str = "kafka", @@ -134,7 +130,7 @@ def __init__( server-side log entries that correspond to this client. Also submitted to :class:`~.consumer.group_coordinator.GroupCoordinator` for logging with respect to consumer group administration. - """ + """, ), ] = SERVICE_NAME, # publisher args @@ -166,7 +162,7 @@ def __init__( If unset, defaults to ``acks=1``. If `enable_idempotence` is :data:`True` defaults to ``acks=all``. - """ + """, ), ] = _missing, key_serializer: Annotated[ @@ -185,7 +181,7 @@ def __init__( Compression is of full batches of data, so the efficacy of batching will also impact the compression ratio (more batching means better compression). - """ + """, ), ] = None, max_batch_size: Annotated[ @@ -194,12 +190,12 @@ def __init__( """ Maximum size of buffered data per partition. After this amount `send` coroutine will block until batch is drained. - """ + """, ), ] = 16 * 1024, partitioner: Annotated[ Callable[ - [bytes, List[Partition], List[Partition]], + [bytes, list[Partition], list[Partition]], Partition, ], Doc( @@ -212,7 +208,7 @@ def __init__( messages with the same key are assigned to the same partition. When a key is :data:`None`, the message is delivered to a random partition (filtered to partitions with available leaders only, if possible). - """ + """, ), ] = DefaultPartitioner(), max_request_size: Annotated[ @@ -224,7 +220,7 @@ def __init__( has its own cap on record size which may be different from this. This setting will limit the number of record batches the producer will send in a single request to avoid sending huge requests. - """ + """, ), ] = 1024 * 1024, linger_ms: Annotated[ @@ -239,7 +235,7 @@ def __init__( This setting accomplishes this by adding a small amount of artificial delay; that is, if first request is processed faster, than `linger_ms`, producer will wait ``linger_ms - process_time``. - """ + """, ), ] = 0, enable_idempotence: Annotated[ @@ -252,7 +248,7 @@ def __init__( etc., may write duplicates of the retried message in the stream. Note that enabling idempotence acks to set to ``all``. If it is not explicitly set by the user it will be chosen. - """ + """, ), ] = False, transactional_id: Optional[str] = None, @@ -261,7 +257,7 @@ def __init__( graceful_timeout: Annotated[ Optional[float], Doc( - "Graceful shutdown timeout. Broker waits for all running subscribers completion before shut down." + "Graceful shutdown timeout. Broker waits for all running subscribers completion before shut down.", ), ] = 15.0, decoder: Annotated[ @@ -276,7 +272,7 @@ def __init__( Iterable[ Union[ "BrokerMiddleware[ConsumerRecord]", - "BrokerMiddleware[Tuple[ConsumerRecord, ...]]", + "BrokerMiddleware[tuple[ConsumerRecord, ...]]", ] ], Doc("Middlewares to apply to all broker publishers/subscribers."), @@ -285,13 +281,13 @@ def __init__( security: Annotated[ Optional["BaseSecurity"], Doc( - "Security options to connect broker and generate Specification server security information." + "Security options to connect broker and generate Specification server security information.", ), ] = None, specification_url: Annotated[ Optional[str], Doc( - "Specification hardcoded server addresses. Use `servers` if not specified." + "Specification hardcoded server addresses. Use `servers` if not specified.", ), ] = None, protocol: Annotated[ @@ -328,13 +324,13 @@ def __init__( bool, Doc( "Whether to add broker to app scope in lifespan. " - "You should disable this option at old ASGI servers." + "You should disable this option at old ASGI servers.", ), ] = True, schema_url: Annotated[ Optional[str], Doc( - "Specification schema url. You should set this option to `None` to disable Specification routes at all." + "Specification schema url. You should set this option to `None` to disable Specification routes at all.", ), ] = "/asyncapi", # FastAPI args @@ -343,7 +339,7 @@ def __init__( Doc("An optional path prefix for the router."), ] = "", tags: Annotated[ - Optional[List[Union[str, "Enum"]]], + Optional[list[Union[str, "Enum"]]], Doc( """ A list of tags to be applied to all the *path operations* in this @@ -353,7 +349,7 @@ def __init__( Read more about it in the [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ + """, ), ] = None, dependencies: Annotated[ @@ -365,22 +361,22 @@ def __init__( Read more about it in the [FastAPI docs for Bigger Applications - Multiple Files](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies). - """ + """, ), ] = None, default_response_class: Annotated[ - Type["Response"], + type["Response"], Doc( """ The default response class to be used. Read more in the [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#default-response-class). - """ + """, ), ] = Default(JSONResponse), responses: Annotated[ - Optional[Dict[Union[int, str], "AnyDict"]], + Optional[dict[Union[int, str], "AnyDict"]], Doc( """ Additional responses to be shown in OpenAPI. @@ -392,11 +388,11 @@ def __init__( And in the [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies). - """ + """, ), ] = None, callbacks: Annotated[ - Optional[List[BaseRoute]], + Optional[list[BaseRoute]], Doc( """ OpenAPI callbacks that should apply to all *path operations* in this @@ -406,11 +402,11 @@ def __init__( Read more about it in the [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). - """ + """, ), ] = None, routes: Annotated[ - Optional[List[BaseRoute]], + Optional[list[BaseRoute]], Doc( """ **Note**: you probably shouldn't use this parameter, it is inherited @@ -419,7 +415,7 @@ def __init__( --- A list of routes to serve incoming HTTP and WebSocket requests. - """ + """, ), deprecated( """ @@ -428,7 +424,7 @@ def __init__( In FastAPI, you normally would use the *path operation methods*, like `router.get()`, `router.post()`, etc. - """ + """, ), ] = None, redirect_slashes: Annotated[ @@ -437,7 +433,7 @@ def __init__( """ Whether to detect and redirect slashes in URLs when the client doesn't use the same format. - """ + """, ), ] = True, default: Annotated[ @@ -446,7 +442,7 @@ def __init__( """ Default function handler for this router. Used to handle 404 Not Found errors. - """ + """, ), ] = None, dependency_overrides_provider: Annotated[ @@ -457,18 +453,18 @@ def __init__( You shouldn't need to use it. It normally points to the `FastAPI` app object. - """ + """, ), ] = None, route_class: Annotated[ - Type["APIRoute"], + type["APIRoute"], Doc( """ Custom route (*path operation*) class to be used by this router. Read more about it in the [FastAPI docs for Custom Request and APIRoute class](https://fastapi.tiangolo.com/how-to/custom-request-and-route/#custom-apiroute-class-in-a-router). - """ + """, ), ] = APIRoute, on_startup: Annotated[ @@ -480,7 +476,7 @@ def __init__( You should instead use the `lifespan` handlers. Read more in the [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/). - """ + """, ), ] = None, on_shutdown: Annotated[ @@ -493,7 +489,7 @@ def __init__( Read more in the [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/). - """ + """, ), ] = None, lifespan: Annotated[ @@ -505,7 +501,7 @@ def __init__( Read more in the [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/). - """ + """, ), ] = None, deprecated: Annotated[ @@ -518,7 +514,7 @@ def __init__( Read more about it in the [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ + """, ), ] = None, include_in_schema: Annotated[ @@ -532,7 +528,7 @@ def __init__( Read more about it in the [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi). - """ + """, ), ] = True, generate_unique_id_function: Annotated[ @@ -547,7 +543,7 @@ def __init__( Read more about it in the [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). - """ + """, ), ] = Default(generate_unique_id), ) -> None: @@ -625,21 +621,21 @@ def subscriber( partition assignment (if enabled), and to use for fetching and committing offsets. If `None`, auto-partition assignment (via group coordinator) and offset commits are disabled. - """ + """, ), ] = None, key_deserializer: Annotated[ Optional[Callable[[bytes], Any]], Doc( "Any callable that takes a raw message `bytes` " - "key and returns a deserialized one." + "key and returns a deserialized one.", ), ] = None, value_deserializer: Annotated[ Optional[Callable[[bytes], Any]], Doc( "Any callable that takes a raw message `bytes` " - "value and returns a deserialized value." + "value and returns a deserialized value.", ), ] = None, fetch_max_bytes: Annotated[ @@ -654,7 +650,7 @@ def subscriber( performs fetches to multiple brokers in parallel so memory usage will depend on the number of brokers containing partitions for the topic. - """ + """, ), ] = 50 * 1024 * 1024, fetch_min_bytes: Annotated[ @@ -664,7 +660,7 @@ def subscriber( Minimum amount of data the server should return for a fetch request, otherwise wait up to `fetch_max_wait_ms` for more data to accumulate. - """ + """, ), ] = 1, fetch_max_wait_ms: Annotated[ @@ -675,7 +671,7 @@ def subscriber( the server will block before answering the fetch request if there isn't sufficient data to immediately satisfy the requirement given by `fetch_min_bytes`. - """ + """, ), ] = 500, max_partition_fetch_bytes: Annotated[ @@ -690,7 +686,7 @@ def subscriber( send messages larger than the consumer can fetch. If that happens, the consumer can get stuck trying to fetch a large message on a certain partition. - """ + """, ), ] = 1 * 1024 * 1024, auto_offset_reset: Annotated[ @@ -702,7 +698,7 @@ def subscriber( * `earliest` will move to the oldest available message * `latest` will move to the most recent * `none` will raise an exception so you can handle this case - """ + """, ), ] = "latest", auto_commit: Annotated[ @@ -711,7 +707,7 @@ def subscriber( """ If `True` the consumer's offset will be periodically committed in the background. - """ + """, ), ] = True, auto_commit_interval_ms: Annotated[ @@ -719,7 +715,7 @@ def subscriber( Doc( """ Milliseconds between automatic - offset commits, if `auto_commit` is `True`.""" + offset commits, if `auto_commit` is `True`.""", ), ] = 5 * 1000, check_crcs: Annotated[ @@ -730,7 +726,7 @@ def subscriber( consumed. This ensures no on-the-wire or on-disk corruption to the messages occurred. This check adds some overhead, so it may be disabled in cases seeking extreme performance. - """ + """, ), ] = True, partition_assignment_strategy: Annotated[ @@ -746,7 +742,7 @@ def subscriber( one. The coordinator will choose the old assignment strategy until all members have been updated. Then it will choose the new strategy. - """ + """, ), ] = (RoundRobinPartitionAssignor,), max_poll_interval_ms: Annotated[ @@ -759,7 +755,7 @@ def subscriber( rebalance in order to reassign the partitions to another consumer group member. If API methods block waiting for messages, that time does not count against this timeout. - """ + """, ), ] = 5 * 60 * 1000, rebalance_timeout_ms: Annotated[ @@ -773,7 +769,7 @@ def subscriber( decouple this setting to allow finer tuning by users that use `ConsumerRebalanceListener` to delay rebalacing. Defaults to ``session_timeout_ms`` - """ + """, ), ] = None, session_timeout_ms: Annotated[ @@ -788,7 +784,7 @@ def subscriber( group and trigger a rebalance. The allowed range is configured with the **broker** configuration properties `group.min.session.timeout.ms` and `group.max.session.timeout.ms`. - """ + """, ), ] = 10 * 1000, heartbeat_interval_ms: Annotated[ @@ -804,7 +800,7 @@ def subscriber( should be set no higher than 1/3 of that value. It can be adjusted even lower to control the expected time for normal rebalances. - """ + """, ), ] = 3 * 1000, consumer_timeout_ms: Annotated[ @@ -814,7 +810,7 @@ def subscriber( Maximum wait timeout for background fetching routine. Mostly defines how fast the system will see rebalance and request new data for new partitions. - """ + """, ), ] = 200, max_poll_records: Annotated[ @@ -823,7 +819,7 @@ def subscriber( """ The maximum number of records returned in a single call by batch consumer. Has no limit by default. - """ + """, ), ] = None, exclude_internal_topics: Annotated[ @@ -834,7 +830,7 @@ def subscriber( (such as offsets) should be exposed to the consumer. If set to True the only way to receive records from an internal topic is subscribing to it. - """ + """, ), ] = True, isolation_level: Annotated[ @@ -864,7 +860,7 @@ def subscriber( to the high watermark when there are in flight transactions. Further, when in `read_committed` the seek_to_end method will return the LSO. See method docs below. - """ + """, ), ] = "read_uncommitted", batch_timeout_ms: Annotated[ @@ -875,7 +871,7 @@ def subscriber( data is not available in the buffer. If 0, returns immediately with any records that are available currently in the buffer, else returns empty. - """ + """, ), ] = 200, max_records: Annotated[ @@ -911,7 +907,7 @@ def subscriber( to subscribe. It is guaranteed, however, that the partitions revoked/assigned through this interface are from topics subscribed in this call. - """ + """, ), ] = None, pattern: Annotated[ @@ -919,7 +915,7 @@ def subscriber( Doc( """ Pattern to match available topics. You must provide either topics or pattern, but not both. - """ + """, ), ] = None, partitions: Annotated[ @@ -928,7 +924,7 @@ def subscriber( """ An explicit partitions list to assign. You can't use 'topics' and 'partitions' in the same time. - """ + """, ), ] = (), # broker args @@ -959,7 +955,7 @@ def subscriber( no_reply: Annotated[ bool, Doc( - "Whether to disable **FastStream** RPC and Reply To auto responses or not." + "Whether to disable **FastStream** RPC and Reply To auto responses or not.", ), ] = False, # Specification information @@ -971,7 +967,7 @@ def subscriber( Optional[str], Doc( "Specification subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -1010,7 +1006,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). - """ + """, ), ] = Default(None), response_model_include: Annotated[ @@ -1022,7 +1018,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = None, response_model_exclude: Annotated[ @@ -1034,7 +1030,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = None, response_model_by_alias: Annotated[ @@ -1046,7 +1042,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = True, response_model_exclude_unset: Annotated[ @@ -1064,7 +1060,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ + """, ), ] = False, response_model_exclude_defaults: Annotated[ @@ -1081,7 +1077,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ + """, ), ] = False, response_model_exclude_none: Annotated[ @@ -1098,7 +1094,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). - """ + """, ), ] = False, ) -> "SpecificationDefaultSubscriber": ... @@ -1115,21 +1111,21 @@ def subscriber( partition assignment (if enabled), and to use for fetching and committing offsets. If `None`, auto-partition assignment (via group coordinator) and offset commits are disabled. - """ + """, ), ] = None, key_deserializer: Annotated[ Optional[Callable[[bytes], Any]], Doc( "Any callable that takes a raw message `bytes` " - "key and returns a deserialized one." + "key and returns a deserialized one.", ), ] = None, value_deserializer: Annotated[ Optional[Callable[[bytes], Any]], Doc( "Any callable that takes a raw message `bytes` " - "value and returns a deserialized value." + "value and returns a deserialized value.", ), ] = None, fetch_max_bytes: Annotated[ @@ -1144,7 +1140,7 @@ def subscriber( performs fetches to multiple brokers in parallel so memory usage will depend on the number of brokers containing partitions for the topic. - """ + """, ), ] = 50 * 1024 * 1024, fetch_min_bytes: Annotated[ @@ -1154,7 +1150,7 @@ def subscriber( Minimum amount of data the server should return for a fetch request, otherwise wait up to `fetch_max_wait_ms` for more data to accumulate. - """ + """, ), ] = 1, fetch_max_wait_ms: Annotated[ @@ -1165,7 +1161,7 @@ def subscriber( the server will block before answering the fetch request if there isn't sufficient data to immediately satisfy the requirement given by `fetch_min_bytes`. - """ + """, ), ] = 500, max_partition_fetch_bytes: Annotated[ @@ -1180,7 +1176,7 @@ def subscriber( send messages larger than the consumer can fetch. If that happens, the consumer can get stuck trying to fetch a large message on a certain partition. - """ + """, ), ] = 1 * 1024 * 1024, auto_offset_reset: Annotated[ @@ -1192,7 +1188,7 @@ def subscriber( * `earliest` will move to the oldest available message * `latest` will move to the most recent * `none` will raise an exception so you can handle this case - """ + """, ), ] = "latest", auto_commit: Annotated[ @@ -1201,7 +1197,7 @@ def subscriber( """ If `True` the consumer's offset will be periodically committed in the background. - """ + """, ), ] = True, auto_commit_interval_ms: Annotated[ @@ -1209,7 +1205,7 @@ def subscriber( Doc( """ Milliseconds between automatic - offset commits, if `auto_commit` is `True`.""" + offset commits, if `auto_commit` is `True`.""", ), ] = 5 * 1000, check_crcs: Annotated[ @@ -1220,7 +1216,7 @@ def subscriber( consumed. This ensures no on-the-wire or on-disk corruption to the messages occurred. This check adds some overhead, so it may be disabled in cases seeking extreme performance. - """ + """, ), ] = True, partition_assignment_strategy: Annotated[ @@ -1236,7 +1232,7 @@ def subscriber( one. The coordinator will choose the old assignment strategy until all members have been updated. Then it will choose the new strategy. - """ + """, ), ] = (RoundRobinPartitionAssignor,), max_poll_interval_ms: Annotated[ @@ -1249,7 +1245,7 @@ def subscriber( rebalance in order to reassign the partitions to another consumer group member. If API methods block waiting for messages, that time does not count against this timeout. - """ + """, ), ] = 5 * 60 * 1000, rebalance_timeout_ms: Annotated[ @@ -1263,7 +1259,7 @@ def subscriber( decouple this setting to allow finer tuning by users that use `ConsumerRebalanceListener` to delay rebalacing. Defaults to ``session_timeout_ms`` - """ + """, ), ] = None, session_timeout_ms: Annotated[ @@ -1278,7 +1274,7 @@ def subscriber( group and trigger a rebalance. The allowed range is configured with the **broker** configuration properties `group.min.session.timeout.ms` and `group.max.session.timeout.ms`. - """ + """, ), ] = 10 * 1000, heartbeat_interval_ms: Annotated[ @@ -1294,7 +1290,7 @@ def subscriber( should be set no higher than 1/3 of that value. It can be adjusted even lower to control the expected time for normal rebalances. - """ + """, ), ] = 3 * 1000, consumer_timeout_ms: Annotated[ @@ -1304,7 +1300,7 @@ def subscriber( Maximum wait timeout for background fetching routine. Mostly defines how fast the system will see rebalance and request new data for new partitions. - """ + """, ), ] = 200, max_poll_records: Annotated[ @@ -1313,7 +1309,7 @@ def subscriber( """ The maximum number of records returned in a single call by batch consumer. Has no limit by default. - """ + """, ), ] = None, exclude_internal_topics: Annotated[ @@ -1324,7 +1320,7 @@ def subscriber( (such as offsets) should be exposed to the consumer. If set to True the only way to receive records from an internal topic is subscribing to it. - """ + """, ), ] = True, isolation_level: Annotated[ @@ -1354,7 +1350,7 @@ def subscriber( to the high watermark when there are in flight transactions. Further, when in `read_committed` the seek_to_end method will return the LSO. See method docs below. - """ + """, ), ] = "read_uncommitted", batch_timeout_ms: Annotated[ @@ -1365,7 +1361,7 @@ def subscriber( data is not available in the buffer. If 0, returns immediately with any records that are available currently in the buffer, else returns empty. - """ + """, ), ] = 200, max_records: Annotated[ @@ -1401,7 +1397,7 @@ def subscriber( to subscribe. It is guaranteed, however, that the partitions revoked/assigned through this interface are from topics subscribed in this call. - """ + """, ), ] = None, pattern: Annotated[ @@ -1409,7 +1405,7 @@ def subscriber( Doc( """ Pattern to match available topics. You must provide either topics or pattern, but not both. - """ + """, ), ] = None, partitions: Annotated[ @@ -1418,7 +1414,7 @@ def subscriber( """ An explicit partitions list to assign. You can't use 'topics' and 'partitions' in the same time. - """ + """, ), ] = (), # broker args @@ -1449,7 +1445,7 @@ def subscriber( no_reply: Annotated[ bool, Doc( - "Whether to disable **FastStream** RPC and Reply To auto responses or not." + "Whether to disable **FastStream** RPC and Reply To auto responses or not.", ), ] = False, # Specification information @@ -1461,7 +1457,7 @@ def subscriber( Optional[str], Doc( "Specification subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -1500,7 +1496,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). - """ + """, ), ] = Default(None), response_model_include: Annotated[ @@ -1512,7 +1508,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = None, response_model_exclude: Annotated[ @@ -1524,7 +1520,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = None, response_model_by_alias: Annotated[ @@ -1536,7 +1532,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = True, response_model_exclude_unset: Annotated[ @@ -1554,7 +1550,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ + """, ), ] = False, response_model_exclude_defaults: Annotated[ @@ -1571,7 +1567,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ + """, ), ] = False, response_model_exclude_none: Annotated[ @@ -1588,7 +1584,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). - """ + """, ), ] = False, ) -> "SpecificationBatchSubscriber": ... @@ -1605,21 +1601,21 @@ def subscriber( partition assignment (if enabled), and to use for fetching and committing offsets. If `None`, auto-partition assignment (via group coordinator) and offset commits are disabled. - """ + """, ), ] = None, key_deserializer: Annotated[ Optional[Callable[[bytes], Any]], Doc( "Any callable that takes a raw message `bytes` " - "key and returns a deserialized one." + "key and returns a deserialized one.", ), ] = None, value_deserializer: Annotated[ Optional[Callable[[bytes], Any]], Doc( "Any callable that takes a raw message `bytes` " - "value and returns a deserialized value." + "value and returns a deserialized value.", ), ] = None, fetch_max_bytes: Annotated[ @@ -1634,7 +1630,7 @@ def subscriber( performs fetches to multiple brokers in parallel so memory usage will depend on the number of brokers containing partitions for the topic. - """ + """, ), ] = 50 * 1024 * 1024, fetch_min_bytes: Annotated[ @@ -1644,7 +1640,7 @@ def subscriber( Minimum amount of data the server should return for a fetch request, otherwise wait up to `fetch_max_wait_ms` for more data to accumulate. - """ + """, ), ] = 1, fetch_max_wait_ms: Annotated[ @@ -1655,7 +1651,7 @@ def subscriber( the server will block before answering the fetch request if there isn't sufficient data to immediately satisfy the requirement given by `fetch_min_bytes`. - """ + """, ), ] = 500, max_partition_fetch_bytes: Annotated[ @@ -1670,7 +1666,7 @@ def subscriber( send messages larger than the consumer can fetch. If that happens, the consumer can get stuck trying to fetch a large message on a certain partition. - """ + """, ), ] = 1 * 1024 * 1024, auto_offset_reset: Annotated[ @@ -1682,7 +1678,7 @@ def subscriber( * `earliest` will move to the oldest available message * `latest` will move to the most recent * `none` will raise an exception so you can handle this case - """ + """, ), ] = "latest", auto_commit: Annotated[ @@ -1691,7 +1687,7 @@ def subscriber( """ If `True` the consumer's offset will be periodically committed in the background. - """ + """, ), ] = True, auto_commit_interval_ms: Annotated[ @@ -1699,7 +1695,7 @@ def subscriber( Doc( """ Milliseconds between automatic - offset commits, if `auto_commit` is `True`.""" + offset commits, if `auto_commit` is `True`.""", ), ] = 5 * 1000, check_crcs: Annotated[ @@ -1710,7 +1706,7 @@ def subscriber( consumed. This ensures no on-the-wire or on-disk corruption to the messages occurred. This check adds some overhead, so it may be disabled in cases seeking extreme performance. - """ + """, ), ] = True, partition_assignment_strategy: Annotated[ @@ -1726,7 +1722,7 @@ def subscriber( one. The coordinator will choose the old assignment strategy until all members have been updated. Then it will choose the new strategy. - """ + """, ), ] = (RoundRobinPartitionAssignor,), max_poll_interval_ms: Annotated[ @@ -1739,7 +1735,7 @@ def subscriber( rebalance in order to reassign the partitions to another consumer group member. If API methods block waiting for messages, that time does not count against this timeout. - """ + """, ), ] = 5 * 60 * 1000, rebalance_timeout_ms: Annotated[ @@ -1753,7 +1749,7 @@ def subscriber( decouple this setting to allow finer tuning by users that use `ConsumerRebalanceListener` to delay rebalacing. Defaults to ``session_timeout_ms`` - """ + """, ), ] = None, session_timeout_ms: Annotated[ @@ -1768,7 +1764,7 @@ def subscriber( group and trigger a rebalance. The allowed range is configured with the **broker** configuration properties `group.min.session.timeout.ms` and `group.max.session.timeout.ms`. - """ + """, ), ] = 10 * 1000, heartbeat_interval_ms: Annotated[ @@ -1784,7 +1780,7 @@ def subscriber( should be set no higher than 1/3 of that value. It can be adjusted even lower to control the expected time for normal rebalances. - """ + """, ), ] = 3 * 1000, consumer_timeout_ms: Annotated[ @@ -1794,7 +1790,7 @@ def subscriber( Maximum wait timeout for background fetching routine. Mostly defines how fast the system will see rebalance and request new data for new partitions. - """ + """, ), ] = 200, max_poll_records: Annotated[ @@ -1803,7 +1799,7 @@ def subscriber( """ The maximum number of records returned in a single call by batch consumer. Has no limit by default. - """ + """, ), ] = None, exclude_internal_topics: Annotated[ @@ -1814,7 +1810,7 @@ def subscriber( (such as offsets) should be exposed to the consumer. If set to True the only way to receive records from an internal topic is subscribing to it. - """ + """, ), ] = True, isolation_level: Annotated[ @@ -1844,7 +1840,7 @@ def subscriber( to the high watermark when there are in flight transactions. Further, when in `read_committed` the seek_to_end method will return the LSO. See method docs below. - """ + """, ), ] = "read_uncommitted", batch_timeout_ms: Annotated[ @@ -1855,7 +1851,7 @@ def subscriber( data is not available in the buffer. If 0, returns immediately with any records that are available currently in the buffer, else returns empty. - """ + """, ), ] = 200, max_records: Annotated[ @@ -1891,7 +1887,7 @@ def subscriber( to subscribe. It is guaranteed, however, that the partitions revoked/assigned through this interface are from topics subscribed in this call. - """ + """, ), ] = None, pattern: Annotated[ @@ -1899,7 +1895,7 @@ def subscriber( Doc( """ Pattern to match available topics. You must provide either topics or pattern, but not both. - """ + """, ), ] = None, partitions: Annotated[ @@ -1908,7 +1904,7 @@ def subscriber( """ An explicit partitions list to assign. You can't use 'topics' and 'partitions' in the same time. - """ + """, ), ] = (), # broker args @@ -1939,7 +1935,7 @@ def subscriber( no_reply: Annotated[ bool, Doc( - "Whether to disable **FastStream** RPC and Reply To auto responses or not." + "Whether to disable **FastStream** RPC and Reply To auto responses or not.", ), ] = False, # Specification information @@ -1951,7 +1947,7 @@ def subscriber( Optional[str], Doc( "Specification subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -1990,7 +1986,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). - """ + """, ), ] = Default(None), response_model_include: Annotated[ @@ -2002,7 +1998,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = None, response_model_exclude: Annotated[ @@ -2014,7 +2010,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = None, response_model_by_alias: Annotated[ @@ -2026,7 +2022,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = True, response_model_exclude_unset: Annotated[ @@ -2044,7 +2040,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ + """, ), ] = False, response_model_exclude_defaults: Annotated[ @@ -2061,7 +2057,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ + """, ), ] = False, response_model_exclude_none: Annotated[ @@ -2078,7 +2074,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). - """ + """, ), ] = False, ) -> Union[ @@ -2098,21 +2094,21 @@ def subscriber( partition assignment (if enabled), and to use for fetching and committing offsets. If `None`, auto-partition assignment (via group coordinator) and offset commits are disabled. - """ + """, ), ] = None, key_deserializer: Annotated[ Optional[Callable[[bytes], Any]], Doc( "Any callable that takes a raw message `bytes` " - "key and returns a deserialized one." + "key and returns a deserialized one.", ), ] = None, value_deserializer: Annotated[ Optional[Callable[[bytes], Any]], Doc( "Any callable that takes a raw message `bytes` " - "value and returns a deserialized value." + "value and returns a deserialized value.", ), ] = None, fetch_max_bytes: Annotated[ @@ -2127,7 +2123,7 @@ def subscriber( performs fetches to multiple brokers in parallel so memory usage will depend on the number of brokers containing partitions for the topic. - """ + """, ), ] = 50 * 1024 * 1024, fetch_min_bytes: Annotated[ @@ -2137,7 +2133,7 @@ def subscriber( Minimum amount of data the server should return for a fetch request, otherwise wait up to `fetch_max_wait_ms` for more data to accumulate. - """ + """, ), ] = 1, fetch_max_wait_ms: Annotated[ @@ -2148,7 +2144,7 @@ def subscriber( the server will block before answering the fetch request if there isn't sufficient data to immediately satisfy the requirement given by `fetch_min_bytes`. - """ + """, ), ] = 500, max_partition_fetch_bytes: Annotated[ @@ -2163,7 +2159,7 @@ def subscriber( send messages larger than the consumer can fetch. If that happens, the consumer can get stuck trying to fetch a large message on a certain partition. - """ + """, ), ] = 1 * 1024 * 1024, auto_offset_reset: Annotated[ @@ -2175,7 +2171,7 @@ def subscriber( * `earliest` will move to the oldest available message * `latest` will move to the most recent * `none` will raise an exception so you can handle this case - """ + """, ), ] = "latest", auto_commit: Annotated[ @@ -2184,7 +2180,7 @@ def subscriber( """ If `True` the consumer's offset will be periodically committed in the background. - """ + """, ), ] = True, auto_commit_interval_ms: Annotated[ @@ -2192,7 +2188,7 @@ def subscriber( Doc( """ Milliseconds between automatic - offset commits, if `auto_commit` is `True`.""" + offset commits, if `auto_commit` is `True`.""", ), ] = 5 * 1000, check_crcs: Annotated[ @@ -2203,7 +2199,7 @@ def subscriber( consumed. This ensures no on-the-wire or on-disk corruption to the messages occurred. This check adds some overhead, so it may be disabled in cases seeking extreme performance. - """ + """, ), ] = True, partition_assignment_strategy: Annotated[ @@ -2219,7 +2215,7 @@ def subscriber( one. The coordinator will choose the old assignment strategy until all members have been updated. Then it will choose the new strategy. - """ + """, ), ] = (RoundRobinPartitionAssignor,), max_poll_interval_ms: Annotated[ @@ -2232,7 +2228,7 @@ def subscriber( rebalance in order to reassign the partitions to another consumer group member. If API methods block waiting for messages, that time does not count against this timeout. - """ + """, ), ] = 5 * 60 * 1000, rebalance_timeout_ms: Annotated[ @@ -2246,7 +2242,7 @@ def subscriber( decouple this setting to allow finer tuning by users that use `ConsumerRebalanceListener` to delay rebalacing. Defaults to ``session_timeout_ms`` - """ + """, ), ] = None, session_timeout_ms: Annotated[ @@ -2261,7 +2257,7 @@ def subscriber( group and trigger a rebalance. The allowed range is configured with the **broker** configuration properties `group.min.session.timeout.ms` and `group.max.session.timeout.ms`. - """ + """, ), ] = 10 * 1000, heartbeat_interval_ms: Annotated[ @@ -2277,7 +2273,7 @@ def subscriber( should be set no higher than 1/3 of that value. It can be adjusted even lower to control the expected time for normal rebalances. - """ + """, ), ] = 3 * 1000, consumer_timeout_ms: Annotated[ @@ -2287,7 +2283,7 @@ def subscriber( Maximum wait timeout for background fetching routine. Mostly defines how fast the system will see rebalance and request new data for new partitions. - """ + """, ), ] = 200, max_poll_records: Annotated[ @@ -2296,7 +2292,7 @@ def subscriber( """ The maximum number of records returned in a single call by batch consumer. Has no limit by default. - """ + """, ), ] = None, exclude_internal_topics: Annotated[ @@ -2307,7 +2303,7 @@ def subscriber( (such as offsets) should be exposed to the consumer. If set to True the only way to receive records from an internal topic is subscribing to it. - """ + """, ), ] = True, isolation_level: Annotated[ @@ -2337,7 +2333,7 @@ def subscriber( to the high watermark when there are in flight transactions. Further, when in `read_committed` the seek_to_end method will return the LSO. See method docs below. - """ + """, ), ] = "read_uncommitted", batch_timeout_ms: Annotated[ @@ -2348,7 +2344,7 @@ def subscriber( data is not available in the buffer. If 0, returns immediately with any records that are available currently in the buffer, else returns empty. - """ + """, ), ] = 200, max_records: Annotated[ @@ -2384,7 +2380,7 @@ def subscriber( to subscribe. It is guaranteed, however, that the partitions revoked/assigned through this interface are from topics subscribed in this call. - """ + """, ), ] = None, pattern: Annotated[ @@ -2392,7 +2388,7 @@ def subscriber( Doc( """ Pattern to match available topics. You must provide either topics or pattern, but not both. - """ + """, ), ] = None, partitions: Annotated[ @@ -2401,7 +2397,7 @@ def subscriber( """ An explicit partitions list to assign. You can't use 'topics' and 'partitions' in the same time. - """ + """, ), ] = (), # broker args @@ -2432,7 +2428,7 @@ def subscriber( no_reply: Annotated[ bool, Doc( - "Whether to disable **FastStream** RPC and Reply To auto responses or not." + "Whether to disable **FastStream** RPC and Reply To auto responses or not.", ), ] = False, # Specification information @@ -2444,7 +2440,7 @@ def subscriber( Optional[str], Doc( "Specification subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -2483,7 +2479,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). - """ + """, ), ] = Default(None), response_model_include: Annotated[ @@ -2495,7 +2491,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = None, response_model_exclude: Annotated[ @@ -2507,7 +2503,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = None, response_model_by_alias: Annotated[ @@ -2519,7 +2515,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = True, response_model_exclude_unset: Annotated[ @@ -2537,7 +2533,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ + """, ), ] = False, response_model_exclude_defaults: Annotated[ @@ -2554,7 +2550,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ + """, ), ] = False, response_model_exclude_none: Annotated[ @@ -2571,7 +2567,7 @@ def subscriber( Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). - """ + """, ), ] = False, ) -> Union[ @@ -2629,8 +2625,7 @@ def subscriber( if batch: return cast("SpecificationBatchSubscriber", subscriber) - else: - return cast("SpecificationDefaultSubscriber", subscriber) + return cast("SpecificationDefaultSubscriber", subscriber) @overload # type: ignore[override] def publisher( @@ -2651,7 +2646,7 @@ def publisher( partition (but if key is `None`, partition is chosen randomly). Must be type `bytes`, or be serializable to bytes via configured `key_serializer`. - """ + """, ), ] = None, partition: Annotated[ @@ -2660,15 +2655,15 @@ def publisher( """ Specify a partition. If not set, the partition will be selected using the configured `partitioner`. - """ + """, ), ] = None, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc( "Message headers to store metainformation. " "**content-type** and **correlation_id** will be set automatically by framework anyway. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, reply_to: Annotated[ @@ -2697,7 +2692,7 @@ def publisher( Optional[Any], Doc( "Specification publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ @@ -2725,7 +2720,7 @@ def publisher( partition (but if key is `None`, partition is chosen randomly). Must be type `bytes`, or be serializable to bytes via configured `key_serializer`. - """ + """, ), ] = None, partition: Annotated[ @@ -2734,15 +2729,15 @@ def publisher( """ Specify a partition. If not set, the partition will be selected using the configured `partitioner`. - """ + """, ), ] = None, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc( "Message headers to store metainformation. " "**content-type** and **correlation_id** will be set automatically by framework anyway. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, reply_to: Annotated[ @@ -2771,7 +2766,7 @@ def publisher( Optional[Any], Doc( "Specification publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ @@ -2799,7 +2794,7 @@ def publisher( partition (but if key is `None`, partition is chosen randomly). Must be type `bytes`, or be serializable to bytes via configured `key_serializer`. - """ + """, ), ] = None, partition: Annotated[ @@ -2808,15 +2803,15 @@ def publisher( """ Specify a partition. If not set, the partition will be selected using the configured `partitioner`. - """ + """, ), ] = None, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc( "Message headers to store metainformation. " "**content-type** and **correlation_id** will be set automatically by framework anyway. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, reply_to: Annotated[ @@ -2845,7 +2840,7 @@ def publisher( Optional[Any], Doc( "Specification publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ @@ -2876,7 +2871,7 @@ def publisher( partition (but if key is `None`, partition is chosen randomly). Must be type `bytes`, or be serializable to bytes via configured `key_serializer`. - """ + """, ), ] = None, partition: Annotated[ @@ -2885,15 +2880,15 @@ def publisher( """ Specify a partition. If not set, the partition will be selected using the configured `partitioner`. - """ + """, ), ] = None, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc( "Message headers to store metainformation. " "**content-type** and **correlation_id** will be set automatically by framework anyway. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, reply_to: Annotated[ @@ -2922,7 +2917,7 @@ def publisher( Optional[Any], Doc( "Specification publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ diff --git a/faststream/kafka/message.py b/faststream/kafka/message.py index 1bc750a77c..aa0eeefae9 100644 --- a/faststream/kafka/message.py +++ b/faststream/kafka/message.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Any, Protocol, Tuple, Union +from typing import TYPE_CHECKING, Any, Protocol, Union from aiokafka import TopicPartition as AIOKafkaTopicPartition @@ -42,9 +42,9 @@ class KafkaMessage( StreamMessage[ Union[ "ConsumerRecord", - Tuple["ConsumerRecord", ...], + tuple["ConsumerRecord", ...], ] - ] + ], ): """Represents a Kafka message in the FastStream framework. diff --git a/faststream/kafka/opentelemetry/provider.py b/faststream/kafka/opentelemetry/provider.py index 9a2d3eec45..f9a43f54f6 100644 --- a/faststream/kafka/opentelemetry/provider.py +++ b/faststream/kafka/opentelemetry/provider.py @@ -1,4 +1,5 @@ -from typing import TYPE_CHECKING, Sequence, Tuple, Union, cast +from collections.abc import Sequence +from typing import TYPE_CHECKING, Union, cast from opentelemetry.semconv.trace import SpanAttributes @@ -45,7 +46,7 @@ def get_publish_destination_name( class KafkaTelemetrySettingsProvider( - BaseKafkaTelemetrySettingsProvider["ConsumerRecord"] + BaseKafkaTelemetrySettingsProvider["ConsumerRecord"], ): def get_consume_attrs_from_message( self, @@ -74,31 +75,29 @@ def get_consume_destination_name( class BatchKafkaTelemetrySettingsProvider( - BaseKafkaTelemetrySettingsProvider[Tuple["ConsumerRecord", ...]] + BaseKafkaTelemetrySettingsProvider[tuple["ConsumerRecord", ...]], ): def get_consume_attrs_from_message( self, - msg: "StreamMessage[Tuple[ConsumerRecord, ...]]", + msg: "StreamMessage[tuple[ConsumerRecord, ...]]", ) -> "AnyDict": raw_message = msg.raw_message[0] - attrs = { + return { SpanAttributes.MESSAGING_SYSTEM: self.messaging_system, SpanAttributes.MESSAGING_MESSAGE_ID: msg.message_id, SpanAttributes.MESSAGING_MESSAGE_CONVERSATION_ID: msg.correlation_id, SpanAttributes.MESSAGING_MESSAGE_PAYLOAD_SIZE_BYTES: len( - bytearray().join(cast(Sequence[bytes], msg.body)) + bytearray().join(cast(Sequence[bytes], msg.body)), ), SpanAttributes.MESSAGING_BATCH_MESSAGE_COUNT: len(msg.raw_message), SpanAttributes.MESSAGING_KAFKA_DESTINATION_PARTITION: raw_message.partition, MESSAGING_DESTINATION_PUBLISH_NAME: raw_message.topic, } - return attrs - def get_consume_destination_name( self, - msg: "StreamMessage[Tuple[ConsumerRecord, ...]]", + msg: "StreamMessage[tuple[ConsumerRecord, ...]]", ) -> str: return cast(str, msg.raw_message[0].topic) @@ -111,5 +110,4 @@ def telemetry_attributes_provider_factory( ]: if isinstance(msg, Sequence): return BatchKafkaTelemetrySettingsProvider() - else: - return KafkaTelemetrySettingsProvider() + return KafkaTelemetrySettingsProvider() diff --git a/faststream/kafka/parser.py b/faststream/kafka/parser.py index c4ff44c0f2..c4ce947a34 100644 --- a/faststream/kafka/parser.py +++ b/faststream/kafka/parser.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Type, cast +from typing import TYPE_CHECKING, Any, Optional, cast from faststream._internal.context.repository import context from faststream.kafka.message import FAKE_CONSUMER, KafkaMessage @@ -19,7 +19,7 @@ class AioKafkaParser: def __init__( self, - msg_class: Type[KafkaMessage], + msg_class: type[KafkaMessage], regex: Optional["Pattern[str]"], ) -> None: self.msg_class = msg_class @@ -52,21 +52,20 @@ async def decode_message( """Decodes a message.""" return decode_message(msg) - def get_path(self, topic: str) -> Dict[str, str]: + def get_path(self, topic: str) -> dict[str, str]: if self.regex and (match := self.regex.match(topic)): return match.groupdict() - else: - return {} + return {} class AioKafkaBatchParser(AioKafkaParser): async def parse_message( self, - message: Tuple["ConsumerRecord", ...], - ) -> "StreamMessage[Tuple[ConsumerRecord, ...]]": + message: tuple["ConsumerRecord", ...], + ) -> "StreamMessage[tuple[ConsumerRecord, ...]]": """Parses a batch of messages from a Kafka consumer.""" - body: List[Any] = [] - batch_headers: List[Dict[str, str]] = [] + body: list[Any] = [] + batch_headers: list[dict[str, str]] = [] first = message[0] last = message[-1] @@ -94,7 +93,7 @@ async def parse_message( async def decode_message( self, - msg: "StreamMessage[Tuple[ConsumerRecord, ...]]", + msg: "StreamMessage[tuple[ConsumerRecord, ...]]", ) -> "DecodedMessage": """Decode a batch of messages.""" # super() should be here due python can't find it in comprehension diff --git a/faststream/kafka/publisher/producer.py b/faststream/kafka/publisher/producer.py index 0b18adde67..93441fb2bd 100644 --- a/faststream/kafka/publisher/producer.py +++ b/faststream/kafka/publisher/producer.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Any, Dict, Optional, Union +from typing import TYPE_CHECKING, Any, Optional, Union from typing_extensions import override @@ -45,7 +45,7 @@ async def publish( # type: ignore[override] key: Union[bytes, Any, None] = None, partition: Optional[int] = None, timestamp_ms: Optional[int] = None, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, reply_to: str = "", no_confirm: bool = False, ) -> None: @@ -85,7 +85,7 @@ async def publish_batch( topic: str, partition: Optional[int] = None, timestamp_ms: Optional[int] = None, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, reply_to: str = "", no_confirm: bool = False, ) -> None: @@ -124,6 +124,7 @@ async def publish_batch( @override async def request(self, *args: Any, **kwargs: Any) -> Optional[Any]: + msg = "Kafka doesn't support `request` method without test client." raise OperationForbiddenError( - "Kafka doesn't support `request` method without test client." + msg, ) diff --git a/faststream/kafka/publisher/publisher.py b/faststream/kafka/publisher/publisher.py index e84ca8ba41..db575aac29 100644 --- a/faststream/kafka/publisher/publisher.py +++ b/faststream/kafka/publisher/publisher.py @@ -1,11 +1,9 @@ +from collections.abc import Iterable from typing import ( TYPE_CHECKING, Any, - Dict, - Iterable, Literal, Optional, - Tuple, Union, overload, ) @@ -37,7 +35,7 @@ class SpecificationPublisher(LogicPublisher[MsgType]): def get_name(self) -> str: return f"{self.topic}:Publisher" - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> dict[str, Channel]: payloads = self.get_payloads() return { @@ -48,12 +46,12 @@ def get_schema(self) -> Dict[str, Channel]: title=f"{self.name}:Message", payload=resolve_payloads(payloads, "Publisher"), correlationId=CorrelationId( - location="$message.header#/correlation_id" + location="$message.header#/correlation_id", ), ), ), bindings=ChannelBinding(kafka=kafka.ChannelBinding(topic=self.topic)), - ) + ), } @overload # type: ignore[override] @@ -64,10 +62,10 @@ def create( key: Optional[bytes], topic: str, partition: Optional[int], - headers: Optional[Dict[str, str]], + headers: Optional[dict[str, str]], reply_to: str, # Publisher args - broker_middlewares: Iterable["BrokerMiddleware[Tuple[ConsumerRecord, ...]]"], + broker_middlewares: Iterable["BrokerMiddleware[tuple[ConsumerRecord, ...]]"], middlewares: Iterable["PublisherMiddleware"], # Specification args schema_: Optional[Any], @@ -84,7 +82,7 @@ def create( key: Optional[bytes], topic: str, partition: Optional[int], - headers: Optional[Dict[str, str]], + headers: Optional[dict[str, str]], reply_to: str, # Publisher args broker_middlewares: Iterable["BrokerMiddleware[ConsumerRecord]"], @@ -104,11 +102,11 @@ def create( key: Optional[bytes], topic: str, partition: Optional[int], - headers: Optional[Dict[str, str]], + headers: Optional[dict[str, str]], reply_to: str, # Publisher args broker_middlewares: Iterable[ - "BrokerMiddleware[Union[Tuple[ConsumerRecord, ...], ConsumerRecord]]" + "BrokerMiddleware[Union[tuple[ConsumerRecord, ...], ConsumerRecord]]" ], middlewares: Iterable["PublisherMiddleware"], # Specification args @@ -129,11 +127,11 @@ def create( key: Optional[bytes], topic: str, partition: Optional[int], - headers: Optional[Dict[str, str]], + headers: Optional[dict[str, str]], reply_to: str, # Publisher args broker_middlewares: Iterable[ - "BrokerMiddleware[Union[Tuple[ConsumerRecord, ...], ConsumerRecord]]" + "BrokerMiddleware[Union[tuple[ConsumerRecord, ...], ConsumerRecord]]" ], middlewares: Iterable["PublisherMiddleware"], # Specification args @@ -147,7 +145,8 @@ def create( ]: if batch: if key: - raise SetupError("You can't setup `key` with batch publisher") + msg = "You can't setup `key` with batch publisher" + raise SetupError(msg) return SpecificationBatchPublisher( topic=topic, @@ -161,26 +160,25 @@ def create( description_=description_, include_in_schema=include_in_schema, ) - else: - return SpecificationDefaultPublisher( - key=key, - # basic args - topic=topic, - partition=partition, - headers=headers, - reply_to=reply_to, - broker_middlewares=broker_middlewares, - middlewares=middlewares, - schema_=schema_, - title_=title_, - description_=description_, - include_in_schema=include_in_schema, - ) + return SpecificationDefaultPublisher( + key=key, + # basic args + topic=topic, + partition=partition, + headers=headers, + reply_to=reply_to, + broker_middlewares=broker_middlewares, + middlewares=middlewares, + schema_=schema_, + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + ) class SpecificationBatchPublisher( BatchPublisher, - SpecificationPublisher[Tuple["ConsumerRecord", ...]], + SpecificationPublisher[tuple["ConsumerRecord", ...]], ): pass diff --git a/faststream/kafka/publisher/usecase.py b/faststream/kafka/publisher/usecase.py index d7894e9ac1..de0094033e 100644 --- a/faststream/kafka/publisher/usecase.py +++ b/faststream/kafka/publisher/usecase.py @@ -1,20 +1,18 @@ +from collections.abc import Awaitable, Iterable from functools import partial from itertools import chain from typing import ( TYPE_CHECKING, + Annotated, Any, - Awaitable, Callable, - Dict, - Iterable, Optional, - Tuple, Union, cast, ) from aiokafka import ConsumerRecord -from typing_extensions import Annotated, Doc, override +from typing_extensions import Doc, override from faststream._internal.publisher.usecase import PublisherUsecase from faststream._internal.subscriber.utils import process_msg @@ -39,7 +37,7 @@ def __init__( *, topic: str, partition: Optional[int], - headers: Optional[Dict[str, str]], + headers: Optional[dict[str, str]], reply_to: str, # Publisher args broker_middlewares: Iterable["BrokerMiddleware[MsgType]"], @@ -68,7 +66,7 @@ def __init__( self._producer = None def add_prefix(self, prefix: str) -> None: - self.topic = "".join((prefix, self.topic)) + self.topic = f"{prefix}{self.topic}" @override async def request( @@ -93,7 +91,7 @@ async def request( partition (but if key is `None`, partition is chosen randomly). Must be type `bytes`, or be serializable to bytes via configured `key_serializer`. - """ + """, ), ] = None, partition: Annotated[ @@ -102,7 +100,7 @@ async def request( """ Specify a partition. If not set, the partition will be selected using the configured `partitioner`. - """ + """, ), ] = None, timestamp_ms: Annotated[ @@ -111,18 +109,18 @@ async def request( """ Epoch milliseconds (from Jan 1 1970 UTC) to use as the message timestamp. Defaults to current time. - """ + """, ), ] = None, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc("Message headers to store metainformation."), ] = None, correlation_id: Annotated[ Optional[str], Doc( "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages." + "**correlation_id** is a useful option to trace messages.", ), ] = None, timeout: Annotated[ @@ -180,7 +178,7 @@ def __init__( key: Optional[bytes], topic: str, partition: Optional[int], - headers: Optional[Dict[str, str]], + headers: Optional[dict[str, str]], reply_to: str, # Publisher args broker_middlewares: Iterable["BrokerMiddleware[ConsumerRecord]"], @@ -231,7 +229,7 @@ async def publish( partition (but if key is `None`, partition is chosen randomly). Must be type `bytes`, or be serializable to bytes via configured `key_serializer`. - """ + """, ), ] = None, partition: Annotated[ @@ -240,7 +238,7 @@ async def publish( """ Specify a partition. If not set, the partition will be selected using the configured `partitioner`. - """ + """, ), ] = None, timestamp_ms: Annotated[ @@ -249,18 +247,18 @@ async def publish( """ Epoch milliseconds (from Jan 1 1970 UTC) to use as the message timestamp. Defaults to current time. - """ + """, ), ] = None, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc("Message headers to store metainformation."), ] = None, correlation_id: Annotated[ Optional[str], Doc( "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages." + "**correlation_id** is a useful option to trace messages.", ), ] = None, reply_to: Annotated[ @@ -332,7 +330,7 @@ async def request( partition (but if key is `None`, partition is chosen randomly). Must be type `bytes`, or be serializable to bytes via configured `key_serializer`. - """ + """, ), ] = None, partition: Annotated[ @@ -341,7 +339,7 @@ async def request( """ Specify a partition. If not set, the partition will be selected using the configured `partitioner`. - """ + """, ), ] = None, timestamp_ms: Annotated[ @@ -350,18 +348,18 @@ async def request( """ Epoch milliseconds (from Jan 1 1970 UTC) to use as the message timestamp. Defaults to current time. - """ + """, ), ] = None, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc("Message headers to store metainformation."), ] = None, correlation_id: Annotated[ Optional[str], Doc( "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages." + "**correlation_id** is a useful option to trace messages.", ), ] = None, timeout: Annotated[ @@ -387,7 +385,7 @@ async def request( ) -class BatchPublisher(LogicPublisher[Tuple["ConsumerRecord", ...]]): +class BatchPublisher(LogicPublisher[tuple["ConsumerRecord", ...]]): @override async def publish( self, @@ -409,7 +407,7 @@ async def publish( """ Specify a partition. If not set, the partition will be selected using the configured `partitioner`. - """ + """, ), ] = None, timestamp_ms: Annotated[ @@ -418,11 +416,11 @@ async def publish( """ Epoch milliseconds (from Jan 1 1970 UTC) to use as the message timestamp. Defaults to current time. - """ + """, ), ] = None, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc("Messages headers to store metainformation."), ] = None, reply_to: Annotated[ @@ -433,7 +431,7 @@ async def publish( Optional[str], Doc( "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages." + "**correlation_id** is a useful option to trace messages.", ), ] = None, no_confirm: Annotated[ diff --git a/faststream/kafka/response.py b/faststream/kafka/response.py index 353ac8251a..3d04d6ab35 100644 --- a/faststream/kafka/response.py +++ b/faststream/kafka/response.py @@ -29,9 +29,8 @@ def __init__( @override def as_publish_kwargs(self) -> "AnyDict": - publish_options = { + return { **super().as_publish_kwargs(), "timestamp_ms": self.timestamp_ms, "key": self.key, } - return publish_options diff --git a/faststream/kafka/router.py b/faststream/kafka/router.py index f06cd069b5..e79e422e8b 100644 --- a/faststream/kafka/router.py +++ b/faststream/kafka/router.py @@ -1,19 +1,16 @@ +from collections.abc import Awaitable, Iterable, Sequence from typing import ( TYPE_CHECKING, + Annotated, Any, - Awaitable, Callable, - Dict, - Iterable, Literal, Optional, - Sequence, - Tuple, Union, ) from aiokafka.coordinator.assignors.roundrobin import RoundRobinPartitionAssignor -from typing_extensions import Annotated, Doc +from typing_extensions import Doc from faststream._internal.broker.router import ( ArgsContainer, @@ -62,7 +59,7 @@ def __init__( partition (but if key is `None`, partition is chosen randomly). Must be type `bytes`, or be serializable to bytes via configured `key_serializer`. - """ + """, ), ] = None, partition: Annotated[ @@ -71,15 +68,15 @@ def __init__( """ Specify a partition. If not set, the partition will be selected using the configured `partitioner`. - """ + """, ), ] = None, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc( "Message headers to store metainformation. " "**content-type** and **correlation_id** will be set automatically by framework anyway. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, reply_to: Annotated[ @@ -108,7 +105,7 @@ def __init__( Optional[Any], Doc( "AsyncAPI publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ @@ -145,7 +142,7 @@ def __init__( ], Doc( "Message handler function " - "to wrap the same with `@broker.subscriber(...)` way." + "to wrap the same with `@broker.subscriber(...)` way.", ), ], *topics: Annotated[ @@ -168,21 +165,21 @@ def __init__( partition assignment (if enabled), and to use for fetching and committing offsets. If `None`, auto-partition assignment (via group coordinator) and offset commits are disabled. - """ + """, ), ] = None, key_deserializer: Annotated[ Optional[Callable[[bytes], Any]], Doc( "Any callable that takes a raw message `bytes` " - "key and returns a deserialized one." + "key and returns a deserialized one.", ), ] = None, value_deserializer: Annotated[ Optional[Callable[[bytes], Any]], Doc( "Any callable that takes a raw message `bytes` " - "value and returns a deserialized value." + "value and returns a deserialized value.", ), ] = None, fetch_max_bytes: Annotated[ @@ -197,7 +194,7 @@ def __init__( performs fetches to multiple brokers in parallel so memory usage will depend on the number of brokers containing partitions for the topic. - """ + """, ), ] = 50 * 1024 * 1024, fetch_min_bytes: Annotated[ @@ -207,7 +204,7 @@ def __init__( Minimum amount of data the server should return for a fetch request, otherwise wait up to `fetch_max_wait_ms` for more data to accumulate. - """ + """, ), ] = 1, fetch_max_wait_ms: Annotated[ @@ -218,7 +215,7 @@ def __init__( the server will block before answering the fetch request if there isn't sufficient data to immediately satisfy the requirement given by `fetch_min_bytes`. - """ + """, ), ] = 500, max_partition_fetch_bytes: Annotated[ @@ -233,7 +230,7 @@ def __init__( send messages larger than the consumer can fetch. If that happens, the consumer can get stuck trying to fetch a large message on a certain partition. - """ + """, ), ] = 1 * 1024 * 1024, auto_offset_reset: Annotated[ @@ -245,7 +242,7 @@ def __init__( * `earliest` will move to the oldest available message * `latest` will move to the most recent * `none` will raise an exception so you can handle this case - """ + """, ), ] = "latest", auto_commit: Annotated[ @@ -254,7 +251,7 @@ def __init__( """ If `True` the consumer's offset will be periodically committed in the background. - """ + """, ), ] = True, auto_commit_interval_ms: Annotated[ @@ -262,7 +259,7 @@ def __init__( Doc( """ Milliseconds between automatic - offset commits, if `auto_commit` is `True`.""" + offset commits, if `auto_commit` is `True`.""", ), ] = 5 * 1000, check_crcs: Annotated[ @@ -273,7 +270,7 @@ def __init__( consumed. This ensures no on-the-wire or on-disk corruption to the messages occurred. This check adds some overhead, so it may be disabled in cases seeking extreme performance. - """ + """, ), ] = True, partition_assignment_strategy: Annotated[ @@ -289,7 +286,7 @@ def __init__( one. The coordinator will choose the old assignment strategy until all members have been updated. Then it will choose the new strategy. - """ + """, ), ] = (RoundRobinPartitionAssignor,), max_poll_interval_ms: Annotated[ @@ -302,7 +299,7 @@ def __init__( rebalance in order to reassign the partitions to another consumer group member. If API methods block waiting for messages, that time does not count against this timeout. - """ + """, ), ] = 5 * 60 * 1000, rebalance_timeout_ms: Annotated[ @@ -316,7 +313,7 @@ def __init__( decouple this setting to allow finer tuning by users that use `ConsumerRebalanceListener` to delay rebalacing. Defaults to ``session_timeout_ms`` - """ + """, ), ] = None, session_timeout_ms: Annotated[ @@ -331,7 +328,7 @@ def __init__( group and trigger a rebalance. The allowed range is configured with the **broker** configuration properties `group.min.session.timeout.ms` and `group.max.session.timeout.ms`. - """ + """, ), ] = 10 * 1000, heartbeat_interval_ms: Annotated[ @@ -347,7 +344,7 @@ def __init__( should be set no higher than 1/3 of that value. It can be adjusted even lower to control the expected time for normal rebalances. - """ + """, ), ] = 3 * 1000, consumer_timeout_ms: Annotated[ @@ -357,7 +354,7 @@ def __init__( Maximum wait timeout for background fetching routine. Mostly defines how fast the system will see rebalance and request new data for new partitions. - """ + """, ), ] = 200, max_poll_records: Annotated[ @@ -366,7 +363,7 @@ def __init__( """ The maximum number of records returned in a single call by batch consumer. Has no limit by default. - """ + """, ), ] = None, exclude_internal_topics: Annotated[ @@ -377,7 +374,7 @@ def __init__( (such as offsets) should be exposed to the consumer. If set to True the only way to receive records from an internal topic is subscribing to it. - """ + """, ), ] = True, isolation_level: Annotated[ @@ -407,7 +404,7 @@ def __init__( to the high watermark when there are in flight transactions. Further, when in `read_committed` the seek_to_end method will return the LSO. See method docs below. - """ + """, ), ] = "read_uncommitted", batch_timeout_ms: Annotated[ @@ -418,7 +415,7 @@ def __init__( data is not available in the buffer. If 0, returns immediately with any records that are available currently in the buffer, else returns empty. - """ + """, ), ] = 200, max_records: Annotated[ @@ -450,7 +447,7 @@ def __init__( to subscribe. It is guaranteed, however, that the partitions revoked/assigned through this interface are from topics subscribed in this call. - """ + """, ), ] = None, pattern: Annotated[ @@ -458,7 +455,7 @@ def __init__( Doc( """ Pattern to match available topics. You must provide either topics or pattern, but not both. - """ + """, ), ] = None, partitions: Annotated[ @@ -466,7 +463,7 @@ def __init__( Doc( """ A topic and partition tuple. You can't use 'topics' and 'partitions' in the same time. - """ + """, ), ] = (), # broker args @@ -497,7 +494,7 @@ def __init__( no_reply: Annotated[ bool, Doc( - "Whether to disable **FastStream** RPC and Reply To auto responses or not." + "Whether to disable **FastStream** RPC and Reply To auto responses or not.", ), ] = False, # AsyncAPI args @@ -509,7 +506,7 @@ def __init__( Optional[str], Doc( "AsyncAPI subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -568,7 +565,7 @@ class KafkaRouter( BrokerRouter[ Union[ "ConsumerRecord", - Tuple["ConsumerRecord", ...], + tuple["ConsumerRecord", ...], ] ], ): @@ -588,14 +585,14 @@ def __init__( dependencies: Annotated[ Iterable["Depends"], Doc( - "Dependencies list (`[Depends(),]`) to apply to all routers' publishers/subscribers." + "Dependencies list (`[Depends(),]`) to apply to all routers' publishers/subscribers.", ), ] = (), middlewares: Annotated[ Iterable[ Union[ "BrokerMiddleware[ConsumerRecord]", - "BrokerMiddleware[Tuple[ConsumerRecord, ...]]", + "BrokerMiddleware[tuple[ConsumerRecord, ...]]", ] ], Doc("Router middlewares to apply to all routers' publishers/subscribers."), diff --git a/faststream/kafka/schemas/params.py b/faststream/kafka/schemas/params.py index 9943e7e13c..64a301614e 100644 --- a/faststream/kafka/schemas/params.py +++ b/faststream/kafka/schemas/params.py @@ -1,6 +1,6 @@ import ssl from asyncio import AbstractEventLoop -from typing import List, Literal, Optional, Union +from typing import Literal, Optional, Union from aiokafka.abc import AbstractTokenProvider from typing_extensions import TypedDict @@ -25,7 +25,7 @@ class ConsumerConnectionParams(TypedDict, total=False): sasl_kerberos_service_name : The service """ - bootstrap_servers: Union[str, List[str]] + bootstrap_servers: Union[str, list[str]] loop: Optional[AbstractEventLoop] client_id: str request_timeout_ms: int diff --git a/faststream/kafka/security.py b/faststream/kafka/security.py index 12860d191c..cd8359901b 100644 --- a/faststream/kafka/security.py +++ b/faststream/kafka/security.py @@ -16,20 +16,20 @@ def parse_security(security: Optional[BaseSecurity]) -> "AnyDict": if security is None: return {} - elif isinstance(security, SASLPlaintext): + if isinstance(security, SASLPlaintext): return _parse_sasl_plaintext(security) - elif isinstance(security, SASLScram256): + if isinstance(security, SASLScram256): return _parse_sasl_scram256(security) - elif isinstance(security, SASLScram512): + if isinstance(security, SASLScram512): return _parse_sasl_scram512(security) - elif isinstance(security, SASLOAuthBearer): + if isinstance(security, SASLOAuthBearer): return _parse_sasl_oauthbearer(security) - elif isinstance(security, SASLGSSAPI): + if isinstance(security, SASLGSSAPI): return _parse_sasl_gssapi(security) - elif isinstance(security, BaseSecurity): + if isinstance(security, BaseSecurity): return _parse_base_security(security) - else: - raise NotImplementedError(f"KafkaBroker does not support `{type(security)}`.") + msg = f"KafkaBroker does not support `{type(security)}`." + raise NotImplementedError(msg) def _parse_base_security(security: BaseSecurity) -> "AnyDict": diff --git a/faststream/kafka/subscriber/factory.py b/faststream/kafka/subscriber/factory.py index 3f8515dd35..a31a5fde93 100644 --- a/faststream/kafka/subscriber/factory.py +++ b/faststream/kafka/subscriber/factory.py @@ -1,9 +1,8 @@ +from collections.abc import Iterable from typing import ( TYPE_CHECKING, - Iterable, Literal, Optional, - Tuple, Union, overload, ) @@ -41,7 +40,7 @@ def create_subscriber( no_reply: bool, retry: bool, broker_dependencies: Iterable["Depends"], - broker_middlewares: Iterable["BrokerMiddleware[Tuple[ConsumerRecord, ...]]"], + broker_middlewares: Iterable["BrokerMiddleware[tuple[ConsumerRecord, ...]]"], # Specification args title_: Optional[str], description_: Optional[str], @@ -94,7 +93,7 @@ def create_subscriber( retry: bool, broker_dependencies: Iterable["Depends"], broker_middlewares: Iterable[ - "BrokerMiddleware[Union[ConsumerRecord, Tuple[ConsumerRecord, ...]]]" + "BrokerMiddleware[Union[ConsumerRecord, tuple[ConsumerRecord, ...]]]" ], # Specification args title_: Optional[str], @@ -124,7 +123,7 @@ def create_subscriber( retry: bool, broker_dependencies: Iterable["Depends"], broker_middlewares: Iterable[ - "BrokerMiddleware[Union[ConsumerRecord, Tuple[ConsumerRecord, ...]]]" + "BrokerMiddleware[Union[ConsumerRecord, tuple[ConsumerRecord, ...]]]" ], # Specification args title_: Optional[str], @@ -135,18 +134,23 @@ def create_subscriber( "SpecificationBatchSubscriber", ]: if is_manual and not group_id: - raise SetupError("You must use `group_id` with manual commit mode.") + msg = "You must use `group_id` with manual commit mode." + raise SetupError(msg) if not topics and not partitions and not pattern: + msg = "You should provide either `topics` or `partitions` or `pattern`." raise SetupError( - "You should provide either `topics` or `partitions` or `pattern`." + msg, ) - elif topics and partitions: - raise SetupError("You can't provide both `topics` and `partitions`.") - elif topics and pattern: - raise SetupError("You can't provide both `topics` and `pattern`.") - elif partitions and pattern: - raise SetupError("You can't provide both `partitions` and `pattern`.") + if topics and partitions: + msg = "You can't provide both `topics` and `partitions`." + raise SetupError(msg) + if topics and pattern: + msg = "You can't provide both `topics` and `pattern`." + raise SetupError(msg) + if partitions and pattern: + msg = "You can't provide both `partitions` and `pattern`." + raise SetupError(msg) if batch: return SpecificationBatchSubscriber( @@ -169,21 +173,20 @@ def create_subscriber( include_in_schema=include_in_schema, ) - else: - return SpecificationDefaultSubscriber( - *topics, - group_id=group_id, - listener=listener, - pattern=pattern, - connection_args=connection_args, - partitions=partitions, - is_manual=is_manual, - no_ack=no_ack, - no_reply=no_reply, - retry=retry, - broker_dependencies=broker_dependencies, - broker_middlewares=broker_middlewares, - title_=title_, - description_=description_, - include_in_schema=include_in_schema, - ) + return SpecificationDefaultSubscriber( + *topics, + group_id=group_id, + listener=listener, + pattern=pattern, + connection_args=connection_args, + partitions=partitions, + is_manual=is_manual, + no_ack=no_ack, + no_reply=no_reply, + retry=retry, + broker_dependencies=broker_dependencies, + broker_middlewares=broker_middlewares, + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + ) diff --git a/faststream/kafka/subscriber/subscriber.py b/faststream/kafka/subscriber/subscriber.py index e173186d66..b49f10e77e 100644 --- a/faststream/kafka/subscriber/subscriber.py +++ b/faststream/kafka/subscriber/subscriber.py @@ -1,7 +1,5 @@ from typing import ( TYPE_CHECKING, - Dict, - Tuple, ) from faststream._internal.types import MsgType @@ -26,7 +24,7 @@ class SpecificationSubscriber(LogicSubscriber[MsgType]): def get_name(self) -> str: return f'{",".join(self.topics)}:{self.call_name}' - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> dict[str, Channel]: channels = {} payloads = self.get_payloads() @@ -41,7 +39,7 @@ def get_schema(self) -> Dict[str, Channel]: title=f"{handler_name}:Message", payload=resolve_payloads(payloads), correlationId=CorrelationId( - location="$message.header#/correlation_id" + location="$message.header#/correlation_id", ), ), ), @@ -62,6 +60,6 @@ class SpecificationDefaultSubscriber( class SpecificationBatchSubscriber( BatchSubscriber, - SpecificationSubscriber[Tuple["ConsumerRecord", ...]], + SpecificationSubscriber[tuple["ConsumerRecord", ...]], ): pass diff --git a/faststream/kafka/subscriber/usecase.py b/faststream/kafka/subscriber/usecase.py index b8715126ca..7a38b79055 100644 --- a/faststream/kafka/subscriber/usecase.py +++ b/faststream/kafka/subscriber/usecase.py @@ -1,16 +1,12 @@ import asyncio from abc import abstractmethod +from collections.abc import Iterable, Sequence from itertools import chain from typing import ( TYPE_CHECKING, Any, Callable, - Dict, - Iterable, - List, Optional, - Sequence, - Tuple, ) import anyio @@ -187,7 +183,8 @@ async def get_one( ), "You can't use `get_one` method if subscriber has registered handlers." raw_messages = await self.consumer.getmany( - timeout_ms=timeout * 1000, max_records=1 + timeout_ms=timeout * 1000, + max_records=1, ) if not raw_messages: @@ -221,7 +218,7 @@ def _make_response_publisher( @abstractmethod async def get_msg(self) -> MsgType: - raise NotImplementedError() + raise NotImplementedError async def _consume(self) -> None: assert self.consumer, "You should start subscriber at first." # nosec B101 @@ -248,20 +245,19 @@ async def _consume(self) -> None: await self.consume(msg) @property - def topic_names(self) -> List[str]: + def topic_names(self) -> list[str]: if self._pattern: return [self._pattern] - elif self.topics: + if self.topics: return list(self.topics) - else: - return [f"{p.topic}-{p.partition}" for p in self.partitions] + return [f"{p.topic}-{p.partition}" for p in self.partitions] @staticmethod def build_log_context( message: Optional["StreamMessage[Any]"], topic: str, group_id: Optional[str] = None, - ) -> Dict[str, str]: + ) -> dict[str, str]: return { "topic": topic, "group_id": group_id or "", @@ -269,11 +265,11 @@ def build_log_context( } def add_prefix(self, prefix: str) -> None: - self.topics = tuple("".join((prefix, t)) for t in self.topics) + self.topics = tuple(f"{prefix}{t}" for t in self.topics) self.partitions = [ TopicPartition( - topic="".join((prefix, p.topic)), + topic=f"{prefix}{p.topic}", partition=p.partition, ) for p in self.partitions @@ -346,7 +342,7 @@ async def get_msg(self) -> "ConsumerRecord": def get_log_context( self, message: Optional["StreamMessage[ConsumerRecord]"], - ) -> Dict[str, str]: + ) -> dict[str, str]: if message is None: topic = ",".join(self.topic_names) else: @@ -359,7 +355,7 @@ def get_log_context( ) -class BatchSubscriber(LogicSubscriber[Tuple["ConsumerRecord", ...]]): +class BatchSubscriber(LogicSubscriber[tuple["ConsumerRecord", ...]]): def __init__( self, *topics: str, @@ -378,7 +374,7 @@ def __init__( retry: bool, broker_dependencies: Iterable["Depends"], broker_middlewares: Iterable[ - "BrokerMiddleware[Sequence[Tuple[ConsumerRecord, ...]]]" + "BrokerMiddleware[Sequence[tuple[ConsumerRecord, ...]]]" ], # AsyncAPI args title_: Optional[str], @@ -425,7 +421,7 @@ def __init__( include_in_schema=include_in_schema, ) - async def get_msg(self) -> Tuple["ConsumerRecord", ...]: + async def get_msg(self) -> tuple["ConsumerRecord", ...]: assert self.consumer, "You should setup subscriber at first." # nosec B101 messages = await self.consumer.getmany( @@ -441,8 +437,8 @@ async def get_msg(self) -> Tuple["ConsumerRecord", ...]: def get_log_context( self, - message: Optional["StreamMessage[Tuple[ConsumerRecord, ...]]"], - ) -> Dict[str, str]: + message: Optional["StreamMessage[tuple[ConsumerRecord, ...]]"], + ) -> dict[str, str]: if message is None: topic = ",".join(self.topic_names) else: diff --git a/faststream/kafka/testing.py b/faststream/kafka/testing.py index 0ab5f228c2..a0135e9083 100755 --- a/faststream/kafka/testing.py +++ b/faststream/kafka/testing.py @@ -1,14 +1,11 @@ import re -from datetime import datetime +from collections.abc import Generator, Iterable +from datetime import datetime, timezone from typing import ( TYPE_CHECKING, Any, Callable, - Dict, - Generator, - Iterable, Optional, - Tuple, ) from unittest.mock import AsyncMock, MagicMock @@ -52,7 +49,7 @@ async def _fake_connect( # type: ignore[override] def create_publisher_fake_subscriber( broker: KafkaBroker, publisher: "SpecificationPublisher[Any]", - ) -> Tuple["LogicSubscriber[Any]", bool]: + ) -> tuple["LogicSubscriber[Any]", bool]: sub: Optional[LogicSubscriber[Any]] = None for handler in broker._subscribers: if _is_handler_matches(handler, publisher.topic, publisher.partition): @@ -64,7 +61,8 @@ def create_publisher_fake_subscriber( if publisher.partition: tp = TopicPartition( - topic=publisher.topic, partition=publisher.partition + topic=publisher.topic, + partition=publisher.partition, ) sub = broker.subscriber( partitions=[tp], @@ -106,7 +104,7 @@ async def publish( # type: ignore[override] key: Optional[bytes] = None, partition: Optional[int] = None, timestamp_ms: Optional[int] = None, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, correlation_id: Optional[str] = None, *, reply_to: str = "", @@ -145,7 +143,7 @@ async def request( # type: ignore[override] key: Optional[bytes] = None, partition: Optional[int] = None, timestamp_ms: Optional[int] = None, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, correlation_id: Optional[str] = None, *, timeout: Optional[float] = 0.5, @@ -182,7 +180,7 @@ async def publish_batch( topic: str, partition: Optional[int] = None, timestamp_ms: Optional[int] = None, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, reply_to: str = "", correlation_id: Optional[str] = None, no_confirm: bool = False, @@ -213,8 +211,6 @@ async def publish_batch( for m in messages: await self._execute_handler(m, topic, handler) - return None - async def _execute_handler( self, msg: Any, @@ -237,7 +233,7 @@ def build_message( partition: Optional[int] = None, timestamp_ms: Optional[int] = None, key: Optional[bytes] = None, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, correlation_id: Optional[str] = None, *, reply_to: str = "", @@ -260,7 +256,7 @@ def build_message( value=msg, topic=topic, partition=partition or 0, - timestamp=timestamp_ms or int(datetime.now().timestamp()), + timestamp=timestamp_ms or int(datetime.now(timezone.utc).timestamp()), timestamp_type=0, key=k, serialized_key_size=len(k), @@ -305,5 +301,5 @@ def _is_handler_matches( for p in handler.partitions ) or topic in handler.topics - or (handler._pattern and re.match(handler._pattern, topic)) + or (handler._pattern and re.match(handler._pattern, topic)), ) diff --git a/faststream/message/__init__.py b/faststream/message/__init__.py index 58eb791b89..51064d78a4 100644 --- a/faststream/message/__init__.py +++ b/faststream/message/__init__.py @@ -2,9 +2,9 @@ from .utils import decode_message, encode_message, gen_cor_id __all__ = ( - "StreamMessage", "AckStatus", - "gen_cor_id", + "StreamMessage", "decode_message", "encode_message", + "gen_cor_id", ) diff --git a/faststream/message/message.py b/faststream/message/message.py index 2400d00127..4d41404771 100644 --- a/faststream/message/message.py +++ b/faststream/message/message.py @@ -3,7 +3,6 @@ TYPE_CHECKING, Any, Generic, - List, Optional, TypeVar, Union, @@ -33,7 +32,7 @@ def __init__( *, headers: Optional["AnyDict"] = None, reply_to: str = "", - batch_headers: Optional[List["AnyDict"]] = None, + batch_headers: Optional[list["AnyDict"]] = None, path: Optional["AnyDict"] = None, content_type: Optional[str] = None, correlation_id: Optional[str] = None, @@ -70,7 +69,7 @@ def __repr__(self) -> str: f"committed={self.committed}", f"raw_message={self.raw_message}", ), - ) + ), ) return f"{self.__class__.__name__}({inner})" diff --git a/faststream/message/utils.py b/faststream/message/utils.py index 490493a125..5483c27bb5 100644 --- a/faststream/message/utils.py +++ b/faststream/message/utils.py @@ -1,11 +1,10 @@ import json +from collections.abc import Sequence from contextlib import suppress from typing import ( TYPE_CHECKING, Any, Optional, - Sequence, - Tuple, Union, cast, ) @@ -49,7 +48,7 @@ def decode_message(message: "StreamMessage[Any]") -> "DecodedMessage": def encode_message( msg: Union[Sequence["SendableMessage"], "SendableMessage"], -) -> Tuple[bytes, Optional[str]]: +) -> tuple[bytes, Optional[str]]: """Encodes a message.""" if msg is None: return ( diff --git a/faststream/middlewares/base.py b/faststream/middlewares/base.py index 8d0a623abe..a9ff8642ba 100644 --- a/faststream/middlewares/base.py +++ b/faststream/middlewares/base.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Any, Optional, Type +from typing import TYPE_CHECKING, Any, Optional from typing_extensions import Self @@ -17,11 +17,10 @@ def __init__(self, msg: Optional[Any] = None) -> None: async def on_receive(self) -> None: """Hook to call on message receive.""" - pass async def after_processed( self, - exc_type: Optional[Type[BaseException]] = None, + exc_type: Optional[type[BaseException]] = None, exc_val: Optional[BaseException] = None, exc_tb: Optional["TracebackType"] = None, ) -> Optional[bool]: @@ -34,7 +33,7 @@ async def __aenter__(self) -> Self: async def __aexit__( self, - exc_type: Optional[Type[BaseException]] = None, + exc_type: Optional[type[BaseException]] = None, exc_val: Optional[BaseException] = None, exc_tb: Optional["TracebackType"] = None, ) -> Optional[bool]: diff --git a/faststream/middlewares/exception.py b/faststream/middlewares/exception.py index 291c65c470..2732037945 100644 --- a/faststream/middlewares/exception.py +++ b/faststream/middlewares/exception.py @@ -1,15 +1,10 @@ +from collections.abc import Awaitable from typing import ( TYPE_CHECKING, Any, - Awaitable, Callable, - ContextManager, - Dict, - List, NoReturn, Optional, - Tuple, - Type, Union, cast, overload, @@ -24,6 +19,7 @@ from faststream.middlewares.base import BaseMiddleware if TYPE_CHECKING: + from contextlib import AbstractContextManager from types import TracebackType from faststream._internal.basic_types import AsyncFuncAny @@ -31,21 +27,22 @@ GeneralExceptionHandler: TypeAlias = Union[ - Callable[..., None], Callable[..., Awaitable[None]] + Callable[..., None], + Callable[..., Awaitable[None]], ] PublishingExceptionHandler: TypeAlias = Callable[..., "Any"] CastedGeneralExceptionHandler: TypeAlias = Callable[..., Awaitable[None]] CastedPublishingExceptionHandler: TypeAlias = Callable[..., Awaitable["Any"]] -CastedHandlers: TypeAlias = List[ - Tuple[ - Type[Exception], +CastedHandlers: TypeAlias = list[ + tuple[ + type[Exception], CastedGeneralExceptionHandler, ] ] -CastedPublishingHandlers: TypeAlias = List[ - Tuple[ - Type[Exception], +CastedPublishingHandlers: TypeAlias = list[ + tuple[ + type[Exception], CastedPublishingExceptionHandler, ] ] @@ -77,11 +74,11 @@ async def consume_scope( if issubclass(exc_type, handler_type): return await handler(exc) - raise exc + raise async def after_processed( self, - exc_type: Optional[Type[BaseException]] = None, + exc_type: Optional[type[BaseException]] = None, exc_val: Optional[BaseException] = None, exc_tb: Optional["TracebackType"] = None, ) -> Optional[bool]: @@ -90,7 +87,7 @@ async def after_processed( if issubclass(exc_type, handler_type): # TODO: remove it after context will be moved to middleware # In case parser/decoder error occurred - scope: ContextManager[Any] + scope: AbstractContextManager[Any] if not context.get_local("message"): scope = context.scope("message", self.msg) else: @@ -115,14 +112,14 @@ class ExceptionMiddleware: def __init__( self, handlers: Optional[ - Dict[ - Type[Exception], + dict[ + type[Exception], GeneralExceptionHandler, ] ] = None, publish_handlers: Optional[ - Dict[ - Type[Exception], + dict[ + type[Exception], PublishingExceptionHandler, ] ] = None, @@ -133,7 +130,7 @@ def __init__( ( exc_type, apply_types( - cast(Callable[..., Awaitable[None]], to_async(handler)) + cast(Callable[..., Awaitable[None]], to_async(handler)), ), ) for exc_type, handler in (handlers or {}).items() @@ -151,20 +148,20 @@ def __init__( @overload def add_handler( self, - exc: Type[Exception], + exc: type[Exception], publish: Literal[False] = False, ) -> Callable[[GeneralExceptionHandler], GeneralExceptionHandler]: ... @overload def add_handler( self, - exc: Type[Exception], + exc: type[Exception], publish: Literal[True], ) -> Callable[[PublishingExceptionHandler], PublishingExceptionHandler]: ... def add_handler( self, - exc: Type[Exception], + exc: type[Exception], publish: bool = False, ) -> Union[ Callable[[GeneralExceptionHandler], GeneralExceptionHandler], @@ -179,26 +176,24 @@ def pub_wrapper( ( exc, apply_types(to_async(func)), - ) + ), ) return func return pub_wrapper - else: - - def default_wrapper( - func: GeneralExceptionHandler, - ) -> GeneralExceptionHandler: - self._handlers.append( - ( - exc, - apply_types(to_async(func)), - ) - ) - return func + def default_wrapper( + func: GeneralExceptionHandler, + ) -> GeneralExceptionHandler: + self._handlers.append( + ( + exc, + apply_types(to_async(func)), + ), + ) + return func - return default_wrapper + return default_wrapper def __call__(self, msg: Optional[Any]) -> BaseExceptionMiddleware: """Real middleware runtime constructor.""" diff --git a/faststream/middlewares/logging.py b/faststream/middlewares/logging.py index db7f6fe598..57ff030a94 100644 --- a/faststream/middlewares/logging.py +++ b/faststream/middlewares/logging.py @@ -1,5 +1,5 @@ import logging -from typing import TYPE_CHECKING, Any, Optional, Type +from typing import TYPE_CHECKING, Any, Optional from faststream._internal.context.repository import context from faststream._internal.setup.logger import LoggerState @@ -40,7 +40,7 @@ async def on_consume( async def __aexit__( self, - exc_type: Optional[Type[BaseException]] = None, + exc_type: Optional[type[BaseException]] = None, exc_val: Optional[BaseException] = None, exc_tb: Optional["TracebackType"] = None, ) -> bool: diff --git a/faststream/nats/__init__.py b/faststream/nats/__init__.py index abd0fe73ee..42018a3a2a 100644 --- a/faststream/nats/__init__.py +++ b/faststream/nats/__init__.py @@ -22,29 +22,29 @@ from faststream.nats.testing import TestNatsBroker __all__ = ( - "TestApp", - "NatsBroker", - "JStream", - "PullSub", - "KvWatch", - "ObjWatch", - "NatsRoute", - "NatsRouter", - "NatsPublisher", - "TestNatsBroker", - "NatsMessage", - "NatsResponse", + "AckPolicy", # Nats imports "ConsumerConfig", "DeliverPolicy", - "AckPolicy", - "ReplayPolicy", "DiscardPolicy", - "RetentionPolicy", "ExternalStream", + "JStream", + "KvWatch", + "NatsBroker", + "NatsMessage", + "NatsPublisher", + "NatsResponse", + "NatsRoute", + "NatsRouter", + "ObjWatch", "Placement", + "PullSub", "RePublish", + "ReplayPolicy", + "RetentionPolicy", "StorageType", "StreamConfig", "StreamSource", + "TestApp", + "TestNatsBroker", ) diff --git a/faststream/nats/annotations.py b/faststream/nats/annotations.py index f33f0eac78..9bd2e29066 100644 --- a/faststream/nats/annotations.py +++ b/faststream/nats/annotations.py @@ -1,25 +1,28 @@ +from typing import Annotated + from nats.aio.client import Client as _NatsClient from nats.js.client import JetStreamContext as _JetStream from nats.js.object_store import ObjectStore as _ObjectStore -from typing_extensions import Annotated from faststream._internal.context import Context from faststream.annotations import ContextRepo, Logger from faststream.nats.broker import NatsBroker as _Broker from faststream.nats.message import NatsMessage as _Message -from faststream.nats.publisher.producer import NatsFastProducer as _CoreProducer -from faststream.nats.publisher.producer import NatsJSFastProducer as _JsProducer +from faststream.nats.publisher.producer import ( + NatsFastProducer as _CoreProducer, + NatsJSFastProducer as _JsProducer, +) from faststream.nats.subscriber.usecase import OBJECT_STORAGE_CONTEXT_KEY from faststream.params import NoCast __all__ = ( - "Logger", - "ContextRepo", - "NoCast", - "NatsMessage", - "NatsBroker", "Client", + "ContextRepo", "JsClient", + "Logger", + "NatsBroker", + "NatsMessage", + "NoCast", "ObjectStorage", ) diff --git a/faststream/nats/broker/broker.py b/faststream/nats/broker/broker.py index bddbd94224..ee91cc291e 100644 --- a/faststream/nats/broker/broker.py +++ b/faststream/nats/broker/broker.py @@ -1,14 +1,12 @@ import logging import warnings +from collections.abc import Iterable from typing import ( TYPE_CHECKING, + Annotated, Any, Callable, - Dict, - Iterable, - List, Optional, - Type, Union, ) @@ -29,7 +27,7 @@ from nats.aio.msg import Msg from nats.errors import Error from nats.js.errors import BadRequestError -from typing_extensions import Annotated, Doc, override +from typing_extensions import Doc, override from faststream.__about__ import SERVICE_NAME from faststream._internal.broker.broker import BrokerUsecase @@ -97,7 +95,8 @@ class NatsInitKwargs(TypedDict, total=False): Doc("Callback to report when a new server joins the cluster."), ] reconnected_cb: Annotated[ - Optional["Callback"], Doc("Callback to report success reconnection.") + Optional["Callback"], + Doc("Callback to report success reconnection."), ] name: Annotated[ Optional[str], @@ -107,7 +106,7 @@ class NatsInitKwargs(TypedDict, total=False): bool, Doc( "Turn on NATS server pedantic mode that performs extra checks on the protocol. " - "https://docs.nats.io/using-nats/developer/connecting/misc#turn-on-pedantic-mode" + "https://docs.nats.io/using-nats/developer/connecting/misc#turn-on-pedantic-mode", ), ] verbose: Annotated[ @@ -141,11 +140,12 @@ class NatsInitKwargs(TypedDict, total=False): dont_randomize: Annotated[ bool, Doc( - "Boolean indicating should client randomly shuffle servers list for reconnection randomness." + "Boolean indicating should client randomly shuffle servers list for reconnection randomness.", ), ] flusher_queue_size: Annotated[ - int, Doc("Max count of commands awaiting to be flushed to the socket") + int, + Doc("Max count of commands awaiting to be flushed to the socket"), ] no_echo: Annotated[ bool, @@ -180,14 +180,14 @@ class NatsInitKwargs(TypedDict, total=False): Doc( "A callback used to sign a nonce from the server while " "authenticating with nkeys. The user should sign the nonce and " - "return the base64 encoded signature." + "return the base64 encoded signature.", ), ] user_jwt_cb: Annotated[ Optional["JWTCallback"], Doc( "A callback used to fetch and return the account " - "signed JWT for this user." + "signed JWT for this user.", ), ] user_credentials: Annotated[ @@ -201,7 +201,7 @@ class NatsInitKwargs(TypedDict, total=False): inbox_prefix: Annotated[ Union[str, bytes], Doc( - "Prefix for generating unique inboxes, subjects with that prefix and NUID.ß" + "Prefix for generating unique inboxes, subjects with that prefix and NUID.ß", ), ] pending_size: Annotated[ @@ -220,7 +220,7 @@ class NatsBroker( ): """A class to represent a NATS broker.""" - url: List[str] + url: list[str] stream: Optional["JetStreamContext"] _producer: Optional["NatsFastProducer"] @@ -252,7 +252,8 @@ def __init__( Doc("Callback to report when a new server joins the cluster."), ] = None, reconnected_cb: Annotated[ - Optional["Callback"], Doc("Callback to report success reconnection.") + Optional["Callback"], + Doc("Callback to report success reconnection."), ] = None, name: Annotated[ Optional[str], @@ -262,7 +263,7 @@ def __init__( bool, Doc( "Turn on NATS server pedantic mode that performs extra checks on the protocol. " - "https://docs.nats.io/using-nats/developer/connecting/misc#turn-on-pedantic-mode" + "https://docs.nats.io/using-nats/developer/connecting/misc#turn-on-pedantic-mode", ), ] = False, verbose: Annotated[ @@ -296,11 +297,12 @@ def __init__( dont_randomize: Annotated[ bool, Doc( - "Boolean indicating should client randomly shuffle servers list for reconnection randomness." + "Boolean indicating should client randomly shuffle servers list for reconnection randomness.", ), ] = False, flusher_queue_size: Annotated[ - int, Doc("Max count of commands awaiting to be flushed to the socket") + int, + Doc("Max count of commands awaiting to be flushed to the socket"), ] = DEFAULT_MAX_FLUSHER_QUEUE_SIZE, no_echo: Annotated[ bool, @@ -335,14 +337,14 @@ def __init__( Doc( "A callback used to sign a nonce from the server while " "authenticating with nkeys. The user should sign the nonce and " - "return the base64 encoded signature." + "return the base64 encoded signature.", ), ] = None, user_jwt_cb: Annotated[ Optional["JWTCallback"], Doc( "A callback used to fetch and return the account " - "signed JWT for this user." + "signed JWT for this user.", ), ] = None, user_credentials: Annotated[ @@ -356,7 +358,7 @@ def __init__( inbox_prefix: Annotated[ Union[str, bytes], Doc( - "Prefix for generating unique inboxes, subjects with that prefix and NUID.ß" + "Prefix for generating unique inboxes, subjects with that prefix and NUID.ß", ), ] = DEFAULT_INBOX_PREFIX, pending_size: Annotated[ @@ -371,7 +373,7 @@ def __init__( graceful_timeout: Annotated[ Optional[float], Doc( - "Graceful shutdown timeout. Broker waits for all running subscribers completion before shut down." + "Graceful shutdown timeout. Broker waits for all running subscribers completion before shut down.", ), ] = None, decoder: Annotated[ @@ -394,7 +396,7 @@ def __init__( security: Annotated[ Optional["BaseSecurity"], Doc( - "Security options to connect broker and generate AsyncAPI server security information." + "Security options to connect broker and generate AsyncAPI server security information.", ), ] = None, specification_url: Annotated[ @@ -603,7 +605,7 @@ async def _connect(self, **kwargs: Any) -> "Client": async def close( self, - exc_type: Optional[Type[BaseException]] = None, + exc_type: Optional[type[BaseException]] = None, exc_val: Optional[BaseException] = None, exc_tb: Optional["TracebackType"] = None, ) -> None: @@ -653,13 +655,16 @@ async def start(self) -> None: await self.stream.update_stream( config=stream.config, subjects=tuple( - set(old_config.subjects or ()).union(stream.subjects) + set(old_config.subjects or ()).union(stream.subjects), ), ) else: # pragma: no cover self._state.logger_state.log( - str(e), logging.ERROR, log_context, exc_info=e + str(e), + logging.ERROR, + log_context, + exc_info=e, ) finally: @@ -675,7 +680,7 @@ async def publish( # type: ignore[override] "SendableMessage", Doc( "Message body to send. " - "Can be any encodable object (native python types or `pydantic.BaseModel`)." + "Can be any encodable object (native python types or `pydantic.BaseModel`).", ), ], subject: Annotated[ @@ -683,10 +688,10 @@ async def publish( # type: ignore[override] Doc("NATS subject to send message."), ], headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc( "Message headers to store metainformation. " - "**content-type** and **correlation_id** will be set automatically by framework anyway." + "**content-type** and **correlation_id** will be set automatically by framework anyway.", ), ] = None, reply_to: Annotated[ @@ -697,14 +702,14 @@ async def publish( # type: ignore[override] Optional[str], Doc( "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages." + "**correlation_id** is a useful option to trace messages.", ), ] = None, stream: Annotated[ Optional[str], Doc( "This option validates that the target subject is in presented stream. " - "Can be omitted without any effect." + "Can be omitted without any effect.", ), ] = None, timeout: Annotated[ @@ -734,7 +739,7 @@ async def publish( # type: ignore[override] { "stream": stream, "timeout": timeout, - } + }, ) await super().publish( @@ -751,7 +756,7 @@ async def request( # type: ignore[override] "SendableMessage", Doc( "Message body to send. " - "Can be any encodable object (native python types or `pydantic.BaseModel`)." + "Can be any encodable object (native python types or `pydantic.BaseModel`).", ), ], subject: Annotated[ @@ -759,24 +764,24 @@ async def request( # type: ignore[override] Doc("NATS subject to send message."), ], headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc( "Message headers to store metainformation. " - "**content-type** and **correlation_id** will be set automatically by framework anyway." + "**content-type** and **correlation_id** will be set automatically by framework anyway.", ), ] = None, correlation_id: Annotated[ Optional[str], Doc( "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages." + "**correlation_id** is a useful option to trace messages.", ), ] = None, stream: Annotated[ Optional[str], Doc( "This option validates that the target subject is in presented stream. " - "Can be omitted without any effect." + "Can be omitted without any effect.", ), ] = None, timeout: Annotated[ @@ -924,7 +929,10 @@ async def wrapper(err: Exception) -> None: if isinstance(err, Error) and self.__is_connected: self._state.logger_state.log( - f"Connection broken with {err!r}", logging.WARNING, c, exc_info=err + f"Connection broken with {err!r}", + logging.WARNING, + c, + exc_info=err, ) self.__is_connected = False diff --git a/faststream/nats/broker/logging.py b/faststream/nats/broker/logging.py index 0cf9ad45c3..f4e2500cdb 100644 --- a/faststream/nats/broker/logging.py +++ b/faststream/nats/broker/logging.py @@ -27,19 +27,19 @@ def setup_log_contest(self, params: "AnyDict") -> None: ( self._max_subject_len, len(params.get("subject", "")), - ) + ), ) self._max_queue_len = max( ( self._max_queue_len, len(params.get("queue", "")), - ) + ), ) self._max_stream_len = max( ( self._max_stream_len, len(params.get("stream", "")), - ) + ), ) def get_logger(self) -> Optional["LoggerProto"]: @@ -55,18 +55,18 @@ def get_logger(self) -> Optional["LoggerProto"]: }, message_id_ln=message_id_ln, fmt=self._log_fmt - or ( - "%(asctime)s %(levelname)-8s - " - + ( + or "".join(( + "%(asctime)s %(levelname)-8s - ", + ( f"%(stream)-{self._max_stream_len}s | " if self._max_stream_len else "" - ) - + (f"%(queue)-{self._max_queue_len}s | " if self._max_queue_len else "") - + f"%(subject)-{self._max_subject_len}s | " - + f"%(message_id)-{message_id_ln}s - " - "%(message)s" - ), + ), + (f"%(queue)-{self._max_queue_len}s | " if self._max_queue_len else ""), + f"%(subject)-{self._max_subject_len}s | ", + f"%(message_id)-{message_id_ln}s - ", + "%(message)s", + )), ) diff --git a/faststream/nats/broker/registrator.py b/faststream/nats/broker/registrator.py index 5a13f02966..580501f2e8 100644 --- a/faststream/nats/broker/registrator.py +++ b/faststream/nats/broker/registrator.py @@ -1,7 +1,8 @@ -from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Optional, Union, cast +from collections.abc import Iterable +from typing import TYPE_CHECKING, Annotated, Any, Optional, Union, cast from nats.js import api -from typing_extensions import Annotated, Doc, override +from typing_extensions import Doc, override from faststream._internal.broker.abc_broker import ABCBroker from faststream.nats.helpers import StreamBuilder @@ -26,8 +27,8 @@ class NatsRegistrator(ABCBroker["Msg"]): """Includable to NatsBroker router.""" - _subscribers: List["SpecificationSubscriber"] - _publishers: List["SpecificationPublisher"] + _subscribers: list["SpecificationSubscriber"] + _publishers: list["SpecificationPublisher"] def __init__(self, **kwargs: Any) -> None: self._stream_builder = StreamBuilder() @@ -45,7 +46,7 @@ def subscriber( # type: ignore[override] str, Doc( "Subscribers' NATS queue name. Subscribers with same queue name will be load balanced by the NATS " - "server." + "server.", ), ] = "", pending_msgs_limit: Annotated[ @@ -55,7 +56,7 @@ def subscriber( # type: ignore[override] "been answered. In case of NATS Core, if that limits exceeds, you will receive NATS 'Slow Consumer' " "error. " "That's literally means that your worker can't handle the whole load. In case of NATS JetStream, " - "you will no longer receive messages until some of delivered messages will be acked in any way." + "you will no longer receive messages until some of delivered messages will be acked in any way.", ), ] = None, pending_bytes_limit: Annotated[ @@ -65,7 +66,7 @@ def subscriber( # type: ignore[override] "been answered. In case of NATS Core, if that limit exceeds, you will receive NATS 'Slow Consumer' " "error." "That's literally means that your worker can't handle the whole load. In case of NATS JetStream, " - "you will no longer receive messages until some of delivered messages will be acked in any way." + "you will no longer receive messages until some of delivered messages will be acked in any way.", ), ] = None, # Core arguments @@ -77,7 +78,7 @@ def subscriber( # type: ignore[override] durable: Annotated[ Optional[str], Doc( - "Name of the durable consumer to which the the subscription should be bound." + "Name of the durable consumer to which the the subscription should be bound.", ), ] = None, config: Annotated[ @@ -103,7 +104,7 @@ def subscriber( # type: ignore[override] headers_only: Annotated[ Optional[bool], Doc( - "Should be message delivered without payload, only headers and metadata." + "Should be message delivered without payload, only headers and metadata.", ), ] = None, # pull arguments @@ -111,7 +112,7 @@ def subscriber( # type: ignore[override] Union[bool, "PullSub"], Doc( "NATS Pull consumer parameters container. " - "Should be used with `stream` only." + "Should be used with `stream` only.", ), ] = False, kv_watch: Annotated[ @@ -125,7 +126,7 @@ def subscriber( # type: ignore[override] inbox_prefix: Annotated[ bytes, Doc( - "Prefix for generating unique inboxes, subjects with that prefix and NUID." + "Prefix for generating unique inboxes, subjects with that prefix and NUID.", ), ] = api.INBOX_PREFIX, # custom @@ -169,7 +170,7 @@ def subscriber( # type: ignore[override] no_reply: Annotated[ bool, Doc( - "Whether to disable **FastStream** RPC and Reply To auto responses or not." + "Whether to disable **FastStream** RPC and Reply To auto responses or not.", ), ] = False, # AsyncAPI information @@ -181,7 +182,7 @@ def subscriber( # type: ignore[override] Optional[str], Doc( "AsyncAPI subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -229,7 +230,7 @@ def subscriber( # type: ignore[override] title_=title, description_=description, include_in_schema=self._solve_include_in_schema(include_in_schema), - ) + ), ), ) @@ -252,11 +253,11 @@ def publisher( # type: ignore[override] ], *, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc( "Message headers to store metainformation. " "**content-type** and **correlation_id** will be set automatically by framework anyway. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, reply_to: Annotated[ @@ -268,7 +269,7 @@ def publisher( # type: ignore[override] Union[str, "JStream", None], Doc( "This option validates that the target `subject` is in presented stream. " - "Can be omitted without any effect." + "Can be omitted without any effect.", ), ] = None, timeout: Annotated[ @@ -293,7 +294,7 @@ def publisher( # type: ignore[override] Optional[Any], Doc( "AsyncAPI publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ @@ -329,7 +330,7 @@ def publisher( # type: ignore[override] description_=description, schema_=schema, include_in_schema=self._solve_include_in_schema(include_in_schema), - ) + ), ), ) @@ -356,7 +357,7 @@ def include_router( # type: ignore[override] new_subjects = [] for subj in stream.subjects: if subj in sub_router_subjects: - new_subjects.append("".join((self.prefix, subj))) + new_subjects.append(f"{self.prefix}{subj}") else: new_subjects.append(subj) stream.subjects = new_subjects diff --git a/faststream/nats/fastapi/__init__.py b/faststream/nats/fastapi/__init__.py index 7ff134e5de..7351e313a2 100644 --- a/faststream/nats/fastapi/__init__.py +++ b/faststream/nats/fastapi/__init__.py @@ -1,6 +1,7 @@ +from typing import Annotated + from nats.aio.client import Client as NatsClient from nats.js.client import JetStreamContext -from typing_extensions import Annotated from faststream._internal.fastapi.context import Context, ContextRepo, Logger from faststream.nats.broker import NatsBroker as NB @@ -16,14 +17,14 @@ NatsJsProducer = Annotated[NatsJSFastProducer, Context("broker._js_producer")] __all__ = ( + "Client", "Context", - "Logger", "ContextRepo", - "NatsRouter", + "JsClient", + "Logger", "NatsBroker", + "NatsJsProducer", "NatsMessage", - "Client", - "JsClient", "NatsProducer", - "NatsJsProducer", + "NatsRouter", ) diff --git a/faststream/nats/fastapi/fastapi.py b/faststream/nats/fastapi/fastapi.py index 276be0968a..ad910b71b6 100644 --- a/faststream/nats/fastapi/fastapi.py +++ b/faststream/nats/fastapi/fastapi.py @@ -1,14 +1,11 @@ import logging +from collections.abc import Iterable, Sequence from typing import ( TYPE_CHECKING, + Annotated, Any, Callable, - Dict, - Iterable, - List, Optional, - Sequence, - Type, Union, cast, ) @@ -30,7 +27,7 @@ from nats.js import api from starlette.responses import JSONResponse from starlette.routing import BaseRoute -from typing_extensions import Annotated, Doc, deprecated, override +from typing_extensions import Doc, deprecated, override from faststream.__about__ import SERVICE_NAME from faststream._internal.constants import EMPTY @@ -100,7 +97,8 @@ def __init__( Doc("Callback to report when a new server joins the cluster."), ] = None, reconnected_cb: Annotated[ - Optional["Callback"], Doc("Callback to report success reconnection.") + Optional["Callback"], + Doc("Callback to report success reconnection."), ] = None, name: Annotated[ Optional[str], @@ -110,7 +108,7 @@ def __init__( bool, Doc( "Turn on NATS server pedantic mode that performs extra checks on the protocol. " - "https://docs.nats.io/using-nats/developer/connecting/misc#turn-on-pedantic-mode" + "https://docs.nats.io/using-nats/developer/connecting/misc#turn-on-pedantic-mode", ), ] = False, verbose: Annotated[ @@ -144,11 +142,12 @@ def __init__( dont_randomize: Annotated[ bool, Doc( - "Boolean indicating should client randomly shuffle servers list for reconnection randomness." + "Boolean indicating should client randomly shuffle servers list for reconnection randomness.", ), ] = False, flusher_queue_size: Annotated[ - int, Doc("Max count of commands awaiting to be flushed to the socket") + int, + Doc("Max count of commands awaiting to be flushed to the socket"), ] = DEFAULT_MAX_FLUSHER_QUEUE_SIZE, no_echo: Annotated[ bool, @@ -183,14 +182,14 @@ def __init__( Doc( "A callback used to sign a nonce from the server while " "authenticating with nkeys. The user should sign the nonce and " - "return the base64 encoded signature." + "return the base64 encoded signature.", ), ] = None, user_jwt_cb: Annotated[ Optional["JWTCallback"], Doc( "A callback used to fetch and return the account " - "signed JWT for this user." + "signed JWT for this user.", ), ] = None, user_credentials: Annotated[ @@ -204,7 +203,7 @@ def __init__( inbox_prefix: Annotated[ Union[str, bytes], Doc( - "Prefix for generating unique inboxes, subjects with that prefix and NUID.ß" + "Prefix for generating unique inboxes, subjects with that prefix and NUID.ß", ), ] = DEFAULT_INBOX_PREFIX, pending_size: Annotated[ @@ -219,7 +218,7 @@ def __init__( graceful_timeout: Annotated[ Optional[float], Doc( - "Graceful shutdown timeout. Broker waits for all running subscribers completion before shut down." + "Graceful shutdown timeout. Broker waits for all running subscribers completion before shut down.", ), ] = 15.0, decoder: Annotated[ @@ -238,7 +237,7 @@ def __init__( security: Annotated[ Optional["BaseSecurity"], Doc( - "Security options to connect broker and generate AsyncAPI server security information." + "Security options to connect broker and generate AsyncAPI server security information.", ), ] = None, specification_url: Annotated[ @@ -279,13 +278,13 @@ def __init__( bool, Doc( "Whether to add broker to app scope in lifespan. " - "You should disable this option at old ASGI servers." + "You should disable this option at old ASGI servers.", ), ] = True, schema_url: Annotated[ Optional[str], Doc( - "AsyncAPI schema url. You should set this option to `None` to disable AsyncAPI routes at all." + "AsyncAPI schema url. You should set this option to `None` to disable AsyncAPI routes at all.", ), ] = "/asyncapi", # FastAPI args @@ -294,7 +293,7 @@ def __init__( Doc("An optional path prefix for the router."), ] = "", tags: Annotated[ - Optional[List[Union[str, "Enum"]]], + Optional[list[Union[str, "Enum"]]], Doc( """ A list of tags to be applied to all the *path operations* in this @@ -304,7 +303,7 @@ def __init__( Read more about it in the [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ + """, ), ] = None, dependencies: Annotated[ @@ -316,22 +315,22 @@ def __init__( Read more about it in the [FastAPI docs for Bigger Applications - Multiple Files](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies). - """ + """, ), ] = None, default_response_class: Annotated[ - Type["Response"], + type["Response"], Doc( """ The default response class to be used. Read more in the [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#default-response-class). - """ + """, ), ] = Default(JSONResponse), responses: Annotated[ - Optional[Dict[Union[int, str], "AnyDict"]], + Optional[dict[Union[int, str], "AnyDict"]], Doc( """ Additional responses to be shown in OpenAPI. @@ -343,11 +342,11 @@ def __init__( And in the [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies). - """ + """, ), ] = None, callbacks: Annotated[ - Optional[List[BaseRoute]], + Optional[list[BaseRoute]], Doc( """ OpenAPI callbacks that should apply to all *path operations* in this @@ -357,11 +356,11 @@ def __init__( Read more about it in the [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). - """ + """, ), ] = None, routes: Annotated[ - Optional[List[BaseRoute]], + Optional[list[BaseRoute]], Doc( """ **Note**: you probably shouldn't use this parameter, it is inherited @@ -370,7 +369,7 @@ def __init__( --- A list of routes to serve incoming HTTP and WebSocket requests. - """ + """, ), deprecated( """ @@ -379,7 +378,7 @@ def __init__( In FastAPI, you normally would use the *path operation methods*, like `router.get()`, `router.post()`, etc. - """ + """, ), ] = None, redirect_slashes: Annotated[ @@ -388,7 +387,7 @@ def __init__( """ Whether to detect and redirect slashes in URLs when the client doesn't use the same format. - """ + """, ), ] = True, default: Annotated[ @@ -397,7 +396,7 @@ def __init__( """ Default function handler for this router. Used to handle 404 Not Found errors. - """ + """, ), ] = None, dependency_overrides_provider: Annotated[ @@ -408,18 +407,18 @@ def __init__( You shouldn't need to use it. It normally points to the `FastAPI` app object. - """ + """, ), ] = None, route_class: Annotated[ - Type["APIRoute"], + type["APIRoute"], Doc( """ Custom route (*path operation*) class to be used by this router. Read more about it in the [FastAPI docs for Custom Request and APIRoute class](https://fastapi.tiangolo.com/how-to/custom-request-and-route/#custom-apiroute-class-in-a-router). - """ + """, ), ] = APIRoute, on_startup: Annotated[ @@ -431,7 +430,7 @@ def __init__( You should instead use the `lifespan` handlers. Read more in the [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/). - """ + """, ), ] = None, on_shutdown: Annotated[ @@ -444,7 +443,7 @@ def __init__( Read more in the [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/). - """ + """, ), ] = None, lifespan: Annotated[ @@ -456,7 +455,7 @@ def __init__( Read more in the [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/). - """ + """, ), ] = None, deprecated: Annotated[ @@ -469,7 +468,7 @@ def __init__( Read more about it in the [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ + """, ), ] = None, include_in_schema: Annotated[ @@ -483,7 +482,7 @@ def __init__( Read more about it in the [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi). - """ + """, ), ] = True, generate_unique_id_function: Annotated[ @@ -498,7 +497,7 @@ def __init__( Read more about it in the [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). - """ + """, ), ] = Default(generate_unique_id), ) -> None: @@ -580,7 +579,7 @@ def subscriber( # type: ignore[override] str, Doc( "Subscribers' NATS queue name. Subscribers with same queue name will be load balanced by the NATS " - "server." + "server.", ), ] = "", pending_msgs_limit: Annotated[ @@ -590,7 +589,7 @@ def subscriber( # type: ignore[override] "been answered. In case of NATS Core, if that limits exceeds, you will receive NATS 'Slow Consumer' " "error. " "That's literally means that your worker can't handle the whole load. In case of NATS JetStream, " - "you will no longer receive messages until some of delivered messages will be acked in any way." + "you will no longer receive messages until some of delivered messages will be acked in any way.", ), ] = None, pending_bytes_limit: Annotated[ @@ -600,7 +599,7 @@ def subscriber( # type: ignore[override] "been answered. In case of NATS Core, if that limit exceeds, you will receive NATS 'Slow Consumer' " "error." "That's literally means that your worker can't handle the whole load. In case of NATS JetStream, " - "you will no longer receive messages until some of delivered messages will be acked in any way." + "you will no longer receive messages until some of delivered messages will be acked in any way.", ), ] = None, # Core arguments @@ -612,7 +611,7 @@ def subscriber( # type: ignore[override] durable: Annotated[ Optional[str], Doc( - "Name of the durable consumer to which the the subscription should be bound." + "Name of the durable consumer to which the the subscription should be bound.", ), ] = None, config: Annotated[ @@ -638,7 +637,7 @@ def subscriber( # type: ignore[override] headers_only: Annotated[ Optional[bool], Doc( - "Should be message delivered without payload, only headers and metadata." + "Should be message delivered without payload, only headers and metadata.", ), ] = None, # pull arguments @@ -646,7 +645,7 @@ def subscriber( # type: ignore[override] Optional["PullSub"], Doc( "NATS Pull consumer parameters container. " - "Should be used with `stream` only." + "Should be used with `stream` only.", ), ] = None, kv_watch: Annotated[ @@ -660,7 +659,7 @@ def subscriber( # type: ignore[override] inbox_prefix: Annotated[ bytes, Doc( - "Prefix for generating unique inboxes, subjects with that prefix and NUID." + "Prefix for generating unique inboxes, subjects with that prefix and NUID.", ), ] = api.INBOX_PREFIX, # custom @@ -704,7 +703,7 @@ def subscriber( # type: ignore[override] no_reply: Annotated[ bool, Doc( - "Whether to disable **FastStream** RPC and Reply To auto responses or not." + "Whether to disable **FastStream** RPC and Reply To auto responses or not.", ), ] = False, # AsyncAPI information @@ -716,7 +715,7 @@ def subscriber( # type: ignore[override] Optional[str], Doc( "AsyncAPI subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -755,7 +754,7 @@ def subscriber( # type: ignore[override] Read more about it in the [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). - """ + """, ), ] = Default(None), response_model_include: Annotated[ @@ -767,7 +766,7 @@ def subscriber( # type: ignore[override] Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = None, response_model_exclude: Annotated[ @@ -779,7 +778,7 @@ def subscriber( # type: ignore[override] Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = None, response_model_by_alias: Annotated[ @@ -791,7 +790,7 @@ def subscriber( # type: ignore[override] Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = True, response_model_exclude_unset: Annotated[ @@ -809,7 +808,7 @@ def subscriber( # type: ignore[override] Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ + """, ), ] = False, response_model_exclude_defaults: Annotated[ @@ -826,7 +825,7 @@ def subscriber( # type: ignore[override] Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ + """, ), ] = False, response_model_exclude_none: Annotated[ @@ -843,7 +842,7 @@ def subscriber( # type: ignore[override] Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). - """ + """, ), ] = False, ) -> "SpecificationSubscriber": @@ -898,11 +897,11 @@ def publisher( # type: ignore[override] Doc("NATS subject to send message."), ], headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc( "Message headers to store metainformation. " "**content-type** and **correlation_id** will be set automatically by framework anyway. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, reply_to: Annotated[ @@ -914,7 +913,7 @@ def publisher( # type: ignore[override] Union[str, "JStream", None], Doc( "This option validates that the target `subject` is in presented stream. " - "Can be omitted without any effect." + "Can be omitted without any effect.", ), ] = None, timeout: Annotated[ @@ -939,7 +938,7 @@ def publisher( # type: ignore[override] Optional[Any], Doc( "AsyncAPI publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ diff --git a/faststream/nats/helpers/__init__.py b/faststream/nats/helpers/__init__.py index 28b3479a7b..e6e661ff97 100644 --- a/faststream/nats/helpers/__init__.py +++ b/faststream/nats/helpers/__init__.py @@ -4,6 +4,6 @@ __all__ = ( "KVBucketDeclarer", - "StreamBuilder", "OSBucketDeclarer", + "StreamBuilder", ) diff --git a/faststream/nats/helpers/bucket_declarer.py b/faststream/nats/helpers/bucket_declarer.py index 916b706254..2a0c3f68e4 100644 --- a/faststream/nats/helpers/bucket_declarer.py +++ b/faststream/nats/helpers/bucket_declarer.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Dict, Optional +from typing import TYPE_CHECKING, Optional from nats.js.api import KeyValueConfig @@ -9,7 +9,7 @@ class KVBucketDeclarer: - buckets: Dict[str, "KeyValue"] + buckets: dict[str, "KeyValue"] def __init__(self, connection: "JetStreamContext") -> None: self._connection = connection @@ -47,7 +47,7 @@ async def create_key_value( placement=placement, republish=republish, direct=direct, - ) + ), ) else: key_value = await self._connection.key_value(bucket) diff --git a/faststream/nats/helpers/obj_storage_declarer.py b/faststream/nats/helpers/obj_storage_declarer.py index 1d2ae50715..f137fa1586 100644 --- a/faststream/nats/helpers/obj_storage_declarer.py +++ b/faststream/nats/helpers/obj_storage_declarer.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Dict, Optional +from typing import TYPE_CHECKING, Optional from nats.js.api import ObjectStoreConfig @@ -9,7 +9,7 @@ class OSBucketDeclarer: - buckets: Dict[str, "ObjectStore"] + buckets: dict[str, "ObjectStore"] def __init__(self, connection: "JetStreamContext") -> None: self._connection = connection diff --git a/faststream/nats/helpers/object_builder.py b/faststream/nats/helpers/object_builder.py index 5d40a44da6..7e9fb86f13 100644 --- a/faststream/nats/helpers/object_builder.py +++ b/faststream/nats/helpers/object_builder.py @@ -1,4 +1,4 @@ -from typing import Dict, Optional, Union +from typing import Optional, Union from faststream.nats.schemas import JStream @@ -8,7 +8,7 @@ class StreamBuilder: __slots__ = ("objects",) - objects: Dict[str, "JStream"] + objects: dict[str, "JStream"] def __init__(self) -> None: """Initialize the builder.""" diff --git a/faststream/nats/message.py b/faststream/nats/message.py index 69c5cc9ac1..c3e5b5a158 100644 --- a/faststream/nats/message.py +++ b/faststream/nats/message.py @@ -1,4 +1,4 @@ -from typing import List, Union +from typing import Optional from nats.aio.msg import Msg from nats.js.api import ObjectInfo @@ -19,7 +19,7 @@ async def ack(self) -> None: async def nack( self, - delay: Union[int, float, None] = None, + delay: Optional[float] = None, ) -> None: if not self.raw_message._ackd: await self.raw_message.nak(delay=delay) @@ -35,7 +35,7 @@ async def in_progress(self) -> None: await self.raw_message.in_progress() -class NatsBatchMessage(StreamMessage[List[Msg]]): +class NatsBatchMessage(StreamMessage[list[Msg]]): """A class to represent a NATS batch message.""" async def ack(self) -> None: @@ -49,7 +49,7 @@ async def ack(self) -> None: async def nack( self, - delay: Union[int, float, None] = None, + delay: Optional[float] = None, ) -> None: for m in filter( lambda m: not m._ackd, diff --git a/faststream/nats/opentelemetry/provider.py b/faststream/nats/opentelemetry/provider.py index 32c8a216d1..93364d7bb2 100644 --- a/faststream/nats/opentelemetry/provider.py +++ b/faststream/nats/opentelemetry/provider.py @@ -1,4 +1,5 @@ -from typing import TYPE_CHECKING, List, Optional, Sequence, Union, overload +from collections.abc import Sequence +from typing import TYPE_CHECKING, Optional, Union, overload from nats.aio.msg import Msg from opentelemetry.semconv.trace import SpanAttributes @@ -58,11 +59,11 @@ def get_consume_destination_name( class NatsBatchTelemetrySettingsProvider( - BaseNatsTelemetrySettingsProvider[List["Msg"]] + BaseNatsTelemetrySettingsProvider[list["Msg"]], ): def get_consume_attrs_from_message( self, - msg: "StreamMessage[List[Msg]]", + msg: "StreamMessage[list[Msg]]", ) -> "AnyDict": return { SpanAttributes.MESSAGING_SYSTEM: self.messaging_system, @@ -75,7 +76,7 @@ def get_consume_attrs_from_message( def get_consume_destination_name( self, - msg: "StreamMessage[List[Msg]]", + msg: "StreamMessage[list[Msg]]", ) -> str: return msg.raw_message[0].subject @@ -110,8 +111,7 @@ def telemetry_attributes_provider_factory( ]: if isinstance(msg, Sequence): return NatsBatchTelemetrySettingsProvider() - elif isinstance(msg, Msg) or msg is None: + if isinstance(msg, Msg) or msg is None: return NatsTelemetrySettingsProvider() - else: - # KeyValue and Object Storage watch cases - return None + # KeyValue and Object Storage watch cases + return None diff --git a/faststream/nats/parser.py b/faststream/nats/parser.py index e9820d8fad..0f3b2f4c8c 100644 --- a/faststream/nats/parser.py +++ b/faststream/nats/parser.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Any, Dict, List, Optional +from typing import TYPE_CHECKING, Any, Optional from faststream.message import ( StreamMessage, @@ -115,10 +115,10 @@ class BatchParser(JsParser): async def parse_batch( self, - message: List["Msg"], - ) -> "StreamMessage[List[Msg]]": - body: List[bytes] = [] - batch_headers: List[Dict[str, str]] = [] + message: list["Msg"], + ) -> "StreamMessage[list[Msg]]": + body: list[bytes] = [] + batch_headers: list[dict[str, str]] = [] if message: path = self.get_path(message[0].subject) @@ -142,9 +142,9 @@ async def parse_batch( async def decode_batch( self, - msg: "StreamMessage[List[Msg]]", - ) -> List["DecodedMessage"]: - data: List[DecodedMessage] = [] + msg: "StreamMessage[list[Msg]]", + ) -> list["DecodedMessage"]: + data: list[DecodedMessage] = [] path: Optional[AnyDict] = None for m in msg.raw_message: @@ -158,7 +158,8 @@ async def decode_batch( class KvParser(NatsBaseParser): async def parse_message( - self, msg: "KeyValue.Entry" + self, + msg: "KeyValue.Entry", ) -> StreamMessage["KeyValue.Entry"]: return NatsKvMessage( raw_message=msg, diff --git a/faststream/nats/publisher/producer.py b/faststream/nats/publisher/producer.py index f4859d1f6e..05d3a81402 100644 --- a/faststream/nats/publisher/producer.py +++ b/faststream/nats/publisher/producer.py @@ -1,5 +1,5 @@ import asyncio -from typing import TYPE_CHECKING, Any, Dict, Optional +from typing import TYPE_CHECKING, Any, Optional import anyio import nats @@ -48,7 +48,7 @@ async def publish( # type: ignore[override] subject: str, *, correlation_id: str, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, reply_to: str = "", **kwargs: Any, # suprress stream option ) -> None: @@ -67,8 +67,6 @@ async def publish( # type: ignore[override] headers=headers_to_send, ) - return None - @override async def request( # type: ignore[override] self, @@ -76,7 +74,7 @@ async def request( # type: ignore[override] subject: str, *, correlation_id: str, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, timeout: float = 0.5, ) -> "Msg": payload, content_type = encode_message(message) @@ -121,7 +119,7 @@ async def publish( # type: ignore[override] subject: str, *, correlation_id: str, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, reply_to: str = "", stream: Optional[str] = None, timeout: Optional[float] = None, @@ -154,7 +152,7 @@ async def request( # type: ignore[override] subject: str, *, correlation_id: str, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, stream: Optional[str] = None, timeout: float = 0.5, ) -> "Msg": diff --git a/faststream/nats/publisher/publisher.py b/faststream/nats/publisher/publisher.py index 2a16be477b..f80cd8dccb 100644 --- a/faststream/nats/publisher/publisher.py +++ b/faststream/nats/publisher/publisher.py @@ -1,4 +1,5 @@ -from typing import TYPE_CHECKING, Any, Dict, Iterable, Optional +from collections.abc import Iterable +from typing import TYPE_CHECKING, Any, Optional from typing_extensions import override @@ -22,7 +23,7 @@ class SpecificationPublisher(LogicPublisher): def get_name(self) -> str: return f"{self.subject}:Publisher" - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> dict[str, Channel]: payloads = self.get_payloads() return { @@ -33,16 +34,16 @@ def get_schema(self) -> Dict[str, Channel]: title=f"{self.name}:Message", payload=resolve_payloads(payloads, "Publisher"), correlationId=CorrelationId( - location="$message.header#/correlation_id" + location="$message.header#/correlation_id", ), ), ), bindings=ChannelBinding( nats=nats.ChannelBinding( subject=self.subject, - ) + ), ), - ) + ), } @override @@ -52,7 +53,7 @@ def create( # type: ignore[override] *, subject: str, reply_to: str, - headers: Optional[Dict[str, str]], + headers: Optional[dict[str, str]], stream: Optional["JStream"], timeout: Optional[float], # Publisher args diff --git a/faststream/nats/publisher/usecase.py b/faststream/nats/publisher/usecase.py index c458126839..f76e24d070 100644 --- a/faststream/nats/publisher/usecase.py +++ b/faststream/nats/publisher/usecase.py @@ -1,18 +1,17 @@ +from collections.abc import Awaitable, Iterable from functools import partial from itertools import chain from typing import ( TYPE_CHECKING, + Annotated, Any, - Awaitable, Callable, - Dict, - Iterable, Optional, Union, ) from nats.aio.msg import Msg -from typing_extensions import Annotated, Doc, override +from typing_extensions import Doc, override from faststream._internal.publisher.usecase import PublisherUsecase from faststream._internal.subscriber.utils import process_msg @@ -37,7 +36,7 @@ def __init__( *, subject: str, reply_to: str, - headers: Optional[Dict[str, str]], + headers: Optional[dict[str, str]], stream: Optional["JStream"], timeout: Optional[float], # Publisher args @@ -72,7 +71,7 @@ async def publish( message: "SendableMessage", subject: str = "", *, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, reply_to: str = "", correlation_id: Optional[str] = None, stream: Optional[str] = None, @@ -131,7 +130,7 @@ async def request( "SendableMessage", Doc( "Message body to send. " - "Can be any encodable object (native python types or `pydantic.BaseModel`)." + "Can be any encodable object (native python types or `pydantic.BaseModel`).", ), ], subject: Annotated[ @@ -140,17 +139,17 @@ async def request( ] = "", *, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc( "Message headers to store metainformation. " - "**content-type** and **correlation_id** will be set automatically by framework anyway." + "**content-type** and **correlation_id** will be set automatically by framework anyway.", ), ] = None, correlation_id: Annotated[ Optional[str], Doc( "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages." + "**correlation_id** is a useful option to trace messages.", ), ] = None, timeout: Annotated[ diff --git a/faststream/nats/response.py b/faststream/nats/response.py index 928be98ef5..625ac866f0 100644 --- a/faststream/nats/response.py +++ b/faststream/nats/response.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Dict, Optional +from typing import TYPE_CHECKING, Optional from typing_extensions import override @@ -13,7 +13,7 @@ def __init__( self, body: "SendableMessage", *, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, correlation_id: Optional[str] = None, stream: Optional[str] = None, ) -> None: @@ -26,8 +26,7 @@ def __init__( @override def as_publish_kwargs(self) -> "AnyDict": - publish_options = { + return { **super().as_publish_kwargs(), "stream": self.stream, } - return publish_options diff --git a/faststream/nats/router.py b/faststream/nats/router.py index 45c8d9866a..982f274b50 100644 --- a/faststream/nats/router.py +++ b/faststream/nats/router.py @@ -1,16 +1,15 @@ +from collections.abc import Awaitable, Iterable from typing import ( TYPE_CHECKING, + Annotated, Any, - Awaitable, Callable, - Dict, - Iterable, Optional, Union, ) from nats.js import api -from typing_extensions import Annotated, Doc +from typing_extensions import Doc from faststream._internal.broker.router import ( ArgsContainer, @@ -48,11 +47,11 @@ def __init__( ], *, headers: Annotated[ - Optional[Dict[str, str]], + Optional[dict[str, str]], Doc( "Message headers to store metainformation. " "**content-type** and **correlation_id** will be set automatically by framework anyway. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, reply_to: Annotated[ @@ -64,7 +63,7 @@ def __init__( Union[str, "JStream", None], Doc( "This option validates that the target `subject` is in presented stream. " - "Can be omitted without any effect." + "Can be omitted without any effect.", ), ] = None, timeout: Annotated[ @@ -89,7 +88,7 @@ def __init__( Optional[Any], Doc( "AsyncAPI publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ @@ -123,7 +122,7 @@ def __init__( ], Doc( "Message handler function " - "to wrap the same with `@broker.subscriber(...)` way." + "to wrap the same with `@broker.subscriber(...)` way.", ), ], subject: Annotated[ @@ -138,7 +137,7 @@ def __init__( str, Doc( "Subscribers' NATS queue name. Subscribers with same queue name will be load balanced by the NATS " - "server." + "server.", ), ] = "", pending_msgs_limit: Annotated[ @@ -148,7 +147,7 @@ def __init__( "been answered. In case of NATS Core, if that limits exceeds, you will receive NATS 'Slow Consumer' " "error. " "That's literally means that your worker can't handle the whole load. In case of NATS JetStream, " - "you will no longer receive messages until some of delivered messages will be acked in any way." + "you will no longer receive messages until some of delivered messages will be acked in any way.", ), ] = None, pending_bytes_limit: Annotated[ @@ -158,7 +157,7 @@ def __init__( "been answered. In case of NATS Core, if that limit exceeds, you will receive NATS 'Slow Consumer' " "error." "That's literally means that your worker can't handle the whole load. In case of NATS JetStream, " - "you will no longer receive messages until some of delivered messages will be acked in any way." + "you will no longer receive messages until some of delivered messages will be acked in any way.", ), ] = None, # Core arguments @@ -170,7 +169,7 @@ def __init__( durable: Annotated[ Optional[str], Doc( - "Name of the durable consumer to which the the subscription should be bound." + "Name of the durable consumer to which the the subscription should be bound.", ), ] = None, config: Annotated[ @@ -196,7 +195,7 @@ def __init__( headers_only: Annotated[ Optional[bool], Doc( - "Should be message delivered without payload, only headers and metadata." + "Should be message delivered without payload, only headers and metadata.", ), ] = None, # pull arguments @@ -204,7 +203,7 @@ def __init__( Optional["PullSub"], Doc( "NATS Pull consumer parameters container. " - "Should be used with `stream` only." + "Should be used with `stream` only.", ), ] = None, kv_watch: Annotated[ @@ -218,7 +217,7 @@ def __init__( inbox_prefix: Annotated[ bytes, Doc( - "Prefix for generating unique inboxes, subjects with that prefix and NUID." + "Prefix for generating unique inboxes, subjects with that prefix and NUID.", ), ] = api.INBOX_PREFIX, # custom @@ -262,7 +261,7 @@ def __init__( no_reply: Annotated[ bool, Doc( - "Whether to disable **FastStream** RPC and Reply To auto responses or not." + "Whether to disable **FastStream** RPC and Reply To auto responses or not.", ), ] = False, # AsyncAPI information @@ -274,7 +273,7 @@ def __init__( Optional[str], Doc( "AsyncAPI subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -337,7 +336,7 @@ def __init__( dependencies: Annotated[ Iterable["Depends"], Doc( - "Dependencies list (`[Depends(),]`) to apply to all routers' publishers/subscribers." + "Dependencies list (`[Depends(),]`) to apply to all routers' publishers/subscribers.", ), ] = (), middlewares: Annotated[ diff --git a/faststream/nats/schemas/__init__.py b/faststream/nats/schemas/__init__.py index ca9f56f48d..1edd51bcbe 100644 --- a/faststream/nats/schemas/__init__.py +++ b/faststream/nats/schemas/__init__.py @@ -5,7 +5,7 @@ __all__ = ( "JStream", - "PullSub", "KvWatch", "ObjWatch", + "PullSub", ) diff --git a/faststream/nats/schemas/js_stream.py b/faststream/nats/schemas/js_stream.py index c155df5e0d..da6e41f3bf 100644 --- a/faststream/nats/schemas/js_stream.py +++ b/faststream/nats/schemas/js_stream.py @@ -1,8 +1,8 @@ from itertools import zip_longest -from typing import TYPE_CHECKING, List, Optional, Tuple +from typing import TYPE_CHECKING, Annotated, Optional from nats.js.api import DiscardPolicy, StreamConfig -from typing_extensions import Annotated, Doc +from typing_extensions import Doc from faststream._internal.proto import NameRequired from faststream._internal.utils.path import compile_path @@ -23,10 +23,10 @@ class JStream(NameRequired): """A class to represent a JetStream stream.""" __slots__ = ( - "name", "config", - "subjects", "declare", + "name", + "subjects", ) def __init__( @@ -40,12 +40,12 @@ def __init__( Doc("Stream description if needed."), ] = None, subjects: Annotated[ - Optional[List[str]], + Optional[list[str]], Doc( "Subjects, used by stream to grab messages from them. Any message sent by NATS Core will be consumed " "by stream. Also, stream acknowledge message publisher with message, sent on reply subject of " "publisher. Can be single string or list of them. Dots separate tokens of subjects, every token may " - "be matched with exact same token or wildcards." + "be matched with exact same token or wildcards.", ), ] = None, retention: Annotated[ @@ -60,24 +60,25 @@ def __init__( "which guarantees message to be consumed only once. Since message acked, it will be deleted from the " "stream immediately. Note: Message will be deleted only if limit is reached or message acked " "successfully. Message that reached MaxDelivery limit will remain in the stream and should be " - "manually deleted! Note: All policies will be responsive to Limits." + "manually deleted! Note: All policies will be responsive to Limits.", ), ] = None, max_consumers: Annotated[ - Optional[int], Doc("Max number of consumers to be bound with this stream.") + Optional[int], + Doc("Max number of consumers to be bound with this stream."), ] = None, max_msgs: Annotated[ Optional[int], Doc( "Max number of messages to be stored in the stream. Stream can automatically delete old messages or " - "stop receiving new messages, look for 'DiscardPolicy'" + "stop receiving new messages, look for 'DiscardPolicy'", ), ] = None, max_bytes: Annotated[ Optional[int], Doc( "Max bytes of all messages to be stored in the stream. Stream can automatically delete old messages or " - "stop receiving new messages, look for 'DiscardPolicy'" + "stop receiving new messages, look for 'DiscardPolicy'", ), ] = None, discard: Annotated[ @@ -88,27 +89,27 @@ def __init__( Optional[float], Doc( "TTL in seconds for messages. Since message arrive, TTL begun. As soon as TTL exceeds, message will be " - "deleted." + "deleted.", ), ] = None, # in seconds max_msgs_per_subject: Annotated[ int, Doc( - "Limit message count per every unique subject. Stream index subjects to it's pretty fast tho.-" + "Limit message count per every unique subject. Stream index subjects to it's pretty fast tho.-", ), ] = -1, max_msg_size: Annotated[ Optional[int], Doc( "Limit message size to be received. Note: the whole message can't be larger than NATS Core message " - "limit." + "limit.", ), ] = -1, storage: Annotated[ Optional["StorageType"], Doc( "Storage type, disk or memory. Disk is more durable, memory is faster. Memory can be better choice " - "for systems, where new value overrides previous." + "for systems, where new value overrides previous.", ), ] = None, num_replicas: Annotated[ @@ -116,14 +117,14 @@ def __init__( Doc( "Replicas of stream to be used. All replicas create RAFT group with leader. In case of losing lesser " "than half, cluster will be available to reads and writes. In case of losing slightly more than half, " - "cluster may be available but for reads only." + "cluster may be available but for reads only.", ), ] = None, no_ack: Annotated[ bool, Doc( "Should stream acknowledge writes or not. Without acks publisher can't determine, does message " - "received by stream or not." + "received by stream or not.", ), ] = False, template_owner: Optional[str] = None, @@ -132,25 +133,25 @@ def __init__( Doc( "A TTL for keys in implicit TTL-based hashmap of stream. That hashmap allows to early drop duplicate " "messages. Essential feature for idempotent writes. Note: disabled by default. Look for 'Nats-Msg-Id' " - "in NATS documentation for more information." + "in NATS documentation for more information.", ), ] = 0, placement: Annotated[ Optional["Placement"], Doc( - "NATS Cluster for stream to be deployed in. Value is name of that cluster." + "NATS Cluster for stream to be deployed in. Value is name of that cluster.", ), ] = None, mirror: Annotated[ Optional["StreamSource"], Doc( - "Should stream be read-only replica of another stream, if so, value is name of that stream." + "Should stream be read-only replica of another stream, if so, value is name of that stream.", ), ] = None, sources: Annotated[ - Optional[List["StreamSource"]], + Optional[list["StreamSource"]], Doc( - "Should stream mux multiple streams into single one, if so, values is names of those streams." + "Should stream mux multiple streams into single one, if so, values is names of those streams.", ), ] = None, sealed: Annotated[ @@ -245,14 +246,14 @@ def is_subject_match_wildcard(subject: str, wildcard: str) -> bool: if base == ">": break - if base != "*" and current != base: + if base not in {"*", current}: call = False break return call -def compile_nats_wildcard(pattern: str) -> Tuple[Optional["Pattern[str]"], str]: +def compile_nats_wildcard(pattern: str) -> tuple[Optional["Pattern[str]"], str]: return compile_path( pattern, replace_symbol="*", diff --git a/faststream/nats/schemas/kv_watch.py b/faststream/nats/schemas/kv_watch.py index 0489618273..1bc3f1374f 100644 --- a/faststream/nats/schemas/kv_watch.py +++ b/faststream/nats/schemas/kv_watch.py @@ -19,13 +19,13 @@ class KvWatch(NameRequired): __slots__ = ( "bucket", + "declare", "headers_only", - "include_history", "ignore_deletes", - "meta_only", "inactive_threshold", + "include_history", + "meta_only", "timeout", - "declare", ) def __init__( diff --git a/faststream/nats/schemas/obj_watch.py b/faststream/nats/schemas/obj_watch.py index 3a5648e7c8..c8a3b9f245 100644 --- a/faststream/nats/schemas/obj_watch.py +++ b/faststream/nats/schemas/obj_watch.py @@ -13,11 +13,11 @@ class ObjWatch: """ __slots__ = ( + "declare", "ignore_deletes", "include_history", "meta_only", "timeout", - "declare", ) def __init__( @@ -56,7 +56,6 @@ def validate(cls, value: Union[bool, "ObjWatch"]) -> Optional["ObjWatch"]: ... def validate(cls, value: Union[bool, "ObjWatch"]) -> Optional["ObjWatch"]: if value is True: return ObjWatch() - elif value is False: + if value is False: return None - else: - return value + return value diff --git a/faststream/nats/schemas/pull_sub.py b/faststream/nats/schemas/pull_sub.py index b38b48ebdb..2075b31834 100644 --- a/faststream/nats/schemas/pull_sub.py +++ b/faststream/nats/schemas/pull_sub.py @@ -47,7 +47,6 @@ def validate(cls, value: Union[bool, "PullSub"]) -> Optional["PullSub"]: ... def validate(cls, value: Union[bool, "PullSub"]) -> Optional["PullSub"]: if value is True: return PullSub() - elif value is False: + if value is False: return None - else: - return value + return value diff --git a/faststream/nats/security.py b/faststream/nats/security.py index 4d1e855caf..8aa20e6acc 100644 --- a/faststream/nats/security.py +++ b/faststream/nats/security.py @@ -12,12 +12,12 @@ def parse_security(security: Optional[BaseSecurity]) -> "AnyDict": if security is None: return {} - elif isinstance(security, SASLPlaintext): + if isinstance(security, SASLPlaintext): return _parse_sasl_plaintext(security) - elif isinstance(security, BaseSecurity): + if isinstance(security, BaseSecurity): return _parse_base_security(security) - else: - raise NotImplementedError(f"NatsBroker does not support {type(security)}") + msg = f"NatsBroker does not support {type(security)}" + raise NotImplementedError(msg) def _parse_base_security(security: BaseSecurity) -> "AnyDict": diff --git a/faststream/nats/subscriber/factory.py b/faststream/nats/subscriber/factory.py index 5395df4dbe..b3170988b8 100644 --- a/faststream/nats/subscriber/factory.py +++ b/faststream/nats/subscriber/factory.py @@ -1,4 +1,5 @@ -from typing import TYPE_CHECKING, Any, Iterable, Optional, Union +from collections.abc import Iterable +from typing import TYPE_CHECKING, Any, Optional, Union from nats.aio.subscription import ( DEFAULT_SUB_PENDING_BYTES_LIMIT, @@ -79,10 +80,12 @@ def create_subscriber( "SpecificationObjStoreWatchSubscriber", ]: if pull_sub is not None and stream is None: - raise SetupError("Pull subscriber can be used only with a stream") + msg = "Pull subscriber can be used only with a stream" + raise SetupError(msg) if not subject and not config: - raise SetupError("You must provide either `subject` or `config` option.") + msg = "You must provide either `subject` or `config` option." + raise SetupError(msg) config = config or ConsumerConfig(filter_subjects=[]) @@ -111,7 +114,7 @@ def create_subscriber( "deliver_policy": deliver_policy, "headers_only": headers_only, "manual_ack": not ack_first, - } + }, ) else: @@ -146,7 +149,7 @@ def create_subscriber( include_in_schema=include_in_schema, ) - elif stream is None: + if stream is None: if max_workers > 1: return SpecificationConcurrentCoreSubscriber( max_workers=max_workers, @@ -167,11 +170,32 @@ def create_subscriber( include_in_schema=include_in_schema, ) - else: - return SpecificationCoreSubscriber( + return SpecificationCoreSubscriber( + subject=subject, + config=config, + queue=queue, + # basic args + extra_options=extra_options, + # Subscriber args + no_ack=no_ack, + no_reply=no_reply, + retry=retry, + broker_dependencies=broker_dependencies, + broker_middlewares=broker_middlewares, + # Specification + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + ) + + if max_workers > 1: + if pull_sub is not None: + return SpecificationConcurrentPullStreamSubscriber( + max_workers=max_workers, + pull_sub=pull_sub, + stream=stream, subject=subject, config=config, - queue=queue, # basic args extra_options=extra_options, # Subscriber args @@ -186,108 +210,81 @@ def create_subscriber( include_in_schema=include_in_schema, ) - else: - if max_workers > 1: - if pull_sub is not None: - return SpecificationConcurrentPullStreamSubscriber( - max_workers=max_workers, - pull_sub=pull_sub, - stream=stream, - subject=subject, - config=config, - # basic args - extra_options=extra_options, - # Subscriber args - no_ack=no_ack, - no_reply=no_reply, - retry=retry, - broker_dependencies=broker_dependencies, - broker_middlewares=broker_middlewares, - # Specification - title_=title_, - description_=description_, - include_in_schema=include_in_schema, - ) - - else: - return SpecificationConcurrentPushStreamSubscriber( - max_workers=max_workers, - stream=stream, - subject=subject, - config=config, - queue=queue, - # basic args - extra_options=extra_options, - # Subscriber args - no_ack=no_ack, - no_reply=no_reply, - retry=retry, - broker_dependencies=broker_dependencies, - broker_middlewares=broker_middlewares, - # Specification - title_=title_, - description_=description_, - include_in_schema=include_in_schema, - ) + return SpecificationConcurrentPushStreamSubscriber( + max_workers=max_workers, + stream=stream, + subject=subject, + config=config, + queue=queue, + # basic args + extra_options=extra_options, + # Subscriber args + no_ack=no_ack, + no_reply=no_reply, + retry=retry, + broker_dependencies=broker_dependencies, + broker_middlewares=broker_middlewares, + # Specification + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + ) - else: - if pull_sub is not None: - if pull_sub.batch: - return SpecificationBatchPullStreamSubscriber( - pull_sub=pull_sub, - stream=stream, - subject=subject, - config=config, - # basic args - extra_options=extra_options, - # Subscriber args - no_ack=no_ack, - no_reply=no_reply, - retry=retry, - broker_dependencies=broker_dependencies, - broker_middlewares=broker_middlewares, - # Specification - title_=title_, - description_=description_, - include_in_schema=include_in_schema, - ) + if pull_sub is not None: + if pull_sub.batch: + return SpecificationBatchPullStreamSubscriber( + pull_sub=pull_sub, + stream=stream, + subject=subject, + config=config, + # basic args + extra_options=extra_options, + # Subscriber args + no_ack=no_ack, + no_reply=no_reply, + retry=retry, + broker_dependencies=broker_dependencies, + broker_middlewares=broker_middlewares, + # Specification + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + ) - else: - return SpecificationPullStreamSubscriber( - pull_sub=pull_sub, - stream=stream, - subject=subject, - config=config, - # basic args - extra_options=extra_options, - # Subscriber args - no_ack=no_ack, - no_reply=no_reply, - retry=retry, - broker_dependencies=broker_dependencies, - broker_middlewares=broker_middlewares, - # Specification - title_=title_, - description_=description_, - include_in_schema=include_in_schema, - ) + return SpecificationPullStreamSubscriber( + pull_sub=pull_sub, + stream=stream, + subject=subject, + config=config, + # basic args + extra_options=extra_options, + # Subscriber args + no_ack=no_ack, + no_reply=no_reply, + retry=retry, + broker_dependencies=broker_dependencies, + broker_middlewares=broker_middlewares, + # Specification + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + ) - else: - return SpecificationStreamSubscriber( - stream=stream, - subject=subject, - queue=queue, - config=config, - # basic args - extra_options=extra_options, - # Subscriber args - no_ack=no_ack, - no_reply=no_reply, - retry=retry, - broker_dependencies=broker_dependencies, - broker_middlewares=broker_middlewares, - # Specification information - title_=title_, - description_=description_, - include_in_schema=include_in_schema, - ) + return SpecificationStreamSubscriber( + stream=stream, + subject=subject, + queue=queue, + config=config, + # basic args + extra_options=extra_options, + # Subscriber args + no_ack=no_ack, + no_reply=no_reply, + retry=retry, + broker_dependencies=broker_dependencies, + broker_middlewares=broker_middlewares, + # Specification information + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + ) diff --git a/faststream/nats/subscriber/subscriber.py b/faststream/nats/subscriber/subscriber.py index a7a26f33d2..09320906a4 100644 --- a/faststream/nats/subscriber/subscriber.py +++ b/faststream/nats/subscriber/subscriber.py @@ -1,4 +1,4 @@ -from typing import Any, Dict +from typing import Any from typing_extensions import override @@ -27,7 +27,7 @@ class SpecificationSubscriber(LogicSubscriber[Any, Any]): def get_name(self) -> str: return f"{self.subject}:{self.call_name}" - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> dict[str, Channel]: payloads = self.get_payloads() return { @@ -38,7 +38,7 @@ def get_schema(self) -> Dict[str, Channel]: title=f"{self.name}:Message", payload=resolve_payloads(payloads), correlationId=CorrelationId( - location="$message.header#/correlation_id" + location="$message.header#/correlation_id", ), ), ), @@ -46,9 +46,9 @@ def get_schema(self) -> Dict[str, Channel]: nats=nats.ChannelBinding( subject=self.subject, queue=getattr(self, "queue", "") or None, - ) + ), ), - ) + ), } @@ -112,7 +112,7 @@ def get_name(self) -> str: return "" @override - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> dict[str, Channel]: return {} @@ -127,5 +127,5 @@ def get_name(self) -> str: return "" @override - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> dict[str, Channel]: return {} diff --git a/faststream/nats/subscriber/usecase.py b/faststream/nats/subscriber/usecase.py index 9a44ddf6e2..457db20587 100644 --- a/faststream/nats/subscriber/usecase.py +++ b/faststream/nats/subscriber/usecase.py @@ -1,18 +1,14 @@ import asyncio from abc import abstractmethod +from collections.abc import Awaitable, Coroutine, Iterable, Sequence from contextlib import suppress from typing import ( TYPE_CHECKING, + Annotated, Any, - Awaitable, Callable, - Coroutine, - Dict, Generic, - Iterable, - List, Optional, - Sequence, TypeVar, Union, cast, @@ -22,7 +18,7 @@ from fast_depends.dependencies import Depends from nats.errors import ConnectionClosedError, TimeoutError from nats.js.api import ConsumerConfig, ObjectInfo -from typing_extensions import Annotated, Doc, override +from typing_extensions import Doc, override from faststream._internal.context.repository import context from faststream._internal.publisher.fake import FakePublisher @@ -73,7 +69,7 @@ ConnectionType = TypeVar("ConnectionType") -class LogicSubscriber(Generic[ConnectionType, MsgType], SubscriberUsecase[MsgType]): +class LogicSubscriber(SubscriberUsecase[MsgType], Generic[ConnectionType, MsgType]): """A class to represent a NATS handler.""" subscription: Optional[Unsubscriptable] @@ -187,7 +183,7 @@ async def _create_subscription( connection: ConnectionType, ) -> None: """Create NATS subscription object to consume messages.""" - raise NotImplementedError() + raise NotImplementedError @staticmethod def build_log_context( @@ -208,7 +204,7 @@ def build_log_context( str, Doc("Stream object we are listening"), ] = "", - ) -> Dict[str, str]: + ) -> dict[str, str]: """Static method to build log context out of `self.consume` scope.""" return { "subject": subject, @@ -220,11 +216,10 @@ def build_log_context( def add_prefix(self, prefix: str) -> None: """Include Subscriber in router.""" if self.subject: - self.subject = "".join((prefix, self.subject)) + self.subject = f"{prefix}{self.subject}" else: self.config.filter_subjects = [ - "".join((prefix, subject)) - for subject in (self.config.filter_subjects or ()) + f"{prefix}{subject}" for subject in (self.config.filter_subjects or ()) ] @property @@ -295,7 +290,7 @@ def get_log_context( Optional["StreamMessage[MsgType]"], Doc("Message which we are building context for"), ], - ) -> Dict[str, str]: + ) -> dict[str, str]: """Log context factory using in `self.consume` scope.""" return self.build_log_context( message=message, @@ -305,7 +300,7 @@ def get_log_context( class _TasksMixin(LogicSubscriber[Any, Any]): def __init__(self, **kwargs: Any) -> None: - self.tasks: List[asyncio.Task[Any]] = [] + self.tasks: list[asyncio.Task[Any]] = [] super().__init__(**kwargs) @@ -336,7 +331,7 @@ def __init__( self.max_workers = max_workers self.send_stream, self.receive_stream = anyio.create_memory_object_stream( - max_buffer_size=max_workers + max_buffer_size=max_workers, ) self.limiter = anyio.Semaphore(max_workers) @@ -472,7 +467,7 @@ def get_log_context( Optional["StreamMessage[Msg]"], Doc("Message which we are building context for"), ], - ) -> Dict[str, str]: + ) -> dict[str, str]: """Log context factory using in `self.consume` scope.""" return self.build_log_context( message=message, @@ -597,7 +592,7 @@ def get_log_context( Optional["StreamMessage[Msg]"], Doc("Message which we are building context for"), ], - ) -> Dict[str, str]: + ) -> dict[str, str]: """Log context factory using in `self.consume` scope.""" return self.build_log_context( message=message, @@ -894,7 +889,7 @@ async def _create_subscription( class BatchPullStreamSubscriber( _TasksMixin, - _DefaultSubscriber["JetStreamContext", List["Msg"]], + _DefaultSubscriber["JetStreamContext", list["Msg"]], ): """Batch-message consumer class.""" @@ -915,7 +910,7 @@ def __init__( no_reply: bool, retry: Union[bool, int], broker_dependencies: Iterable[Depends], - broker_middlewares: Iterable["BrokerMiddleware[List[Msg]]"], + broker_middlewares: Iterable["BrokerMiddleware[list[Msg]]"], # AsyncAPI args title_: Optional[str], description_: Optional[str], @@ -1077,7 +1072,7 @@ async def get_one( include_history=self.kv_watch.include_history, ignore_deletes=self.kv_watch.ignore_deletes, meta_only=self.kv_watch.meta_only, - ) + ), ) else: fetch_sub = self._fetch_sub @@ -1119,7 +1114,7 @@ async def _create_subscription( include_history=self.kv_watch.include_history, ignore_deletes=self.kv_watch.ignore_deletes, meta_only=self.kv_watch.meta_only, - ) + ), ) self.add_task(self._consume_watch()) @@ -1155,7 +1150,7 @@ def get_log_context( Optional["StreamMessage[KeyValue.Entry]"], Doc("Message which we are building context for"), ], - ) -> Dict[str, str]: + ) -> dict[str, str]: """Log context factory using in `self.consume` scope.""" return self.build_log_context( message=message, @@ -1181,7 +1176,7 @@ def __init__( config: "ConsumerConfig", obj_watch: "ObjWatch", broker_dependencies: Iterable[Depends], - broker_middlewares: Iterable["BrokerMiddleware[List[Msg]]"], + broker_middlewares: Iterable["BrokerMiddleware[list[Msg]]"], # AsyncAPI args title_: Optional[str], description_: Optional[str], @@ -1308,7 +1303,7 @@ def get_log_context( Optional["StreamMessage[ObjectInfo]"], Doc("Message which we are building context for"), ], - ) -> Dict[str, str]: + ) -> dict[str, str]: """Log context factory using in `self.consume` scope.""" return self.build_log_context( message=message, diff --git a/faststream/nats/testing.py b/faststream/nats/testing.py index ceabb66ed9..4df82ae989 100644 --- a/faststream/nats/testing.py +++ b/faststream/nats/testing.py @@ -1,12 +1,8 @@ +from collections.abc import Generator, Iterable from typing import ( TYPE_CHECKING, Any, - Dict, - Generator, - Iterable, - List, Optional, - Tuple, Union, ) from unittest.mock import AsyncMock @@ -39,7 +35,7 @@ class TestNatsBroker(TestBroker[NatsBroker]): def create_publisher_fake_subscriber( broker: NatsBroker, publisher: "SpecificationPublisher", - ) -> Tuple["LogicSubscriber[Any, Any]", bool]: + ) -> tuple["LogicSubscriber[Any, Any]", bool]: sub: Optional[LogicSubscriber[Any, Any]] = None publisher_stream = publisher.stream.name if publisher.stream else None for handler in broker._subscribers: @@ -82,7 +78,7 @@ async def publish( # type: ignore[override] message: "SendableMessage", subject: str, reply_to: str = "", - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, correlation_id: Optional[str] = None, # NatsJSFastProducer compatibility timeout: Optional[float] = None, @@ -101,7 +97,7 @@ async def publish( # type: ignore[override] subject, stream, ): - msg: Union[List[PatchedMessage], PatchedMessage] + msg: Union[list[PatchedMessage], PatchedMessage] if (pull := getattr(handler, "pull_sub", None)) and pull.batch: msg = [incoming] @@ -110,8 +106,6 @@ async def publish( # type: ignore[override] await self._execute_handler(msg, subject, handler) - return None - @override async def request( # type: ignore[override] self, @@ -119,7 +113,7 @@ async def request( # type: ignore[override] subject: str, *, correlation_id: Optional[str] = None, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, timeout: float = 0.5, # NatsJSFastProducer compatibility stream: Optional[str] = None, @@ -136,7 +130,7 @@ async def request( # type: ignore[override] subject, stream, ): - msg: Union[List[PatchedMessage], PatchedMessage] + msg: Union[list[PatchedMessage], PatchedMessage] if (pull := getattr(handler, "pull_sub", None)) and pull.batch: msg = [incoming] @@ -165,10 +159,10 @@ async def _execute_handler( def _find_handler( - subscribers: Iterable["LogicSubscriber[Any]"], + subscribers: Iterable["LogicSubscriber[Any, Any]"], subject: str, stream: Optional[str] = None, -) -> Generator["LogicSubscriber[Any]", None, None]: +) -> Generator["LogicSubscriber[Any, Any]", None, None]: published_queues = set() for handler in subscribers: # pragma: no branch if _is_handler_matches(handler, subject, stream): @@ -208,11 +202,11 @@ def build_message( *, reply_to: str = "", correlation_id: Optional[str] = None, - headers: Optional[Dict[str, str]] = None, + headers: Optional[dict[str, str]] = None, ) -> "PatchedMessage": msg, content_type = encode_message(message) return PatchedMessage( - _client=None, # type: ignore + _client=None, # type: ignore[arg-type] subject=subject, reply=reply_to, data=msg, @@ -234,7 +228,7 @@ async def ack_sync( ) -> "PatchedMessage": # pragma: no cover return self - async def nak(self, delay: Union[int, float, None] = None) -> None: + async def nak(self, delay: Optional[float] = None) -> None: pass async def term(self) -> None: diff --git a/faststream/opentelemetry/annotations.py b/faststream/opentelemetry/annotations.py index cdf2378cc3..aeb4fe85f6 100644 --- a/faststream/opentelemetry/annotations.py +++ b/faststream/opentelemetry/annotations.py @@ -1,5 +1,6 @@ +from typing import Annotated + from opentelemetry.trace import Span -from typing_extensions import Annotated from faststream import Context from faststream.opentelemetry.baggage import Baggage diff --git a/faststream/opentelemetry/baggage.py b/faststream/opentelemetry/baggage.py index e03e9cb327..1a84a1d904 100644 --- a/faststream/opentelemetry/baggage.py +++ b/faststream/opentelemetry/baggage.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Any, List, Optional, cast +from typing import TYPE_CHECKING, Any, Optional, cast from opentelemetry import baggage, context from opentelemetry.baggage.propagation import W3CBaggagePropagator @@ -17,7 +17,7 @@ class Baggage: def __init__( self, payload: "AnyDict", - batch_payload: Optional[List["AnyDict"]] = None, + batch_payload: Optional[list["AnyDict"]] = None, ) -> None: self._baggage = dict(payload) self._batch_baggage = [dict(b) for b in batch_payload] if batch_payload else [] @@ -26,7 +26,7 @@ def get_all(self) -> "AnyDict": """Get a copy of the current baggage.""" return self._baggage.copy() - def get_all_batch(self) -> List["AnyDict"]: + def get_all_batch(self) -> list["AnyDict"]: """Get a copy of all batch baggage if exists.""" return self._batch_baggage.copy() @@ -66,7 +66,7 @@ def from_msg(cls, msg: "StreamMessage[Any]") -> Self: return cls(cast("AnyDict", payload)) cumulative_baggage: AnyDict = {} - batch_baggage: List[AnyDict] = [] + batch_baggage: list[AnyDict] = [] for headers in msg.batch_headers: payload = baggage.get_all(_BAGGAGE_PROPAGATOR.extract(headers)) diff --git a/faststream/opentelemetry/middleware.py b/faststream/opentelemetry/middleware.py index 95527118ff..8305e3457a 100644 --- a/faststream/opentelemetry/middleware.py +++ b/faststream/opentelemetry/middleware.py @@ -1,7 +1,7 @@ import time from collections import defaultdict from copy import copy -from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Tuple, Type, cast +from typing import TYPE_CHECKING, Any, Callable, Optional, cast from opentelemetry import baggage, context, metrics, trace from opentelemetry.baggage.propagation import W3CBaggagePropagator @@ -10,8 +10,10 @@ from opentelemetry.trace import Link, Span from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator -from faststream import BaseMiddleware -from faststream import context as fs_context +from faststream import ( + BaseMiddleware, + context as fs_context, +) from faststream.opentelemetry.baggage import Baggage from faststream.opentelemetry.consts import ( ERROR_TYPE, @@ -41,10 +43,10 @@ class _MetricsContainer: __slots__ = ( "include_messages_counters", - "publish_duration", - "publish_counter", - "process_duration", "process_counter", + "process_duration", + "publish_counter", + "publish_duration", ) def __init__(self, meter: "Meter", include_messages_counters: bool) -> None: @@ -74,7 +76,10 @@ def __init__(self, meter: "Meter", include_messages_counters: bool) -> None: ) def observe_publish( - self, attrs: "AnyDict", duration: float, msg_count: int + self, + attrs: "AnyDict", + duration: float, + msg_count: int, ) -> None: self.publish_duration.record( amount=duration, @@ -89,7 +94,10 @@ def observe_publish( ) def observe_consume( - self, attrs: "AnyDict", duration: float, msg_count: int + self, + attrs: "AnyDict", + duration: float, + msg_count: int, ) -> None: self.process_duration.record( amount=duration, @@ -110,7 +118,8 @@ def __init__( *, tracer: "Tracer", settings_provider_factory: Callable[ - [Any], Optional[TelemetrySettingsProvider[Any]] + [Any], + Optional[TelemetrySettingsProvider[Any]], ], metrics_container: _MetricsContainer, msg: Optional[Any] = None, @@ -121,7 +130,7 @@ def __init__( self._metrics = metrics_container self._current_span: Optional[Span] = None self._origin_context: Optional[Context] = None - self._scope_tokens: List[Tuple[str, Token[Any]]] = [] + self._scope_tokens: list[tuple[str, Token[Any]]] = [] self.__settings_provider = settings_provider_factory(msg) async def publish_scope( @@ -153,12 +162,14 @@ async def publish_scope( trace_attributes[SpanAttributes.MESSAGING_BATCH_MESSAGE_COUNT] = msg_count current_context = _BAGGAGE_PROPAGATOR.extract(headers, current_context) _BAGGAGE_PROPAGATOR.inject( - headers, baggage.set_baggage(WITH_BATCH, True, context=current_context) + headers, + baggage.set_baggage(WITH_BATCH, True, context=current_context), ) if self._current_span and self._current_span.is_recording(): current_context = trace.set_span_in_context( - self._current_span, current_context + self._current_span, + current_context, ) _TRACE_PROPAGATOR.inject(headers, context=self._origin_context) @@ -182,7 +193,8 @@ async def publish_scope( context=current_context, ) as span: span.set_attribute( - SpanAttributes.MESSAGING_OPERATION, MessageAction.PUBLISH + SpanAttributes.MESSAGING_OPERATION, + MessageAction.PUBLISH, ) result = await call_next(msg, *args, headers=headers, **kwargs) @@ -243,13 +255,14 @@ async def consume_scope( end_on_exit=False, ) as span: span.set_attribute( - SpanAttributes.MESSAGING_OPERATION, MessageAction.PROCESS + SpanAttributes.MESSAGING_OPERATION, + MessageAction.PROCESS, ) self._current_span = span self._scope_tokens.append(("span", fs_context.set_local("span", span))) self._scope_tokens.append( - ("baggage", fs_context.set_local("baggage", Baggage.from_msg(msg))) + ("baggage", fs_context.set_local("baggage", Baggage.from_msg(msg))), ) new_context = trace.set_span_in_context(span, current_context) @@ -264,7 +277,8 @@ async def consume_scope( finally: duration = time.perf_counter() - start_time msg_count = trace_attributes.get( - SpanAttributes.MESSAGING_BATCH_MESSAGE_COUNT, 1 + SpanAttributes.MESSAGING_BATCH_MESSAGE_COUNT, + 1, ) self._metrics.observe_consume(metrics_attributes, duration, msg_count) @@ -272,7 +286,7 @@ async def consume_scope( async def after_processed( self, - exc_type: Optional[Type[BaseException]] = None, + exc_type: Optional[type[BaseException]] = None, exc_val: Optional[BaseException] = None, exc_tb: Optional["TracebackType"] = None, ) -> Optional[bool]: @@ -284,17 +298,18 @@ async def after_processed( class TelemetryMiddleware: # NOTE: should it be class or function? __slots__ = ( - "_tracer", "_meter", "_metrics", "_settings_provider_factory", + "_tracer", ) def __init__( self, *, settings_provider_factory: Callable[ - [Any], Optional[TelemetrySettingsProvider[Any]] + [Any], + Optional[TelemetrySettingsProvider[Any]], ], tracer_provider: Optional["TracerProvider"] = None, meter_provider: Optional["MeterProvider"] = None, @@ -342,20 +357,20 @@ def _create_span_name(destination: str, action: str) -> str: def _is_batch_message(msg: "StreamMessage[Any]") -> bool: with_batch = baggage.get_baggage( - WITH_BATCH, _BAGGAGE_PROPAGATOR.extract(msg.headers) + WITH_BATCH, + _BAGGAGE_PROPAGATOR.extract(msg.headers), ) return bool(msg.batch_headers or with_batch) -def _get_msg_links(msg: "StreamMessage[Any]") -> List[Link]: +def _get_msg_links(msg: "StreamMessage[Any]") -> list[Link]: if not msg.batch_headers: if (span := _get_span_from_headers(msg.headers)) is not None: return [Link(span.get_span_context())] - else: - return [] + return [] links = {} - counter: Dict[str, int] = defaultdict(lambda: 0) + counter: dict[str, int] = defaultdict(lambda: 0) for headers in msg.batch_headers: if (correlation_id := headers.get("correlation_id")) is None: diff --git a/faststream/params/__init__.py b/faststream/params/__init__.py index f771a71eef..204cec6df5 100644 --- a/faststream/params/__init__.py +++ b/faststream/params/__init__.py @@ -4,9 +4,9 @@ from .params import Context, Header, Path __all__ = ( - "NoCast", "Context", + "Depends", "Header", + "NoCast", "Path", - "Depends", ) diff --git a/faststream/params/no_cast.py b/faststream/params/no_cast.py index e030b40306..282cd267e8 100644 --- a/faststream/params/no_cast.py +++ b/faststream/params/no_cast.py @@ -1,7 +1,6 @@ -from typing import Any, TypeVar +from typing import Annotated, Any, TypeVar from fast_depends.library import CustomField -from typing_extensions import Annotated from faststream._internal.basic_types import AnyDict diff --git a/faststream/rabbit/__init__.py b/faststream/rabbit/__init__.py index ab2152af76..4489a20f28 100644 --- a/faststream/rabbit/__init__.py +++ b/faststream/rabbit/__init__.py @@ -11,16 +11,16 @@ from faststream.rabbit.testing import TestRabbitBroker __all__ = ( - "RabbitBroker", - "TestApp", - "TestRabbitBroker", - "RabbitRouter", - "RabbitRoute", - "RabbitPublisher", - "RabbitResponse", "ExchangeType", + "RabbitBroker", "RabbitExchange", - "RabbitQueue", # Annotations "RabbitMessage", + "RabbitPublisher", + "RabbitQueue", + "RabbitResponse", + "RabbitRoute", + "RabbitRouter", + "TestApp", + "TestRabbitBroker", ) diff --git a/faststream/rabbit/annotations.py b/faststream/rabbit/annotations.py index e6800a5958..4a135ecae9 100644 --- a/faststream/rabbit/annotations.py +++ b/faststream/rabbit/annotations.py @@ -1,5 +1,6 @@ +from typing import Annotated + from aio_pika import RobustChannel, RobustConnection -from typing_extensions import Annotated from faststream._internal.context import Context from faststream.annotations import ContextRepo, Logger @@ -9,14 +10,14 @@ from faststream.rabbit.publisher.producer import AioPikaFastProducer __all__ = ( - "Logger", + "Channel", + "Connection", "ContextRepo", + "Logger", "NoCast", - "RabbitMessage", "RabbitBroker", + "RabbitMessage", "RabbitProducer", - "Channel", - "Connection", ) RabbitMessage = Annotated[RM, Context("message")] @@ -25,10 +26,3 @@ Channel = Annotated[RobustChannel, Context("broker._channel")] Connection = Annotated[RobustConnection, Context("broker._connection")] - -# NOTE: transaction is not for the public usage yet -# async def _get_transaction(connection: Connection) -> RabbitTransaction: -# async with connection.channel(publisher_confirms=False) as channel: -# yield channel.transaction() - -# Transaction = Annotated[RabbitTransaction, Depends(_get_transaction)] diff --git a/faststream/rabbit/broker/broker.py b/faststream/rabbit/broker/broker.py index d9999feb74..7e15392154 100644 --- a/faststream/rabbit/broker/broker.py +++ b/faststream/rabbit/broker/broker.py @@ -1,11 +1,11 @@ import logging +from collections.abc import Iterable from typing import ( TYPE_CHECKING, + Annotated, Any, Callable, - Iterable, Optional, - Type, Union, cast, ) @@ -13,7 +13,7 @@ import anyio from aio_pika import IncomingMessage, RobustConnection, connect_robust -from typing_extensions import Annotated, Doc, override +from typing_extensions import Doc, override from faststream.__about__ import SERVICE_NAME from faststream._internal.broker.broker import BrokerUsecase @@ -106,7 +106,7 @@ def __init__( fail_fast: Annotated[ bool, Doc( - "Broker startup raises `AMQPConnectionError` if RabbitMQ is unreachable." + "Broker startup raises `AMQPConnectionError` if RabbitMQ is unreachable.", ), ] = True, reconnect_interval: Annotated[ @@ -123,14 +123,14 @@ def __init__( Doc( "if `True` the `publish` method will " "return `bool` type after publish is complete." - "Otherwise it will returns `None`." + "Otherwise it will returns `None`.", ), ] = True, on_return_raises: Annotated[ bool, Doc( "raise an :class:`aio_pika.exceptions.DeliveryError`" - "when mandatory message will be returned" + "when mandatory message will be returned", ), ] = False, # broker args @@ -138,7 +138,7 @@ def __init__( Optional[int], Doc( "RabbitMQ channel `qos` option. " - "It limits max messages processing in the same time count." + "It limits max messages processing in the same time count.", ), ] = None, app_id: Annotated[ @@ -149,7 +149,7 @@ def __init__( graceful_timeout: Annotated[ Optional[float], Doc( - "Graceful shutdown timeout. Broker waits for all running subscribers completion before shut down." + "Graceful shutdown timeout. Broker waits for all running subscribers completion before shut down.", ), ] = None, decoder: Annotated[ @@ -172,7 +172,7 @@ def __init__( security: Annotated[ Optional["BaseSecurity"], Doc( - "Security options to connect broker and generate AsyncAPI server security information." + "Security options to connect broker and generate AsyncAPI server security information.", ), ] = None, specification_url: Annotated[ @@ -340,7 +340,7 @@ async def connect( # type: ignore[override] security: Annotated[ Optional["BaseSecurity"], Doc( - "Security options to connect broker and generate AsyncAPI server security information." + "Security options to connect broker and generate AsyncAPI server security information.", ), ] = None, timeout: Annotated[ @@ -350,7 +350,7 @@ async def connect( # type: ignore[override] fail_fast: Annotated[ bool, Doc( - "Broker startup raises `AMQPConnectionError` if RabbitMQ is unreachable." + "Broker startup raises `AMQPConnectionError` if RabbitMQ is unreachable.", ), ] = EMPTY, reconnect_interval: Annotated[ @@ -367,14 +367,14 @@ async def connect( # type: ignore[override] Doc( "if `True` the `publish` method will " "return `bool` type after publish is complete." - "Otherwise it will returns `None`." + "Otherwise it will returns `None`.", ), ] = EMPTY, on_return_raises: Annotated[ bool, Doc( "raise an :class:`aio_pika.exceptions.DeliveryError`" - "when mandatory message will be returned" + "when mandatory message will be returned", ), ] = EMPTY, ) -> "RobustConnection": @@ -405,7 +405,7 @@ async def connect( # type: ignore[override] url = None if url is EMPTY else url if url or any( - (host, port, virtualhost, ssl_options, client_properties, security) + (host, port, virtualhost, ssl_options, client_properties, security), ): security_args = parse_security(security) @@ -424,9 +424,7 @@ async def connect( # type: ignore[override] if ssl_context := security_args.get("ssl_context"): kwargs["ssl_context"] = ssl_context - connection = await super().connect(**kwargs) - - return connection + return await super().connect(**kwargs) @override async def _connect( # type: ignore[override] @@ -479,7 +477,7 @@ async def _connect( # type: ignore[override] async def close( self, - exc_type: Optional[Type[BaseException]] = None, + exc_type: Optional[type[BaseException]] = None, exc_val: Optional[BaseException] = None, exc_tb: Optional["TracebackType"] = None, ) -> None: @@ -534,21 +532,21 @@ async def publish( # type: ignore[override] str, Doc( "Message routing key to publish with. " - "Overrides `queue` option if presented." + "Overrides `queue` option if presented.", ), ] = "", mandatory: Annotated[ bool, Doc( "Client waits for confirmation that the message is placed to some queue. " - "RabbitMQ returns message to client if there is no suitable queue." + "RabbitMQ returns message to client if there is no suitable queue.", ), ] = True, immediate: Annotated[ bool, Doc( "Client expects that there is consumer ready to take the message to work. " - "RabbitMQ returns message to client if there is no suitable consumer." + "RabbitMQ returns message to client if there is no suitable consumer.", ), ] = False, timeout: Annotated[ @@ -562,7 +560,7 @@ async def publish( # type: ignore[override] reply_to: Annotated[ Optional[str], Doc( - "Reply message routing key to send with (always sending to default exchange)." + "Reply message routing key to send with (always sending to default exchange).", ), ] = None, # message args @@ -570,7 +568,7 @@ async def publish( # type: ignore[override] Optional[str], Doc( "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages." + "**correlation_id** is a useful option to trace messages.", ), ] = None, headers: Annotated[ @@ -582,7 +580,7 @@ async def publish( # type: ignore[override] Doc( "Message **content-type** header. " "Used by application, not core RabbitMQ. " - "Will be set automatically if not specified." + "Will be set automatically if not specified.", ), ] = None, content_encoding: Annotated[ @@ -667,21 +665,21 @@ async def request( # type: ignore[override] str, Doc( "Message routing key to publish with. " - "Overrides `queue` option if presented." + "Overrides `queue` option if presented.", ), ] = "", mandatory: Annotated[ bool, Doc( "Client waits for confirmation that the message is placed to some queue. " - "RabbitMQ returns message to client if there is no suitable queue." + "RabbitMQ returns message to client if there is no suitable queue.", ), ] = True, immediate: Annotated[ bool, Doc( "Client expects that there is consumer ready to take the message to work. " - "RabbitMQ returns message to client if there is no suitable consumer." + "RabbitMQ returns message to client if there is no suitable consumer.", ), ] = False, timeout: Annotated[ @@ -697,7 +695,7 @@ async def request( # type: ignore[override] Optional[str], Doc( "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages." + "**correlation_id** is a useful option to trace messages.", ), ] = None, headers: Annotated[ @@ -709,7 +707,7 @@ async def request( # type: ignore[override] Doc( "Message **content-type** header. " "Used by application, not core RabbitMQ. " - "Will be set automatically if not specified." + "Will be set automatically if not specified.", ), ] = None, content_encoding: Annotated[ diff --git a/faststream/rabbit/broker/registrator.py b/faststream/rabbit/broker/registrator.py index 9f9773e62d..32aedfcfec 100644 --- a/faststream/rabbit/broker/registrator.py +++ b/faststream/rabbit/broker/registrator.py @@ -1,6 +1,7 @@ -from typing import TYPE_CHECKING, Any, Iterable, List, Optional, Union, cast +from collections.abc import Iterable +from typing import TYPE_CHECKING, Annotated, Any, Optional, Union, cast -from typing_extensions import Annotated, Doc, override +from typing_extensions import Doc, override from faststream._internal.broker.abc_broker import ABCBroker from faststream.rabbit.publisher.publisher import SpecificationPublisher @@ -29,8 +30,8 @@ class RabbitRegistrator(ABCBroker["IncomingMessage"]): """Includable to RabbitBroker router.""" - _subscribers: List["SpecificationSubscriber"] - _publishers: List["SpecificationPublisher"] + _subscribers: list["SpecificationSubscriber"] + _publishers: list["SpecificationPublisher"] @override def subscriber( # type: ignore[override] @@ -39,7 +40,7 @@ def subscriber( # type: ignore[override] Union[str, "RabbitQueue"], Doc( "RabbitMQ queue to listen. " - "**FastStream** declares and binds queue object to `exchange` automatically if it is not passive (by default)." + "**FastStream** declares and binds queue object to `exchange` automatically if it is not passive (by default).", ), ], exchange: Annotated[ @@ -47,7 +48,7 @@ def subscriber( # type: ignore[override] Doc( "RabbitMQ exchange to bind queue to. " "Uses default exchange if not presented. " - "**FastStream** declares exchange object automatically if it is not passive (by default)." + "**FastStream** declares exchange object automatically if it is not passive (by default).", ), ] = None, *, @@ -83,7 +84,7 @@ def subscriber( # type: ignore[override] no_reply: Annotated[ bool, Doc( - "Whether to disable **FastStream** RPC and Reply To auto responses or not." + "Whether to disable **FastStream** RPC and Reply To auto responses or not.", ), ] = False, # AsyncAPI information @@ -95,7 +96,7 @@ def subscriber( # type: ignore[override] Optional[str], Doc( "AsyncAPI subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -120,7 +121,7 @@ def subscriber( # type: ignore[override] title_=title, description_=description, include_in_schema=self._solve_include_in_schema(include_in_schema), - ) + ), ), ) @@ -147,21 +148,21 @@ def publisher( # type: ignore[override] str, Doc( "Default message routing key to publish with. " - "Overrides `queue` option if presented." + "Overrides `queue` option if presented.", ), ] = "", mandatory: Annotated[ bool, Doc( "Client waits for confirmation that the message is placed to some queue. " - "RabbitMQ returns message to client if there is no suitable queue." + "RabbitMQ returns message to client if there is no suitable queue.", ), ] = True, immediate: Annotated[ bool, Doc( "Client expects that there is consumer ready to take the message to work. " - "RabbitMQ returns message to client if there is no suitable consumer." + "RabbitMQ returns message to client if there is no suitable consumer.", ), ] = False, timeout: Annotated[ @@ -175,7 +176,7 @@ def publisher( # type: ignore[override] reply_to: Annotated[ Optional[str], Doc( - "Reply message routing key to send with (always sending to default exchange)." + "Reply message routing key to send with (always sending to default exchange).", ), ] = None, priority: Annotated[ @@ -200,7 +201,7 @@ def publisher( # type: ignore[override] Optional[Any], Doc( "AsyncAPI publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ @@ -212,7 +213,7 @@ def publisher( # type: ignore[override] Optional["HeadersType"], Doc( "Message headers to store metainformation. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, content_type: Annotated[ @@ -220,7 +221,7 @@ def publisher( # type: ignore[override] Doc( "Message **content-type** header. " "Used by application, not core RabbitMQ. " - "Will be set automatically if not specified." + "Will be set automatically if not specified.", ), ] = None, content_encoding: Annotated[ @@ -262,7 +263,7 @@ def publisher( # type: ignore[override] expiration=expiration, ) - publisher = cast( + return cast( SpecificationPublisher, super().publisher( SpecificationPublisher.create( @@ -278,8 +279,6 @@ def publisher( # type: ignore[override] description_=description, schema_=schema, include_in_schema=self._solve_include_in_schema(include_in_schema), - ) + ), ), ) - - return publisher diff --git a/faststream/rabbit/fastapi/__init__.py b/faststream/rabbit/fastapi/__init__.py index dcbc649abc..da296cd366 100644 --- a/faststream/rabbit/fastapi/__init__.py +++ b/faststream/rabbit/fastapi/__init__.py @@ -1,4 +1,4 @@ -from typing_extensions import Annotated +from typing import Annotated from faststream._internal.fastapi.context import Context, ContextRepo, Logger from faststream.rabbit.broker import RabbitBroker as RB @@ -12,10 +12,10 @@ __all__ = ( "Context", - "Logger", "ContextRepo", - "RabbitMessage", + "Logger", "RabbitBroker", + "RabbitMessage", "RabbitProducer", "RabbitRouter", ) diff --git a/faststream/rabbit/fastapi/router.py b/faststream/rabbit/fastapi/router.py index 85e63a14c4..69a7a23d73 100644 --- a/faststream/rabbit/fastapi/router.py +++ b/faststream/rabbit/fastapi/router.py @@ -1,14 +1,11 @@ import logging +from collections.abc import Iterable, Sequence from typing import ( TYPE_CHECKING, + Annotated, Any, Callable, - Dict, - Iterable, - List, Optional, - Sequence, - Type, Union, cast, ) @@ -18,7 +15,7 @@ from fastapi.utils import generate_unique_id from starlette.responses import JSONResponse from starlette.routing import BaseRoute -from typing_extensions import Annotated, Doc, deprecated, override +from typing_extensions import Doc, deprecated, override from faststream.__about__ import SERVICE_NAME from faststream._internal.constants import EMPTY @@ -96,7 +93,7 @@ def __init__( fail_fast: Annotated[ bool, Doc( - "Broker startup raises `AMQPConnectionError` if RabbitMQ is unreachable." + "Broker startup raises `AMQPConnectionError` if RabbitMQ is unreachable.", ), ] = True, reconnect_interval: Annotated[ @@ -113,14 +110,14 @@ def __init__( Doc( "if `True` the `publish` method will " "return `bool` type after publish is complete." - "Otherwise it will returns `None`." + "Otherwise it will returns `None`.", ), ] = True, on_return_raises: Annotated[ bool, Doc( "raise an :class:`aio_pika.exceptions.DeliveryError`" - "when mandatory message will be returned" + "when mandatory message will be returned", ), ] = False, # broker args @@ -128,7 +125,7 @@ def __init__( Optional[int], Doc( "RabbitMQ channel `qos` option. " - "It limits max messages processing in the same time count." + "It limits max messages processing in the same time count.", ), ] = None, app_id: Annotated[ @@ -139,7 +136,7 @@ def __init__( graceful_timeout: Annotated[ Optional[float], Doc( - "Graceful shutdown timeout. Broker waits for all running subscribers completion before shut down." + "Graceful shutdown timeout. Broker waits for all running subscribers completion before shut down.", ), ] = 15.0, decoder: Annotated[ @@ -158,7 +155,7 @@ def __init__( security: Annotated[ Optional["BaseSecurity"], Doc( - "Security options to connect broker and generate AsyncAPI server security information." + "Security options to connect broker and generate AsyncAPI server security information.", ), ] = None, specification_url: Annotated[ @@ -199,13 +196,13 @@ def __init__( bool, Doc( "Whether to add broker to app scope in lifespan. " - "You should disable this option at old ASGI servers." + "You should disable this option at old ASGI servers.", ), ] = True, schema_url: Annotated[ Optional[str], Doc( - "AsyncAPI schema url. You should set this option to `None` to disable AsyncAPI routes at all." + "AsyncAPI schema url. You should set this option to `None` to disable AsyncAPI routes at all.", ), ] = "/asyncapi", # FastAPI args @@ -214,7 +211,7 @@ def __init__( Doc("An optional path prefix for the router."), ] = "", tags: Annotated[ - Optional[List[Union[str, "Enum"]]], + Optional[list[Union[str, "Enum"]]], Doc( """ A list of tags to be applied to all the *path operations* in this @@ -224,7 +221,7 @@ def __init__( Read more about it in the [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ + """, ), ] = None, dependencies: Annotated[ @@ -236,22 +233,22 @@ def __init__( Read more about it in the [FastAPI docs for Bigger Applications - Multiple Files](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies). - """ + """, ), ] = None, default_response_class: Annotated[ - Type["Response"], + type["Response"], Doc( """ The default response class to be used. Read more in the [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#default-response-class). - """ + """, ), ] = Default(JSONResponse), responses: Annotated[ - Optional[Dict[Union[int, str], "AnyDict"]], + Optional[dict[Union[int, str], "AnyDict"]], Doc( """ Additional responses to be shown in OpenAPI. @@ -263,11 +260,11 @@ def __init__( And in the [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies). - """ + """, ), ] = None, callbacks: Annotated[ - Optional[List[BaseRoute]], + Optional[list[BaseRoute]], Doc( """ OpenAPI callbacks that should apply to all *path operations* in this @@ -277,11 +274,11 @@ def __init__( Read more about it in the [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). - """ + """, ), ] = None, routes: Annotated[ - Optional[List[BaseRoute]], + Optional[list[BaseRoute]], Doc( """ **Note**: you probably shouldn't use this parameter, it is inherited @@ -290,7 +287,7 @@ def __init__( --- A list of routes to serve incoming HTTP and WebSocket requests. - """ + """, ), deprecated( """ @@ -299,7 +296,7 @@ def __init__( In FastAPI, you normally would use the *path operation methods*, like `router.get()`, `router.post()`, etc. - """ + """, ), ] = None, redirect_slashes: Annotated[ @@ -308,7 +305,7 @@ def __init__( """ Whether to detect and redirect slashes in URLs when the client doesn't use the same format. - """ + """, ), ] = True, default: Annotated[ @@ -317,7 +314,7 @@ def __init__( """ Default function handler for this router. Used to handle 404 Not Found errors. - """ + """, ), ] = None, dependency_overrides_provider: Annotated[ @@ -328,18 +325,18 @@ def __init__( You shouldn't need to use it. It normally points to the `FastAPI` app object. - """ + """, ), ] = None, route_class: Annotated[ - Type["APIRoute"], + type["APIRoute"], Doc( """ Custom route (*path operation*) class to be used by this router. Read more about it in the [FastAPI docs for Custom Request and APIRoute class](https://fastapi.tiangolo.com/how-to/custom-request-and-route/#custom-apiroute-class-in-a-router). - """ + """, ), ] = APIRoute, on_startup: Annotated[ @@ -351,7 +348,7 @@ def __init__( You should instead use the `lifespan` handlers. Read more in the [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/). - """ + """, ), ] = None, on_shutdown: Annotated[ @@ -364,7 +361,7 @@ def __init__( Read more in the [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/). - """ + """, ), ] = None, lifespan: Annotated[ @@ -376,7 +373,7 @@ def __init__( Read more in the [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/). - """ + """, ), ] = None, deprecated: Annotated[ @@ -389,7 +386,7 @@ def __init__( Read more about it in the [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ + """, ), ] = None, include_in_schema: Annotated[ @@ -403,7 +400,7 @@ def __init__( Read more about it in the [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi). - """ + """, ), ] = True, generate_unique_id_function: Annotated[ @@ -418,7 +415,7 @@ def __init__( Read more about it in the [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). - """ + """, ), ] = Default(generate_unique_id), ) -> None: @@ -479,7 +476,7 @@ def subscriber( # type: ignore[override] Union[str, RabbitQueue], Doc( "RabbitMQ queue to listen. " - "**FastStream** declares and binds queue object to `exchange` automatically if it is not passive (by default)." + "**FastStream** declares and binds queue object to `exchange` automatically if it is not passive (by default).", ), ], exchange: Annotated[ @@ -487,7 +484,7 @@ def subscriber( # type: ignore[override] Doc( "RabbitMQ exchange to bind queue to. " "Uses default exchange if not presented. " - "**FastStream** declares exchange object automatically if it is not passive (by default)." + "**FastStream** declares exchange object automatically if it is not passive (by default).", ), ] = None, *, @@ -503,7 +500,7 @@ def subscriber( # type: ignore[override] parser: Annotated[ Optional["CustomCallable"], Doc( - "Parser to map original **aio_pika.IncomingMessage** Msg to FastStream one." + "Parser to map original **aio_pika.IncomingMessage** Msg to FastStream one.", ), ] = None, decoder: Annotated[ @@ -525,7 +522,7 @@ def subscriber( # type: ignore[override] no_reply: Annotated[ bool, Doc( - "Whether to disable **FastStream** RPC and Reply To auto responses or not." + "Whether to disable **FastStream** RPC and Reply To auto responses or not.", ), ] = False, # AsyncAPI information @@ -537,7 +534,7 @@ def subscriber( # type: ignore[override] Optional[str], Doc( "AsyncAPI subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -576,7 +573,7 @@ def subscriber( # type: ignore[override] Read more about it in the [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). - """ + """, ), ] = Default(None), response_model_include: Annotated[ @@ -588,7 +585,7 @@ def subscriber( # type: ignore[override] Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = None, response_model_exclude: Annotated[ @@ -600,7 +597,7 @@ def subscriber( # type: ignore[override] Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = None, response_model_by_alias: Annotated[ @@ -612,7 +609,7 @@ def subscriber( # type: ignore[override] Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = True, response_model_exclude_unset: Annotated[ @@ -630,7 +627,7 @@ def subscriber( # type: ignore[override] Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ + """, ), ] = False, response_model_exclude_defaults: Annotated[ @@ -647,7 +644,7 @@ def subscriber( # type: ignore[override] Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ + """, ), ] = False, response_model_exclude_none: Annotated[ @@ -664,7 +661,7 @@ def subscriber( # type: ignore[override] Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). - """ + """, ), ] = False, ) -> SpecificationSubscriber: @@ -711,21 +708,21 @@ def publisher( str, Doc( "Default message routing key to publish with. " - "Overrides `queue` option if presented." + "Overrides `queue` option if presented.", ), ] = "", mandatory: Annotated[ bool, Doc( "Client waits for confirmation that the message is placed to some queue. " - "RabbitMQ returns message to client if there is no suitable queue." + "RabbitMQ returns message to client if there is no suitable queue.", ), ] = True, immediate: Annotated[ bool, Doc( "Client expects that there is consumer ready to take the message to work. " - "RabbitMQ returns message to client if there is no suitable consumer." + "RabbitMQ returns message to client if there is no suitable consumer.", ), ] = False, timeout: Annotated[ @@ -739,7 +736,7 @@ def publisher( reply_to: Annotated[ Optional[str], Doc( - "Reply message routing key to send with (always sending to default exchange)." + "Reply message routing key to send with (always sending to default exchange).", ), ] = None, priority: Annotated[ @@ -764,7 +761,7 @@ def publisher( Optional[Any], Doc( "AsyncAPI publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ @@ -776,7 +773,7 @@ def publisher( Optional["HeadersType"], Doc( "Message headers to store metainformation. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, content_type: Annotated[ @@ -784,7 +781,7 @@ def publisher( Doc( "Message **content-type** header. " "Used by application, not core RabbitMQ. " - "Will be set automatically if not specified." + "Will be set automatically if not specified.", ), ] = None, content_encoding: Annotated[ diff --git a/faststream/rabbit/helpers/declarer.py b/faststream/rabbit/helpers/declarer.py index 57c21a3a78..b7bf52165c 100644 --- a/faststream/rabbit/helpers/declarer.py +++ b/faststream/rabbit/helpers/declarer.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Dict, cast +from typing import TYPE_CHECKING, cast if TYPE_CHECKING: import aio_pika @@ -10,8 +10,8 @@ class RabbitDeclarer: """An utility class to declare RabbitMQ queues and exchanges.""" __channel: "aio_pika.RobustChannel" - __queues: Dict["RabbitQueue", "aio_pika.RobustQueue"] - __exchanges: Dict["RabbitExchange", "aio_pika.RobustExchange"] + __queues: dict["RabbitQueue", "aio_pika.RobustQueue"] + __exchanges: dict["RabbitExchange", "aio_pika.RobustExchange"] def __init__(self, channel: "aio_pika.RobustChannel") -> None: self.__channel = channel diff --git a/faststream/rabbit/opentelemetry/provider.py b/faststream/rabbit/opentelemetry/provider.py index 15febc0480..ffa14e60e6 100644 --- a/faststream/rabbit/opentelemetry/provider.py +++ b/faststream/rabbit/opentelemetry/provider.py @@ -49,7 +49,9 @@ def get_publish_attrs_from_kwargs( return { SpanAttributes.MESSAGING_SYSTEM: self.messaging_system, SpanAttributes.MESSAGING_DESTINATION_NAME: getattr( - exchange, "name", exchange or "" + exchange, + "name", + exchange or "", ), SpanAttributes.MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY: kwargs[ "routing_key" diff --git a/faststream/rabbit/parser.py b/faststream/rabbit/parser.py index f9970c80a7..70b2ba5492 100644 --- a/faststream/rabbit/parser.py +++ b/faststream/rabbit/parser.py @@ -79,26 +79,25 @@ def encode_message( if isinstance(message, Message): return message - else: - message_body, generated_content_type = encode_message(message) + message_body, generated_content_type = encode_message(message) - delivery_mode = ( - DeliveryMode.PERSISTENT if persist else DeliveryMode.NOT_PERSISTENT - ) + delivery_mode = ( + DeliveryMode.PERSISTENT if persist else DeliveryMode.NOT_PERSISTENT + ) - return Message( - message_body, - content_type=content_type or generated_content_type, - delivery_mode=delivery_mode, - reply_to=reply_to, - correlation_id=correlation_id or gen_cor_id(), - headers=headers, - content_encoding=content_encoding, - priority=priority, - expiration=expiration, - message_id=message_id, - timestamp=timestamp, - type=message_type, - user_id=user_id, - app_id=app_id, - ) + return Message( + message_body, + content_type=content_type or generated_content_type, + delivery_mode=delivery_mode, + reply_to=reply_to, + correlation_id=correlation_id or gen_cor_id(), + headers=headers, + content_encoding=content_encoding, + priority=priority, + expiration=expiration, + message_id=message_id, + timestamp=timestamp, + type=message_type, + user_id=user_id, + app_id=app_id, + ) diff --git a/faststream/rabbit/publisher/producer.py b/faststream/rabbit/publisher/producer.py index 64e0421116..780ef16424 100644 --- a/faststream/rabbit/publisher/producer.py +++ b/faststream/rabbit/publisher/producer.py @@ -1,7 +1,6 @@ from typing import ( TYPE_CHECKING, Optional, - Type, Union, cast, ) @@ -234,7 +233,7 @@ async def __aenter__(self) -> "MemoryObjectReceiveStream[IncomingMessage]": async def __aexit__( self, - exc_type: Optional[Type[BaseException]] = None, + exc_type: Optional[type[BaseException]] = None, exc_val: Optional[BaseException] = None, exc_tb: Optional["TracebackType"] = None, ) -> None: diff --git a/faststream/rabbit/publisher/publisher.py b/faststream/rabbit/publisher/publisher.py index f3967eb769..18796b92b4 100644 --- a/faststream/rabbit/publisher/publisher.py +++ b/faststream/rabbit/publisher/publisher.py @@ -1,4 +1,5 @@ -from typing import TYPE_CHECKING, Any, Dict, Iterable, Optional +from collections.abc import Iterable +from typing import TYPE_CHECKING, Any, Optional from typing_extensions import override @@ -27,9 +28,13 @@ class SpecificationPublisher(LogicPublisher): Creating by ```python - publisher: SpecificationPublisher = broker.publisher(...) - # or - publisher: SpecificationPublisher = router.publisher(...) + publisher: SpecificationPublisher = ( + broker.publisher(...) + ) + # or + publisher: SpecificationPublisher = ( + router.publisher(...) + ) ``` """ @@ -42,7 +47,7 @@ def get_name(self) -> str: return f"{routing}:{getattr(self.exchange, 'name', None) or '_'}:Publisher" - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> dict[str, Channel]: payloads = self.get_payloads() return { @@ -68,38 +73,36 @@ def get_schema(self) -> Dict[str, Channel]: served_words=2 if self.title_ is None else 1, ), correlationId=CorrelationId( - location="$message.header#/correlation_id" + location="$message.header#/correlation_id", ), ), ), bindings=ChannelBinding( amqp=amqp.ChannelBinding( - **{ - "is_": "routingKey", # type: ignore - "queue": amqp.Queue( - name=self.queue.name, - durable=self.queue.durable, - exclusive=self.queue.exclusive, - autoDelete=self.queue.auto_delete, + is_="routingKey", + queue=amqp.Queue( + name=self.queue.name, + durable=self.queue.durable, + exclusive=self.queue.exclusive, + autoDelete=self.queue.auto_delete, + vhost=self.virtual_host, + ) + if is_routing_exchange(self.exchange) and self.queue.name + else None, + exchange=( + amqp.Exchange(type="default", vhost=self.virtual_host) + if not self.exchange.name + else amqp.Exchange( + type=self.exchange.type.value, + name=self.exchange.name, + durable=self.exchange.durable, + autoDelete=self.exchange.auto_delete, vhost=self.virtual_host, ) - if is_routing_exchange(self.exchange) and self.queue.name - else None, - "exchange": ( - amqp.Exchange(type="default", vhost=self.virtual_host) - if not self.exchange.name - else amqp.Exchange( - type=self.exchange.type.value, - name=self.exchange.name, - durable=self.exchange.durable, - autoDelete=self.exchange.auto_delete, - vhost=self.virtual_host, - ) - ), - } - ) + ), + ), ), - ) + ), } @override diff --git a/faststream/rabbit/publisher/usecase.py b/faststream/rabbit/publisher/usecase.py index 6ca24446c7..49cdf71f14 100644 --- a/faststream/rabbit/publisher/usecase.py +++ b/faststream/rabbit/publisher/usecase.py @@ -1,18 +1,18 @@ +from collections.abc import Awaitable, Iterable from copy import deepcopy from functools import partial from itertools import chain from typing import ( TYPE_CHECKING, + Annotated, Any, - Awaitable, Callable, - Iterable, Optional, Union, ) from aio_pika import IncomingMessage -from typing_extensions import Annotated, Doc, TypedDict, Unpack, override +from typing_extensions import Doc, TypedDict, Unpack, override from faststream._internal.publisher.usecase import PublisherUsecase from faststream._internal.subscriber.utils import process_msg @@ -40,21 +40,21 @@ class RequestPublishKwargs(TypedDict, total=False): Optional["HeadersType"], Doc( "Message headers to store metainformation. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] mandatory: Annotated[ Optional[bool], Doc( "Client waits for confirmation that the message is placed to some queue. " - "RabbitMQ returns message to client if there is no suitable queue." + "RabbitMQ returns message to client if there is no suitable queue.", ), ] immediate: Annotated[ Optional[bool], Doc( "Client expects that there is consumer ready to take the message to work. " - "RabbitMQ returns message to client if there is no suitable consumer." + "RabbitMQ returns message to client if there is no suitable consumer.", ), ] timeout: Annotated[ @@ -79,7 +79,7 @@ class RequestPublishKwargs(TypedDict, total=False): Doc( "Message **content-type** header. " "Used by application, not core RabbitMQ. " - "Will be set automatically if not specified." + "Will be set automatically if not specified.", ), ] user_id: Annotated[ @@ -102,7 +102,7 @@ class PublishKwargs(RequestPublishKwargs, total=False): reply_to: Annotated[ Optional[str], Doc( - "Reply message routing key to send with (always sending to default exchange)." + "Reply message routing key to send with (always sending to default exchange).", ), ] @@ -191,7 +191,7 @@ async def publish( str, Doc( "Message routing key to publish with. " - "Overrides `queue` option if presented." + "Overrides `queue` option if presented.", ), ] = "", # message args @@ -199,7 +199,7 @@ async def publish( Optional[str], Doc( "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages." + "**correlation_id** is a useful option to trace messages.", ), ] = None, message_id: Annotated[ @@ -267,7 +267,7 @@ async def request( str, Doc( "Message routing key to publish with. " - "Overrides `queue` option if presented." + "Overrides `queue` option if presented.", ), ] = "", # message args @@ -275,7 +275,7 @@ async def request( Optional[str], Doc( "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages." + "**correlation_id** is a useful option to trace messages.", ), ] = None, message_id: Annotated[ diff --git a/faststream/rabbit/response.py b/faststream/rabbit/response.py index e75aab7979..756c665c4b 100644 --- a/faststream/rabbit/response.py +++ b/faststream/rabbit/response.py @@ -48,7 +48,7 @@ def __init__( @override def as_publish_kwargs(self) -> "AnyDict": - publish_options = { + return { **super().as_publish_kwargs(), "message_id": self.message_id, "mandatory": self.mandatory, @@ -61,4 +61,3 @@ def as_publish_kwargs(self) -> "AnyDict": "expiration": self.expiration, "content_encoding": self.content_encoding, } - return publish_options diff --git a/faststream/rabbit/router.py b/faststream/rabbit/router.py index a2de4128f2..8106d48078 100644 --- a/faststream/rabbit/router.py +++ b/faststream/rabbit/router.py @@ -1,6 +1,7 @@ -from typing import TYPE_CHECKING, Any, Awaitable, Callable, Iterable, Optional, Union +from collections.abc import Awaitable, Iterable +from typing import TYPE_CHECKING, Annotated, Any, Callable, Optional, Union -from typing_extensions import Annotated, Doc +from typing_extensions import Doc from faststream._internal.broker.router import ( ArgsContainer, @@ -50,21 +51,21 @@ def __init__( str, Doc( "Default message routing key to publish with. " - "Overrides `queue` option if presented." + "Overrides `queue` option if presented.", ), ] = "", mandatory: Annotated[ bool, Doc( "Client waits for confirmation that the message is placed to some queue. " - "RabbitMQ returns message to client if there is no suitable queue." + "RabbitMQ returns message to client if there is no suitable queue.", ), ] = True, immediate: Annotated[ bool, Doc( "Client expects that there is consumer ready to take the message to work. " - "RabbitMQ returns message to client if there is no suitable consumer." + "RabbitMQ returns message to client if there is no suitable consumer.", ), ] = False, timeout: Annotated[ @@ -78,7 +79,7 @@ def __init__( reply_to: Annotated[ Optional[str], Doc( - "Reply message routing key to send with (always sending to default exchange)." + "Reply message routing key to send with (always sending to default exchange).", ), ] = None, priority: Annotated[ @@ -103,7 +104,7 @@ def __init__( Optional[Any], Doc( "AsyncAPI publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ @@ -115,7 +116,7 @@ def __init__( Optional["HeadersType"], Doc( "Message headers to store metainformation. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, content_type: Annotated[ @@ -123,7 +124,7 @@ def __init__( Doc( "Message **content-type** header. " "Used by application, not core RabbitMQ. " - "Will be set automatically if not specified." + "Will be set automatically if not specified.", ), ] = None, content_encoding: Annotated[ @@ -184,14 +185,14 @@ def __init__( ], Doc( "Message handler function " - "to wrap the same with `@broker.subscriber(...)` way." + "to wrap the same with `@broker.subscriber(...)` way.", ), ], queue: Annotated[ Union[str, "RabbitQueue"], Doc( "RabbitMQ queue to listen. " - "**FastStream** declares and binds queue object to `exchange` automatically if it is not passive (by default)." + "**FastStream** declares and binds queue object to `exchange` automatically if it is not passive (by default).", ), ], exchange: Annotated[ @@ -199,7 +200,7 @@ def __init__( Doc( "RabbitMQ exchange to bind queue to. " "Uses default exchange if not presented. " - "**FastStream** declares exchange object automatically if it is not passive (by default)." + "**FastStream** declares exchange object automatically if it is not passive (by default).", ), ] = None, *, @@ -239,7 +240,7 @@ def __init__( no_reply: Annotated[ bool, Doc( - "Whether to disable **FastStream** RPC and Reply To auto responses or not." + "Whether to disable **FastStream** RPC and Reply To auto responses or not.", ), ] = False, # AsyncAPI information @@ -251,7 +252,7 @@ def __init__( Optional[str], Doc( "AsyncAPI subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -298,7 +299,7 @@ def __init__( dependencies: Annotated[ Iterable["Depends"], Doc( - "Dependencies list (`[Depends(),]`) to apply to all routers' publishers/subscribers." + "Dependencies list (`[Depends(),]`) to apply to all routers' publishers/subscribers.", ), ] = (), middlewares: Annotated[ diff --git a/faststream/rabbit/schemas/__init__.py b/faststream/rabbit/schemas/__init__.py index 02e423031d..51c9766dd2 100644 --- a/faststream/rabbit/schemas/__init__.py +++ b/faststream/rabbit/schemas/__init__.py @@ -4,11 +4,11 @@ from faststream.rabbit.schemas.queue import RabbitQueue __all__ = ( - "ExchangeType", - "RabbitQueue", - "RabbitExchange", "RABBIT_REPLY", "BaseRMQInformation", + "ExchangeType", + "RabbitExchange", + "RabbitQueue", ) RABBIT_REPLY = RabbitQueue("amq.rabbitmq.reply-to", passive=True) diff --git a/faststream/rabbit/schemas/exchange.py b/faststream/rabbit/schemas/exchange.py index 1461b721a8..a95f78bba8 100644 --- a/faststream/rabbit/schemas/exchange.py +++ b/faststream/rabbit/schemas/exchange.py @@ -1,7 +1,7 @@ import warnings -from typing import TYPE_CHECKING, Any, Optional, Union +from typing import TYPE_CHECKING, Annotated, Any, Optional, Union -from typing_extensions import Annotated, Doc, override +from typing_extensions import Doc, override from faststream._internal.basic_types import AnyDict from faststream._internal.proto import NameRequired @@ -15,17 +15,17 @@ class RabbitExchange(NameRequired): """A class to represent a RabbitMQ exchange.""" __slots__ = ( - "name", - "type", - "durable", + "arguments", "auto_delete", + "bind_arguments", + "bind_to", + "durable", + "name", "passive", - "arguments", - "timeout", "robust", - "bind_to", - "bind_arguments", "routing_key", + "timeout", + "type", ) def __hash__(self) -> int: @@ -37,7 +37,7 @@ def __hash__(self) -> int: hash(self.routing_key), int(self.durable), int(self.auto_delete), - ) + ), ) @property @@ -59,7 +59,7 @@ def __init__( "https://www.rabbitmq.com/tutorials/amqp-concepts#exchanges" "\n" "Or in the FastStream one: " - "https://faststream.airt.ai/latest/rabbit/examples/" + "https://faststream.airt.ai/latest/rabbit/examples/", ), ] = ExchangeType.DIRECT, durable: Annotated[ @@ -79,7 +79,7 @@ def __init__( Doc( "Exchange declarationg arguments. " "You can find usage example in the official RabbitMQ documentation: " - "https://www.rabbitmq.com/docs/ae" + "https://www.rabbitmq.com/docs/ae", ), ] = None, timeout: Annotated[ @@ -95,7 +95,7 @@ def __init__( Doc( "Another `RabbitExchange` object to bind the current one to. " "You can find more information in the official RabbitMQ blog post: " - "https://www.rabbitmq.com/blog/2010/10/19/exchange-to-exchange-bindings" + "https://www.rabbitmq.com/blog/2010/10/19/exchange-to-exchange-bindings", ), ] = None, bind_arguments: Annotated[ diff --git a/faststream/rabbit/schemas/queue.py b/faststream/rabbit/schemas/queue.py index 1c20d136df..6a26a64dba 100644 --- a/faststream/rabbit/schemas/queue.py +++ b/faststream/rabbit/schemas/queue.py @@ -1,7 +1,7 @@ from copy import deepcopy -from typing import TYPE_CHECKING, Optional +from typing import TYPE_CHECKING, Annotated, Optional -from typing_extensions import Annotated, Doc +from typing_extensions import Doc from faststream._internal.proto import NameRequired from faststream._internal.utils.path import compile_path @@ -21,17 +21,17 @@ class RabbitQueue(NameRequired): """ __slots__ = ( - "name", + "arguments", + "auto_delete", + "bind_arguments", "durable", "exclusive", + "name", "passive", - "auto_delete", - "arguments", - "timeout", + "path_regex", "robust", "routing_key", - "path_regex", - "bind_arguments", + "timeout", ) def __hash__(self) -> int: @@ -42,7 +42,7 @@ def __hash__(self) -> int: int(self.durable), int(self.exclusive), int(self.auto_delete), - ) + ), ) @property @@ -64,7 +64,7 @@ def __init__( bool, Doc( "The queue can be used only in the current connection " - "and will be deleted after connection closed." + "and will be deleted after connection closed.", ), ] = False, passive: Annotated[ @@ -79,7 +79,7 @@ def __init__( Optional["AnyDict"], Doc( "Queue declarationg arguments. " - "You can find information about them in the official RabbitMQ documentation: https://www.rabbitmq.com/docs/queues#optional-arguments" + "You can find information about them in the official RabbitMQ documentation: https://www.rabbitmq.com/docs/queues#optional-arguments", ), ] = None, timeout: Annotated[ @@ -121,9 +121,9 @@ def __init__( def add_prefix(self, prefix: str) -> "RabbitQueue": new_q: RabbitQueue = deepcopy(self) - new_q.name = "".join((prefix, new_q.name)) + new_q.name = f"{prefix}{new_q.name}" if new_q.routing_key: - new_q.routing_key = "".join((prefix, new_q.routing_key)) + new_q.routing_key = f"{prefix}{new_q.routing_key}" return new_q diff --git a/faststream/rabbit/security.py b/faststream/rabbit/security.py index 6878272818..591cc665d7 100644 --- a/faststream/rabbit/security.py +++ b/faststream/rabbit/security.py @@ -13,12 +13,12 @@ def parse_security(security: Optional[BaseSecurity]) -> "AnyDict": """Convert security object to connection arguments.""" if security is None: return {} - elif isinstance(security, SASLPlaintext): + if isinstance(security, SASLPlaintext): return _parse_sasl_plaintext(security) - elif isinstance(security, BaseSecurity): + if isinstance(security, BaseSecurity): return _parse_base_security(security) - else: - raise NotImplementedError(f"RabbitBroker does not support {type(security)}") + msg = f"RabbitBroker does not support {type(security)}" + raise NotImplementedError(msg) def _parse_base_security(security: BaseSecurity) -> "AnyDict": diff --git a/faststream/rabbit/subscriber/factory.py b/faststream/rabbit/subscriber/factory.py index 6652dd41c0..c69884503a 100644 --- a/faststream/rabbit/subscriber/factory.py +++ b/faststream/rabbit/subscriber/factory.py @@ -1,4 +1,5 @@ -from typing import TYPE_CHECKING, Iterable, Optional, Union +from collections.abc import Iterable +from typing import TYPE_CHECKING, Optional, Union from faststream.rabbit.subscriber.subscriber import SpecificationSubscriber diff --git a/faststream/rabbit/subscriber/subscriber.py b/faststream/rabbit/subscriber/subscriber.py index 5ed253a8e2..275f509d2b 100644 --- a/faststream/rabbit/subscriber/subscriber.py +++ b/faststream/rabbit/subscriber/subscriber.py @@ -1,5 +1,3 @@ -from typing import Dict - from faststream.rabbit.subscriber.usecase import LogicSubscriber from faststream.rabbit.utils import is_routing_exchange from faststream.specification.asyncapi.utils import resolve_payloads @@ -19,7 +17,7 @@ class SpecificationSubscriber(LogicSubscriber): def get_name(self) -> str: return f"{self.queue.name}:{getattr(self.exchange, 'name', None) or '_'}:{self.call_name}" - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> dict[str, Channel]: payloads = self.get_payloads() return { @@ -37,36 +35,34 @@ def get_schema(self) -> Dict[str, Channel]: title=f"{self.name}:Message", payload=resolve_payloads(payloads), correlationId=CorrelationId( - location="$message.header#/correlation_id" + location="$message.header#/correlation_id", ), ), ), bindings=ChannelBinding( amqp=amqp.ChannelBinding( - **{ - "is_": "routingKey", # type: ignore - "queue": amqp.Queue( - name=self.queue.name, - durable=self.queue.durable, - exclusive=self.queue.exclusive, - autoDelete=self.queue.auto_delete, + is_="routingKey", + queue=amqp.Queue( + name=self.queue.name, + durable=self.queue.durable, + exclusive=self.queue.exclusive, + autoDelete=self.queue.auto_delete, + vhost=self.virtual_host, + ) + if is_routing_exchange(self.exchange) and self.queue.name + else None, + exchange=( + amqp.Exchange(type="default", vhost=self.virtual_host) + if not self.exchange.name + else amqp.Exchange( + type=self.exchange.type.value, + name=self.exchange.name, + durable=self.exchange.durable, + autoDelete=self.exchange.auto_delete, vhost=self.virtual_host, ) - if is_routing_exchange(self.exchange) and self.queue.name - else None, - "exchange": ( - amqp.Exchange(type="default", vhost=self.virtual_host) - if not self.exchange.name - else amqp.Exchange( - type=self.exchange.type.value, - name=self.exchange.name, - durable=self.exchange.durable, - autoDelete=self.exchange.auto_delete, - vhost=self.virtual_host, - ) - ), - } - ) + ), + ), ), - ) + ), } diff --git a/faststream/rabbit/subscriber/usecase.py b/faststream/rabbit/subscriber/usecase.py index 7a00c64878..e7fc7e5205 100644 --- a/faststream/rabbit/subscriber/usecase.py +++ b/faststream/rabbit/subscriber/usecase.py @@ -1,10 +1,8 @@ +from collections.abc import Iterable, Sequence from typing import ( TYPE_CHECKING, Any, - Dict, - Iterable, Optional, - Sequence, Union, ) @@ -131,7 +129,8 @@ def _setup( # type: ignore[override] async def start(self) -> None: """Starts the consumer for the RabbitMQ queue.""" if self.declarer is None: - raise SetupError("You should setup subscriber at first.") + msg = "You should setup subscriber at first." + raise SetupError(msg) self._queue_obj = queue = await self.declarer.declare_queue(self.queue) @@ -225,7 +224,7 @@ def build_log_context( message: Optional["StreamMessage[Any]"], queue: "RabbitQueue", exchange: Optional["RabbitExchange"] = None, - ) -> Dict[str, str]: + ) -> dict[str, str]: return { "queue": queue.name, "exchange": getattr(exchange, "name", ""), @@ -235,7 +234,7 @@ def build_log_context( def get_log_context( self, message: Optional["StreamMessage[Any]"], - ) -> Dict[str, str]: + ) -> dict[str, str]: return self.build_log_context( message=message, queue=self.queue, diff --git a/faststream/rabbit/testing.py b/faststream/rabbit/testing.py index 31069bab85..5831fc903c 100644 --- a/faststream/rabbit/testing.py +++ b/faststream/rabbit/testing.py @@ -1,5 +1,6 @@ +from collections.abc import Generator, Mapping from contextlib import contextmanager -from typing import TYPE_CHECKING, Any, Generator, Mapping, Optional, Tuple, Union +from typing import TYPE_CHECKING, Any, Optional, Union from unittest import mock from unittest.mock import AsyncMock @@ -39,15 +40,19 @@ class TestRabbitBroker(TestBroker[RabbitBroker]): @contextmanager def _patch_broker(self, broker: RabbitBroker) -> Generator[None, None, None]: - with mock.patch.object( - broker, - "_channel", - new_callable=AsyncMock, - ), mock.patch.object( - broker, - "declarer", - new_callable=AsyncMock, - ), super()._patch_broker(broker): + with ( + mock.patch.object( + broker, + "_channel", + new_callable=AsyncMock, + ), + mock.patch.object( + broker, + "declarer", + new_callable=AsyncMock, + ), + super()._patch_broker(broker), + ): yield @staticmethod @@ -58,7 +63,7 @@ async def _fake_connect(broker: RabbitBroker, *args: Any, **kwargs: Any) -> None def create_publisher_fake_subscriber( broker: RabbitBroker, publisher: SpecificationPublisher, - ) -> Tuple["LogicSubscriber", bool]: + ) -> tuple["LogicSubscriber", bool]: sub: Optional[LogicSubscriber] = None for handler in broker._subscribers: if _is_handler_matches( @@ -92,15 +97,12 @@ class PatchedMessage(IncomingMessage): async def ack(self, multiple: bool = False) -> None: """Asynchronously acknowledge a message.""" - pass async def nack(self, multiple: bool = False, requeue: bool = True) -> None: """Nack the message.""" - pass async def reject(self, requeue: bool = False) -> None: """Rejects a task.""" - pass def build_message( @@ -165,7 +167,7 @@ def build_message( message_type=message_type, user_id=msg.user_id, app_id=msg.app_id, - ) + ), ), body=msg.body, channel=AsyncMock(), @@ -185,7 +187,8 @@ def __init__(self, broker: RabbitBroker) -> None: default_parser = AioPikaParser() self._parser = resolve_custom_func(broker._parser, default_parser.parse_message) self._decoder = resolve_custom_func( - broker._decoder, default_parser.decode_message + broker._decoder, + default_parser.decode_message, ) @override @@ -236,12 +239,13 @@ async def publish( # type: ignore[override] for handler in self.broker._subscribers: # pragma: no branch if _is_handler_matches( - handler, incoming.routing_key, incoming.headers, exch + handler, + incoming.routing_key, + incoming.headers, + exch, ): await self._execute_handler(incoming, handler) - return None - @override async def request( # type: ignore[override] self, @@ -288,7 +292,10 @@ async def request( # type: ignore[override] for handler in self.broker._subscribers: # pragma: no branch if _is_handler_matches( - handler, incoming.routing_key, incoming.headers, exch + handler, + incoming.routing_key, + incoming.headers, + exch, ): with anyio.fail_after(timeout): return await self._execute_handler(incoming, handler) @@ -296,7 +303,9 @@ async def request( # type: ignore[override] raise SubscriberNotFound async def _execute_handler( - self, msg: PatchedMessage, handler: "LogicSubscriber" + self, + msg: PatchedMessage, + handler: "LogicSubscriber", ) -> "PatchedMessage": result = await handler.process_message(msg) @@ -320,33 +329,32 @@ def _is_handler_matches( if handler.exchange is None or handler.exchange.type == ExchangeType.DIRECT: return handler.queue.name == routing_key - elif handler.exchange.type == ExchangeType.FANOUT: + if handler.exchange.type == ExchangeType.FANOUT: return True - elif handler.exchange.type == ExchangeType.TOPIC: + if handler.exchange.type == ExchangeType.TOPIC: return apply_pattern(handler.queue.routing, routing_key) - elif handler.exchange.type == ExchangeType.HEADERS: + if handler.exchange.type == ExchangeType.HEADERS: queue_headers = (handler.queue.bind_arguments or {}).copy() if not queue_headers: return True - else: - match_rule = queue_headers.pop("x-match", "all") + match_rule = queue_headers.pop("x-match", "all") - full_match = True - is_headers_empty = True - for k, v in queue_headers.items(): - if headers.get(k) != v: - full_match = False - else: - is_headers_empty = False + full_match = True + is_headers_empty = True + for k, v in queue_headers.items(): + if headers.get(k) != v: + full_match = False + else: + is_headers_empty = False - if is_headers_empty: - return False + if is_headers_empty: + return False - return full_match or (match_rule == "any") + return full_match or (match_rule == "any") raise AssertionError @@ -361,7 +369,7 @@ def apply_pattern(pattern: str, current: str) -> bool: if (next_symb := next(current_queue, None)) is None: return False - elif pattern_symb == "#": + if pattern_symb == "#": next_pattern = next(pattern_queue, None) if next_pattern is None: @@ -381,7 +389,7 @@ def apply_pattern(pattern: str, current: str) -> bool: pattern_symb = next(pattern_queue, None) - elif pattern_symb == "*" or pattern_symb == next_symb: + elif pattern_symb in {"*", next_symb}: pattern_symb = next(pattern_queue, None) else: diff --git a/faststream/rabbit/utils.py b/faststream/rabbit/utils.py index 1af8a30f7b..feb4c4cc8e 100644 --- a/faststream/rabbit/utils.py +++ b/faststream/rabbit/utils.py @@ -49,7 +49,7 @@ def build_url( def is_routing_exchange(exchange: Optional["RabbitExchange"]) -> bool: """Check if an exchange requires routing_key to deliver message.""" - return not exchange or exchange.type in ( + return not exchange or exchange.type in { ExchangeType.DIRECT.value, ExchangeType.TOPIC.value, - ) + } diff --git a/faststream/redis/__init__.py b/faststream/redis/__init__.py index dafc1744bd..6dc43db274 100644 --- a/faststream/redis/__init__.py +++ b/faststream/redis/__init__.py @@ -7,16 +7,16 @@ from faststream.redis.testing import TestRedisBroker __all__ = ( + "ListSub", + "PubSub", "Redis", "RedisBroker", "RedisMessage", - "RedisRoute", - "RedisRouter", "RedisPublisher", "RedisResponse", - "TestRedisBroker", - "TestApp", - "PubSub", - "ListSub", + "RedisRoute", + "RedisRouter", "StreamSub", + "TestApp", + "TestRedisBroker", ) diff --git a/faststream/redis/annotations.py b/faststream/redis/annotations.py index a34f106e62..4bbbb9b324 100644 --- a/faststream/redis/annotations.py +++ b/faststream/redis/annotations.py @@ -1,5 +1,6 @@ +from typing import Annotated + from redis.asyncio.client import Redis as RedisClient -from typing_extensions import Annotated from faststream._internal.context import Context from faststream.annotations import ContextRepo, Logger @@ -8,12 +9,12 @@ from faststream.redis.message import UnifyRedisMessage __all__ = ( - "Logger", "ContextRepo", + "Logger", "NoCast", - "RedisMessage", - "RedisBroker", "Redis", + "RedisBroker", + "RedisMessage", ) RedisMessage = Annotated[UnifyRedisMessage, Context("message")] diff --git a/faststream/redis/broker/broker.py b/faststream/redis/broker/broker.py index bb4afd2582..76c4265754 100644 --- a/faststream/redis/broker/broker.py +++ b/faststream/redis/broker/broker.py @@ -1,13 +1,12 @@ import logging +from collections.abc import Iterable, Mapping from functools import partial from typing import ( TYPE_CHECKING, + Annotated, Any, Callable, - Iterable, - Mapping, Optional, - Type, Union, ) from urllib.parse import urlparse @@ -23,7 +22,7 @@ parse_url, ) from redis.exceptions import ConnectionError -from typing_extensions import Annotated, Doc, TypeAlias, override +from typing_extensions import Doc, TypeAlias, override from faststream.__about__ import __version__ from faststream._internal.broker.broker import BrokerUsecase @@ -76,9 +75,9 @@ class RedisInitKwargs(TypedDict, total=False): encoding: Optional[str] encoding_errors: Optional[str] decode_responses: Optional[bool] - parser_class: Optional[Type["BaseParser"]] - connection_class: Optional[Type["Connection"]] - encoder_class: Optional[Type["Encoder"]] + parser_class: Optional[type["BaseParser"]] + connection_class: Optional[type["Connection"]] + encoder_class: Optional[type["Encoder"]] Channel: TypeAlias = str @@ -100,7 +99,7 @@ def __init__( host: str = EMPTY, port: Union[str, int] = EMPTY, db: Union[str, int] = EMPTY, - connection_class: Type["Connection"] = EMPTY, + connection_class: type["Connection"] = EMPTY, client_name: Optional[str] = None, health_check_interval: float = 0, max_connections: Optional[int] = None, @@ -114,13 +113,13 @@ def __init__( encoding: str = "utf-8", encoding_errors: str = "strict", decode_responses: bool = False, - parser_class: Type["BaseParser"] = DefaultParser, - encoder_class: Type["Encoder"] = Encoder, + parser_class: type["BaseParser"] = DefaultParser, + encoder_class: type["Encoder"] = Encoder, # broker args graceful_timeout: Annotated[ Optional[float], Doc( - "Graceful shutdown timeout. Broker waits for all running subscribers completion before shut down." + "Graceful shutdown timeout. Broker waits for all running subscribers completion before shut down.", ), ] = 15.0, decoder: Annotated[ @@ -143,7 +142,7 @@ def __init__( security: Annotated[ Optional["BaseSecurity"], Doc( - "Security options to connect broker and generate AsyncAPI server security information." + "Security options to connect broker and generate AsyncAPI server security information.", ), ] = None, specification_url: Annotated[ @@ -243,7 +242,9 @@ def __init__( tags=tags, # logging logger_state=make_redis_logger_state( - logger=logger, log_level=log_level, log_fmt=log_fmt + logger=logger, + log_level=log_level, + log_fmt=log_fmt, ), # FastDepends args apply_types=apply_types, @@ -277,7 +278,7 @@ async def _connect( # type: ignore[override] host: str, port: Union[str, int], db: Union[str, int], - connection_class: Type["Connection"], + connection_class: type["Connection"], client_name: Optional[str], health_check_interval: float, max_connections: Optional[int], @@ -291,8 +292,8 @@ async def _connect( # type: ignore[override] encoding: str, encoding_errors: str, decode_responses: bool, - parser_class: Type["BaseParser"], - encoder_class: Type["Encoder"], + parser_class: type["BaseParser"], + encoder_class: type["Encoder"], ) -> "Redis[bytes]": url_options: AnyDict = { **dict(parse_url(url)), @@ -339,7 +340,7 @@ async def _connect( # type: ignore[override] async def close( self, - exc_type: Optional[Type[BaseException]] = None, + exc_type: Optional[type[BaseException]] = None, exc_val: Optional[BaseException] = None, exc_tb: Optional["TracebackType"] = None, ) -> None: @@ -385,7 +386,7 @@ async def publish( # type: ignore[override] Optional[str], Doc( "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages." + "**correlation_id** is a useful option to trace messages.", ), ] = None, list: Annotated[ @@ -400,7 +401,7 @@ async def publish( # type: ignore[override] Optional[int], Doc( "Redis Stream maxlen publish option. " - "Remove eldest message if maxlen exceeded." + "Remove eldest message if maxlen exceeded.", ), ] = None, ) -> None: @@ -463,7 +464,7 @@ async def publish_batch( Optional[str], Doc( "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages." + "**correlation_id** is a useful option to trace messages.", ), ] = None, ) -> None: diff --git a/faststream/redis/broker/logging.py b/faststream/redis/broker/logging.py index f3f89ad324..fba197c5da 100644 --- a/faststream/redis/broker/logging.py +++ b/faststream/redis/broker/logging.py @@ -25,7 +25,7 @@ def setup_log_contest(self, params: "AnyDict") -> None: ( self._max_channel_name, len(params.get("channel", "")), - ) + ), ) def get_logger(self) -> Optional["LoggerProto"]: diff --git a/faststream/redis/broker/registrator.py b/faststream/redis/broker/registrator.py index 38cc160bde..da6759f03a 100644 --- a/faststream/redis/broker/registrator.py +++ b/faststream/redis/broker/registrator.py @@ -1,6 +1,7 @@ -from typing import TYPE_CHECKING, Any, Iterable, List, Optional, Union, cast +from collections.abc import Iterable +from typing import TYPE_CHECKING, Annotated, Any, Optional, Union, cast -from typing_extensions import Annotated, Doc, override +from typing_extensions import Doc, override from faststream._internal.broker.abc_broker import ABCBroker from faststream.redis.message import UnifyRedisDict @@ -25,8 +26,8 @@ class RedisRegistrator(ABCBroker[UnifyRedisDict]): """Includable to RedisBroker router.""" - _subscribers: List["SubsciberType"] - _publishers: List["PublisherType"] + _subscribers: list["SubsciberType"] + _publishers: list["PublisherType"] @override def subscriber( # type: ignore[override] @@ -52,7 +53,7 @@ def subscriber( # type: ignore[override] parser: Annotated[ Optional["CustomCallable"], Doc( - "Parser to map original **aio_pika.IncomingMessage** Msg to FastStream one." + "Parser to map original **aio_pika.IncomingMessage** Msg to FastStream one.", ), ] = None, decoder: Annotated[ @@ -74,7 +75,7 @@ def subscriber( # type: ignore[override] no_reply: Annotated[ bool, Doc( - "Whether to disable **FastStream** RPC and Reply To auto responses or not." + "Whether to disable **FastStream** RPC and Reply To auto responses or not.", ), ] = False, # AsyncAPI information @@ -86,7 +87,7 @@ def subscriber( # type: ignore[override] Optional[str], Doc( "AsyncAPI subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -111,7 +112,7 @@ def subscriber( # type: ignore[override] title_=title, description_=description, include_in_schema=self._solve_include_in_schema(include_in_schema), - ) + ), ), ) @@ -142,7 +143,7 @@ def publisher( # type: ignore[override] Optional["AnyDict"], Doc( "Message headers to store metainformation. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, reply_to: Annotated[ @@ -166,7 +167,7 @@ def publisher( # type: ignore[override] Optional[Any], Doc( "AsyncAPI publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ @@ -198,6 +199,6 @@ def publisher( # type: ignore[override] description_=description, schema_=schema, include_in_schema=self._solve_include_in_schema(include_in_schema), - ) + ), ), ) diff --git a/faststream/redis/fastapi/__init__.py b/faststream/redis/fastapi/__init__.py index 86cb87a12b..da6dfd1c85 100644 --- a/faststream/redis/fastapi/__init__.py +++ b/faststream/redis/fastapi/__init__.py @@ -1,5 +1,6 @@ +from typing import Annotated + from redis.asyncio.client import Redis as RedisClient -from typing_extensions import Annotated from faststream._internal.fastapi.context import Context, ContextRepo, Logger from faststream.redis.broker.broker import RedisBroker as RB @@ -8,12 +9,12 @@ __all__ = ( "Context", - "Logger", "ContextRepo", - "RedisRouter", - "RedisMessage", - "RedisBroker", + "Logger", "Redis", + "RedisBroker", + "RedisMessage", + "RedisRouter", ) RedisMessage = Annotated[RM, Context("message")] diff --git a/faststream/redis/fastapi/fastapi.py b/faststream/redis/fastapi/fastapi.py index 2c50440075..0a1a93e441 100644 --- a/faststream/redis/fastapi/fastapi.py +++ b/faststream/redis/fastapi/fastapi.py @@ -1,15 +1,11 @@ import logging +from collections.abc import Iterable, Mapping, Sequence from typing import ( TYPE_CHECKING, + Annotated, Any, Callable, - Dict, - Iterable, - List, - Mapping, Optional, - Sequence, - Type, Union, cast, ) @@ -24,7 +20,7 @@ ) from starlette.responses import JSONResponse from starlette.routing import BaseRoute -from typing_extensions import Annotated, Doc, deprecated, override +from typing_extensions import Doc, deprecated, override from faststream.__about__ import SERVICE_NAME from faststream._internal.constants import EMPTY @@ -69,7 +65,7 @@ def __init__( host: str = EMPTY, port: Union[str, int] = EMPTY, db: Union[str, int] = EMPTY, - connection_class: Type["Connection"] = EMPTY, + connection_class: type["Connection"] = EMPTY, client_name: Optional[str] = SERVICE_NAME, health_check_interval: float = 0, max_connections: Optional[int] = None, @@ -83,13 +79,13 @@ def __init__( encoding: str = "utf-8", encoding_errors: str = "strict", decode_responses: bool = False, - parser_class: Type["BaseParser"] = DefaultParser, - encoder_class: Type["Encoder"] = Encoder, + parser_class: type["BaseParser"] = DefaultParser, + encoder_class: type["Encoder"] = Encoder, # broker base args graceful_timeout: Annotated[ Optional[float], Doc( - "Graceful shutdown timeout. Broker waits for all running subscribers completion before shut down." + "Graceful shutdown timeout. Broker waits for all running subscribers completion before shut down.", ), ] = 15.0, decoder: Annotated[ @@ -108,7 +104,7 @@ def __init__( security: Annotated[ Optional["BaseSecurity"], Doc( - "Security options to connect broker and generate AsyncAPI server security information." + "Security options to connect broker and generate AsyncAPI server security information.", ), ] = None, specification_url: Annotated[ @@ -149,13 +145,13 @@ def __init__( bool, Doc( "Whether to add broker to app scope in lifespan. " - "You should disable this option at old ASGI servers." + "You should disable this option at old ASGI servers.", ), ] = True, schema_url: Annotated[ Optional[str], Doc( - "AsyncAPI schema url. You should set this option to `None` to disable AsyncAPI routes at all." + "AsyncAPI schema url. You should set this option to `None` to disable AsyncAPI routes at all.", ), ] = "/asyncapi", # FastAPI args @@ -164,7 +160,7 @@ def __init__( Doc("An optional path prefix for the router."), ] = "", tags: Annotated[ - Optional[List[Union[str, "Enum"]]], + Optional[list[Union[str, "Enum"]]], Doc( """ A list of tags to be applied to all the *path operations* in this @@ -174,7 +170,7 @@ def __init__( Read more about it in the [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ + """, ), ] = None, dependencies: Annotated[ @@ -186,22 +182,22 @@ def __init__( Read more about it in the [FastAPI docs for Bigger Applications - Multiple Files](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies). - """ + """, ), ] = None, default_response_class: Annotated[ - Type["Response"], + type["Response"], Doc( """ The default response class to be used. Read more in the [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#default-response-class). - """ + """, ), ] = Default(JSONResponse), responses: Annotated[ - Optional[Dict[Union[int, str], "AnyDict"]], + Optional[dict[Union[int, str], "AnyDict"]], Doc( """ Additional responses to be shown in OpenAPI. @@ -213,11 +209,11 @@ def __init__( And in the [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies). - """ + """, ), ] = None, callbacks: Annotated[ - Optional[List[BaseRoute]], + Optional[list[BaseRoute]], Doc( """ OpenAPI callbacks that should apply to all *path operations* in this @@ -227,11 +223,11 @@ def __init__( Read more about it in the [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). - """ + """, ), ] = None, routes: Annotated[ - Optional[List[BaseRoute]], + Optional[list[BaseRoute]], Doc( """ **Note**: you probably shouldn't use this parameter, it is inherited @@ -240,7 +236,7 @@ def __init__( --- A list of routes to serve incoming HTTP and WebSocket requests. - """ + """, ), deprecated( """ @@ -249,7 +245,7 @@ def __init__( In FastAPI, you normally would use the *path operation methods*, like `router.get()`, `router.post()`, etc. - """ + """, ), ] = None, redirect_slashes: Annotated[ @@ -258,7 +254,7 @@ def __init__( """ Whether to detect and redirect slashes in URLs when the client doesn't use the same format. - """ + """, ), ] = True, default: Annotated[ @@ -267,7 +263,7 @@ def __init__( """ Default function handler for this router. Used to handle 404 Not Found errors. - """ + """, ), ] = None, dependency_overrides_provider: Annotated[ @@ -278,18 +274,18 @@ def __init__( You shouldn't need to use it. It normally points to the `FastAPI` app object. - """ + """, ), ] = None, route_class: Annotated[ - Type["APIRoute"], + type["APIRoute"], Doc( """ Custom route (*path operation*) class to be used by this router. Read more about it in the [FastAPI docs for Custom Request and APIRoute class](https://fastapi.tiangolo.com/how-to/custom-request-and-route/#custom-apiroute-class-in-a-router). - """ + """, ), ] = APIRoute, on_startup: Annotated[ @@ -301,7 +297,7 @@ def __init__( You should instead use the `lifespan` handlers. Read more in the [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/). - """ + """, ), ] = None, on_shutdown: Annotated[ @@ -314,7 +310,7 @@ def __init__( Read more in the [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/). - """ + """, ), ] = None, lifespan: Annotated[ @@ -326,7 +322,7 @@ def __init__( Read more in the [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/). - """ + """, ), ] = None, deprecated: Annotated[ @@ -339,7 +335,7 @@ def __init__( Read more about it in the [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ + """, ), ] = None, include_in_schema: Annotated[ @@ -353,7 +349,7 @@ def __init__( Read more about it in the [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi). - """ + """, ), ] = True, generate_unique_id_function: Annotated[ @@ -368,7 +364,7 @@ def __init__( Read more about it in the [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). - """ + """, ), ] = Default(generate_unique_id), ) -> None: @@ -454,7 +450,7 @@ def subscriber( # type: ignore[override] parser: Annotated[ Optional["CustomCallable"], Doc( - "Parser to map original **aio_pika.IncomingMessage** Msg to FastStream one." + "Parser to map original **aio_pika.IncomingMessage** Msg to FastStream one.", ), ] = None, decoder: Annotated[ @@ -476,7 +472,7 @@ def subscriber( # type: ignore[override] no_reply: Annotated[ bool, Doc( - "Whether to disable **FastStream** RPC and Reply To auto responses or not." + "Whether to disable **FastStream** RPC and Reply To auto responses or not.", ), ] = False, # AsyncAPI information @@ -488,7 +484,7 @@ def subscriber( # type: ignore[override] Optional[str], Doc( "AsyncAPI subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -527,7 +523,7 @@ def subscriber( # type: ignore[override] Read more about it in the [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). - """ + """, ), ] = Default(None), response_model_include: Annotated[ @@ -539,7 +535,7 @@ def subscriber( # type: ignore[override] Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = None, response_model_exclude: Annotated[ @@ -551,7 +547,7 @@ def subscriber( # type: ignore[override] Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = None, response_model_by_alias: Annotated[ @@ -563,7 +559,7 @@ def subscriber( # type: ignore[override] Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ + """, ), ] = True, response_model_exclude_unset: Annotated[ @@ -581,7 +577,7 @@ def subscriber( # type: ignore[override] Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ + """, ), ] = False, response_model_exclude_defaults: Annotated[ @@ -598,7 +594,7 @@ def subscriber( # type: ignore[override] Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ + """, ), ] = False, response_model_exclude_none: Annotated[ @@ -615,7 +611,7 @@ def subscriber( # type: ignore[override] Read more about it in the [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). - """ + """, ), ] = False, ) -> SpecificationSubscriber: @@ -665,7 +661,7 @@ def publisher( Optional["AnyDict"], Doc( "Message headers to store metainformation. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, reply_to: Annotated[ @@ -689,7 +685,7 @@ def publisher( Optional[Any], Doc( "AsyncAPI publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ diff --git a/faststream/redis/message.py b/faststream/redis/message.py index 68d11d7f90..b13dad9308 100644 --- a/faststream/redis/message.py +++ b/faststream/redis/message.py @@ -1,7 +1,5 @@ from typing import ( TYPE_CHECKING, - Dict, - List, Literal, Optional, TypeVar, @@ -39,9 +37,9 @@ class UnifyRedisDict(TypedDict): channel: str data: Union[ bytes, - List[bytes], - Dict[bytes, bytes], - List[Dict[bytes, bytes]], + list[bytes], + dict[bytes, bytes], + list[dict[bytes, bytes]], ] pattern: NotRequired[Optional[bytes]] @@ -80,19 +78,17 @@ class BatchListMessage(ListMessage): """A class to represent a List messages batch.""" type: Literal["blist"] - data: List[bytes] + data: list[bytes] class RedisListMessage(BrokerStreamMessage[DefaultListMessage]): """StreamMessage for single List message.""" - pass - class RedisBatchListMessage(BrokerStreamMessage[BatchListMessage]): """StreamMessage for single List message.""" - decoded_body: List["DecodedMessage"] + decoded_body: list["DecodedMessage"] DATA_KEY = "__data__" @@ -101,17 +97,17 @@ class RedisBatchListMessage(BrokerStreamMessage[BatchListMessage]): class StreamMessage(TypedDict): channel: str - message_ids: List[bytes] + message_ids: list[bytes] class DefaultStreamMessage(StreamMessage): type: Literal["stream"] - data: Dict[bytes, bytes] + data: dict[bytes, bytes] class BatchStreamMessage(StreamMessage): type: Literal["bstream"] - data: List[Dict[bytes, bytes]] + data: list[dict[bytes, bytes]] _StreamMsgType = TypeVar("_StreamMsgType", bound=StreamMessage) @@ -152,4 +148,4 @@ class RedisStreamMessage(_RedisStreamMessageMixin[DefaultStreamMessage]): class RedisBatchStreamMessage(_RedisStreamMessageMixin[BatchStreamMessage]): - decoded_body: List["DecodedMessage"] + decoded_body: list["DecodedMessage"] diff --git a/faststream/redis/opentelemetry/provider.py b/faststream/redis/opentelemetry/provider.py index 043a6efbe5..ea8c17462c 100644 --- a/faststream/redis/opentelemetry/provider.py +++ b/faststream/redis/opentelemetry/provider.py @@ -1,4 +1,5 @@ -from typing import TYPE_CHECKING, Sized, cast +from collections.abc import Sized +from typing import TYPE_CHECKING, cast from opentelemetry.semconv.trace import SpanAttributes @@ -30,7 +31,7 @@ def get_consume_attrs_from_message( if cast(str, msg.raw_message.get("type", "")).startswith("b"): attrs[SpanAttributes.MESSAGING_BATCH_MESSAGE_COUNT] = len( - cast(Sized, msg._decoded_body) + cast(Sized, msg._decoded_body), ) return attrs diff --git a/faststream/redis/parser.py b/faststream/redis/parser.py index b529b70648..1d33c0e9f3 100644 --- a/faststream/redis/parser.py +++ b/faststream/redis/parser.py @@ -1,12 +1,8 @@ +from collections.abc import Mapping, Sequence from typing import ( TYPE_CHECKING, Any, - List, - Mapping, Optional, - Sequence, - Tuple, - Type, TypeVar, Union, ) @@ -102,29 +98,29 @@ def encode( { "data": msg.data, "headers": msg.headers, - } + }, ) @staticmethod - def parse(data: bytes) -> Tuple[bytes, "AnyDict"]: + def parse(data: bytes) -> tuple[bytes, "AnyDict"]: headers: AnyDict try: # FastStream message format parsed_data = json_loads(data) - data = parsed_data["data"].encode() + final_data = parsed_data["data"].encode() headers = parsed_data["headers"] except Exception: # Raw Redis message format - data = data + final_data = data headers = {} - return data, headers + return final_data, headers class SimpleParser: - msg_class: Type["StreamMessage[Any]"] + msg_class: type["StreamMessage[Any]"] def __init__( self, @@ -155,7 +151,7 @@ async def parse_message( def _parse_data( self, message: Mapping[str, Any], - ) -> Tuple[bytes, "AnyDict", List["AnyDict"]]: + ) -> tuple[bytes, "AnyDict", list["AnyDict"]]: return (*RawMessage.parse(message["data"]), []) def get_path(self, message: Mapping[str, Any]) -> "AnyDict": @@ -166,8 +162,7 @@ def get_path(self, message: Mapping[str, Any]) -> "AnyDict": ): return match.groupdict() - else: - return {} + return {} async def decode_message( self, @@ -190,9 +185,9 @@ class RedisBatchListParser(SimpleParser): def _parse_data( self, message: Mapping[str, Any], - ) -> Tuple[bytes, "AnyDict", List["AnyDict"]]: - body: List[Any] = [] - batch_headers: List[AnyDict] = [] + ) -> tuple[bytes, "AnyDict", list["AnyDict"]]: + body: list[Any] = [] + batch_headers: list[AnyDict] = [] for x in message["data"]: msg_data, msg_headers = _decode_batch_body_item(x) @@ -216,8 +211,9 @@ class RedisStreamParser(SimpleParser): @classmethod def _parse_data( - cls, message: Mapping[str, Any] - ) -> Tuple[bytes, "AnyDict", List["AnyDict"]]: + cls, + message: Mapping[str, Any], + ) -> tuple[bytes, "AnyDict", list["AnyDict"]]: data = message["data"] return (*RawMessage.parse(data.get(bDATA_KEY) or dump_json(data)), []) @@ -228,9 +224,9 @@ class RedisBatchStreamParser(SimpleParser): def _parse_data( self, message: Mapping[str, Any], - ) -> Tuple[bytes, "AnyDict", List["AnyDict"]]: - body: List[Any] = [] - batch_headers: List[AnyDict] = [] + ) -> tuple[bytes, "AnyDict", list["AnyDict"]]: + body: list[Any] = [] + batch_headers: list[AnyDict] = [] for x in message["data"]: msg_data, msg_headers = _decode_batch_body_item(x.get(bDATA_KEY, x)) @@ -249,7 +245,7 @@ def _parse_data( ) -def _decode_batch_body_item(msg_content: bytes) -> Tuple[Any, "AnyDict"]: +def _decode_batch_body_item(msg_content: bytes) -> tuple[Any, "AnyDict"]: msg_body, headers = RawMessage.parse(msg_content) try: return json_loads(msg_body), headers diff --git a/faststream/redis/publisher/producer.py b/faststream/redis/publisher/producer.py index 189347a7c4..8c196e1a71 100644 --- a/faststream/redis/publisher/producer.py +++ b/faststream/redis/publisher/producer.py @@ -80,9 +80,8 @@ async def publish( # type: ignore[override] maxlen=maxlen, ) else: - raise AssertionError("unreachable") - - return None + msg = "unreachable" + raise AssertionError(msg) @override async def request( # type: ignore[override] @@ -123,7 +122,8 @@ async def request( # type: ignore[override] maxlen=maxlen, ) else: - raise AssertionError("unreachable") + msg = "unreachable" + raise AssertionError(msg) with anyio.fail_after(timeout) as scope: # skip subscribe message diff --git a/faststream/redis/publisher/publisher.py b/faststream/redis/publisher/publisher.py index ac66d37c41..11b7e5f4c4 100644 --- a/faststream/redis/publisher/publisher.py +++ b/faststream/redis/publisher/publisher.py @@ -1,4 +1,5 @@ -from typing import TYPE_CHECKING, Any, Dict, Iterable, Optional, Union +from collections.abc import Iterable +from typing import TYPE_CHECKING, Any, Optional, Union from typing_extensions import TypeAlias, override @@ -34,7 +35,7 @@ class SpecificationPublisher(LogicPublisher, RedisAsyncAPIProtocol): """A class to represent a Redis publisher.""" - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> dict[str, Channel]: payloads = self.get_payloads() return { @@ -45,14 +46,14 @@ def get_schema(self) -> Dict[str, Channel]: title=f"{self.name}:Message", payload=resolve_payloads(payloads, "Publisher"), correlationId=CorrelationId( - location="$message.header#/correlation_id" + location="$message.header#/correlation_id", ), ), ), bindings=ChannelBinding( redis=self.channel_binding, ), - ) + ), } @override @@ -89,7 +90,7 @@ def create( # type: ignore[override] include_in_schema=include_in_schema, ) - elif (stream := StreamSub.validate(stream)) is not None: + if (stream := StreamSub.validate(stream)) is not None: return AsyncAPIStreamPublisher( stream=stream, # basic args @@ -104,7 +105,7 @@ def create( # type: ignore[override] include_in_schema=include_in_schema, ) - elif (list := ListSub.validate(list)) is not None: + if (list := ListSub.validate(list)) is not None: if list.batch: return AsyncAPIListBatchPublisher( list=list, @@ -119,23 +120,21 @@ def create( # type: ignore[override] schema_=schema_, include_in_schema=include_in_schema, ) - else: - return AsyncAPIListPublisher( - list=list, - # basic args - headers=headers, - reply_to=reply_to, - broker_middlewares=broker_middlewares, - middlewares=middlewares, - # AsyncAPI args - title_=title_, - description_=description_, - schema_=schema_, - include_in_schema=include_in_schema, - ) + return AsyncAPIListPublisher( + list=list, + # basic args + headers=headers, + reply_to=reply_to, + broker_middlewares=broker_middlewares, + middlewares=middlewares, + # AsyncAPI args + title_=title_, + description_=description_, + schema_=schema_, + include_in_schema=include_in_schema, + ) - else: - raise SetupError(INCORRECT_SETUP_MSG) + raise SetupError(INCORRECT_SETUP_MSG) class AsyncAPIChannelPublisher(ChannelPublisher, SpecificationPublisher): diff --git a/faststream/redis/publisher/usecase.py b/faststream/redis/publisher/usecase.py index c65175a029..9aae92c837 100644 --- a/faststream/redis/publisher/usecase.py +++ b/faststream/redis/publisher/usecase.py @@ -1,10 +1,11 @@ from abc import abstractmethod +from collections.abc import Awaitable, Iterable from copy import deepcopy from functools import partial from itertools import chain -from typing import TYPE_CHECKING, Any, Awaitable, Callable, Iterable, Optional +from typing import TYPE_CHECKING, Annotated, Any, Callable, Optional -from typing_extensions import Annotated, Doc, override +from typing_extensions import Doc, override from faststream._internal.publisher.usecase import PublisherUsecase from faststream._internal.subscriber.utils import process_msg @@ -56,7 +57,7 @@ def __init__( @abstractmethod def subscriber_property(self, *, name_only: bool) -> "AnyDict": - raise NotImplementedError() + raise NotImplementedError class ChannelPublisher(LogicPublisher): @@ -98,7 +99,7 @@ def subscriber_property(self, *, name_only: bool) -> "AnyDict": def add_prefix(self, prefix: str) -> None: channel = deepcopy(self.channel) - channel.name = "".join((prefix, channel.name)) + channel.name = f"{prefix}{channel.name}" self.channel = channel @override @@ -124,7 +125,7 @@ async def publish( Optional[str], Doc( "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages." + "**correlation_id** is a useful option to trace messages.", ), ] = None, # publisher specific @@ -177,7 +178,7 @@ async def request( Optional[str], Doc( "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages." + "**correlation_id** is a useful option to trace messages.", ), ] = None, headers: Annotated[ @@ -267,7 +268,7 @@ def subscriber_property(self, *, name_only: bool) -> "AnyDict": def add_prefix(self, prefix: str) -> None: list_sub = deepcopy(self.list) - list_sub.name = "".join((prefix, list_sub.name)) + list_sub.name = f"{prefix}{list_sub.name}" self.list = list_sub @override @@ -293,7 +294,7 @@ async def publish( Optional[str], Doc( "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages." + "**correlation_id** is a useful option to trace messages.", ), ] = None, # publisher specific @@ -345,7 +346,7 @@ async def request( Optional[str], Doc( "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages." + "**correlation_id** is a useful option to trace messages.", ), ] = None, headers: Annotated[ @@ -488,7 +489,7 @@ def subscriber_property(self, *, name_only: bool) -> "AnyDict": def add_prefix(self, prefix: str) -> None: stream_sub = deepcopy(self.stream) - stream_sub.name = "".join((prefix, stream_sub.name)) + stream_sub.name = f"{prefix}{stream_sub.name}" self.stream = stream_sub @override @@ -514,7 +515,7 @@ async def publish( Optional[str], Doc( "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages." + "**correlation_id** is a useful option to trace messages.", ), ] = None, *, @@ -522,7 +523,7 @@ async def publish( Optional[int], Doc( "Redis Stream maxlen publish option. " - "Remove eldest message if maxlen exceeded." + "Remove eldest message if maxlen exceeded.", ), ] = None, # publisher specific @@ -576,14 +577,14 @@ async def request( Optional[int], Doc( "Redis Stream maxlen publish option. " - "Remove eldest message if maxlen exceeded." + "Remove eldest message if maxlen exceeded.", ), ] = None, correlation_id: Annotated[ Optional[str], Doc( "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages." + "**correlation_id** is a useful option to trace messages.", ), ] = None, headers: Annotated[ diff --git a/faststream/redis/response.py b/faststream/redis/response.py index 2896fd48b8..b5f4a231f9 100644 --- a/faststream/redis/response.py +++ b/faststream/redis/response.py @@ -26,8 +26,7 @@ def __init__( @override def as_publish_kwargs(self) -> "AnyDict": - publish_options = { + return { **super().as_publish_kwargs(), "maxlen": self.maxlen, } - return publish_options diff --git a/faststream/redis/router.py b/faststream/redis/router.py index bf1035d7f6..4e651c78eb 100644 --- a/faststream/redis/router.py +++ b/faststream/redis/router.py @@ -1,6 +1,7 @@ -from typing import TYPE_CHECKING, Any, Awaitable, Callable, Iterable, Optional, Union +from collections.abc import Awaitable, Iterable +from typing import TYPE_CHECKING, Annotated, Any, Callable, Optional, Union -from typing_extensions import Annotated, Doc +from typing_extensions import Doc from faststream._internal.broker.router import ( ArgsContainer, @@ -49,7 +50,7 @@ def __init__( Optional["AnyDict"], Doc( "Message headers to store metainformation. " - "Can be overridden by `publish.headers` if specified." + "Can be overridden by `publish.headers` if specified.", ), ] = None, reply_to: Annotated[ @@ -73,7 +74,7 @@ def __init__( Optional[Any], Doc( "AsyncAPI publishing message type. " - "Should be any python-native object annotation or `pydantic.BaseModel`." + "Should be any python-native object annotation or `pydantic.BaseModel`.", ), ] = None, include_in_schema: Annotated[ @@ -107,7 +108,7 @@ def __init__( ], Doc( "Message handler function " - "to wrap the same with `@broker.subscriber(...)` way." + "to wrap the same with `@broker.subscriber(...)` way.", ), ], channel: Annotated[ @@ -135,7 +136,7 @@ def __init__( parser: Annotated[ Optional["CustomCallable"], Doc( - "Parser to map original **aio_pika.IncomingMessage** Msg to FastStream one." + "Parser to map original **aio_pika.IncomingMessage** Msg to FastStream one.", ), ] = None, decoder: Annotated[ @@ -157,7 +158,7 @@ def __init__( no_reply: Annotated[ bool, Doc( - "Whether to disable **FastStream** RPC and Reply To auto responses or not." + "Whether to disable **FastStream** RPC and Reply To auto responses or not.", ), ] = False, # AsyncAPI information @@ -169,7 +170,7 @@ def __init__( Optional[str], Doc( "AsyncAPI subscriber object description. " - "Uses decorated docstring as default." + "Uses decorated docstring as default.", ), ] = None, include_in_schema: Annotated[ @@ -216,7 +217,7 @@ def __init__( dependencies: Annotated[ Iterable["Depends"], Doc( - "Dependencies list (`[Depends(),]`) to apply to all routers' publishers/subscribers." + "Dependencies list (`[Depends(),]`) to apply to all routers' publishers/subscribers.", ), ] = (), middlewares: Annotated[ diff --git a/faststream/redis/schemas/__init__.py b/faststream/redis/schemas/__init__.py index 817d7a0654..e45791d755 100644 --- a/faststream/redis/schemas/__init__.py +++ b/faststream/redis/schemas/__init__.py @@ -3,8 +3,8 @@ from faststream.redis.schemas.stream_sub import StreamSub __all__ = ( - "PubSub", "ListSub", + "PubSub", "StreamSub", ) diff --git a/faststream/redis/schemas/list_sub.py b/faststream/redis/schemas/list_sub.py index 571100e651..b842cc29e3 100644 --- a/faststream/redis/schemas/list_sub.py +++ b/faststream/redis/schemas/list_sub.py @@ -8,9 +8,9 @@ class ListSub(NameRequired): """A class to represent a Redis List subscriber.""" __slots__ = ( - "name", "batch", "max_records", + "name", "polling_interval", ) diff --git a/faststream/redis/schemas/proto.py b/faststream/redis/schemas/proto.py index 0a64d4dd7f..0e1d929211 100644 --- a/faststream/redis/schemas/proto.py +++ b/faststream/redis/schemas/proto.py @@ -25,8 +25,11 @@ def validate_options( stream: Union["StreamSub", str, None], ) -> None: if all((channel, list)): - raise SetupError("You can't use `PubSub` and `ListSub` both") - elif all((channel, stream)): - raise SetupError("You can't use `PubSub` and `StreamSub` both") - elif all((list, stream)): - raise SetupError("You can't use `ListSub` and `StreamSub` both") + msg = "You can't use `PubSub` and `ListSub` both" + raise SetupError(msg) + if all((channel, stream)): + msg = "You can't use `PubSub` and `StreamSub` both" + raise SetupError(msg) + if all((list, stream)): + msg = "You can't use `ListSub` and `StreamSub` both" + raise SetupError(msg) diff --git a/faststream/redis/schemas/pub_sub.py b/faststream/redis/schemas/pub_sub.py index c4e60ee201..88d41ac8eb 100644 --- a/faststream/redis/schemas/pub_sub.py +++ b/faststream/redis/schemas/pub_sub.py @@ -7,9 +7,9 @@ class PubSub(NameRequired): __slots__ = ( "name", - "polling_interval", - "pattern", "path_regex", + "pattern", + "polling_interval", ) def __init__( diff --git a/faststream/redis/schemas/stream_sub.py b/faststream/redis/schemas/stream_sub.py index cc1fa59070..50a0b6d606 100644 --- a/faststream/redis/schemas/stream_sub.py +++ b/faststream/redis/schemas/stream_sub.py @@ -9,15 +9,15 @@ class StreamSub(NameRequired): """A class to represent a Redis Stream subscriber.""" __slots__ = ( - "name", - "polling_interval", - "last_id", - "group", - "consumer", - "no_ack", "batch", + "consumer", + "group", + "last_id", "max_records", "maxlen", + "name", + "no_ack", + "polling_interval", ) def __init__( @@ -33,7 +33,8 @@ def __init__( max_records: Optional[int] = None, ) -> None: if (group and not consumer) or (not group and consumer): - raise SetupError("You should specify `group` and `consumer` both") + msg = "You should specify `group` and `consumer` both" + raise SetupError(msg) if group and consumer and no_ack: warnings.warn( diff --git a/faststream/redis/security.py b/faststream/redis/security.py index 8fea384ecc..153c369c79 100644 --- a/faststream/redis/security.py +++ b/faststream/redis/security.py @@ -11,12 +11,12 @@ def parse_security(security: Optional[BaseSecurity]) -> "AnyDict": if security is None: return {} - elif isinstance(security, SASLPlaintext): + if isinstance(security, SASLPlaintext): return _parse_sasl_plaintext(security) - elif isinstance(security, BaseSecurity): + if isinstance(security, BaseSecurity): return _parse_base_security(security) - else: - raise NotImplementedError(f"RedisBroker does not support {type(security)}") + msg = f"RedisBroker does not support {type(security)}" + raise NotImplementedError(msg) def _parse_base_security(security: BaseSecurity) -> "AnyDict": @@ -38,8 +38,7 @@ def _connection_arguments(self) -> Any: } return {"connection_class": SSLConnection} - else: - return {} + return {} def _parse_sasl_plaintext(security: SASLPlaintext) -> "AnyDict": diff --git a/faststream/redis/subscriber/factory.py b/faststream/redis/subscriber/factory.py index d1097e41ce..8cd414f278 100644 --- a/faststream/redis/subscriber/factory.py +++ b/faststream/redis/subscriber/factory.py @@ -1,4 +1,5 @@ -from typing import TYPE_CHECKING, Iterable, Optional, Union +from collections.abc import Iterable +from typing import TYPE_CHECKING, Optional, Union from typing_extensions import TypeAlias @@ -61,7 +62,7 @@ def create_subscriber( include_in_schema=include_in_schema, ) - elif (stream_sub := StreamSub.validate(stream)) is not None: + if (stream_sub := StreamSub.validate(stream)) is not None: if stream_sub.batch: return AsyncAPIStreamBatchSubscriber( stream=stream_sub, @@ -76,22 +77,21 @@ def create_subscriber( description_=description_, include_in_schema=include_in_schema, ) - else: - return AsyncAPIStreamSubscriber( - stream=stream_sub, - # basic args - no_ack=no_ack, - no_reply=no_reply, - retry=retry, - broker_dependencies=broker_dependencies, - broker_middlewares=broker_middlewares, - # AsyncAPI args - title_=title_, - description_=description_, - include_in_schema=include_in_schema, - ) + return AsyncAPIStreamSubscriber( + stream=stream_sub, + # basic args + no_ack=no_ack, + no_reply=no_reply, + retry=retry, + broker_dependencies=broker_dependencies, + broker_middlewares=broker_middlewares, + # AsyncAPI args + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + ) - elif (list_sub := ListSub.validate(list)) is not None: + if (list_sub := ListSub.validate(list)) is not None: if list_sub.batch: return AsyncAPIListBatchSubscriber( list=list_sub, @@ -106,20 +106,18 @@ def create_subscriber( description_=description_, include_in_schema=include_in_schema, ) - else: - return AsyncAPIListSubscriber( - list=list_sub, - # basic args - no_ack=no_ack, - no_reply=no_reply, - retry=retry, - broker_dependencies=broker_dependencies, - broker_middlewares=broker_middlewares, - # AsyncAPI args - title_=title_, - description_=description_, - include_in_schema=include_in_schema, - ) + return AsyncAPIListSubscriber( + list=list_sub, + # basic args + no_ack=no_ack, + no_reply=no_reply, + retry=retry, + broker_dependencies=broker_dependencies, + broker_middlewares=broker_middlewares, + # AsyncAPI args + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + ) - else: - raise SetupError(INCORRECT_SETUP_MSG) + raise SetupError(INCORRECT_SETUP_MSG) diff --git a/faststream/redis/subscriber/subscriber.py b/faststream/redis/subscriber/subscriber.py index 54a9b57578..eba6c89f40 100644 --- a/faststream/redis/subscriber/subscriber.py +++ b/faststream/redis/subscriber/subscriber.py @@ -1,5 +1,3 @@ -from typing import Dict - from faststream.redis.schemas import ListSub, StreamSub from faststream.redis.schemas.proto import RedisAsyncAPIProtocol from faststream.redis.subscriber.usecase import ( @@ -20,7 +18,7 @@ class SpecificationSubscriber(LogicSubscriber, RedisAsyncAPIProtocol): """A class to represent a Redis handler.""" - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> dict[str, Channel]: payloads = self.get_payloads() return { @@ -31,14 +29,14 @@ def get_schema(self) -> Dict[str, Channel]: title=f"{self.name}:Message", payload=resolve_payloads(payloads), correlationId=CorrelationId( - location="$message.header#/correlation_id" + location="$message.header#/correlation_id", ), ), ), bindings=ChannelBinding( redis=self.channel_binding, ), - ) + ), } diff --git a/faststream/redis/subscriber/usecase.py b/faststream/redis/subscriber/usecase.py index 351ed34842..6ecc4793c6 100644 --- a/faststream/redis/subscriber/usecase.py +++ b/faststream/redis/subscriber/usecase.py @@ -1,24 +1,21 @@ import asyncio import math from abc import abstractmethod +from collections.abc import Awaitable, Iterable, Sequence from contextlib import suppress from copy import deepcopy from typing import ( TYPE_CHECKING, Any, - Awaitable, Callable, - Dict, - Iterable, - List, Optional, - Sequence, - Tuple, ) import anyio -from redis.asyncio.client import PubSub as RPubSub -from redis.asyncio.client import Redis +from redis.asyncio.client import ( + PubSub as RPubSub, + Redis, +) from redis.exceptions import ResponseError from typing_extensions import TypeAlias, override @@ -160,7 +157,7 @@ async def start( if self.calls: self.task = asyncio.create_task( - self._consume(*args, start_signal=start_signal) + self._consume(*args, start_signal=start_signal), ) with anyio.fail_after(3.0): @@ -192,7 +189,7 @@ async def _consume(self, *args: Any, start_signal: anyio.Event) -> None: @abstractmethod async def _get_msgs(self, *args: Any) -> None: - raise NotImplementedError() + raise NotImplementedError async def close(self) -> None: await super().close() @@ -205,7 +202,7 @@ async def close(self) -> None: def build_log_context( message: Optional["BrokerStreamMessage[Any]"], channel: str = "", - ) -> Dict[str, str]: + ) -> dict[str, str]: return { "channel": channel, "message_id": getattr(message, "message_id", ""), @@ -252,7 +249,7 @@ def __init__( def get_log_context( self, message: Optional["BrokerStreamMessage[Any]"], - ) -> Dict[str, str]: + ) -> dict[str, str]: return self.build_log_context( message=message, channel=self.channel.name, @@ -331,7 +328,7 @@ async def _get_msgs(self, psub: RPubSub) -> None: def add_prefix(self, prefix: str) -> None: new_ch = deepcopy(self.channel) - new_ch.name = "".join((prefix, new_ch.name)) + new_ch.name = f"{prefix}{new_ch.name}" self.channel = new_ch @@ -373,7 +370,7 @@ def __init__( def get_log_context( self, message: Optional["BrokerStreamMessage[Any]"], - ) -> Dict[str, str]: + ) -> dict[str, str]: return self.build_log_context( message=message, channel=self.list_sub.name, @@ -435,7 +432,7 @@ async def get_one( # type: ignore[override] def add_prefix(self, prefix: str) -> None: new_list = deepcopy(self.list_sub) - new_list.name = "".join((prefix, new_list.name)) + new_list.name = f"{prefix}{new_list.name}" self.list_sub = new_list @@ -579,7 +576,7 @@ def __init__( def get_log_context( self, message: Optional["BrokerStreamMessage[Any]"], - ) -> Dict[str, str]: + ) -> dict[str, str]: return self.build_log_context( message=message, channel=self.stream_sub.name, @@ -604,13 +601,13 @@ async def start(self) -> None: read: Callable[ [str], Awaitable[ - Tuple[ - Tuple[ + tuple[ + tuple[ TopicName, - Tuple[ - Tuple[ + tuple[ + tuple[ Offset, - Dict[bytes, bytes], + dict[bytes, bytes], ], ..., ], @@ -630,18 +627,18 @@ async def start(self) -> None: ) except ResponseError as e: if "already exists" not in str(e): - raise e + raise def read( _: str, ) -> Awaitable[ - Tuple[ - Tuple[ + tuple[ + tuple[ TopicName, - Tuple[ - Tuple[ + tuple[ + tuple[ Offset, - Dict[bytes, bytes], + dict[bytes, bytes], ], ..., ], @@ -663,13 +660,13 @@ def read( def read( last_id: str, ) -> Awaitable[ - Tuple[ - Tuple[ + tuple[ + tuple[ TopicName, - Tuple[ - Tuple[ + tuple[ + tuple[ Offset, - Dict[bytes, bytes], + dict[bytes, bytes], ], ..., ], @@ -724,7 +721,7 @@ async def get_one( # type: ignore[override] def add_prefix(self, prefix: str) -> None: new_stream = deepcopy(self.stream_sub) - new_stream.name = "".join((prefix, new_stream.name)) + new_stream.name = f"{prefix}{new_stream.name}" self.stream_sub = new_stream @@ -766,13 +763,13 @@ async def _get_msgs( read: Callable[ [str], Awaitable[ - Tuple[ - Tuple[ + tuple[ + tuple[ TopicName, - Tuple[ - Tuple[ + tuple[ + tuple[ Offset, - Dict[bytes, bytes], + dict[bytes, bytes], ], ..., ], @@ -835,7 +832,7 @@ async def _get_msgs( read: Callable[ [str], Awaitable[ - Tuple[Tuple[bytes, Tuple[Tuple[bytes, Dict[bytes, bytes]], ...]], ...], + tuple[tuple[bytes, tuple[tuple[bytes, dict[bytes, bytes]], ...]], ...], ], ], ) -> None: @@ -843,8 +840,8 @@ async def _get_msgs( if msgs: self.last_id = msgs[-1][0].decode() - data: List[Dict[bytes, bytes]] = [] - ids: List[bytes] = [] + data: list[dict[bytes, bytes]] = [] + ids: list[bytes] = [] for message_id, i in msgs: data.append(i) ids.append(message_id) diff --git a/faststream/redis/testing.py b/faststream/redis/testing.py index c8a491b1dd..8f065bf5a7 100644 --- a/faststream/redis/testing.py +++ b/faststream/redis/testing.py @@ -1,12 +1,10 @@ import re +from collections.abc import Sequence from typing import ( TYPE_CHECKING, Any, - List, Optional, Protocol, - Sequence, - Tuple, Union, cast, ) @@ -52,7 +50,7 @@ class TestRedisBroker(TestBroker[RedisBroker]): def create_publisher_fake_subscriber( broker: RedisBroker, publisher: "SpecificationPublisher", - ) -> Tuple["LogicSubscriber", bool]: + ) -> tuple["LogicSubscriber", bool]: sub: Optional[LogicSubscriber] = None named_property = publisher.subscriber_property(name_only=True) @@ -86,7 +84,6 @@ async def _fake_connect( # type: ignore[override] async def get_msg(*args: Any, timeout: float, **kwargs: Any) -> None: await anyio.sleep(timeout) - return None pub_sub.get_message = get_msg @@ -144,8 +141,6 @@ async def publish( await self._execute_handler(msg, handler) - return None - @override async def request( # type: ignore[override] self, @@ -210,10 +205,10 @@ async def publish_batch( await self._execute_handler(msg, handler) - return None - async def _execute_handler( - self, msg: Any, handler: "LogicSubscriber" + self, + msg: Any, + handler: "LogicSubscriber", ) -> "PubSubMessage": result = await handler.process_message(msg) @@ -236,13 +231,12 @@ def build_message( reply_to: str = "", headers: Optional["AnyDict"] = None, ) -> bytes: - data = RawMessage.encode( + return RawMessage.encode( message=message, reply_to=reply_to, headers=headers, correlation_id=correlation_id, ) - return data class Visitor(Protocol): @@ -278,7 +272,7 @@ def visit( re.match( sub_channel.name.replace(".", "\\.").replace("*", ".*"), channel or "", - ) + ), ) ) or channel == sub_channel.name: return channel @@ -326,15 +320,14 @@ def get_message( # type: ignore[override] return BatchListMessage( type="blist", channel=channel, - data=body if isinstance(body, List) else [body], + data=body if isinstance(body, list) else [body], ) - else: - return DefaultListMessage( - type="list", - channel=channel, - data=body, - ) + return DefaultListMessage( + type="list", + channel=channel, + data=body, + ) class StreamVisitor(Visitor): @@ -368,13 +361,12 @@ def get_message( # type: ignore[override] message_ids=[], ) - else: - return DefaultStreamMessage( - type="stream", - channel=channel, - data={bDATA_KEY: body}, - message_ids=[], - ) + return DefaultStreamMessage( + type="stream", + channel=channel, + data={bDATA_KEY: body}, + message_ids=[], + ) class _DestinationKwargs(TypedDict, total=False): diff --git a/faststream/response/response.py b/faststream/response/response.py index 7cfed34628..cbb338bed7 100644 --- a/faststream/response/response.py +++ b/faststream/response/response.py @@ -29,8 +29,7 @@ def add_headers( self.headers = {**extra_headers, **self.headers} def as_publish_kwargs(self) -> "AnyDict": - publish_options = { + return { "headers": self.headers, "correlation_id": self.correlation_id, } - return publish_options diff --git a/faststream/security.py b/faststream/security.py index e4b05b7ac9..583f7fd30d 100644 --- a/faststream/security.py +++ b/faststream/security.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Dict, List, Optional +from typing import TYPE_CHECKING, Optional if TYPE_CHECKING: from ssl import SSLContext @@ -30,11 +30,11 @@ def __init__( self.use_ssl = use_ssl self.ssl_context = ssl_context - def get_requirement(self) -> List["AnyDict"]: + def get_requirement(self) -> list["AnyDict"]: """Get the security requirements.""" return [] - def get_schema(self) -> Dict[str, Dict[str, str]]: + def get_schema(self) -> dict[str, dict[str, str]]: """Get the security schema.""" return {} @@ -47,10 +47,10 @@ class SASLPlaintext(BaseSecurity): # TODO: mv to SecretStr __slots__ = ( - "use_ssl", + "password", "ssl_context", + "use_ssl", "username", - "password", ) def __init__( @@ -68,11 +68,11 @@ def __init__( self.username = username self.password = password - def get_requirement(self) -> List["AnyDict"]: + def get_requirement(self) -> list["AnyDict"]: """Get the security requirements for SASL/PLAINTEXT authentication.""" return [{"user-password": []}] - def get_schema(self) -> Dict[str, Dict[str, str]]: + def get_schema(self) -> dict[str, dict[str, str]]: """Get the security schema for SASL/PLAINTEXT authentication.""" return {"user-password": {"type": "userPassword"}} @@ -85,10 +85,10 @@ class SASLScram256(BaseSecurity): # TODO: mv to SecretStr __slots__ = ( - "use_ssl", + "password", "ssl_context", + "use_ssl", "username", - "password", ) def __init__( @@ -106,11 +106,11 @@ def __init__( self.username = username self.password = password - def get_requirement(self) -> List["AnyDict"]: + def get_requirement(self) -> list["AnyDict"]: """Get the security requirements for SASL/SCRAM-SHA-256 authentication.""" return [{"scram256": []}] - def get_schema(self) -> Dict[str, Dict[str, str]]: + def get_schema(self) -> dict[str, dict[str, str]]: """Get the security schema for SASL/SCRAM-SHA-256 authentication.""" return {"scram256": {"type": "scramSha256"}} @@ -123,10 +123,10 @@ class SASLScram512(BaseSecurity): # TODO: mv to SecretStr __slots__ = ( - "use_ssl", + "password", "ssl_context", + "use_ssl", "username", - "password", ) def __init__( @@ -144,11 +144,11 @@ def __init__( self.username = username self.password = password - def get_requirement(self) -> List["AnyDict"]: + def get_requirement(self) -> list["AnyDict"]: """Get the security requirements for SASL/SCRAM-SHA-512 authentication.""" return [{"scram512": []}] - def get_schema(self) -> Dict[str, Dict[str, str]]: + def get_schema(self) -> dict[str, dict[str, str]]: """Get the security schema for SASL/SCRAM-SHA-512 authentication.""" return {"scram512": {"type": "scramSha512"}} @@ -159,13 +159,13 @@ class SASLOAuthBearer(BaseSecurity): This class defines basic security configuration for SASL/OAUTHBEARER authentication. """ - __slots__ = ("use_ssl", "ssl_context") + __slots__ = ("ssl_context", "use_ssl") - def get_requirement(self) -> List["AnyDict"]: + def get_requirement(self) -> list["AnyDict"]: """Get the security requirements for SASL/OAUTHBEARER authentication.""" return [{"oauthbearer": []}] - def get_schema(self) -> Dict[str, Dict[str, str]]: + def get_schema(self) -> dict[str, dict[str, str]]: """Get the security schema for SASL/OAUTHBEARER authentication.""" return {"oauthbearer": {"type": "oauthBearer"}} @@ -176,12 +176,12 @@ class SASLGSSAPI(BaseSecurity): This class defines security configuration for SASL/GSSAPI authentication. """ - __slots__ = ("use_ssl", "ssl_context") + __slots__ = ("ssl_context", "use_ssl") - def get_requirement(self) -> List["AnyDict"]: + def get_requirement(self) -> list["AnyDict"]: """Get the security requirements for SASL/GSSAPI authentication.""" return [{"gssapi": []}] - def get_schema(self) -> Dict[str, Dict[str, str]]: + def get_schema(self) -> dict[str, dict[str, str]]: """Get the security schema for SASL/GSSAPI authentication.""" return {"gssapi": {"type": "gssapi"}} diff --git a/faststream/specification/__init__.py b/faststream/specification/__init__.py index 6eac804761..502bf43de6 100644 --- a/faststream/specification/__init__.py +++ b/faststream/specification/__init__.py @@ -3,8 +3,8 @@ __all__ = ( "AsyncAPI", - "ExternalDocs", "Contact", + "ExternalDocs", "License", "Tag", ) diff --git a/faststream/specification/asyncapi/factory.py b/faststream/specification/asyncapi/factory.py index d563f8327b..720a7ebea4 100644 --- a/faststream/specification/asyncapi/factory.py +++ b/faststream/specification/asyncapi/factory.py @@ -1,4 +1,5 @@ -from typing import TYPE_CHECKING, Any, Literal, Optional, Sequence, Union +from collections.abc import Sequence +from typing import TYPE_CHECKING, Any, Literal, Optional, Union from faststream.specification.base.specification import Specification @@ -46,7 +47,7 @@ def __new__( # type: ignore[misc] tags=tags, external_docs=external_docs, ) - elif schema_version.startswith("2.6."): + if schema_version.startswith("2.6."): return AsyncAPI2( broker, title=title, @@ -60,8 +61,8 @@ def __new__( # type: ignore[misc] tags=tags, external_docs=external_docs, ) - else: - raise NotImplementedError(f"Unsupported schema version: {schema_version}") + msg = f"Unsupported schema version: {schema_version}" + raise NotImplementedError(msg) def to_json(self) -> str: raise NotImplementedError diff --git a/faststream/specification/asyncapi/message.py b/faststream/specification/asyncapi/message.py index 26d7d8d3eb..d105200f6f 100644 --- a/faststream/specification/asyncapi/message.py +++ b/faststream/specification/asyncapi/message.py @@ -1,5 +1,6 @@ +from collections.abc import Sequence from inspect import isclass -from typing import TYPE_CHECKING, Any, Optional, Sequence, Type, overload +from typing import TYPE_CHECKING, Any, Optional, overload from pydantic import BaseModel, create_model @@ -50,7 +51,9 @@ def get_response_schema( """Get the response schema for a given call.""" return get_model_schema( getattr( - call, "response_model", None + call, + "response_model", + None, ), # NOTE: FastAPI Dependant object compatibility prefix=prefix, ) @@ -66,14 +69,14 @@ def get_model_schema( @overload def get_model_schema( - call: Type[BaseModel], + call: type[BaseModel], prefix: str = "", exclude: Sequence[str] = (), ) -> AnyDict: ... def get_model_schema( - call: Optional[Type[BaseModel]], + call: Optional[type[BaseModel]], prefix: str = "", exclude: Sequence[str] = (), ) -> Optional[AnyDict]: @@ -118,8 +121,7 @@ def get_model_schema( if param_body.get("$ref"): ref_obj: AnyDict = next(iter(defs.values())) return ref_obj - else: - param_body[DEF_KEY] = defs + param_body[DEF_KEY] = defs original_title = param.title if PYDANTIC_V2 else param.field_info.title diff --git a/faststream/specification/asyncapi/site.py b/faststream/specification/asyncapi/site.py index 43b7c95228..65013c3480 100644 --- a/faststream/specification/asyncapi/site.py +++ b/faststream/specification/asyncapi/site.py @@ -1,6 +1,6 @@ from functools import partial from http import server -from typing import TYPE_CHECKING, Any, Dict +from typing import TYPE_CHECKING, Any from urllib.parse import parse_qs, urlparse from faststream._internal._compat import json_dumps @@ -126,7 +126,7 @@ def __init__( self.schema = schema super().__init__(*args, **kwargs) - def get_query_params(self) -> Dict[str, bool]: + def get_query_params(self) -> dict[str, bool]: return { i: _str_to_bool(next(iter(j))) if j else False for i, j in parse_qs(urlparse(self.path).query).items() @@ -158,4 +158,4 @@ def do_GET(self) -> None: # noqa: N802 def _str_to_bool(v: str) -> bool: - return v.lower() in ("1", "t", "true", "y", "yes") + return v.lower() in {"1", "t", "true", "y", "yes"} diff --git a/faststream/specification/asyncapi/utils.py b/faststream/specification/asyncapi/utils.py index 1ffffec138..2e6ffadfe2 100644 --- a/faststream/specification/asyncapi/utils.py +++ b/faststream/specification/asyncapi/utils.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, List, Tuple +from typing import TYPE_CHECKING if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict @@ -9,7 +9,7 @@ def to_camelcase(*names: str) -> str: def resolve_payloads( - payloads: List[Tuple["AnyDict", str]], + payloads: list[tuple["AnyDict", str]], extra: str = "", served_words: int = 1, ) -> "AnyDict": @@ -25,13 +25,13 @@ def resolve_payloads( if len(words) > 1: # not pydantic model case body["title"] = title = ":".join( filter( - lambda x: bool(x), + bool, ( handler_name, extra if extra not in words else "", *words[served_words:], ), - ) + ), ) one_of_payloads[title] = body diff --git a/faststream/specification/asyncapi/v2_6_0/facade.py b/faststream/specification/asyncapi/v2_6_0/facade.py index daa90684b9..80c7cedd38 100644 --- a/faststream/specification/asyncapi/v2_6_0/facade.py +++ b/faststream/specification/asyncapi/v2_6_0/facade.py @@ -1,4 +1,5 @@ -from typing import TYPE_CHECKING, Any, Optional, Sequence, Union +from collections.abc import Sequence +from typing import TYPE_CHECKING, Any, Optional, Union from faststream.specification.base.specification import Specification @@ -54,7 +55,7 @@ def to_yaml(self) -> str: return self.schema.to_yaml() @property - def schema(self) -> Schema: + def schema(self) -> Schema: # type: ignore[override] return get_app_schema( self.broker, title=self.title, diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index bb6db0c65a..78f2c8857f 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -1,4 +1,5 @@ -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Sequence, Union +from collections.abc import Sequence +from typing import TYPE_CHECKING, Any, Optional, Union from faststream._internal._compat import DEF_KEY from faststream._internal.basic_types import AnyDict, AnyHttpUrl @@ -28,8 +29,6 @@ from faststream.specification.schema.license import License, LicenseDict from faststream.specification.schema.tag import ( Tag as SpecsTag, - ) - from faststream.specification.schema.tag import ( TagDict as SpecsTagDict, ) @@ -54,8 +53,8 @@ def get_app_schema( servers = get_broker_server(broker) channels = get_broker_channels(broker) - messages: Dict[str, Message] = {} - payloads: Dict[str, AnyDict] = {} + messages: dict[str, Message] = {} + payloads: dict[str, AnyDict] = {} for channel in channels.values(): channel.servers = list(servers.keys()) @@ -63,7 +62,7 @@ def get_app_schema( for channel_name, ch in channels.items(): resolve_channel_messages(ch, channel_name, payloads, messages) - schema = Schema( + return Schema( info=Info( title=title, version=app_version, @@ -87,14 +86,13 @@ def get_app_schema( else broker.security.get_schema(), ), ) - return schema def resolve_channel_messages( channel: Channel, channel_name: str, - payloads: Dict[str, AnyDict], - messages: Dict[str, Message], + payloads: dict[str, AnyDict], + messages: dict[str, Message], ) -> None: if channel.subscribe is not None: assert isinstance(channel.subscribe.message, Message) @@ -119,11 +117,11 @@ def resolve_channel_messages( def get_broker_server( broker: "BrokerUsecase[MsgType, ConnectionType]", -) -> Dict[str, Server]: +) -> dict[str, Server]: """Get the broker server for an application.""" servers = {} - tags: Optional[List[Union[Tag, AnyDict]]] = None + tags: Optional[list[Union[Tag, AnyDict]]] = None if broker.tags: tags = [tag_from_spec(tag) for tag in broker.tags] @@ -131,7 +129,7 @@ def get_broker_server( "protocol": broker.protocol, "protocolVersion": broker.protocol_version, "description": broker.description, - "tags": tags if tags else None, + "tags": tags or None, # TODO # "variables": "", # "bindings": "", @@ -154,20 +152,20 @@ def get_broker_server( def get_broker_channels( broker: "BrokerUsecase[MsgType, ConnectionType]", -) -> Dict[str, Channel]: +) -> dict[str, Channel]: """Get the broker channels for an application.""" channels = {} for h in broker._subscribers: schema = h.schema() channels.update( - {key: channel_from_spec(channel) for key, channel in schema.items()} + {key: channel_from_spec(channel) for key, channel in schema.items()}, ) for p in broker._publishers: schema = p.schema() channels.update( - {key: channel_from_spec(channel) for key, channel in schema.items()} + {key: channel_from_spec(channel) for key, channel in schema.items()}, ) return channels @@ -183,7 +181,7 @@ def _resolve_msg_payloads( Payloads and messages are editable dicts to store schemas for reference in AsyncAPI. """ - one_of_list: List[Reference] = [] + one_of_list: list[Reference] = [] m.payload = move_pydantic_refs(m.payload, DEF_KEY) if DEF_KEY in m.payload: @@ -192,11 +190,13 @@ def _resolve_msg_payloads( one_of = m.payload.get("oneOf") if isinstance(one_of, dict): for p_title, p in one_of.items(): - p_title = clear_key(p_title) + formatted_payload_title = clear_key(p_title) payloads.update(p.pop(DEF_KEY, {})) - if p_title not in payloads: - payloads[p_title] = p - one_of_list.append(Reference(**{"$ref": f"#/components/schemas/{p_title}"})) + if formatted_payload_title not in payloads: + payloads[formatted_payload_title] = p + one_of_list.append( + Reference(**{"$ref": f"#/components/schemas/{formatted_payload_title}"}) + ) elif one_of is not None: # Descriminator case @@ -230,7 +230,7 @@ def move_pydantic_refs( key: str, ) -> Any: """Remove pydantic references and replacem them by real schemas.""" - if not isinstance(original, Dict): + if not isinstance(original, dict): return original data = original.copy() @@ -245,7 +245,7 @@ def move_pydantic_refs( elif isinstance(item, dict): data[k] = move_pydantic_refs(data[k], key) - elif isinstance(item, List): + elif isinstance(item, list): for i in range(len(data[k])): data[k][i] = move_pydantic_refs(item[i], key) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/__init__.py index bbcee74f86..1e29c5b8cd 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/__init__.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/__init__.py @@ -1,46 +1,61 @@ -from .channels import Channel -from .channels import from_spec as channel_from_spec +from .channels import ( + Channel, + from_spec as channel_from_spec, +) from .components import Components -from .contact import Contact -from .contact import from_spec as contact_from_spec -from .docs import ExternalDocs -from .docs import from_spec as docs_from_spec +from .contact import ( + Contact, + from_spec as contact_from_spec, +) +from .docs import ( + ExternalDocs, + from_spec as docs_from_spec, +) from .info import Info -from .license import License -from .license import from_spec as license_from_spec -from .message import CorrelationId, Message -from .message import from_spec as message_from_spec -from .operations import Operation -from .operations import from_spec as operation_from_spec +from .license import ( + License, + from_spec as license_from_spec, +) +from .message import ( + CorrelationId, + Message, + from_spec as message_from_spec, +) +from .operations import ( + Operation, + from_spec as operation_from_spec, +) from .schema import Schema from .servers import Server, ServerVariable -from .tag import Tag -from .tag import from_spec as tag_from_spec +from .tag import ( + Tag, + from_spec as tag_from_spec, +) from .utils import Parameter, Reference __all__ = ( - "ExternalDocs", - "docs_from_spec", - "Tag", - "tag_from_spec", "Channel", - "channel_from_spec", - "License", - "license_from_spec", + "Channel", + "Components", "Contact", - "contact_from_spec", "CorrelationId", + "ExternalDocs", + "Info", + "License", "Message", - "message_from_spec", "Operation", - "operation_from_spec", - "Channel", - "channel_from_spec", - "Components", - "Info", + "Parameter", + "Reference", "Schema", "Server", "ServerVariable", - "Reference", - "Parameter", + "Tag", + "channel_from_spec", + "channel_from_spec", + "contact_from_spec", + "docs_from_spec", + "license_from_spec", + "message_from_spec", + "operation_from_spec", + "tag_from_spec", ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/__init__.py index 29930b541e..a0e9cb8389 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/__init__.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/__init__.py @@ -7,7 +7,7 @@ __all__ = ( "ChannelBinding", - "channel_binding_from_spec", "OperationBinding", + "channel_binding_from_spec", "operation_binding_from_spec", ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/__init__.py index 31217c37d7..7ead3ce532 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/__init__.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/__init__.py @@ -1,19 +1,15 @@ from .channel import ( ChannelBinding, -) -from .channel import ( from_spec as channel_binding_from_spec, ) from .operation import ( OperationBinding, -) -from .operation import ( from_spec as operation_binding_from_spec, ) __all__ = ( "ChannelBinding", - "channel_binding_from_spec", "OperationBinding", + "channel_binding_from_spec", "operation_binding_from_spec", ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py index caf5140a78..1317967a1d 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py @@ -102,7 +102,7 @@ def from_spec(cls, binding: spec.bindings.amqp.ChannelBinding) -> Self: "exchange": Exchange.from_spec(binding.exchange) if binding.exchange is not None else None, - } + }, ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/__init__.py index 31217c37d7..7ead3ce532 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/__init__.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/__init__.py @@ -1,19 +1,15 @@ from .channel import ( ChannelBinding, -) -from .channel import ( from_spec as channel_binding_from_spec, ) from .operation import ( OperationBinding, -) -from .operation import ( from_spec as operation_binding_from_spec, ) __all__ = ( "ChannelBinding", - "channel_binding_from_spec", "OperationBinding", + "channel_binding_from_spec", "operation_binding_from_spec", ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/__init__.py index 31217c37d7..7ead3ce532 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/__init__.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/__init__.py @@ -1,19 +1,15 @@ from .channel import ( ChannelBinding, -) -from .channel import ( from_spec as channel_binding_from_spec, ) from .operation import ( OperationBinding, -) -from .operation import ( from_spec as operation_binding_from_spec, ) __all__ = ( "ChannelBinding", - "channel_binding_from_spec", "OperationBinding", + "channel_binding_from_spec", "operation_binding_from_spec", ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel.py index e19da52a5e..258e08ea3a 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel.py @@ -7,17 +7,11 @@ from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( amqp as amqp_bindings, -) -from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( kafka as kafka_bindings, -) -from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( nats as nats_bindings, -) -from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( redis as redis_bindings, + sqs as sqs_bindings, ) -from faststream.specification.asyncapi.v2_6_0.schema.bindings import sqs as sqs_bindings class ChannelBinding(BaseModel): diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation.py index 46864ab289..61d614dd4d 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation.py @@ -7,17 +7,11 @@ from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( amqp as amqp_bindings, -) -from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( kafka as kafka_bindings, -) -from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( nats as nats_bindings, -) -from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( redis as redis_bindings, + sqs as sqs_bindings, ) -from faststream.specification.asyncapi.v2_6_0.schema.bindings import sqs as sqs_bindings class OperationBinding(BaseModel): diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/__init__.py index 31217c37d7..7ead3ce532 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/__init__.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/__init__.py @@ -1,19 +1,15 @@ from .channel import ( ChannelBinding, -) -from .channel import ( from_spec as channel_binding_from_spec, ) from .operation import ( OperationBinding, -) -from .operation import ( from_spec as operation_binding_from_spec, ) __all__ = ( "ChannelBinding", - "channel_binding_from_spec", "OperationBinding", + "channel_binding_from_spec", "operation_binding_from_spec", ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/__init__.py index 31217c37d7..7ead3ce532 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/__init__.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/__init__.py @@ -1,19 +1,15 @@ from .channel import ( ChannelBinding, -) -from .channel import ( from_spec as channel_binding_from_spec, ) from .operation import ( OperationBinding, -) -from .operation import ( from_spec as operation_binding_from_spec, ) __all__ = ( "ChannelBinding", - "channel_binding_from_spec", "OperationBinding", + "channel_binding_from_spec", "operation_binding_from_spec", ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/__init__.py index 31217c37d7..7ead3ce532 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/__init__.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/__init__.py @@ -1,19 +1,15 @@ from .channel import ( ChannelBinding, -) -from .channel import ( from_spec as channel_binding_from_spec, ) from .operation import ( OperationBinding, -) -from .operation import ( from_spec as operation_binding_from_spec, ) __all__ = ( "ChannelBinding", - "channel_binding_from_spec", "OperationBinding", + "channel_binding_from_spec", "operation_binding_from_spec", ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/channels.py b/faststream/specification/asyncapi/v2_6_0/schema/channels.py index 72af50eb97..99ac5585bc 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/channels.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/channels.py @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import Optional from pydantic import BaseModel from typing_extensions import Self @@ -9,8 +9,8 @@ ChannelBinding, channel_binding_from_spec, ) -from faststream.specification.asyncapi.v2_6_0.schema.operations import Operation from faststream.specification.asyncapi.v2_6_0.schema.operations import ( + Operation, from_spec as operation_from_spec, ) @@ -32,7 +32,7 @@ class Channel(BaseModel): """ description: Optional[str] = None - servers: Optional[List[str]] = None + servers: Optional[list[str]] = None bindings: Optional[ChannelBinding] = None subscribe: Optional[Operation] = None publish: Optional[Operation] = None diff --git a/faststream/specification/asyncapi/v2_6_0/schema/components.py b/faststream/specification/asyncapi/v2_6_0/schema/components.py index 884c5b86ba..764d639a24 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/components.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/components.py @@ -1,5 +1,4 @@ from typing import ( - Dict, Optional, ) @@ -40,9 +39,9 @@ class Components(BaseModel): """ - messages: Optional[Dict[str, Message]] = None - schemas: Optional[Dict[str, AnyDict]] = None - securitySchemes: Optional[Dict[str, AnyDict]] = None + messages: Optional[dict[str, Message]] = None + schemas: Optional[dict[str, AnyDict]] = None + securitySchemes: Optional[dict[str, AnyDict]] = None if PYDANTIC_V2: model_config = {"extra": "allow"} diff --git a/faststream/specification/asyncapi/v2_6_0/schema/contact.py b/faststream/specification/asyncapi/v2_6_0/schema/contact.py index 8a3b23c417..809b5190c4 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/contact.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/contact.py @@ -1,9 +1,5 @@ from typing import ( - Any, - Callable, - Iterable, Optional, - Type, Union, overload, ) @@ -11,85 +7,10 @@ from pydantic import AnyHttpUrl, BaseModel from typing_extensions import Self -from faststream._internal._compat import ( - PYDANTIC_V2, - CoreSchema, - GetJsonSchemaHandler, - JsonSchemaValue, - with_info_plain_validator_function, -) +from faststream._internal._compat import PYDANTIC_V2, EmailStr from faststream._internal.basic_types import AnyDict -from faststream._internal.log import logger from faststream.specification import schema as spec -try: - import email_validator - - if email_validator is None: - raise ImportError - from pydantic import EmailStr - -except ImportError: # pragma: no cover - # NOTE: EmailStr mock was copied from the FastAPI - # https://github.com/tiangolo/fastapi/blob/master/fastapi/openapi/models.py#24 - class EmailStr(str): # type: ignore - """EmailStr is a string that should be an email. - - Note: EmailStr mock was copied from the FastAPI: - https://github.com/tiangolo/fastapi/blob/master/fastapi/openapi/models.py#24 - - """ - - @classmethod - def __get_validators__(cls) -> Iterable[Callable[..., Any]]: - """Returns the validators for the EmailStr class.""" - yield cls.validate - - @classmethod - def validate(cls, v: Any) -> str: - """Validates the EmailStr class.""" - logger.warning( - "email-validator bot installed, email fields will be treated as str.\n" - "To install, run: pip install email-validator" - ) - return str(v) - - @classmethod - def _validate(cls, __input_value: Any, _: Any) -> str: - logger.warning( - "email-validator bot installed, email fields will be treated as str.\n" - "To install, run: pip install email-validator" - ) - return str(__input_value) - - @classmethod - def __get_pydantic_json_schema__( - cls, - core_schema: CoreSchema, - handler: GetJsonSchemaHandler, - ) -> JsonSchemaValue: - """Returns the JSON schema for the EmailStr class. - - Args: - core_schema : the core schema - handler : the handler - """ - return {"type": "string", "format": "email"} - - @classmethod - def __get_pydantic_core_schema__( - cls, - source: Type[Any], - handler: Callable[[Any], CoreSchema], - ) -> JsonSchemaValue: - """Returns the core schema for the EmailStr class. - - Args: - source : the source - handler : the handler - """ - return with_info_plain_validator_function(cls._validate) - class Contact(BaseModel): """A class to represent a contact. diff --git a/faststream/specification/asyncapi/v2_6_0/schema/message.py b/faststream/specification/asyncapi/v2_6_0/schema/message.py index 576773bd28..d9cde0e403 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/message.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/message.py @@ -1,4 +1,4 @@ -from typing import List, Optional, Union +from typing import Optional, Union import typing_extensions from pydantic import BaseModel @@ -6,8 +6,8 @@ from faststream._internal._compat import PYDANTIC_V2 from faststream._internal.basic_types import AnyDict from faststream.specification import schema as spec -from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag from faststream.specification.asyncapi.v2_6_0.schema.tag import ( + Tag, from_spec as tag_from_spec, ) @@ -75,7 +75,7 @@ class Message(BaseModel): # examples # traits - tags: Optional[List[Union[Tag, AnyDict]]] = None + tags: Optional[list[Union[Tag, AnyDict]]] = None if PYDANTIC_V2: model_config = {"extra": "allow"} diff --git a/faststream/specification/asyncapi/v2_6_0/schema/operations.py b/faststream/specification/asyncapi/v2_6_0/schema/operations.py index c6ba7e93cf..9d6c6d61fa 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/operations.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/operations.py @@ -1,4 +1,4 @@ -from typing import Dict, List, Optional, Union +from typing import Optional, Union from pydantic import BaseModel from typing_extensions import Self @@ -10,12 +10,12 @@ from faststream.specification.asyncapi.v2_6_0.schema.bindings.main import ( operation_binding_from_spec, ) -from faststream.specification.asyncapi.v2_6_0.schema.message import Message from faststream.specification.asyncapi.v2_6_0.schema.message import ( + Message, from_spec as message_from_spec, ) -from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag from faststream.specification.asyncapi.v2_6_0.schema.tag import ( + Tag, from_spec as tag_from_spec, ) from faststream.specification.asyncapi.v2_6_0.schema.utils import ( @@ -45,12 +45,12 @@ class Operation(BaseModel): message: Union[Message, Reference] - security: Optional[Dict[str, List[str]]] = None + security: Optional[dict[str, list[str]]] = None # TODO # traits - tags: Optional[List[Union[Tag, AnyDict]]] = None + tags: Optional[list[Union[Tag, AnyDict]]] = None if PYDANTIC_V2: model_config = {"extra": "allow"} diff --git a/faststream/specification/asyncapi/v2_6_0/schema/schema.py b/faststream/specification/asyncapi/v2_6_0/schema/schema.py index 17d9851e73..9c19130cc2 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/schema.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/schema.py @@ -1,4 +1,4 @@ -from typing import Dict, List, Literal, Optional, Union +from typing import Literal, Optional, Union from faststream._internal.basic_types import AnyDict from faststream.specification.asyncapi.v2_6_0.schema.channels import Channel @@ -30,8 +30,8 @@ class Schema(BaseSchema): asyncapi: Union[Literal["2.6.0"], str] = "2.6.0" id: Optional[str] = None defaultContentType: Optional[str] = None - servers: Optional[Dict[str, Server]] = None - channels: Dict[str, Channel] + servers: Optional[dict[str, Server]] = None + channels: dict[str, Channel] components: Optional[Components] = None - tags: Optional[List[Union[Tag, AnyDict]]] = None + tags: Optional[list[Union[Tag, AnyDict]]] = None externalDocs: Optional[Union[ExternalDocs, AnyDict]] = None diff --git a/faststream/specification/asyncapi/v2_6_0/schema/servers.py b/faststream/specification/asyncapi/v2_6_0/schema/servers.py index 9220c893b7..a50be2669e 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/servers.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/servers.py @@ -1,4 +1,4 @@ -from typing import Dict, List, Optional, Union +from typing import Optional, Union from pydantic import BaseModel @@ -7,7 +7,7 @@ from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag from faststream.specification.asyncapi.v2_6_0.schema.utils import Reference -SecurityRequirement = List[Dict[str, List[str]]] +SecurityRequirement = list[dict[str, list[str]]] class ServerVariable(BaseModel): @@ -21,10 +21,10 @@ class ServerVariable(BaseModel): """ - enum: Optional[List[str]] = None + enum: Optional[list[str]] = None default: Optional[str] = None description: Optional[str] = None - examples: Optional[List[str]] = None + examples: Optional[list[str]] = None if PYDANTIC_V2: model_config = {"extra": "allow"} @@ -61,9 +61,9 @@ class Server(BaseModel): protocol: str description: Optional[str] = None protocolVersion: Optional[str] = None - tags: Optional[List[Union[Tag, AnyDict]]] = None + tags: Optional[list[Union[Tag, AnyDict]]] = None security: Optional[SecurityRequirement] = None - variables: Optional[Dict[str, Union[ServerVariable, Reference]]] = None + variables: Optional[dict[str, Union[ServerVariable, Reference]]] = None if PYDANTIC_V2: model_config = {"extra": "allow"} diff --git a/faststream/specification/asyncapi/v2_6_0/schema/tag.py b/faststream/specification/asyncapi/v2_6_0/schema/tag.py index 1e1b0d4696..182c4effd9 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/tag.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/tag.py @@ -8,8 +8,6 @@ from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.schema.docs import ( ExternalDocs, -) -from faststream.specification.asyncapi.v2_6_0.schema.docs import ( from_spec as docs_from_spec, ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/utils.py b/faststream/specification/asyncapi/v2_6_0/schema/utils.py index 250022631d..d145abe37d 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/utils.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/utils.py @@ -16,4 +16,3 @@ class Parameter(BaseModel): """A class to represent a parameter.""" # TODO - ... diff --git a/faststream/specification/asyncapi/v3_0_0/facade.py b/faststream/specification/asyncapi/v3_0_0/facade.py index eda740b74b..26e668bd8f 100644 --- a/faststream/specification/asyncapi/v3_0_0/facade.py +++ b/faststream/specification/asyncapi/v3_0_0/facade.py @@ -1,4 +1,5 @@ -from typing import TYPE_CHECKING, Any, Optional, Sequence, Union +from collections.abc import Sequence +from typing import TYPE_CHECKING, Any, Optional, Union from faststream.specification.base.specification import Specification @@ -54,7 +55,7 @@ def to_yaml(self) -> str: return self.schema.to_yaml() @property - def schema(self) -> Schema: + def schema(self) -> Schema: # type: ignore[override] return get_app_schema( self.broker, title=self.title, diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index 122c74c6ec..72b5e7966e 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -1,4 +1,5 @@ -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Sequence, Union +from collections.abc import Sequence +from typing import TYPE_CHECKING, Any, Optional, Union from urllib.parse import urlparse from faststream._internal._compat import DEF_KEY @@ -37,8 +38,6 @@ from faststream.specification.schema.license import License, LicenseDict from faststream.specification.schema.tag import ( Tag as SpecsTag, - ) - from faststream.specification.schema.tag import ( TagDict as SpecsTagDict, ) @@ -64,8 +63,8 @@ def get_app_schema( channels = get_broker_channels(broker) operations = get_broker_operations(broker) - messages: Dict[str, Message] = {} - payloads: Dict[str, AnyDict] = {} + messages: dict[str, Message] = {} + payloads: dict[str, AnyDict] = {} for channel in channels.values(): channel.servers = [ @@ -73,17 +72,21 @@ def get_app_schema( ] for channel_name, channel in channels.items(): - msgs: Dict[str, Union[Message, Reference]] = {} + msgs: dict[str, Union[Message, Reference]] = {} for message_name, message in channel.messages.items(): assert isinstance(message, Message) msgs[message_name] = _resolve_msg_payloads( - message_name, message, channel_name, payloads, messages + message_name, + message, + channel_name, + payloads, + messages, ) channel.messages = msgs - schema = Schema( + return Schema( info=Info( title=title, version=app_version, @@ -108,16 +111,15 @@ def get_app_schema( else broker.security.get_schema(), ), ) - return schema def get_broker_server( broker: "BrokerUsecase[MsgType, ConnectionType]", -) -> Dict[str, Server]: +) -> dict[str, Server]: """Get the broker server for an application.""" servers = {} - tags: Optional[List[Union[Tag, AnyDict]]] = None + tags: Optional[list[Union[Tag, AnyDict]]] = None if broker.tags: tags = [tag_from_spec(tag) for tag in broker.tags] @@ -137,10 +139,9 @@ def get_broker_server( urls = broker.url if isinstance(broker.url, list) else [broker.url] for i, broker_url in enumerate(urls, 1): - if "://" not in broker_url: - broker_url = "//" + broker_url + server_url = broker_url if "://" in broker_url else f"//{broker_url}" - parsed_url = urlparse(broker_url) + parsed_url = urlparse(server_url) server_name = "development" if len(urls) == 1 else f"Server{i}" servers[server_name] = Server( host=parsed_url.netloc, @@ -153,26 +154,30 @@ def get_broker_server( def get_broker_operations( broker: "BrokerUsecase[MsgType, ConnectionType]", -) -> Dict[str, Operation]: +) -> dict[str, Operation]: """Get the broker operations for an application.""" operations = {} for h in broker._subscribers: - for channel_name, specs_channel in h.schema().items(): - channel_name = clear_key(channel_name) + for channel, specs_channel in h.schema().items(): + channel_name = clear_key(channel) if specs_channel.subscribe is not None: operations[f"{channel_name}Subscribe"] = operation_from_spec( - specs_channel.subscribe, Action.RECEIVE, channel_name + specs_channel.subscribe, + Action.RECEIVE, + channel_name, ) for p in broker._publishers: - for channel_name, specs_channel in p.schema().items(): - channel_name = clear_key(channel_name) + for channel, specs_channel in p.schema().items(): + channel_name = clear_key(channel) if specs_channel.publish is not None: operations[f"{channel_name}"] = operation_from_spec( - specs_channel.publish, Action.SEND, channel_name + specs_channel.publish, + Action.SEND, + channel_name, ) return operations @@ -180,7 +185,7 @@ def get_broker_operations( def get_broker_channels( broker: "BrokerUsecase[MsgType, ConnectionType]", -) -> Dict[str, Channel]: +) -> dict[str, Channel]: """Get the broker channels for an application.""" channels = {} @@ -194,6 +199,7 @@ def get_broker_channels( *left, right = message.title.split(":") message.title = ":".join(left) + f":Subscribe{right}" + # TODO: why we are format just a key? channels_schema_v3_0[clear_key(channel_name)] = channel_from_spec( specs_channel, message, @@ -239,7 +245,7 @@ def _resolve_msg_payloads( one_of = m.payload.get("oneOf", None) if isinstance(one_of, dict): one_of_list = [] - processed_payloads: Dict[str, AnyDict] = {} + processed_payloads: dict[str, AnyDict] = {} for name, payload in one_of.items(): processed_payloads[clear_key(name)] = payload one_of_list.append(Reference(**{"$ref": f"#/components/schemas/{name}"})) @@ -249,17 +255,16 @@ def _resolve_msg_payloads( assert m.title messages[clear_key(m.title)] = m return Reference( - **{"$ref": f"#/components/messages/{channel_name}:{message_name}"} + **{"$ref": f"#/components/messages/{channel_name}:{message_name}"}, ) - else: - 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) - payloads[payload_name] = m.payload - m.payload = {"$ref": f"#/components/schemas/{payload_name}"} - assert m.title - messages[clear_key(m.title)] = m - return Reference( - **{"$ref": f"#/components/messages/{channel_name}:{message_name}"} - ) + 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) + payloads[payload_name] = m.payload + m.payload = {"$ref": f"#/components/schemas/{payload_name}"} + assert m.title + messages[clear_key(m.title)] = m + return Reference( + **{"$ref": f"#/components/messages/{channel_name}:{message_name}"}, + ) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/__init__.py b/faststream/specification/asyncapi/v3_0_0/schema/__init__.py index e577810ae7..ef2cfe21b7 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/__init__.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/__init__.py @@ -1,19 +1,23 @@ -from .channels import Channel -from .channels import from_spec as channel_from_spec +from .channels import ( + Channel, + from_spec as channel_from_spec, +) from .components import Components from .info import Info -from .operations import Operation -from .operations import from_spec as operation_from_spec +from .operations import ( + Operation, + from_spec as operation_from_spec, +) from .schema import Schema from .servers import Server __all__ = ( "Channel", - "channel_from_spec", - "Operation", - "operation_from_spec", "Components", + "Info", + "Operation", "Schema", "Server", - "Info", + "channel_from_spec", + "operation_from_spec", ) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/__init__.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/__init__.py index c825556112..d477f704cd 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/bindings/__init__.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/__init__.py @@ -5,7 +5,7 @@ ) __all__ = ( - "channel_binding_from_spec", "OperationBinding", + "channel_binding_from_spec", "operation_binding_from_spec", ) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/__init__.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/__init__.py index f55fd4c5d7..96c7406698 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/__init__.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/__init__.py @@ -1,13 +1,11 @@ from .channel import from_spec as channel_binding_from_spec from .operation import ( OperationBinding, -) -from .operation import ( from_spec as operation_binding_from_spec, ) __all__ = ( - "channel_binding_from_spec", "OperationBinding", + "channel_binding_from_spec", "operation_binding_from_spec", ) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel.py index 2e31575e69..a31498ee5f 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel.py @@ -17,5 +17,5 @@ def from_spec(binding: spec.bindings.amqp.ChannelBinding) -> ChannelBinding: "exchange": Exchange.from_spec(binding.exchange) if binding.exchange is not None else None, - } + }, ) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation.py index 5b46f630a0..1357dd325f 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation.py @@ -3,7 +3,7 @@ References: https://github.com/asyncapi/bindings/tree/master/amqp """ -from typing import List, Optional +from typing import Optional from pydantic import BaseModel, PositiveInt from typing_extensions import Self @@ -21,7 +21,7 @@ class OperationBinding(BaseModel): bindingVersion : string representing the binding version """ - cc: Optional[List[str]] = None + cc: Optional[list[str]] = None ack: bool = True replyTo: Optional[str] = None deliveryMode: Optional[int] = None diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/__init__.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/__init__.py index f55fd4c5d7..96c7406698 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/__init__.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/__init__.py @@ -1,13 +1,11 @@ from .channel import from_spec as channel_binding_from_spec from .operation import ( OperationBinding, -) -from .operation import ( from_spec as operation_binding_from_spec, ) __all__ = ( - "channel_binding_from_spec", "OperationBinding", + "channel_binding_from_spec", "operation_binding_from_spec", ) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation.py index d51b97436b..6d0a70069e 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation.py @@ -7,14 +7,10 @@ from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( kafka as kafka_bindings, -) -from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( nats as nats_bindings, -) -from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( redis as redis_bindings, + sqs as sqs_bindings, ) -from faststream.specification.asyncapi.v2_6_0.schema.bindings import sqs as sqs_bindings from faststream.specification.asyncapi.v3_0_0.schema.bindings import ( amqp as amqp_bindings, ) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/channels.py b/faststream/specification/asyncapi/v3_0_0/schema/channels.py index b7f4e5cf9a..3a5ccd40bb 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/channels.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/channels.py @@ -1,4 +1,4 @@ -from typing import Dict, List, Optional, Union +from typing import Optional, Union from pydantic import BaseModel from typing_extensions import Self @@ -6,8 +6,8 @@ from faststream._internal._compat import PYDANTIC_V2 from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.schema.bindings import ChannelBinding -from faststream.specification.asyncapi.v2_6_0.schema.message import Message from faststream.specification.asyncapi.v2_6_0.schema.message import ( + Message, from_spec as message_from_spec, ) from faststream.specification.asyncapi.v2_6_0.schema.utils import Reference @@ -34,8 +34,8 @@ class Channel(BaseModel): address: str description: Optional[str] = None - servers: Optional[List[Dict[str, str]]] = None - messages: Dict[str, Union[Message, Reference]] + servers: Optional[list[dict[str, str]]] = None + messages: dict[str, Union[Message, Reference]] bindings: Optional[ChannelBinding] = None # TODO: diff --git a/faststream/specification/asyncapi/v3_0_0/schema/components.py b/faststream/specification/asyncapi/v3_0_0/schema/components.py index 342dddfd4f..04f2957a7c 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/components.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/components.py @@ -1,4 +1,4 @@ -from typing import Dict, Optional +from typing import Optional from pydantic import BaseModel @@ -35,9 +35,9 @@ class Components(BaseModel): """ - messages: Optional[Dict[str, Message]] = None - schemas: Optional[Dict[str, AnyDict]] = None - securitySchemes: Optional[Dict[str, AnyDict]] = None + messages: Optional[dict[str, Message]] = None + schemas: Optional[dict[str, AnyDict]] = None + securitySchemes: Optional[dict[str, AnyDict]] = None # parameters # correlationIds # operationTraits diff --git a/faststream/specification/asyncapi/v3_0_0/schema/info.py b/faststream/specification/asyncapi/v3_0_0/schema/info.py index eaf081230d..6d15c9e4dc 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/info.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/info.py @@ -1,5 +1,4 @@ from typing import ( - List, Optional, Union, ) @@ -32,5 +31,5 @@ class Info(BaseInfo): termsOfService: Optional[AnyHttpUrl] = None contact: Optional[Union[Contact, AnyDict]] = None license: Optional[Union[License, AnyDict]] = None - tags: Optional[List[Union["Tag", "AnyDict"]]] = None + tags: Optional[list[Union["Tag", "AnyDict"]]] = None externalDocs: Optional[Union["ExternalDocs", "AnyDict"]] = None diff --git a/faststream/specification/asyncapi/v3_0_0/schema/operations.py b/faststream/specification/asyncapi/v3_0_0/schema/operations.py index 2937c90afb..ffc647674a 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/operations.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/operations.py @@ -1,5 +1,5 @@ from enum import Enum -from typing import Dict, List, Optional, Union +from typing import Optional, Union from pydantic import BaseModel from typing_extensions import Self @@ -43,15 +43,15 @@ class Operation(BaseModel): bindings: Optional[OperationBinding] = None - messages: List[Reference] + messages: list[Reference] channel: Union[Channel, Reference] - security: Optional[Dict[str, List[str]]] = None + security: Optional[dict[str, list[str]]] = None # TODO # traits - tags: Optional[List[Union[Tag, AnyDict]]] = None + tags: Optional[list[Union[Tag, AnyDict]]] = None if PYDANTIC_V2: model_config = {"extra": "allow"} @@ -63,7 +63,10 @@ class Config: @classmethod def from_spec( - cls, operation: spec.operation.Operation, action: Action, channel_name: str + cls, + operation: spec.operation.Operation, + action: Action, + channel_name: str, ) -> Self: return cls( action=action, @@ -77,9 +80,9 @@ def from_spec( **{ "$ref": f"#/channels/{channel_name}/messages/SubscribeMessage" if action is Action.RECEIVE - else f"#/channels/{channel_name}/messages/Message" + else f"#/channels/{channel_name}/messages/Message", }, - ) + ), ], channel=Reference( **{"$ref": f"#/channels/{channel_name}"}, @@ -89,6 +92,8 @@ def from_spec( def from_spec( - operation: spec.operation.Operation, action: Action, channel_name: str + operation: spec.operation.Operation, + action: Action, + channel_name: str, ) -> Operation: return Operation.from_spec(operation, action, channel_name) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/schema.py b/faststream/specification/asyncapi/v3_0_0/schema/schema.py index a8af859127..ad60b8bfae 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/schema.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/schema.py @@ -1,4 +1,4 @@ -from typing import Dict, Literal, Optional, Union +from typing import Literal, Optional, Union from faststream.specification.asyncapi.v3_0_0.schema.channels import Channel from faststream.specification.asyncapi.v3_0_0.schema.components import Components @@ -26,7 +26,7 @@ class Schema(BaseSchema): asyncapi: Union[Literal["3.0.0"], str] = "3.0.0" id: Optional[str] = None defaultContentType: Optional[str] = None - servers: Optional[Dict[str, Server]] = None - channels: Dict[str, Channel] - operations: Dict[str, Operation] + servers: Optional[dict[str, Server]] = None + channels: dict[str, Channel] + operations: dict[str, Operation] components: Optional[Components] = None diff --git a/faststream/specification/asyncapi/v3_0_0/schema/servers.py b/faststream/specification/asyncapi/v3_0_0/schema/servers.py index 6d49226452..5951d7935b 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/servers.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/servers.py @@ -1,4 +1,4 @@ -from typing import Dict, List, Optional, Union +from typing import Optional, Union from pydantic import BaseModel @@ -7,7 +7,7 @@ from faststream.specification.asyncapi.v2_6_0.schema import ServerVariable, Tag from faststream.specification.asyncapi.v2_6_0.schema.utils import Reference -SecurityRequirement = List[Dict[str, List[str]]] +SecurityRequirement = list[dict[str, list[str]]] class Server(BaseModel): @@ -37,9 +37,9 @@ class Server(BaseModel): protocol: str description: Optional[str] = None protocolVersion: Optional[str] = None - tags: Optional[List[Union[Tag, AnyDict]]] = None + tags: Optional[list[Union[Tag, AnyDict]]] = None security: Optional[SecurityRequirement] = None - variables: Optional[Dict[str, Union[ServerVariable, Reference]]] = None + variables: Optional[dict[str, Union[ServerVariable, Reference]]] = None if PYDANTIC_V2: model_config = {"extra": "allow"} diff --git a/faststream/specification/base/proto.py b/faststream/specification/base/proto.py index 6334008773..09d6e36366 100644 --- a/faststream/specification/base/proto.py +++ b/faststream/specification/base/proto.py @@ -1,5 +1,5 @@ from abc import abstractmethod -from typing import Any, Dict, Optional, Protocol +from typing import Any, Optional, Protocol from faststream.specification.schema.channel import Channel @@ -19,7 +19,7 @@ def name(self) -> str: @abstractmethod def get_name(self) -> str: """Name property fallback.""" - raise NotImplementedError() + raise NotImplementedError @property def description(self) -> Optional[str]: @@ -30,19 +30,18 @@ def get_description(self) -> Optional[str]: """Description property fallback.""" return None - def schema(self) -> Dict[str, Channel]: + def schema(self) -> dict[str, Channel]: """Returns the schema of the API operation as a dictionary of channel names and channel objects.""" if self.include_in_schema: return self.get_schema() - else: - return {} + return {} @abstractmethod - def get_schema(self) -> Dict[str, Channel]: + def get_schema(self) -> dict[str, Channel]: """Generate AsyncAPI schema.""" - raise NotImplementedError() + raise NotImplementedError @abstractmethod def get_payloads(self) -> Any: """Generate AsyncAPI payloads.""" - raise NotImplementedError() + raise NotImplementedError diff --git a/faststream/specification/schema/__init__.py b/faststream/specification/schema/__init__.py index a50f0e2a41..a2ec26fa7a 100644 --- a/faststream/specification/schema/__init__.py +++ b/faststream/specification/schema/__init__.py @@ -16,10 +16,10 @@ from .tag import Tag __all__ = ( + "Contact", "ExternalDocs", "License", "Tag", - "Contact", # module aliases "bindings", "channel", diff --git a/faststream/specification/schema/bindings/kafka.py b/faststream/specification/schema/bindings/kafka.py index ddc4c3c294..142a2a5285 100644 --- a/faststream/specification/schema/bindings/kafka.py +++ b/faststream/specification/schema/bindings/kafka.py @@ -4,7 +4,7 @@ """ from dataclasses import dataclass -from typing import Any, Dict, Optional +from typing import Any, Optional @dataclass @@ -38,7 +38,7 @@ class OperationBinding: bindingVersion : version of the binding (default: "0.4.0") """ - groupId: Optional[Dict[str, Any]] = None - clientId: Optional[Dict[str, Any]] = None - replyTo: Optional[Dict[str, Any]] = None + groupId: Optional[dict[str, Any]] = None + clientId: Optional[dict[str, Any]] = None + replyTo: Optional[dict[str, Any]] = None bindingVersion: str = "0.4.0" diff --git a/faststream/specification/schema/bindings/main.py b/faststream/specification/schema/bindings/main.py index 3fe0e4c62f..20402db1f7 100644 --- a/faststream/specification/schema/bindings/main.py +++ b/faststream/specification/schema/bindings/main.py @@ -1,11 +1,13 @@ from dataclasses import dataclass from typing import Optional -from faststream.specification.schema.bindings import amqp as amqp_bindings -from faststream.specification.schema.bindings import kafka as kafka_bindings -from faststream.specification.schema.bindings import nats as nats_bindings -from faststream.specification.schema.bindings import redis as redis_bindings -from faststream.specification.schema.bindings import sqs as sqs_bindings +from faststream.specification.schema.bindings import ( + amqp as amqp_bindings, + kafka as kafka_bindings, + nats as nats_bindings, + redis as redis_bindings, + sqs as sqs_bindings, +) @dataclass diff --git a/faststream/specification/schema/bindings/nats.py b/faststream/specification/schema/bindings/nats.py index dd615d6a4d..034efada4e 100644 --- a/faststream/specification/schema/bindings/nats.py +++ b/faststream/specification/schema/bindings/nats.py @@ -4,7 +4,7 @@ """ from dataclasses import dataclass -from typing import Any, Dict, Optional +from typing import Any, Optional @dataclass @@ -31,5 +31,5 @@ class OperationBinding: bindingVersion : version of the binding (default is "custom") """ - replyTo: Optional[Dict[str, Any]] = None + replyTo: Optional[dict[str, Any]] = None bindingVersion: str = "custom" diff --git a/faststream/specification/schema/bindings/redis.py b/faststream/specification/schema/bindings/redis.py index cbed7448fe..c1b3e138a0 100644 --- a/faststream/specification/schema/bindings/redis.py +++ b/faststream/specification/schema/bindings/redis.py @@ -4,7 +4,7 @@ """ from dataclasses import dataclass -from typing import Any, Dict, Optional +from typing import Any, Optional @dataclass @@ -33,5 +33,5 @@ class OperationBinding: bindingVersion : version of the binding (default is "custom") """ - replyTo: Optional[Dict[str, Any]] = None + replyTo: Optional[dict[str, Any]] = None bindingVersion: str = "custom" diff --git a/faststream/specification/schema/bindings/sqs.py b/faststream/specification/schema/bindings/sqs.py index cd4b35cc61..b516c4819a 100644 --- a/faststream/specification/schema/bindings/sqs.py +++ b/faststream/specification/schema/bindings/sqs.py @@ -4,7 +4,7 @@ """ from dataclasses import dataclass -from typing import Any, Dict, Optional +from typing import Any, Optional @dataclass @@ -16,7 +16,7 @@ class ChannelBinding: bindingVersion : a string representing the binding version (default: "custom") """ - queue: Dict[str, Any] + queue: dict[str, Any] bindingVersion: str = "custom" @@ -29,5 +29,5 @@ class OperationBinding: bindingVersion : version of the binding, default is "custom" """ - replyTo: Optional[Dict[str, Any]] = None + replyTo: Optional[dict[str, Any]] = None bindingVersion: str = "custom" diff --git a/faststream/specification/schema/channel.py b/faststream/specification/schema/channel.py index 98166e9e06..89db7d7a6f 100644 --- a/faststream/specification/schema/channel.py +++ b/faststream/specification/schema/channel.py @@ -1,5 +1,5 @@ from dataclasses import dataclass -from typing import List, Optional +from typing import Optional from faststream.specification.schema.bindings import ChannelBinding from faststream.specification.schema.operation import Operation @@ -18,7 +18,7 @@ class Channel: """ description: Optional[str] = None - servers: Optional[List[str]] = None + servers: Optional[list[str]] = None bindings: Optional[ChannelBinding] = None subscribe: Optional[Operation] = None publish: Optional[Operation] = None diff --git a/faststream/specification/schema/components.py b/faststream/specification/schema/components.py index 3562fa48b6..39e6011591 100644 --- a/faststream/specification/schema/components.py +++ b/faststream/specification/schema/components.py @@ -1,6 +1,5 @@ from typing import ( Any, - Dict, Optional, ) @@ -27,9 +26,9 @@ class Components(BaseModel): - securitySchemes """ - messages: Optional[Dict[str, Message]] = None - schemas: Optional[Dict[str, Dict[str, Any]]] = None - securitySchemes: Optional[Dict[str, Dict[str, Any]]] = None + messages: Optional[dict[str, Message]] = None + schemas: Optional[dict[str, dict[str, Any]]] = None + securitySchemes: Optional[dict[str, dict[str, Any]]] = None if PYDANTIC_V2: model_config = {"extra": "allow"} diff --git a/faststream/specification/schema/contact.py b/faststream/specification/schema/contact.py index 275062d60e..2de5d06292 100644 --- a/faststream/specification/schema/contact.py +++ b/faststream/specification/schema/contact.py @@ -1,90 +1,11 @@ from typing import ( - Any, - Callable, - Iterable, Optional, - Type, ) from pydantic import AnyHttpUrl, BaseModel from typing_extensions import Required, TypedDict -from faststream._internal._compat import ( - PYDANTIC_V2, - CoreSchema, - GetJsonSchemaHandler, - JsonSchemaValue, - with_info_plain_validator_function, -) -from faststream._internal.log import logger - -try: - import email_validator - - if email_validator is None: - raise ImportError - from pydantic import EmailStr - -except ImportError: # pragma: no cover - # NOTE: EmailStr mock was copied from the FastAPI - # https://github.com/tiangolo/fastapi/blob/master/fastapi/openapi/models.py#24 - class EmailStr(str): # type: ignore - """EmailStr is a string that should be an email. - - Note: EmailStr mock was copied from the FastAPI: - https://github.com/tiangolo/fastapi/blob/master/fastapi/openapi/models.py#24 - - """ - - @classmethod - def __get_validators__(cls) -> Iterable[Callable[..., Any]]: - """Returns the validators for the EmailStr class.""" - yield cls.validate - - @classmethod - def validate(cls, v: Any) -> str: - """Validates the EmailStr class.""" - logger.warning( - "email-validator bot installed, email fields will be treated as str.\n" - "To install, run: pip install email-validator" - ) - return str(v) - - @classmethod - def _validate(cls, __input_value: Any, _: Any) -> str: - logger.warning( - "email-validator bot installed, email fields will be treated as str.\n" - "To install, run: pip install email-validator" - ) - return str(__input_value) - - @classmethod - def __get_pydantic_json_schema__( - cls, - core_schema: CoreSchema, - handler: GetJsonSchemaHandler, - ) -> JsonSchemaValue: - """Returns the JSON schema for the EmailStr class. - - Args: - core_schema : the core schema - handler : the handler - """ - return {"type": "string", "format": "email"} - - @classmethod - def __get_pydantic_core_schema__( - cls, - source: Type[Any], - handler: Callable[[Any], CoreSchema], - ) -> JsonSchemaValue: - """Returns the core schema for the EmailStr class. - - Args: - source : the source - handler : the handler - """ - return with_info_plain_validator_function(cls._validate) +from faststream._internal._compat import PYDANTIC_V2, EmailStr class ContactDict(TypedDict, total=False): diff --git a/faststream/specification/schema/info.py b/faststream/specification/schema/info.py index fb2f0f04e9..67f2341e4f 100644 --- a/faststream/specification/schema/info.py +++ b/faststream/specification/schema/info.py @@ -1,6 +1,5 @@ from typing import ( Any, - Dict, Optional, Union, ) @@ -24,5 +23,5 @@ class Info(BaseModel): """ termsOfService: Optional[AnyHttpUrl] = None - contact: Optional[Union[Contact, ContactDict, Dict[str, Any]]] = None - license: Optional[Union[License, LicenseDict, Dict[str, Any]]] = None + contact: Optional[Union[Contact, ContactDict, dict[str, Any]]] = None + license: Optional[Union[License, LicenseDict, dict[str, Any]]] = None diff --git a/faststream/specification/schema/message.py b/faststream/specification/schema/message.py index 9b5868a388..865ec95553 100644 --- a/faststream/specification/schema/message.py +++ b/faststream/specification/schema/message.py @@ -1,5 +1,5 @@ from dataclasses import dataclass -from typing import Any, Dict, List, Optional, Union +from typing import Any, Optional, Union from faststream.specification.schema.docs import ExternalDocs from faststream.specification.schema.tag import Tag @@ -38,7 +38,7 @@ class Message: externalDocs : external documentation associated with the message """ - payload: Dict[str, Any] + payload: dict[str, Any] title: Optional[str] = None name: Optional[str] = None summary: Optional[str] = None @@ -47,5 +47,5 @@ class Message: correlationId: Optional[CorrelationId] = None contentType: Optional[str] = None - tags: Optional[List[Union[Tag, Dict[str, Any]]]] = None - externalDocs: Optional[Union[ExternalDocs, Dict[str, Any]]] = None + tags: Optional[list[Union[Tag, dict[str, Any]]]] = None + externalDocs: Optional[Union[ExternalDocs, dict[str, Any]]] = None diff --git a/faststream/specification/schema/operation.py b/faststream/specification/schema/operation.py index 23f3343290..e88d3c39e4 100644 --- a/faststream/specification/schema/operation.py +++ b/faststream/specification/schema/operation.py @@ -1,5 +1,5 @@ from dataclasses import dataclass -from typing import Any, Dict, List, Optional, Union +from typing import Any, Optional, Union from faststream.specification.schema.bindings import OperationBinding from faststream.specification.schema.message import Message @@ -28,6 +28,6 @@ class Operation: bindings: Optional[OperationBinding] = None - security: Optional[Dict[str, List[str]]] = None + security: Optional[dict[str, list[str]]] = None - tags: Optional[List[Union[Tag, Dict[str, Any]]]] = None + tags: Optional[list[Union[Tag, dict[str, Any]]]] = None diff --git a/faststream/specification/schema/security.py b/faststream/specification/schema/security.py index 9948a850da..d940cbdc4f 100644 --- a/faststream/specification/schema/security.py +++ b/faststream/specification/schema/security.py @@ -1,4 +1,4 @@ -from typing import Dict, Literal, Optional +from typing import Literal, Optional from pydantic import AnyHttpUrl, BaseModel, Field @@ -12,13 +12,13 @@ class OauthFlowObj(BaseModel): authorizationUrl : Optional[AnyHttpUrl] : The URL for authorization tokenUrl : Optional[AnyHttpUrl] : The URL for token refreshUrl : Optional[AnyHttpUrl] : The URL for refresh - scopes : Dict[str, str] : The scopes for the OAuth flow + scopes : dict[str, str] : The scopes for the OAuth flow """ authorizationUrl: Optional[AnyHttpUrl] = None tokenUrl: Optional[AnyHttpUrl] = None refreshUrl: Optional[AnyHttpUrl] = None - scopes: Dict[str, str] + scopes: dict[str, str] if PYDANTIC_V2: model_config = {"extra": "allow"} diff --git a/faststream/specification/schema/servers.py b/faststream/specification/schema/servers.py index 8bac32b4f6..d296c359a2 100644 --- a/faststream/specification/schema/servers.py +++ b/faststream/specification/schema/servers.py @@ -1,11 +1,11 @@ -from typing import Any, Dict, List, Optional, Union +from typing import Any, Optional, Union from pydantic import BaseModel from faststream._internal._compat import PYDANTIC_V2 from faststream.specification.schema.tag import Tag -SecurityRequirement = List[Dict[str, List[str]]] +SecurityRequirement = list[dict[str, list[str]]] class ServerVariable(BaseModel): @@ -18,10 +18,10 @@ class ServerVariable(BaseModel): examples : list of example values for the server variable (optional) """ - enum: Optional[List[str]] = None + enum: Optional[list[str]] = None default: Optional[str] = None description: Optional[str] = None - examples: Optional[List[str]] = None + examples: Optional[list[str]] = None if PYDANTIC_V2: model_config = {"extra": "allow"} @@ -52,9 +52,9 @@ class Server(BaseModel): protocol: str description: Optional[str] = None protocolVersion: Optional[str] = None - tags: Optional[List[Union[Tag, Dict[str, Any]]]] = None + tags: Optional[list[Union[Tag, dict[str, Any]]]] = None security: Optional[SecurityRequirement] = None - variables: Optional[Dict[str, ServerVariable]] = None + variables: Optional[dict[str, ServerVariable]] = None if PYDANTIC_V2: model_config = {"extra": "allow"} diff --git a/pyproject.toml b/pyproject.toml index a5ba311362..aa321aaa82 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ keywords = [ "message brokers", ] -requires-python = ">=3.8" +requires-python = ">=3.9" classifiers = [ "Development Status :: 5 - Production/Stable", @@ -29,11 +29,11 @@ classifiers = [ "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Operating System :: OS Independent", "Topic :: Software Development :: Libraries :: Application Frameworks", "Topic :: Software Development :: Libraries :: Python Modules", @@ -125,7 +125,6 @@ test-core = [ "pytest==8.3.3", "pytest-asyncio==0.24.0", "dirty-equals==0.8.0", - "typing-extensions>=4.8.0,<4.12.1; python_version < '3.9'", # to fix dirty-equals ] testing = [ @@ -139,8 +138,7 @@ testing = [ dev = [ "faststream[optionals,lint,testing,devdocs]", - "pre-commit==3.5.0; python_version < '3.9'", - "pre-commit==3.8.0; python_version >= '3.9'", + "pre-commit==3.8.0", "detect-secrets==1.5.0", ] @@ -164,7 +162,7 @@ exclude = ["/tests", "/docs"] [tool.mypy] files = ["faststream", "tests/mypy"] strict = true -python_version = "3.8" +python_version = "3.9" ignore_missing_imports = true install_types = true non_interactive = true @@ -182,119 +180,6 @@ disallow_incomplete_defs = true disallow_untyped_decorators = true disallow_any_unimported = false -[tool.ruff] -fix = true -line-length = 88 -target-version = "py38" -include = [ - "faststream/**/*.py", - "faststream/**/*.pyi", - "tests/**/*.py", - "docs/**/*.py", - "pyproject.toml", -] -exclude = ["docs/docs_src"] - -[tool.ruff.lint] -select = [ - "E", # pycodestyle errors https://docs.astral.sh/ruff/rules/#error-e - "W", # pycodestyle warnings https://docs.astral.sh/ruff/rules/#warning-w - "C90", # mccabe https://docs.astral.sh/ruff/rules/#mccabe-c90 - "N", # pep8-naming https://docs.astral.sh/ruff/rules/#pep8-naming-n - "D", # pydocstyle https://docs.astral.sh/ruff/rules/#pydocstyle-d - "I", # isort https://docs.astral.sh/ruff/rules/#isort-i - "F", # pyflakes https://docs.astral.sh/ruff/rules/#pyflakes-f - "ASYNC", # flake8-async https://docs.astral.sh/ruff/rules/#flake8-async-async - "C4", # flake8-comprehensions https://docs.astral.sh/ruff/rules/#flake8-comprehensions-c4 - "B", # flake8-bugbear https://docs.astral.sh/ruff/rules/#flake8-bugbear-b - "Q", # flake8-quotes https://docs.astral.sh/ruff/rules/#flake8-quotes-q - "T20", # flake8-print https://docs.astral.sh/ruff/rules/#flake8-print-t20 - "SIM", # flake8-simplify https://docs.astral.sh/ruff/rules/#flake8-simplify-sim - "PT", # flake8-pytest-style https://docs.astral.sh/ruff/rules/#flake8-pytest-style-pt - "PTH", # flake8-use-pathlib https://docs.astral.sh/ruff/rules/#flake8-use-pathlib-pth - "TCH", # flake8-type-checking https://docs.astral.sh/ruff/rules/#flake8-type-checking-tch - "TID", # flake8-tidy-imports https://docs.astral.sh/ruff/rules/#flake8-tidy-imports-tidb - "RUF", # Ruff-specific rules https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf - "PERF", # Perflint https://docs.astral.sh/ruff/rules/#perflint-perf - "UP", # pyupgrade https://docs.astral.sh/ruff/rules/#pyupgrade-up -] - -ignore = [ - "ASYNC109", # own timeout implementation - - "E501", # line too long, handled by formatter later - "C901", # too complex - - # todo pep8-naming - "N817", # CamelCase `*` imported as acronym `*` - "N815", # Variable `*` in class scope should not be mixedCase - "N803", # Argument name `expandMessageExamples` should be lowercase - - # todo pydocstyle - "D100", # missing docstring in public module - "D101", - "D102", - "D103", - "D104", # missing docstring in public package - "D105", # missing docstring in magic methods - "D106", # missing docstring in public nested class - "D107", # missing docstring in __init__ -] - -[tool.ruff.lint.per-file-ignores] -"tests/**" = [ - "D101", # docstrings - "D102", - "D103", - "PLR2004", # magic-value-comparison - "S101", # use assert -] - -"docs/*.py" = [ - "D101", # docstrings - "D102", - "D103", -] - - -[tool.ruff.lint.isort] -case-sensitive = true - -[tool.ruff.format] -docstring-code-format = true - -[tool.ruff.lint.pydocstyle] -convention = "google" - -[tool.ruff.lint.flake8-bugbear] -extend-immutable-calls = [ - "faststream.Depends", - "faststream.Context", - "faststream.Header", - "faststream.Path", - "faststream.NoCast", - "faststream.params.Depends", - "faststream.params.Context", - "faststream.params.Header", - "faststream.params.Path", - "faststream.params.NoCast", - "faststream._internal.fastapi.context.Context", - "faststream.utils.Header", - "faststream.utils.Path", - "faststream.utils.Depends", - "faststream.utils.Context", - "faststream.utils.context.Depends", - "faststream.utils.context.Context", - "typer.Argument", - "typer.Option", - "pydantic.Field", - "rocketry.args.Arg", - "fastapi.Depends", - "fastapi.Header", - "fastapi.datastructures.Default", - "kafka.partitioner.default.DefaultPartitioner", -] - [tool.pytest.ini_options] minversion = "7.0" addopts = "-q -m 'not slow'" diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 0000000000..b98ef682dd --- /dev/null +++ b/ruff.toml @@ -0,0 +1,148 @@ +# Configuration file example: https://docs.astral.sh/ruff/configuration/ +# All settings: https://docs.astral.sh/ruff/settings/ + +fix = true +preview = true + +line-length = 88 +indent-width = 4 + +target-version = "py39" + +include = [ + "faststream/**/*.py", + "faststream/**/*.pyi", + "tests/**/*.py", + "docs/**/*.py", + "pyproject.toml", +] + +exclude = [ + "docs/docs_src" +] + +[format] +quote-style = "double" +indent-style = "space" +docstring-code-format = false + +[lint] +select = [ + "ALL", +] + +ignore = [ + "A", + "FA", + "TD", + "FIX", + "SLOT", + "ARG", + "EXE", + + "ASYNC109", + "ANN401", + "COM812", + "ISC001", + "TRY301", + "S101", + "SLF001", + "PLR0911", + "PLR0912", + "PLR0913", + "PLR2004", + "PYI036", + "PYI051", + "G004", + + "E501", # line too long, handled by formatter later + "C901", # too complex + + # preview + "CPY", + "PLC0415", + "PLC2701", # FIXME + "PLC2801", + "PLR6301", + "PLW1641", + "RUF029", + + # pep8-naming + "N817", # CamelCase `*` imported as acronym `*` + + # FIXME pydocstyle + "D100", # missing docstring in public module + "D101", + "D102", + "D103", + "D104", # missing docstring in public package + "D105", # missing docstring in magic methods + "D106", # missing docstring in public nested class + "D107", # missing docstring in __init__ + "DOC201", + "DOC202", + "DOC402", + "DOC501", + "DOC502", + + "FBT", # FIXME + "PLW2901", # FIXME + "BLE001", # FIXME + "S110", # FIXME + "PLR0917" # FIXME +] + +[lint.per-file-ignores] +"faststream/specification/**/*.py" = [ + "ERA001", + "N815", # Variable `*` in class scope should not be mixedCase +] + +"**/fastapi/**/*.py" = [ + "N803", # Argument name `expandMessageExamples` should be lowercase +] + +"**/_compat.py" = [ + "PYI063", + "PLW3201", +] + +"tests/**" = [ + "ALL", # FIXME +] + +"docs/*.py" = [ + "ALL", # FIXME +] + +[lint.isort] +case-sensitive = true +combine-as-imports = true +force-wrap-aliases = true + +[lint.pydocstyle] +convention = "google" +ignore-decorators = ["typing.overload"] + +[lint.flake8-bugbear] +extend-immutable-calls = [ + "faststream.Header", + "faststream.Path", + "faststream.Depends", + "faststream.Context", + "faststream.Depends", + "faststream.params.Header", + "faststream.params.Path", + "faststream.params.Depends", + "faststream.params.Context", + "faststream.params.Depends", + "faststream._internal.fastapi.context.Context", + "typer.Argument", + "typer.Option", + "pydantic.Field", + "rocketry.args.Arg", + "fastapi.Depends", + "fastapi.Header", + "fastapi.datastructures.Default", + "kafka.partitioner.default.DefaultPartitioner", +] diff --git a/tests/a_docs/confluent/ack/test_errors.py b/tests/a_docs/confluent/ack/test_errors.py index 08017ba472..98bbe8c4c9 100644 --- a/tests/a_docs/confluent/ack/test_errors.py +++ b/tests/a_docs/confluent/ack/test_errors.py @@ -14,7 +14,9 @@ async def test_ack_exc(): from docs.docs_src.confluent.ack.errors import app, broker, handle with patch.object( - AsyncConfluentConsumer, "commit", spy_decorator(AsyncConfluentConsumer.commit) + AsyncConfluentConsumer, + "commit", + spy_decorator(AsyncConfluentConsumer.commit), ) as m: async with TestKafkaBroker(broker, with_real=True), TestApp(app): await handle.wait_call(20) diff --git a/tests/a_docs/confluent/batch_consuming_pydantic/test_app.py b/tests/a_docs/confluent/batch_consuming_pydantic/test_app.py index 66539c1f06..cf783bad12 100644 --- a/tests/a_docs/confluent/batch_consuming_pydantic/test_app.py +++ b/tests/a_docs/confluent/batch_consuming_pydantic/test_app.py @@ -17,5 +17,5 @@ async def test_me(): topic="test_batch", ) handle_batch.mock.assert_called_with( - [dict(HelloWorld(msg="First Hello")), dict(HelloWorld(msg="Second Hello"))] + [dict(HelloWorld(msg="First Hello")), dict(HelloWorld(msg="Second Hello"))], ) diff --git a/tests/a_docs/confluent/publish_batch/test_app.py b/tests/a_docs/confluent/publish_batch/test_app.py index 9e3b3ecbf3..956686b9d5 100644 --- a/tests/a_docs/confluent/publish_batch/test_app.py +++ b/tests/a_docs/confluent/publish_batch/test_app.py @@ -17,7 +17,7 @@ async def test_batch_publish_decorator(): on_input_data_1.mock.assert_called_once_with(dict(Data(data=2.0))) decrease_and_increase.mock.assert_called_once_with( - [dict(Data(data=1.0)), dict(Data(data=4.0))] + [dict(Data(data=1.0)), dict(Data(data=4.0))], ) @@ -28,5 +28,5 @@ async def test_batch_publish_call(): on_input_data_2.mock.assert_called_once_with(dict(Data(data=2.0))) decrease_and_increase.mock.assert_called_once_with( - [dict(Data(data=1.0)), dict(Data(data=4.0))] + [dict(Data(data=1.0)), dict(Data(data=4.0))], ) diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py index 7c605a3925..1d722b6dd9 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py @@ -10,23 +10,23 @@ def test_basic_customization(): "channels": { "input_data:OnInputData": { "bindings": { - "kafka": {"bindingVersion": "0.4.0", "topic": "input_data"} + "kafka": {"bindingVersion": "0.4.0", "topic": "input_data"}, }, "servers": ["development"], "subscribe": { "message": { - "$ref": "#/components/messages/input_data:OnInputData:Message" - } + "$ref": "#/components/messages/input_data:OnInputData:Message", + }, }, }, "output_data:Publisher": { "bindings": { - "kafka": {"bindingVersion": "0.4.0", "topic": "output_data"} + "kafka": {"bindingVersion": "0.4.0", "topic": "output_data"}, }, "publish": { "message": { - "$ref": "#/components/messages/output_data:Publisher:Message" - } + "$ref": "#/components/messages/output_data:Publisher:Message", + }, }, "servers": ["development"], }, @@ -36,14 +36,14 @@ def test_basic_customization(): "input_data:OnInputData:Message": { "correlationId": {"location": "$message.header#/correlation_id"}, "payload": { - "$ref": "#/components/schemas/OnInputData:Message:Payload" + "$ref": "#/components/schemas/OnInputData:Message:Payload", }, "title": "input_data:OnInputData:Message", }, "output_data:Publisher:Message": { "correlationId": {"location": "$message.header#/correlation_id"}, "payload": { - "$ref": "#/components/schemas/output_data:PublisherPayload" + "$ref": "#/components/schemas/output_data:PublisherPayload", }, "title": "output_data:Publisher:Message", }, @@ -60,6 +60,6 @@ def test_basic_customization(): "protocol": "kafka", "protocolVersion": "auto", "url": "localhost:9092", - } + }, }, } diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_broker.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_broker.py index 08916cb97f..ac0163e235 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_broker.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_broker.py @@ -12,5 +12,5 @@ def test_broker_customization(): "protocol": "kafka", "description": "Kafka broker running locally", "protocolVersion": "auto", - } + }, } diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py index a441441dbe..62dd530896 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py @@ -12,7 +12,7 @@ def test_handler_customization(): "servers": ["development"], "bindings": {"kafka": {"topic": "input_data", "bindingVersion": "0.4.0"}}, "subscribe": { - "message": {"$ref": "#/components/messages/input_data:Consume:Message"} + "message": {"$ref": "#/components/messages/input_data:Consume:Message"}, }, }, "output_data:Produce": { @@ -20,7 +20,9 @@ def test_handler_customization(): "servers": ["development"], "bindings": {"kafka": {"topic": "output_data", "bindingVersion": "0.4.0"}}, "publish": { - "message": {"$ref": "#/components/messages/output_data:Produce:Message"} + "message": { + "$ref": "#/components/messages/output_data:Produce:Message" + }, }, }, } diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_payload.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_payload.py index e9f3cfce18..8f05f393a6 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_payload.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_payload.py @@ -15,10 +15,10 @@ def test_payload_customization(): "minimum": 0, "title": "Data", "type": "number", - } + }, }, "required": ["data"], "title": "DataBasic", "type": "object", - } + }, } diff --git a/tests/a_docs/getting_started/cli/rabbit/test_rabbit_context.py b/tests/a_docs/getting_started/cli/rabbit/test_rabbit_context.py index 71d55dcb34..dde8b99f68 100644 --- a/tests/a_docs/getting_started/cli/rabbit/test_rabbit_context.py +++ b/tests/a_docs/getting_started/cli/rabbit/test_rabbit_context.py @@ -10,7 +10,7 @@ @pytest.mark.asyncio async def test(): with mock_pydantic_settings_env( - {"host": "amqp://guest:guest@localhost:5673/"} # pragma: allowlist secret + {"host": "amqp://guest:guest@localhost:5673/"}, # pragma: allowlist secret ): from docs.docs_src.getting_started.cli.rabbit_context import app, broker diff --git a/tests/a_docs/getting_started/dependencies/test_basic.py b/tests/a_docs/getting_started/dependencies/test_basic.py index 79add9edc5..576f804354 100644 --- a/tests/a_docs/getting_started/dependencies/test_basic.py +++ b/tests/a_docs/getting_started/dependencies/test_basic.py @@ -19,5 +19,5 @@ async def test_basic_kafka(): { "name": "John", "user_id": 1, - } + }, ) diff --git a/tests/a_docs/getting_started/dependencies/test_class.py b/tests/a_docs/getting_started/dependencies/test_class.py index 5bbfd16850..4dd0b8e9dc 100644 --- a/tests/a_docs/getting_started/dependencies/test_class.py +++ b/tests/a_docs/getting_started/dependencies/test_class.py @@ -19,5 +19,5 @@ async def test_basic_kafka(): { "name": "John", "user_id": 1, - } + }, ) diff --git a/tests/a_docs/getting_started/dependencies/test_global.py b/tests/a_docs/getting_started/dependencies/test_global.py index 4d543aabb4..612157675c 100644 --- a/tests/a_docs/getting_started/dependencies/test_global.py +++ b/tests/a_docs/getting_started/dependencies/test_global.py @@ -19,7 +19,7 @@ async def test_global_kafka(): { "name": "John", "user_id": 1, - } + }, ) with pytest.raises(ValueError): # noqa: PT011 diff --git a/tests/a_docs/getting_started/dependencies/test_global_broker.py b/tests/a_docs/getting_started/dependencies/test_global_broker.py index c0b9de9295..5f8cba8c8b 100644 --- a/tests/a_docs/getting_started/dependencies/test_global_broker.py +++ b/tests/a_docs/getting_started/dependencies/test_global_broker.py @@ -19,7 +19,7 @@ async def test_global_broker_kafka(): { "name": "John", "user_id": 1, - } + }, ) with pytest.raises(ValueError): # noqa: PT011 diff --git a/tests/a_docs/getting_started/dependencies/test_sub_dep.py b/tests/a_docs/getting_started/dependencies/test_sub_dep.py index 832b0c853c..ab3dbad862 100644 --- a/tests/a_docs/getting_started/dependencies/test_sub_dep.py +++ b/tests/a_docs/getting_started/dependencies/test_sub_dep.py @@ -19,7 +19,7 @@ async def test_sub_dep_kafka(): { "name": "John", "user_id": 1, - } + }, ) with pytest.raises(AssertionError): diff --git a/tests/a_docs/getting_started/routers/test_delay.py b/tests/a_docs/getting_started/routers/test_delay.py index 031b9cd8c3..fba6584360 100644 --- a/tests/a_docs/getting_started/routers/test_delay.py +++ b/tests/a_docs/getting_started/routers/test_delay.py @@ -21,7 +21,7 @@ async def test_delay_router_kafka(): async with TestKafkaBroker(broker) as br, TestApp(app): next(iter(br._subscribers)).calls[0].handler.mock.assert_called_once_with( - {"name": "John", "user_id": 1} + {"name": "John", "user_id": 1}, ) next(iter(br._publishers)).mock.assert_called_once_with("Hi!") @@ -38,7 +38,7 @@ async def test_delay_router_confluent(): async with TestConfluentKafkaBroker(broker) as br, TestApp(app): next(iter(br._subscribers)).calls[0].handler.mock.assert_called_once_with( - {"name": "John", "user_id": 1} + {"name": "John", "user_id": 1}, ) next(iter(br._publishers)).mock.assert_called_once_with("Hi!") @@ -55,7 +55,7 @@ async def test_delay_router_rabbit(): async with TestRabbitBroker(broker) as br, TestApp(app): next(iter(br._subscribers)).calls[0].handler.mock.assert_called_once_with( - {"name": "John", "user_id": 1} + {"name": "John", "user_id": 1}, ) next(iter(br._publishers)).mock.assert_called_once_with("Hi!") @@ -72,7 +72,7 @@ async def test_delay_router_nats(): async with TestNatsBroker(broker) as br, TestApp(app): next(iter(br._subscribers)).calls[0].handler.mock.assert_called_once_with( - {"name": "John", "user_id": 1} + {"name": "John", "user_id": 1}, ) next(iter(br._publishers)).mock.assert_called_once_with("Hi!") @@ -89,7 +89,7 @@ async def test_delay_router_redis(): async with TestRedisBroker(broker) as br, TestApp(app): next(iter(br._subscribers)).calls[0].handler.mock.assert_called_once_with( - {"name": "John", "user_id": 1} + {"name": "John", "user_id": 1}, ) next(iter(br._publishers)).mock.assert_called_once_with("Hi!") diff --git a/tests/a_docs/getting_started/routers/test_delay_equal.py b/tests/a_docs/getting_started/routers/test_delay_equal.py index d8e08079fd..af40846434 100644 --- a/tests/a_docs/getting_started/routers/test_delay_equal.py +++ b/tests/a_docs/getting_started/routers/test_delay_equal.py @@ -27,7 +27,7 @@ async def test_delay_router_kafka(): async with TestKafkaBroker(broker) as br, TestApp(app): next(iter(br._subscribers)).calls[0].handler.mock.assert_called_once_with( - {"name": "John", "user_id": 1} + {"name": "John", "user_id": 1}, ) next(iter(br._publishers)).mock.assert_called_once_with("Hi!") @@ -50,7 +50,7 @@ async def test_delay_router_confluent(): async with TestConfluentKafkaBroker(broker) as br, TestApp(app): next(iter(br._subscribers)).calls[0].handler.mock.assert_called_once_with( - {"name": "John", "user_id": 1} + {"name": "John", "user_id": 1}, ) next(iter(br._publishers)).mock.assert_called_once_with("Hi!") @@ -73,7 +73,7 @@ async def test_delay_router_rabbit(): async with TestRabbitBroker(broker) as br, TestApp(app): next(iter(br._subscribers)).calls[0].handler.mock.assert_called_once_with( - {"name": "John", "user_id": 1} + {"name": "John", "user_id": 1}, ) next(iter(br._publishers)).mock.assert_called_once_with("Hi!") @@ -96,7 +96,7 @@ async def test_delay_router_nats(): async with TestNatsBroker(broker) as br, TestApp(app): next(iter(br._subscribers)).calls[0].handler.mock.assert_called_once_with( - {"name": "John", "user_id": 1} + {"name": "John", "user_id": 1}, ) next(iter(br._publishers)).mock.assert_called_once_with("Hi!") @@ -119,7 +119,7 @@ async def test_delay_router_redis(): async with TestRedisBroker(broker) as br, TestApp(app): next(iter(br._subscribers)).calls[0].handler.mock.assert_called_once_with( - {"name": "John", "user_id": 1} + {"name": "John", "user_id": 1}, ) next(iter(br._publishers)).mock.assert_called_once_with("Hi!") diff --git a/tests/a_docs/index/test_basic.py b/tests/a_docs/index/test_basic.py index 0e0675318b..185340222a 100644 --- a/tests/a_docs/index/test_basic.py +++ b/tests/a_docs/index/test_basic.py @@ -21,7 +21,7 @@ async def test_index_kafka_base(): handle_msg.mock.assert_called_once_with({"user": "John", "user_id": 1}) list(br._publishers)[0].mock.assert_called_once_with( # noqa: RUF015 - "User: 1 - John registered" + "User: 1 - John registered", ) @@ -37,7 +37,7 @@ async def test_index_confluent_base(): handle_msg.mock.assert_called_once_with({"user": "John", "user_id": 1}) list(br._publishers)[0].mock.assert_called_once_with( # noqa: RUF015 - "User: 1 - John registered" + "User: 1 - John registered", ) @@ -53,7 +53,7 @@ async def test_index_rabbit_base(): handle_msg.mock.assert_called_once_with({"user": "John", "user_id": 1}) list(br._publishers)[0].mock.assert_called_once_with( # noqa: RUF015 - "User: 1 - John registered" + "User: 1 - John registered", ) @@ -69,7 +69,7 @@ async def test_index_nats_base(): handle_msg.mock.assert_called_once_with({"user": "John", "user_id": 1}) list(br._publishers)[0].mock.assert_called_once_with( # noqa: RUF015 - "User: 1 - John registered" + "User: 1 - John registered", ) @@ -85,5 +85,5 @@ async def test_index_redis_base(): handle_msg.mock.assert_called_once_with({"user": "John", "user_id": 1}) list(br._publishers)[0].mock.assert_called_once_with( # noqa: RUF015 - "User: 1 - John registered" + "User: 1 - John registered", ) diff --git a/tests/a_docs/integration/fastapi/test_base.py b/tests/a_docs/integration/fastapi/test_base.py index 195afcecb5..81dc4b7ef2 100644 --- a/tests/a_docs/integration/fastapi/test_base.py +++ b/tests/a_docs/integration/fastapi/test_base.py @@ -25,7 +25,7 @@ async def test_fastapi_kafka_base(): hello.mock.assert_called_once_with({"m": {}}) list(br._publishers)[0].mock.assert_called_with( # noqa: RUF015 - {"response": "Hello, Kafka!"} + {"response": "Hello, Kafka!"}, ) @@ -44,7 +44,7 @@ async def test_fastapi_confluent_base(): hello.mock.assert_called_once_with({"m": {}}) list(br._publishers)[0].mock.assert_called_with( # noqa: RUF015 - {"response": "Hello, Kafka!"} + {"response": "Hello, Kafka!"}, ) @@ -63,7 +63,7 @@ async def test_fastapi_rabbit_base(): hello.mock.assert_called_once_with({"m": {}}) list(br._publishers)[0].mock.assert_called_with( # noqa: RUF015 - {"response": "Hello, Rabbit!"} + {"response": "Hello, Rabbit!"}, ) @@ -82,7 +82,7 @@ async def test_fastapi_nats_base(): hello.mock.assert_called_once_with({"m": {}}) list(br._publishers)[0].mock.assert_called_with( # noqa: RUF015 - {"response": "Hello, NATS!"} + {"response": "Hello, NATS!"}, ) @@ -101,5 +101,5 @@ async def test_fastapi_redis_base(): hello.mock.assert_called_once_with({"m": {}}) list(br._publishers)[0].mock.assert_called_with( # noqa: RUF015 - {"response": "Hello, Redis!"} + {"response": "Hello, Redis!"}, ) diff --git a/tests/a_docs/kafka/ack/test_errors.py b/tests/a_docs/kafka/ack/test_errors.py index a17bb1ad46..72d0d730b2 100644 --- a/tests/a_docs/kafka/ack/test_errors.py +++ b/tests/a_docs/kafka/ack/test_errors.py @@ -14,7 +14,9 @@ async def test_ack_exc(): from docs.docs_src.kafka.ack.errors import app, broker, handle with patch.object( - AIOKafkaConsumer, "commit", spy_decorator(AIOKafkaConsumer.commit) + AIOKafkaConsumer, + "commit", + spy_decorator(AIOKafkaConsumer.commit), ) as m: async with TestKafkaBroker(broker, with_real=True), TestApp(app): await handle.wait_call(10) diff --git a/tests/a_docs/kafka/batch_consuming_pydantic/test_app.py b/tests/a_docs/kafka/batch_consuming_pydantic/test_app.py index 4b39b471f5..0f2e28363c 100644 --- a/tests/a_docs/kafka/batch_consuming_pydantic/test_app.py +++ b/tests/a_docs/kafka/batch_consuming_pydantic/test_app.py @@ -17,5 +17,5 @@ async def test_me(): topic="test_batch", ) handle_batch.mock.assert_called_with( - [dict(HelloWorld(msg="First Hello")), dict(HelloWorld(msg="Second Hello"))] + [dict(HelloWorld(msg="First Hello")), dict(HelloWorld(msg="Second Hello"))], ) diff --git a/tests/a_docs/kafka/publish_batch/test_app.py b/tests/a_docs/kafka/publish_batch/test_app.py index 99bf043700..8c65b242fc 100644 --- a/tests/a_docs/kafka/publish_batch/test_app.py +++ b/tests/a_docs/kafka/publish_batch/test_app.py @@ -17,7 +17,7 @@ async def test_batch_publish_decorator(): on_input_data_1.mock.assert_called_once_with(dict(Data(data=2.0))) decrease_and_increase.mock.assert_called_once_with( - [dict(Data(data=1.0)), dict(Data(data=4.0))] + [dict(Data(data=1.0)), dict(Data(data=4.0))], ) @@ -28,5 +28,5 @@ async def test_batch_publish_call(): on_input_data_2.mock.assert_called_once_with(dict(Data(data=2.0))) decrease_and_increase.mock.assert_called_once_with( - [dict(Data(data=1.0)), dict(Data(data=4.0))] + [dict(Data(data=1.0)), dict(Data(data=4.0))], ) diff --git a/tests/a_docs/rabbit/test_security.py b/tests/a_docs/rabbit/test_security.py index 9a9343d27f..e025ef639c 100644 --- a/tests/a_docs/rabbit/test_security.py +++ b/tests/a_docs/rabbit/test_security.py @@ -26,7 +26,7 @@ async def test_base_security(): "protocolVersion": "0.9.1", "security": [], "url": "amqps://guest:guest@localhost:5672/", # pragma: allowlist secret - } + }, }, } @@ -59,7 +59,7 @@ async def test_plaintext_security(): "protocolVersion": "0.9.1", "security": [{"user-password": []}], "url": "amqps://admin:password@localhost:5672/", # pragma: allowlist secret - } + }, }, } ) diff --git a/tests/a_docs/redis/test_security.py b/tests/a_docs/redis/test_security.py index 8fbd3c87a8..2385c9acdc 100644 --- a/tests/a_docs/redis/test_security.py +++ b/tests/a_docs/redis/test_security.py @@ -51,7 +51,7 @@ async def test_base_security(): "protocolVersion": "custom", "security": [], "url": "redis://localhost:6379", - } + }, }, } @@ -85,6 +85,6 @@ async def test_plaintext_security(): "protocolVersion": "custom", "security": [{"user-password": []}], "url": "redis://localhost:6379", - } + }, }, } diff --git a/tests/asgi/testcase.py b/tests/asgi/testcase.py index f5992cc537..f1b6b240f8 100644 --- a/tests/asgi/testcase.py +++ b/tests/asgi/testcase.py @@ -35,7 +35,7 @@ def test_asgi_ping_unhealthy(self): app = AsgiFastStream( asgi_routes=[ ("/health", make_ping_asgi(broker, timeout=5.0)), - ] + ], ) with TestClient(app) as client: diff --git a/tests/asyncapi/base/v2_6_0/arguments.py b/tests/asyncapi/base/v2_6_0/arguments.py index 4c0d0c0e17..0af0e5f525 100644 --- a/tests/asyncapi/base/v2_6_0/arguments.py +++ b/tests/asyncapi/base/v2_6_0/arguments.py @@ -131,12 +131,12 @@ async def handle(msg: Optional[int]): ... { "anyOf": [{"type": "integer"}, {"type": "null"}], "title": key, - } + }, ) | IsDict( { # TODO: remove when deprecating PydanticV1 "title": key, "type": "integer", - } + }, ), v def test_simple_type_with_default(self): @@ -221,13 +221,13 @@ async def handle(msg: str, another: Optional[int] = None): ... "anyOf": [{"type": "integer"}, {"type": "null"}], "default": None, "title": "Another", - } + }, ) | IsDict( { # TODO: remove when deprecating PydanticV1 "title": "Another", "type": "integer", - } + }, ), "msg": {"title": "Msg", "type": "string"}, }, @@ -314,7 +314,7 @@ async def handle(user: User): ... "enum": ["registered", "banned"], "title": "Status", "type": "string", - } + }, ), "User": { "properties": { @@ -385,7 +385,7 @@ class User(pydantic.BaseModel): if PYDANTIC_V2: model_config = { - "json_schema_extra": {"examples": [{"name": "john", "id": 1}]} + "json_schema_extra": {"examples": [{"name": "john", "id": 1}]}, } else: @@ -456,7 +456,8 @@ class Sub(pydantic.BaseModel): type: Literal["sub"] descriminator = Annotated[ - Union[Sub2, Sub], pydantic.Field(discriminator="type") + Union[Sub2, Sub], + pydantic.Field(discriminator="type"), ] broker = self.broker_class() @@ -481,12 +482,12 @@ async def handle(user: descriminator): ... ], "title": "Handle:Message:Payload", }, - } + }, }, "schemas": { "Sub": { "properties": { - "type": IsPartialDict({"const": "sub", "title": "Type"}) + "type": IsPartialDict({"const": "sub", "title": "Type"}), }, "required": ["type"], "title": "Sub", @@ -494,7 +495,7 @@ async def handle(user: descriminator): ... }, "Sub2": { "properties": { - "type": IsPartialDict({"const": "sub2", "title": "Type"}) + "type": IsPartialDict({"const": "sub2", "title": "Type"}), }, "required": ["type"], "title": "Sub2", @@ -529,12 +530,12 @@ async def handle(user: Model): ... "title": key, "correlationId": {"location": "$message.header#/correlation_id"}, "payload": {"$ref": "#/components/schemas/Model"}, - } + }, }, "schemas": { "Sub": { "properties": { - "type": IsPartialDict({"const": "sub", "title": "Type"}) + "type": IsPartialDict({"const": "sub", "title": "Type"}), }, "required": ["type"], "title": "Sub", @@ -542,7 +543,7 @@ async def handle(user: Model): ... }, "Sub2": { "properties": { - "type": IsPartialDict({"const": "sub2", "title": "Type"}) + "type": IsPartialDict({"const": "sub2", "title": "Type"}), }, "required": ["type"], "title": "Sub2", @@ -557,7 +558,7 @@ async def handle(user: Model): ... {"$ref": "#/components/schemas/Sub"}, ], "title": "Msg", - } + }, }, "required": ["msg"], "title": "Model", @@ -589,7 +590,7 @@ async def handle_default(msg): ... len( next(iter(schema["components"]["messages"].values()))["payload"][ "oneOf" - ] + ], ) == 2 ) @@ -656,7 +657,7 @@ async def handle(id: int, user: Optional[str] = None, message=Context()): ... "required": ["id"], "title": key, "type": "object", - } + }, ) | IsDict( # TODO: remove when deprecating PydanticV1 { "properties": { @@ -666,5 +667,5 @@ async def handle(id: int, user: Optional[str] = None, message=Context()): ... "required": ["id"], "title": "Handle:Message:Payload", "type": "object", - } + }, ) diff --git a/tests/asyncapi/base/v2_6_0/fastapi.py b/tests/asyncapi/base/v2_6_0/fastapi.py index 5c75b87595..6515c8652f 100644 --- a/tests/asyncapi/base/v2_6_0/fastapi.py +++ b/tests/asyncapi/base/v2_6_0/fastapi.py @@ -62,7 +62,7 @@ async def test_fastapi_full_information(self): "description": "Test broker description", "protocolVersion": "1.1.1", "tags": [{"name": "test"}], - } + }, }, "channels": {}, "components": {"messages": {}, "schemas": {}}, diff --git a/tests/asyncapi/base/v2_6_0/naming.py b/tests/asyncapi/base/v2_6_0/naming.py index 798a5088ad..2351d66185 100644 --- a/tests/asyncapi/base/v2_6_0/naming.py +++ b/tests/asyncapi/base/v2_6_0/naming.py @@ -21,15 +21,15 @@ async def handle_user_created(msg: str): ... schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [ - IsStr(regex=r"test[\w:]*:HandleUserCreated") + IsStr(regex=r"test[\w:]*:HandleUserCreated"), ] assert list(schema["components"]["messages"].keys()) == [ - IsStr(regex=r"test[\w:]*:HandleUserCreated:Message") + IsStr(regex=r"test[\w:]*:HandleUserCreated:Message"), ] assert list(schema["components"]["schemas"].keys()) == [ - "HandleUserCreated:Message:Payload" + "HandleUserCreated:Message:Payload", ] def test_pydantic_subscriber_naming(self): @@ -41,11 +41,11 @@ async def handle_user_created(msg: create_model("SimpleModel")): ... schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [ - IsStr(regex=r"test[\w:]*:HandleUserCreated") + IsStr(regex=r"test[\w:]*:HandleUserCreated"), ] assert list(schema["components"]["messages"].keys()) == [ - IsStr(regex=r"test[\w:]*:HandleUserCreated:Message") + IsStr(regex=r"test[\w:]*:HandleUserCreated:Message"), ] assert list(schema["components"]["schemas"].keys()) == ["SimpleModel"] @@ -70,7 +70,7 @@ async def handle_user_created(msg: str): ... ] assert list(schema["components"]["schemas"].keys()) == [ - "HandleUserCreated:Message:Payload" + "HandleUserCreated:Message:Payload", ] def test_subscriber_naming_manual(self): @@ -86,7 +86,7 @@ async def handle_user_created(msg: str): ... assert list(schema["components"]["messages"].keys()) == ["custom:Message"] assert list(schema["components"]["schemas"].keys()) == [ - "custom:Message:Payload" + "custom:Message:Payload", ] def test_subscriber_naming_default(self): @@ -97,11 +97,11 @@ def test_subscriber_naming_default(self): schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [ - IsStr(regex=r"test[\w:]*:Subscriber") + IsStr(regex=r"test[\w:]*:Subscriber"), ] assert list(schema["components"]["messages"].keys()) == [ - IsStr(regex=r"test[\w:]*:Subscriber:Message") + IsStr(regex=r"test[\w:]*:Subscriber:Message"), ] for key, v in schema["components"]["schemas"].items(): @@ -120,11 +120,11 @@ def test_subscriber_naming_default_with_title(self): assert list(schema["components"]["messages"].keys()) == ["custom:Message"] assert list(schema["components"]["schemas"].keys()) == [ - "custom:Message:Payload" + "custom:Message:Payload", ] assert schema["components"]["schemas"]["custom:Message:Payload"] == { - "title": "custom:Message:Payload" + "title": "custom:Message:Payload", } def test_multi_subscribers_naming_default(self): @@ -156,7 +156,7 @@ async def handle_user_created(msg: str): ... ] assert schema["components"]["schemas"]["Subscriber:Message:Payload"] == { - "title": "Subscriber:Message:Payload" + "title": "Subscriber:Message:Payload", } @@ -175,11 +175,11 @@ async def handle_user_id(msg: int): ... schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [ - IsStr(regex=r"test[\w:]*:HandleUserCreated") + IsStr(regex=r"test[\w:]*:HandleUserCreated"), ] assert list(schema["components"]["messages"].keys()) == [ - IsStr(regex=r"test[\w:]*:HandleUserCreated:Message") + IsStr(regex=r"test[\w:]*:HandleUserCreated:Message"), ] assert list(schema["components"]["schemas"].keys()) == [ @@ -201,11 +201,11 @@ async def handle_user_id(msg: int): ... schema = AsyncAPI(broker, schema_version="2.6.0").to_jsonable() assert list(schema["channels"].keys()) == [ - IsStr(regex=r"test[\w:]*:HandleUserCreated") + IsStr(regex=r"test[\w:]*:HandleUserCreated"), ] assert list(schema["components"]["messages"].keys()) == [ - IsStr(regex=r"test[\w:]*:HandleUserCreated:Message") + IsStr(regex=r"test[\w:]*:HandleUserCreated:Message"), ] assert list(schema["components"]["schemas"].keys()) == [ @@ -248,11 +248,11 @@ async def handle_user_created() -> str: ... assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] assert list(schema["components"]["messages"].keys()) == [ - IsStr(regex=r"test[\w:]*:Publisher:Message") + IsStr(regex=r"test[\w:]*:Publisher:Message"), ] assert list(schema["components"]["schemas"].keys()) == [ - IsStr(regex=r"test[\w:]*:Publisher:Message:Payload") + IsStr(regex=r"test[\w:]*:Publisher:Message:Payload"), ] def test_publisher_naming_pydantic(self): @@ -266,7 +266,7 @@ async def handle_user_created() -> create_model("SimpleModel"): ... assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] assert list(schema["components"]["messages"].keys()) == [ - IsStr(regex=r"test[\w:]*:Publisher:Message") + IsStr(regex=r"test[\w:]*:Publisher:Message"), ] assert list(schema["components"]["schemas"].keys()) == [ @@ -286,7 +286,7 @@ async def handle_user_created() -> str: ... assert list(schema["components"]["messages"].keys()) == ["custom:Message"] assert list(schema["components"]["schemas"].keys()) == [ - "custom:Message:Payload" + "custom:Message:Payload", ] def test_publisher_with_schema_naming(self): @@ -300,11 +300,11 @@ async def handle_user_created(): ... assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] assert list(schema["components"]["messages"].keys()) == [ - IsStr(regex=r"test[\w:]*:Publisher:Message") + IsStr(regex=r"test[\w:]*:Publisher:Message"), ] assert list(schema["components"]["schemas"].keys()) == [ - IsStr(regex=r"test[\w:]*:Publisher:Message:Payload") + IsStr(regex=r"test[\w:]*:Publisher:Message:Payload"), ] def test_publisher_manual_naming_with_schema(self): @@ -320,7 +320,7 @@ async def handle_user_created(): ... assert list(schema["components"]["messages"].keys()) == ["custom:Message"] assert list(schema["components"]["schemas"].keys()) == [ - "custom:Message:Payload" + "custom:Message:Payload", ] def test_multi_publishers_naming(self): diff --git a/tests/asyncapi/base/v3_0_0/arguments.py b/tests/asyncapi/base/v3_0_0/arguments.py index 128f2c0468..301a38125e 100644 --- a/tests/asyncapi/base/v3_0_0/arguments.py +++ b/tests/asyncapi/base/v3_0_0/arguments.py @@ -140,12 +140,12 @@ async def handle(msg: Optional[int]): ... { "anyOf": [{"type": "integer"}, {"type": "null"}], "title": key, - } + }, ) | IsDict( { # TODO: remove when deprecating PydanticV1 "title": key, "type": "integer", - } + }, ), v def test_simple_type_with_default(self): @@ -230,13 +230,13 @@ async def handle(msg: str, another: Optional[int] = None): ... "anyOf": [{"type": "integer"}, {"type": "null"}], "default": None, "title": "Another", - } + }, ) | IsDict( { # TODO: remove when deprecating PydanticV1 "title": "Another", "type": "integer", - } + }, ), "msg": {"title": "Msg", "type": "string"}, }, @@ -323,7 +323,7 @@ async def handle(user: User): ... "enum": ["registered", "banned"], "title": "Status", "type": "string", - } + }, ), "User": { "properties": { @@ -394,7 +394,7 @@ class User(pydantic.BaseModel): if PYDANTIC_V2: model_config = { - "json_schema_extra": {"examples": [{"name": "john", "id": 1}]} + "json_schema_extra": {"examples": [{"name": "john", "id": 1}]}, } else: @@ -447,7 +447,7 @@ async def handle_default(msg): ... len( next(iter(schema["components"]["messages"].values()))["payload"][ "oneOf" - ] + ], ) == 2 ) @@ -498,7 +498,8 @@ class Sub(pydantic.BaseModel): type: Literal["sub"] descriminator = Annotated[ - Union[Sub2, Sub], pydantic.Field(discriminator="type") + Union[Sub2, Sub], + pydantic.Field(discriminator="type"), ] broker = self.broker_factory() @@ -516,12 +517,12 @@ async def handle(user: descriminator): ... "title": key, "correlationId": {"location": "$message.header#/correlation_id"}, "payload": {"$ref": "#/components/schemas/Handle:Message:Payload"}, - } + }, }, "schemas": { "Sub": { "properties": { - "type": IsPartialDict({"const": "sub", "title": "Type"}) + "type": IsPartialDict({"const": "sub", "title": "Type"}), }, "required": ["type"], "title": "Sub", @@ -529,7 +530,7 @@ async def handle(user: descriminator): ... }, "Sub2": { "properties": { - "type": IsPartialDict({"const": "sub2", "title": "Type"}) + "type": IsPartialDict({"const": "sub2", "title": "Type"}), }, "required": ["type"], "title": "Sub2", @@ -572,12 +573,12 @@ async def handle(user: Model): ... "title": key, "correlationId": {"location": "$message.header#/correlation_id"}, "payload": {"$ref": "#/components/schemas/Model"}, - } + }, }, "schemas": { "Sub": { "properties": { - "type": IsPartialDict({"const": "sub", "title": "Type"}) + "type": IsPartialDict({"const": "sub", "title": "Type"}), }, "required": ["type"], "title": "Sub", @@ -585,7 +586,7 @@ async def handle(user: Model): ... }, "Sub2": { "properties": { - "type": IsPartialDict({"const": "sub2", "title": "Type"}) + "type": IsPartialDict({"const": "sub2", "title": "Type"}), }, "required": ["type"], "title": "Sub2", @@ -600,7 +601,7 @@ async def handle(user: Model): ... {"$ref": "#/components/schemas/Sub"}, ], "title": "Msg", - } + }, }, "required": ["msg"], "title": "Model", @@ -666,7 +667,7 @@ async def handle(id: int, user: Optional[str] = None, message=Context()): ... "required": ["id"], "title": key, "type": "object", - } + }, ) | IsDict( # TODO: remove when deprecating PydanticV1 { "properties": { @@ -676,5 +677,5 @@ async def handle(id: int, user: Optional[str] = None, message=Context()): ... "required": ["id"], "title": "Handle:Message:Payload", "type": "object", - } + }, ) diff --git a/tests/asyncapi/base/v3_0_0/fastapi.py b/tests/asyncapi/base/v3_0_0/fastapi.py index 6783803987..f29bd84c77 100644 --- a/tests/asyncapi/base/v3_0_0/fastapi.py +++ b/tests/asyncapi/base/v3_0_0/fastapi.py @@ -63,7 +63,7 @@ async def test_fastapi_full_information(self): "description": "Test broker description", "protocolVersion": "1.1.1", "tags": [{"name": "test"}], - } + }, }, "channels": {}, "operations": {}, diff --git a/tests/asyncapi/base/v3_0_0/naming.py b/tests/asyncapi/base/v3_0_0/naming.py index 1f23839c25..4681fffe64 100644 --- a/tests/asyncapi/base/v3_0_0/naming.py +++ b/tests/asyncapi/base/v3_0_0/naming.py @@ -21,15 +21,15 @@ async def handle_user_created(msg: str): ... schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [ - IsStr(regex=r"test[\w:]*:HandleUserCreated") + IsStr(regex=r"test[\w:]*:HandleUserCreated"), ] assert list(schema["components"]["messages"].keys()) == [ - IsStr(regex=r"test[\w:]*:HandleUserCreated:SubscribeMessage") + IsStr(regex=r"test[\w:]*:HandleUserCreated:SubscribeMessage"), ] assert list(schema["components"]["schemas"].keys()) == [ - "HandleUserCreated:Message:Payload" + "HandleUserCreated:Message:Payload", ] def test_pydantic_subscriber_naming(self): @@ -41,11 +41,11 @@ async def handle_user_created(msg: create_model("SimpleModel")): ... schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [ - IsStr(regex=r"test[\w:]*:HandleUserCreated") + IsStr(regex=r"test[\w:]*:HandleUserCreated"), ] assert list(schema["components"]["messages"].keys()) == [ - IsStr(regex=r"test[\w:]*:HandleUserCreated:SubscribeMessage") + IsStr(regex=r"test[\w:]*:HandleUserCreated:SubscribeMessage"), ] assert list(schema["components"]["schemas"].keys()) == ["SimpleModel"] @@ -70,7 +70,7 @@ async def handle_user_created(msg: str): ... ] assert list(schema["components"]["schemas"].keys()) == [ - "HandleUserCreated:Message:Payload" + "HandleUserCreated:Message:Payload", ] def test_subscriber_naming_manual(self): @@ -84,11 +84,11 @@ async def handle_user_created(msg: str): ... assert list(schema["channels"].keys()) == ["custom"] assert list(schema["components"]["messages"].keys()) == [ - "custom:SubscribeMessage" + "custom:SubscribeMessage", ] assert list(schema["components"]["schemas"].keys()) == [ - "custom:Message:Payload" + "custom:Message:Payload", ] def test_subscriber_naming_default(self): @@ -99,11 +99,11 @@ def test_subscriber_naming_default(self): schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [ - IsStr(regex=r"test[\w:]*:Subscriber") + IsStr(regex=r"test[\w:]*:Subscriber"), ] assert list(schema["components"]["messages"].keys()) == [ - IsStr(regex=r"test[\w:]*:Subscriber:SubscribeMessage") + IsStr(regex=r"test[\w:]*:Subscriber:SubscribeMessage"), ] for key, v in schema["components"]["schemas"].items(): @@ -120,15 +120,15 @@ def test_subscriber_naming_default_with_title(self): assert list(schema["channels"].keys()) == ["custom"] assert list(schema["components"]["messages"].keys()) == [ - "custom:SubscribeMessage" + "custom:SubscribeMessage", ] assert list(schema["components"]["schemas"].keys()) == [ - "custom:Message:Payload" + "custom:Message:Payload", ] assert schema["components"]["schemas"]["custom:Message:Payload"] == { - "title": "custom:Message:Payload" + "title": "custom:Message:Payload", } def test_multi_subscribers_naming_default(self): @@ -160,7 +160,7 @@ async def handle_user_created(msg: str): ... ] assert schema["components"]["schemas"]["Subscriber:Message:Payload"] == { - "title": "Subscriber:Message:Payload" + "title": "Subscriber:Message:Payload", } @@ -179,11 +179,11 @@ async def handle_user_id(msg: int): ... schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [ - IsStr(regex=r"test[\w:]*:HandleUserCreated") + IsStr(regex=r"test[\w:]*:HandleUserCreated"), ] assert list(schema["components"]["messages"].keys()) == [ - IsStr(regex=r"test[\w:]*:HandleUserCreated:SubscribeMessage") + IsStr(regex=r"test[\w:]*:HandleUserCreated:SubscribeMessage"), ] assert list(schema["components"]["schemas"].keys()) == [ @@ -205,11 +205,11 @@ async def handle_user_id(msg: int): ... schema = AsyncAPI(broker, schema_version="3.0.0").to_jsonable() assert list(schema["channels"].keys()) == [ - IsStr(regex=r"test[\w:]*:HandleUserCreated") + IsStr(regex=r"test[\w:]*:HandleUserCreated"), ] assert list(schema["components"]["messages"].keys()) == [ - IsStr(regex=r"test[\w:]*:HandleUserCreated:SubscribeMessage") + IsStr(regex=r"test[\w:]*:HandleUserCreated:SubscribeMessage"), ] assert list(schema["components"]["schemas"].keys()) == [ @@ -233,7 +233,7 @@ async def handle_user_id(msg: int): ... assert list(schema["channels"].keys()) == ["custom"] assert list(schema["components"]["messages"].keys()) == [ - "custom:SubscribeMessage" + "custom:SubscribeMessage", ] assert list(schema["components"]["schemas"].keys()) == [ @@ -254,11 +254,11 @@ async def handle_user_created() -> str: ... assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] assert list(schema["components"]["messages"].keys()) == [ - IsStr(regex=r"test[\w:]*:Publisher:Message") + IsStr(regex=r"test[\w:]*:Publisher:Message"), ] assert list(schema["components"]["schemas"].keys()) == [ - IsStr(regex=r"test[\w:]*:Publisher:Message:Payload") + IsStr(regex=r"test[\w:]*:Publisher:Message:Payload"), ] def test_publisher_naming_pydantic(self): @@ -272,7 +272,7 @@ async def handle_user_created() -> create_model("SimpleModel"): ... assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] assert list(schema["components"]["messages"].keys()) == [ - IsStr(regex=r"test[\w:]*:Publisher:Message") + IsStr(regex=r"test[\w:]*:Publisher:Message"), ] assert list(schema["components"]["schemas"].keys()) == [ @@ -292,7 +292,7 @@ async def handle_user_created() -> str: ... assert list(schema["components"]["messages"].keys()) == ["custom:Message"] assert list(schema["components"]["schemas"].keys()) == [ - "custom:Message:Payload" + "custom:Message:Payload", ] def test_publisher_with_schema_naming(self): @@ -306,11 +306,11 @@ async def handle_user_created(): ... assert list(schema["channels"].keys()) == [IsStr(regex=r"test[\w:]*:Publisher")] assert list(schema["components"]["messages"].keys()) == [ - IsStr(regex=r"test[\w:]*:Publisher:Message") + IsStr(regex=r"test[\w:]*:Publisher:Message"), ] assert list(schema["components"]["schemas"].keys()) == [ - IsStr(regex=r"test[\w:]*:Publisher:Message:Payload") + IsStr(regex=r"test[\w:]*:Publisher:Message:Payload"), ] def test_publisher_manual_naming_with_schema(self): @@ -326,7 +326,7 @@ async def handle_user_created(): ... assert list(schema["components"]["messages"].keys()) == ["custom:Message"] assert list(schema["components"]["schemas"].keys()) == [ - "custom:Message:Payload" + "custom:Message:Payload", ] def test_multi_publishers_naming(self): diff --git a/tests/asyncapi/confluent/v2_6_0/test_arguments.py b/tests/asyncapi/confluent/v2_6_0/test_arguments.py index 9e10831bd7..9209977774 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_arguments.py +++ b/tests/asyncapi/confluent/v2_6_0/test_arguments.py @@ -16,5 +16,5 @@ async def handle(msg): ... key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { - "kafka": {"bindingVersion": "0.4.0", "topic": "test"} + "kafka": {"bindingVersion": "0.4.0", "topic": "test"}, } diff --git a/tests/asyncapi/confluent/v2_6_0/test_connection.py b/tests/asyncapi/confluent/v2_6_0/test_connection.py index 04ffb3bb27..fad1953172 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_connection.py +++ b/tests/asyncapi/confluent/v2_6_0/test_connection.py @@ -28,14 +28,15 @@ def test_base(): "protocolVersion": "0.9.0", "tags": [{"description": "experimental", "name": "some-tag"}], "url": "kafka:9092", - } + }, }, } def test_multi(): schema = AsyncAPI( - KafkaBroker(["kafka:9092", "kafka:9093"]), schema_version="2.6.0" + KafkaBroker(["kafka:9092", "kafka:9093"]), + schema_version="2.6.0", ).to_jsonable() assert schema == { diff --git a/tests/asyncapi/confluent/v2_6_0/test_fastapi.py b/tests/asyncapi/confluent/v2_6_0/test_fastapi.py index 1a68210249..18f9512798 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/confluent/v2_6_0/test_fastapi.py @@ -37,5 +37,5 @@ def test_fastapi_security_schema(): "url": "localhost:9092", } assert schema["components"]["securitySchemes"] == { - "user-password": {"type": "userPassword"} + "user-password": {"type": "userPassword"}, } diff --git a/tests/asyncapi/confluent/v2_6_0/test_naming.py b/tests/asyncapi/confluent/v2_6_0/test_naming.py index 1bc6ac2ffe..4be194cc26 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_naming.py +++ b/tests/asyncapi/confluent/v2_6_0/test_naming.py @@ -23,26 +23,28 @@ async def handle(): ... "url": "localhost", "protocol": "kafka", "protocolVersion": "auto", - } + }, }, "channels": { "test:Handle": { "servers": ["development"], "bindings": {"kafka": {"topic": "test", "bindingVersion": "0.4.0"}}, "subscribe": { - "message": {"$ref": "#/components/messages/test:Handle:Message"} + "message": { + "$ref": "#/components/messages/test:Handle:Message" + }, }, - } + }, }, "components": { "messages": { "test:Handle:Message": { "title": "test:Handle:Message", "correlationId": { - "location": "$message.header#/correlation_id" + "location": "$message.header#/correlation_id", }, "payload": {"$ref": "#/components/schemas/EmptyPayload"}, - } + }, }, "schemas": {"EmptyPayload": {"title": "EmptyPayload", "type": "null"}}, }, diff --git a/tests/asyncapi/confluent/v2_6_0/test_publisher.py b/tests/asyncapi/confluent/v2_6_0/test_publisher.py index 27bbf086b6..44239773de 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_publisher.py +++ b/tests/asyncapi/confluent/v2_6_0/test_publisher.py @@ -16,5 +16,5 @@ async def handle(msg): ... key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { - "kafka": {"bindingVersion": "0.4.0", "topic": "test"} + "kafka": {"bindingVersion": "0.4.0", "topic": "test"}, } diff --git a/tests/asyncapi/confluent/v2_6_0/test_router.py b/tests/asyncapi/confluent/v2_6_0/test_router.py index bd95965558..1ea9917ba9 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_router.py +++ b/tests/asyncapi/confluent/v2_6_0/test_router.py @@ -32,35 +32,35 @@ async def handle(msg): ... "url": "localhost", "protocol": "kafka", "protocolVersion": "auto", - } + }, }, "channels": { "test_test:Handle": { "servers": ["development"], "bindings": { - "kafka": {"topic": "test_test", "bindingVersion": "0.4.0"} + "kafka": {"topic": "test_test", "bindingVersion": "0.4.0"}, }, "subscribe": { "message": { - "$ref": "#/components/messages/test_test:Handle:Message" - } + "$ref": "#/components/messages/test_test:Handle:Message", + }, }, - } + }, }, "components": { "messages": { "test_test:Handle:Message": { "title": "test_test:Handle:Message", "correlationId": { - "location": "$message.header#/correlation_id" + "location": "$message.header#/correlation_id", }, "payload": { - "$ref": "#/components/schemas/Handle:Message:Payload" + "$ref": "#/components/schemas/Handle:Message:Payload", }, - } + }, }, "schemas": { - "Handle:Message:Payload": {"title": "Handle:Message:Payload"} + "Handle:Message:Payload": {"title": "Handle:Message:Payload"}, }, }, } diff --git a/tests/asyncapi/confluent/v2_6_0/test_security.py b/tests/asyncapi/confluent/v2_6_0/test_security.py index a11bf60df2..ad25dc1965 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_security.py +++ b/tests/asyncapi/confluent/v2_6_0/test_security.py @@ -19,13 +19,13 @@ "bindings": {"kafka": {"bindingVersion": "0.4.0", "topic": "test_1"}}, "servers": ["development"], "subscribe": { - "message": {"$ref": "#/components/messages/test_1:TestTopic:Message"} + "message": {"$ref": "#/components/messages/test_1:TestTopic:Message"}, }, }, "test_2:Publisher": { "bindings": {"kafka": {"bindingVersion": "0.4.0", "topic": "test_2"}}, "publish": { - "message": {"$ref": "#/components/messages/test_2:Publisher:Message"} + "message": {"$ref": "#/components/messages/test_2:Publisher:Message"}, }, "servers": ["development"], }, @@ -40,7 +40,7 @@ "test_2:Publisher:Message": { "correlationId": {"location": "$message.header#/correlation_id"}, "payload": { - "$ref": "#/components/schemas/test_2:Publisher:Message:Payload" + "$ref": "#/components/schemas/test_2:Publisher:Message:Payload", }, "title": "test_2:Publisher:Message", }, @@ -65,7 +65,7 @@ "protocolVersion": "auto", "security": [], "url": "localhost:9092", - } + }, }, } @@ -105,10 +105,10 @@ async def test_topic(msg: str) -> str: plaintext_security_schema = deepcopy(basic_schema) plaintext_security_schema["servers"]["development"]["security"] = [ - {"user-password": []} + {"user-password": []}, ] plaintext_security_schema["components"]["securitySchemes"] = { - "user-password": {"type": "userPassword"} + "user-password": {"type": "userPassword"}, } assert schema == plaintext_security_schema @@ -134,7 +134,7 @@ async def test_topic(msg: str) -> str: sasl256_security_schema = deepcopy(basic_schema) sasl256_security_schema["servers"]["development"]["security"] = [{"scram256": []}] sasl256_security_schema["components"]["securitySchemes"] = { - "scram256": {"type": "scramSha256"} + "scram256": {"type": "scramSha256"}, } assert schema == sasl256_security_schema @@ -160,7 +160,7 @@ async def test_topic(msg: str) -> str: sasl512_security_schema = deepcopy(basic_schema) sasl512_security_schema["servers"]["development"]["security"] = [{"scram512": []}] sasl512_security_schema["components"]["securitySchemes"] = { - "scram512": {"type": "scramSha512"} + "scram512": {"type": "scramSha512"}, } assert schema == sasl512_security_schema @@ -183,10 +183,10 @@ async def test_topic(msg: str) -> str: sasl_oauthbearer_security_schema = deepcopy(basic_schema) sasl_oauthbearer_security_schema["servers"]["development"]["security"] = [ - {"oauthbearer": []} + {"oauthbearer": []}, ] sasl_oauthbearer_security_schema["components"]["securitySchemes"] = { - "oauthbearer": {"type": "oauthBearer"} + "oauthbearer": {"type": "oauthBearer"}, } assert schema == sasl_oauthbearer_security_schema @@ -208,7 +208,7 @@ async def test_topic(msg: str) -> str: gssapi_security_schema = deepcopy(basic_schema) gssapi_security_schema["servers"]["development"]["security"] = [{"gssapi": []}] gssapi_security_schema["components"]["securitySchemes"] = { - "gssapi": {"type": "gssapi"} + "gssapi": {"type": "gssapi"}, } assert schema == gssapi_security_schema diff --git a/tests/asyncapi/confluent/v3_0_0/test_arguments.py b/tests/asyncapi/confluent/v3_0_0/test_arguments.py index 97e4333888..3a0f8ee9bc 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_arguments.py +++ b/tests/asyncapi/confluent/v3_0_0/test_arguments.py @@ -16,5 +16,5 @@ async def handle(msg): ... key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { - "kafka": {"bindingVersion": "0.4.0", "topic": "test"} + "kafka": {"bindingVersion": "0.4.0", "topic": "test"}, } diff --git a/tests/asyncapi/confluent/v3_0_0/test_connection.py b/tests/asyncapi/confluent/v3_0_0/test_connection.py index a277652f5e..9fec5061cc 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_connection.py +++ b/tests/asyncapi/confluent/v3_0_0/test_connection.py @@ -30,7 +30,7 @@ def test_base(): "tags": [{"description": "experimental", "name": "some-tag"}], "host": "kafka:9092", "pathname": "", - } + }, }, } diff --git a/tests/asyncapi/confluent/v3_0_0/test_fastapi.py b/tests/asyncapi/confluent/v3_0_0/test_fastapi.py index 18a4859956..ec084d97f1 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/confluent/v3_0_0/test_fastapi.py @@ -38,5 +38,5 @@ def test_fastapi_security_schema(): "pathname": "", } assert schema["components"]["securitySchemes"] == { - "user-password": {"type": "userPassword"} + "user-password": {"type": "userPassword"}, } diff --git a/tests/asyncapi/confluent/v3_0_0/test_naming.py b/tests/asyncapi/confluent/v3_0_0/test_naming.py index b2558ca39e..d96569a483 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_naming.py +++ b/tests/asyncapi/confluent/v3_0_0/test_naming.py @@ -24,7 +24,7 @@ async def handle(): ... "pathname": "", "protocol": "kafka", "protocolVersion": "auto", - } + }, }, "channels": { "test:Handle": { @@ -32,7 +32,7 @@ async def handle(): ... "servers": [ { "$ref": "#/servers/development", - } + }, ], "bindings": {"kafka": {"topic": "test", "bindingVersion": "0.4.0"}}, "messages": { @@ -40,7 +40,7 @@ async def handle(): ... "$ref": "#/components/messages/test:Handle:SubscribeMessage", }, }, - } + }, }, "operations": { "test:HandleSubscribe": { @@ -51,19 +51,19 @@ async def handle(): ... "messages": [ { "$ref": "#/channels/test:Handle/messages/SubscribeMessage", - } + }, ], - } + }, }, "components": { "messages": { "test:Handle:SubscribeMessage": { "title": "test:Handle:SubscribeMessage", "correlationId": { - "location": "$message.header#/correlation_id" + "location": "$message.header#/correlation_id", }, "payload": {"$ref": "#/components/schemas/EmptyPayload"}, - } + }, }, "schemas": {"EmptyPayload": {"title": "EmptyPayload", "type": "null"}}, }, diff --git a/tests/asyncapi/confluent/v3_0_0/test_publisher.py b/tests/asyncapi/confluent/v3_0_0/test_publisher.py index e7ac72d523..9df1d4910e 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_publisher.py +++ b/tests/asyncapi/confluent/v3_0_0/test_publisher.py @@ -16,5 +16,5 @@ async def handle(msg): ... key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { - "kafka": {"bindingVersion": "0.4.0", "topic": "test"} + "kafka": {"bindingVersion": "0.4.0", "topic": "test"}, } diff --git a/tests/asyncapi/confluent/v3_0_0/test_router.py b/tests/asyncapi/confluent/v3_0_0/test_router.py index 42efa5bf05..81e0f947b2 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_router.py +++ b/tests/asyncapi/confluent/v3_0_0/test_router.py @@ -33,7 +33,7 @@ async def handle(msg): ... "pathname": "", "protocol": "kafka", "protocolVersion": "auto", - } + }, }, "channels": { "test_test:Handle": { @@ -41,39 +41,39 @@ async def handle(msg): ... "servers": [{"$ref": "#/servers/development"}], "messages": { "SubscribeMessage": { - "$ref": "#/components/messages/test_test:Handle:SubscribeMessage" - } + "$ref": "#/components/messages/test_test:Handle:SubscribeMessage", + }, }, "bindings": { - "kafka": {"topic": "test_test", "bindingVersion": "0.4.0"} + "kafka": {"topic": "test_test", "bindingVersion": "0.4.0"}, }, - } + }, }, "operations": { "test_test:HandleSubscribe": { "action": "receive", "messages": [ { - "$ref": "#/channels/test_test:Handle/messages/SubscribeMessage" - } + "$ref": "#/channels/test_test:Handle/messages/SubscribeMessage", + }, ], "channel": {"$ref": "#/channels/test_test:Handle"}, - } + }, }, "components": { "messages": { "test_test:Handle:SubscribeMessage": { "title": "test_test:Handle:SubscribeMessage", "correlationId": { - "location": "$message.header#/correlation_id" + "location": "$message.header#/correlation_id", }, "payload": { - "$ref": "#/components/schemas/Handle:Message:Payload" + "$ref": "#/components/schemas/Handle:Message:Payload", }, - } + }, }, "schemas": { - "Handle:Message:Payload": {"title": "Handle:Message:Payload"} + "Handle:Message:Payload": {"title": "Handle:Message:Payload"}, }, }, } diff --git a/tests/asyncapi/confluent/v3_0_0/test_security.py b/tests/asyncapi/confluent/v3_0_0/test_security.py index 3fff31d194..61592b7167 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_security.py +++ b/tests/asyncapi/confluent/v3_0_0/test_security.py @@ -23,7 +23,7 @@ "protocol": "kafka-secure", "protocolVersion": "auto", "security": [], - } + }, }, "channels": { "test_1:TestTopic": { @@ -31,8 +31,8 @@ "servers": [{"$ref": "#/servers/development"}], "messages": { "SubscribeMessage": { - "$ref": "#/components/messages/test_1:TestTopic:SubscribeMessage" - } + "$ref": "#/components/messages/test_1:TestTopic:SubscribeMessage", + }, }, "bindings": {"kafka": {"topic": "test_1", "bindingVersion": "0.4.0"}}, }, @@ -40,7 +40,7 @@ "address": "test_2:Publisher", "servers": [{"$ref": "#/servers/development"}], "messages": { - "Message": {"$ref": "#/components/messages/test_2:Publisher:Message"} + "Message": {"$ref": "#/components/messages/test_2:Publisher:Message"}, }, "bindings": {"kafka": {"topic": "test_2", "bindingVersion": "0.4.0"}}, }, @@ -49,7 +49,7 @@ "test_1:TestTopicSubscribe": { "action": "receive", "messages": [ - {"$ref": "#/channels/test_1:TestTopic/messages/SubscribeMessage"} + {"$ref": "#/channels/test_1:TestTopic/messages/SubscribeMessage"}, ], "channel": {"$ref": "#/channels/test_1:TestTopic"}, }, @@ -70,7 +70,7 @@ "title": "test_2:Publisher:Message", "correlationId": {"location": "$message.header#/correlation_id"}, "payload": { - "$ref": "#/components/schemas/test_2:Publisher:Message:Payload" + "$ref": "#/components/schemas/test_2:Publisher:Message:Payload", }, }, }, @@ -124,10 +124,10 @@ async def test_topic(msg: str) -> str: plaintext_security_schema = deepcopy(basic_schema) plaintext_security_schema["servers"]["development"]["security"] = [ - {"user-password": []} + {"user-password": []}, ] plaintext_security_schema["components"]["securitySchemes"] = { - "user-password": {"type": "userPassword"} + "user-password": {"type": "userPassword"}, } assert schema == plaintext_security_schema @@ -153,7 +153,7 @@ async def test_topic(msg: str) -> str: sasl256_security_schema = deepcopy(basic_schema) sasl256_security_schema["servers"]["development"]["security"] = [{"scram256": []}] sasl256_security_schema["components"]["securitySchemes"] = { - "scram256": {"type": "scramSha256"} + "scram256": {"type": "scramSha256"}, } assert schema == sasl256_security_schema @@ -179,7 +179,7 @@ async def test_topic(msg: str) -> str: sasl512_security_schema = deepcopy(basic_schema) sasl512_security_schema["servers"]["development"]["security"] = [{"scram512": []}] sasl512_security_schema["components"]["securitySchemes"] = { - "scram512": {"type": "scramSha512"} + "scram512": {"type": "scramSha512"}, } assert schema == sasl512_security_schema @@ -202,10 +202,10 @@ async def test_topic(msg: str) -> str: sasl_oauthbearer_security_schema = deepcopy(basic_schema) sasl_oauthbearer_security_schema["servers"]["development"]["security"] = [ - {"oauthbearer": []} + {"oauthbearer": []}, ] sasl_oauthbearer_security_schema["components"]["securitySchemes"] = { - "oauthbearer": {"type": "oauthBearer"} + "oauthbearer": {"type": "oauthBearer"}, } assert schema == sasl_oauthbearer_security_schema @@ -227,7 +227,7 @@ async def test_topic(msg: str) -> str: gssapi_security_schema = deepcopy(basic_schema) gssapi_security_schema["servers"]["development"]["security"] = [{"gssapi": []}] gssapi_security_schema["components"]["securitySchemes"] = { - "gssapi": {"type": "gssapi"} + "gssapi": {"type": "gssapi"}, } assert schema == gssapi_security_schema diff --git a/tests/asyncapi/kafka/v2_6_0/test_app.py b/tests/asyncapi/kafka/v2_6_0/test_app.py index 23aa904be8..0fba2e7f12 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_app.py +++ b/tests/asyncapi/kafka/v2_6_0/test_app.py @@ -20,7 +20,7 @@ def test_base(): "protocol": "kafka", "protocolVersion": "auto", "url": "localhost", - } + }, }, } @@ -49,7 +49,7 @@ def test_with_name(): "protocol": "kafka", "protocolVersion": "auto", "url": "localhost", - } + }, }, } @@ -91,7 +91,7 @@ def test_full(): "protocol": "kafka", "protocolVersion": "auto", "url": "localhost", - } + }, }, "tags": [{"description": "experimental", "name": "some-tag"}], } @@ -134,7 +134,7 @@ def test_full_dict(): "protocol": "kafka", "protocolVersion": "auto", "url": "localhost", - } + }, }, "tags": [{"description": "experimental", "name": "some-tag"}], } @@ -182,9 +182,9 @@ def test_extra(): "protocol": "kafka", "protocolVersion": "auto", "url": "localhost", - } + }, }, "tags": [ - {"description": "experimental", "name": "some-tag", "x-field": "extra"} + {"description": "experimental", "name": "some-tag", "x-field": "extra"}, ], } diff --git a/tests/asyncapi/kafka/v2_6_0/test_arguments.py b/tests/asyncapi/kafka/v2_6_0/test_arguments.py index 8ef7f6e63f..719aa73ceb 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_arguments.py +++ b/tests/asyncapi/kafka/v2_6_0/test_arguments.py @@ -16,5 +16,5 @@ async def handle(msg): ... key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { - "kafka": {"bindingVersion": "0.4.0", "topic": "test"} + "kafka": {"bindingVersion": "0.4.0", "topic": "test"}, } diff --git a/tests/asyncapi/kafka/v2_6_0/test_connection.py b/tests/asyncapi/kafka/v2_6_0/test_connection.py index 559ec4a200..4e6890c57c 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_connection.py +++ b/tests/asyncapi/kafka/v2_6_0/test_connection.py @@ -28,7 +28,7 @@ def test_base(): "protocolVersion": "0.9.0", "tags": [{"description": "experimental", "name": "some-tag"}], "url": "kafka:9092", - } + }, }, } diff --git a/tests/asyncapi/kafka/v2_6_0/test_fastapi.py b/tests/asyncapi/kafka/v2_6_0/test_fastapi.py index 719fb472df..28ac0a4a91 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/kafka/v2_6_0/test_fastapi.py @@ -37,5 +37,5 @@ def test_fastapi_security_schema(): "url": "localhost:9092", } assert schema["components"]["securitySchemes"] == { - "user-password": {"type": "userPassword"} + "user-password": {"type": "userPassword"}, } diff --git a/tests/asyncapi/kafka/v2_6_0/test_naming.py b/tests/asyncapi/kafka/v2_6_0/test_naming.py index 3108bb5c3e..6f04bb01d0 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_naming.py +++ b/tests/asyncapi/kafka/v2_6_0/test_naming.py @@ -23,26 +23,28 @@ async def handle(): ... "url": "localhost", "protocol": "kafka", "protocolVersion": "auto", - } + }, }, "channels": { "test:Handle": { "servers": ["development"], "bindings": {"kafka": {"topic": "test", "bindingVersion": "0.4.0"}}, "subscribe": { - "message": {"$ref": "#/components/messages/test:Handle:Message"} + "message": { + "$ref": "#/components/messages/test:Handle:Message" + }, }, - } + }, }, "components": { "messages": { "test:Handle:Message": { "title": "test:Handle:Message", "correlationId": { - "location": "$message.header#/correlation_id" + "location": "$message.header#/correlation_id", }, "payload": {"$ref": "#/components/schemas/EmptyPayload"}, - } + }, }, "schemas": {"EmptyPayload": {"title": "EmptyPayload", "type": "null"}}, }, diff --git a/tests/asyncapi/kafka/v2_6_0/test_publisher.py b/tests/asyncapi/kafka/v2_6_0/test_publisher.py index 65dcbcdb19..41ca253895 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_publisher.py +++ b/tests/asyncapi/kafka/v2_6_0/test_publisher.py @@ -16,5 +16,5 @@ async def handle(msg): ... key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { - "kafka": {"bindingVersion": "0.4.0", "topic": "test"} + "kafka": {"bindingVersion": "0.4.0", "topic": "test"}, } diff --git a/tests/asyncapi/kafka/v2_6_0/test_router.py b/tests/asyncapi/kafka/v2_6_0/test_router.py index 903726b6be..ad0c2bb421 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_router.py +++ b/tests/asyncapi/kafka/v2_6_0/test_router.py @@ -32,35 +32,35 @@ async def handle(msg): ... "url": "localhost", "protocol": "kafka", "protocolVersion": "auto", - } + }, }, "channels": { "test_test:Handle": { "servers": ["development"], "bindings": { - "kafka": {"topic": "test_test", "bindingVersion": "0.4.0"} + "kafka": {"topic": "test_test", "bindingVersion": "0.4.0"}, }, "subscribe": { "message": { - "$ref": "#/components/messages/test_test:Handle:Message" - } + "$ref": "#/components/messages/test_test:Handle:Message", + }, }, - } + }, }, "components": { "messages": { "test_test:Handle:Message": { "title": "test_test:Handle:Message", "correlationId": { - "location": "$message.header#/correlation_id" + "location": "$message.header#/correlation_id", }, "payload": { - "$ref": "#/components/schemas/Handle:Message:Payload" + "$ref": "#/components/schemas/Handle:Message:Payload", }, - } + }, }, "schemas": { - "Handle:Message:Payload": {"title": "Handle:Message:Payload"} + "Handle:Message:Payload": {"title": "Handle:Message:Payload"}, }, }, } diff --git a/tests/asyncapi/kafka/v2_6_0/test_security.py b/tests/asyncapi/kafka/v2_6_0/test_security.py index c7fc972395..7c87b9cb33 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_security.py +++ b/tests/asyncapi/kafka/v2_6_0/test_security.py @@ -19,13 +19,13 @@ "bindings": {"kafka": {"bindingVersion": "0.4.0", "topic": "test_1"}}, "servers": ["development"], "subscribe": { - "message": {"$ref": "#/components/messages/test_1:TestTopic:Message"} + "message": {"$ref": "#/components/messages/test_1:TestTopic:Message"}, }, }, "test_2:Publisher": { "bindings": {"kafka": {"bindingVersion": "0.4.0", "topic": "test_2"}}, "publish": { - "message": {"$ref": "#/components/messages/test_2:Publisher:Message"} + "message": {"$ref": "#/components/messages/test_2:Publisher:Message"}, }, "servers": ["development"], }, @@ -40,7 +40,7 @@ "test_2:Publisher:Message": { "correlationId": {"location": "$message.header#/correlation_id"}, "payload": { - "$ref": "#/components/schemas/test_2:Publisher:Message:Payload" + "$ref": "#/components/schemas/test_2:Publisher:Message:Payload", }, "title": "test_2:Publisher:Message", }, @@ -65,7 +65,7 @@ "protocolVersion": "auto", "security": [], "url": "localhost:9092", - } + }, }, } @@ -105,10 +105,10 @@ async def test_topic(msg: str) -> str: plaintext_security_schema = deepcopy(basic_schema) plaintext_security_schema["servers"]["development"]["security"] = [ - {"user-password": []} + {"user-password": []}, ] plaintext_security_schema["components"]["securitySchemes"] = { - "user-password": {"type": "userPassword"} + "user-password": {"type": "userPassword"}, } assert schema == plaintext_security_schema @@ -134,7 +134,7 @@ async def test_topic(msg: str) -> str: sasl256_security_schema = deepcopy(basic_schema) sasl256_security_schema["servers"]["development"]["security"] = [{"scram256": []}] sasl256_security_schema["components"]["securitySchemes"] = { - "scram256": {"type": "scramSha256"} + "scram256": {"type": "scramSha256"}, } assert schema == sasl256_security_schema @@ -160,7 +160,7 @@ async def test_topic(msg: str) -> str: sasl512_security_schema = deepcopy(basic_schema) sasl512_security_schema["servers"]["development"]["security"] = [{"scram512": []}] sasl512_security_schema["components"]["securitySchemes"] = { - "scram512": {"type": "scramSha512"} + "scram512": {"type": "scramSha512"}, } assert schema == sasl512_security_schema @@ -183,10 +183,10 @@ async def test_topic(msg: str) -> str: sasl_oauthbearer_security_schema = deepcopy(basic_schema) sasl_oauthbearer_security_schema["servers"]["development"]["security"] = [ - {"oauthbearer": []} + {"oauthbearer": []}, ] sasl_oauthbearer_security_schema["components"]["securitySchemes"] = { - "oauthbearer": {"type": "oauthBearer"} + "oauthbearer": {"type": "oauthBearer"}, } assert schema == sasl_oauthbearer_security_schema @@ -210,7 +210,7 @@ async def test_topic(msg: str) -> str: gssapi_security_schema = deepcopy(basic_schema) gssapi_security_schema["servers"]["development"]["security"] = [{"gssapi": []}] gssapi_security_schema["components"]["securitySchemes"] = { - "gssapi": {"type": "gssapi"} + "gssapi": {"type": "gssapi"}, } assert schema == gssapi_security_schema diff --git a/tests/asyncapi/kafka/v3_0_0/test_arguments.py b/tests/asyncapi/kafka/v3_0_0/test_arguments.py index 03d675fddb..2de9f3fe60 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_arguments.py +++ b/tests/asyncapi/kafka/v3_0_0/test_arguments.py @@ -16,5 +16,5 @@ async def handle(msg): ... key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { - "kafka": {"bindingVersion": "0.4.0", "topic": "test"} + "kafka": {"bindingVersion": "0.4.0", "topic": "test"}, } diff --git a/tests/asyncapi/kafka/v3_0_0/test_connection.py b/tests/asyncapi/kafka/v3_0_0/test_connection.py index a9dd5ba99e..4605cbfdc1 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_connection.py +++ b/tests/asyncapi/kafka/v3_0_0/test_connection.py @@ -30,7 +30,7 @@ def test_base(): "tags": [{"description": "experimental", "name": "some-tag"}], "host": "kafka:9092", "pathname": "", - } + }, }, } diff --git a/tests/asyncapi/kafka/v3_0_0/test_fastapi.py b/tests/asyncapi/kafka/v3_0_0/test_fastapi.py index 86c9cbc8ed..a61c443297 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/kafka/v3_0_0/test_fastapi.py @@ -38,5 +38,5 @@ def test_fastapi_security_schema(): "pathname": "", } assert schema["components"]["securitySchemes"] == { - "user-password": {"type": "userPassword"} + "user-password": {"type": "userPassword"}, } diff --git a/tests/asyncapi/kafka/v3_0_0/test_naming.py b/tests/asyncapi/kafka/v3_0_0/test_naming.py index bba306fcbe..91ca65f6bc 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_naming.py +++ b/tests/asyncapi/kafka/v3_0_0/test_naming.py @@ -24,7 +24,7 @@ async def handle(): ... "pathname": "", "protocol": "kafka", "protocolVersion": "auto", - } + }, }, "channels": { "test:Handle": { @@ -32,7 +32,7 @@ async def handle(): ... "servers": [ { "$ref": "#/servers/development", - } + }, ], "bindings": {"kafka": {"topic": "test", "bindingVersion": "0.4.0"}}, "messages": { @@ -40,7 +40,7 @@ async def handle(): ... "$ref": "#/components/messages/test:Handle:SubscribeMessage", }, }, - } + }, }, "operations": { "test:HandleSubscribe": { @@ -51,19 +51,19 @@ async def handle(): ... "messages": [ { "$ref": "#/channels/test:Handle/messages/SubscribeMessage", - } + }, ], - } + }, }, "components": { "messages": { "test:Handle:SubscribeMessage": { "title": "test:Handle:SubscribeMessage", "correlationId": { - "location": "$message.header#/correlation_id" + "location": "$message.header#/correlation_id", }, "payload": {"$ref": "#/components/schemas/EmptyPayload"}, - } + }, }, "schemas": {"EmptyPayload": {"title": "EmptyPayload", "type": "null"}}, }, diff --git a/tests/asyncapi/kafka/v3_0_0/test_publisher.py b/tests/asyncapi/kafka/v3_0_0/test_publisher.py index c4db9d558e..e50919d54c 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_publisher.py +++ b/tests/asyncapi/kafka/v3_0_0/test_publisher.py @@ -16,5 +16,5 @@ async def handle(msg): ... key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { - "kafka": {"bindingVersion": "0.4.0", "topic": "test"} + "kafka": {"bindingVersion": "0.4.0", "topic": "test"}, } diff --git a/tests/asyncapi/kafka/v3_0_0/test_router.py b/tests/asyncapi/kafka/v3_0_0/test_router.py index ee92b456fc..67560d5675 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_router.py +++ b/tests/asyncapi/kafka/v3_0_0/test_router.py @@ -33,7 +33,7 @@ async def handle(msg): ... "pathname": "", "protocol": "kafka", "protocolVersion": "auto", - } + }, }, "channels": { "test_test:Handle": { @@ -41,39 +41,39 @@ async def handle(msg): ... "servers": [{"$ref": "#/servers/development"}], "messages": { "SubscribeMessage": { - "$ref": "#/components/messages/test_test:Handle:SubscribeMessage" - } + "$ref": "#/components/messages/test_test:Handle:SubscribeMessage", + }, }, "bindings": { - "kafka": {"topic": "test_test", "bindingVersion": "0.4.0"} + "kafka": {"topic": "test_test", "bindingVersion": "0.4.0"}, }, - } + }, }, "operations": { "test_test:HandleSubscribe": { "action": "receive", "messages": [ { - "$ref": "#/channels/test_test:Handle/messages/SubscribeMessage" - } + "$ref": "#/channels/test_test:Handle/messages/SubscribeMessage", + }, ], "channel": {"$ref": "#/channels/test_test:Handle"}, - } + }, }, "components": { "messages": { "test_test:Handle:SubscribeMessage": { "title": "test_test:Handle:SubscribeMessage", "correlationId": { - "location": "$message.header#/correlation_id" + "location": "$message.header#/correlation_id", }, "payload": { - "$ref": "#/components/schemas/Handle:Message:Payload" + "$ref": "#/components/schemas/Handle:Message:Payload", }, - } + }, }, "schemas": { - "Handle:Message:Payload": {"title": "Handle:Message:Payload"} + "Handle:Message:Payload": {"title": "Handle:Message:Payload"}, }, }, } diff --git a/tests/asyncapi/kafka/v3_0_0/test_security.py b/tests/asyncapi/kafka/v3_0_0/test_security.py index 4a752552e8..046ab737f5 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_security.py +++ b/tests/asyncapi/kafka/v3_0_0/test_security.py @@ -23,7 +23,7 @@ "protocol": "kafka-secure", "protocolVersion": "auto", "security": [], - } + }, }, "channels": { "test_1:TestTopic": { @@ -31,8 +31,8 @@ "servers": [{"$ref": "#/servers/development"}], "messages": { "SubscribeMessage": { - "$ref": "#/components/messages/test_1:TestTopic:SubscribeMessage" - } + "$ref": "#/components/messages/test_1:TestTopic:SubscribeMessage", + }, }, "bindings": {"kafka": {"topic": "test_1", "bindingVersion": "0.4.0"}}, }, @@ -40,7 +40,7 @@ "address": "test_2:Publisher", "servers": [{"$ref": "#/servers/development"}], "messages": { - "Message": {"$ref": "#/components/messages/test_2:Publisher:Message"} + "Message": {"$ref": "#/components/messages/test_2:Publisher:Message"}, }, "bindings": {"kafka": {"topic": "test_2", "bindingVersion": "0.4.0"}}, }, @@ -49,7 +49,7 @@ "test_1:TestTopicSubscribe": { "action": "receive", "messages": [ - {"$ref": "#/channels/test_1:TestTopic/messages/SubscribeMessage"} + {"$ref": "#/channels/test_1:TestTopic/messages/SubscribeMessage"}, ], "channel": {"$ref": "#/channels/test_1:TestTopic"}, }, @@ -70,7 +70,7 @@ "title": "test_2:Publisher:Message", "correlationId": {"location": "$message.header#/correlation_id"}, "payload": { - "$ref": "#/components/schemas/test_2:Publisher:Message:Payload" + "$ref": "#/components/schemas/test_2:Publisher:Message:Payload", }, }, }, @@ -124,10 +124,10 @@ async def test_topic(msg: str) -> str: plaintext_security_schema = deepcopy(basic_schema) plaintext_security_schema["servers"]["development"]["security"] = [ - {"user-password": []} + {"user-password": []}, ] plaintext_security_schema["components"]["securitySchemes"] = { - "user-password": {"type": "userPassword"} + "user-password": {"type": "userPassword"}, } assert schema == plaintext_security_schema @@ -153,7 +153,7 @@ async def test_topic(msg: str) -> str: sasl256_security_schema = deepcopy(basic_schema) sasl256_security_schema["servers"]["development"]["security"] = [{"scram256": []}] sasl256_security_schema["components"]["securitySchemes"] = { - "scram256": {"type": "scramSha256"} + "scram256": {"type": "scramSha256"}, } assert schema == sasl256_security_schema @@ -179,7 +179,7 @@ async def test_topic(msg: str) -> str: sasl512_security_schema = deepcopy(basic_schema) sasl512_security_schema["servers"]["development"]["security"] = [{"scram512": []}] sasl512_security_schema["components"]["securitySchemes"] = { - "scram512": {"type": "scramSha512"} + "scram512": {"type": "scramSha512"}, } assert schema == sasl512_security_schema @@ -202,10 +202,10 @@ async def test_topic(msg: str) -> str: sasl_oauthbearer_security_schema = deepcopy(basic_schema) sasl_oauthbearer_security_schema["servers"]["development"]["security"] = [ - {"oauthbearer": []} + {"oauthbearer": []}, ] sasl_oauthbearer_security_schema["components"]["securitySchemes"] = { - "oauthbearer": {"type": "oauthBearer"} + "oauthbearer": {"type": "oauthBearer"}, } assert schema == sasl_oauthbearer_security_schema @@ -229,7 +229,7 @@ async def test_topic(msg: str) -> str: gssapi_security_schema = deepcopy(basic_schema) gssapi_security_schema["servers"]["development"]["security"] = [{"gssapi": []}] gssapi_security_schema["components"]["securitySchemes"] = { - "gssapi": {"type": "gssapi"} + "gssapi": {"type": "gssapi"}, } assert schema == gssapi_security_schema diff --git a/tests/asyncapi/nats/v2_6_0/test_arguments.py b/tests/asyncapi/nats/v2_6_0/test_arguments.py index 70f92e2702..6517507af1 100644 --- a/tests/asyncapi/nats/v2_6_0/test_arguments.py +++ b/tests/asyncapi/nats/v2_6_0/test_arguments.py @@ -16,5 +16,5 @@ async def handle(msg): ... key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { - "nats": {"bindingVersion": "custom", "subject": "test"} + "nats": {"bindingVersion": "custom", "subject": "test"}, } diff --git a/tests/asyncapi/nats/v2_6_0/test_connection.py b/tests/asyncapi/nats/v2_6_0/test_connection.py index a53367112f..93c194cbd9 100644 --- a/tests/asyncapi/nats/v2_6_0/test_connection.py +++ b/tests/asyncapi/nats/v2_6_0/test_connection.py @@ -28,7 +28,7 @@ def test_base(): "protocolVersion": "0.9.0", "tags": [{"description": "experimental", "name": "some-tag"}], "url": "nats:9092", - } + }, }, }, schema @@ -63,7 +63,8 @@ def test_multi(): def test_custom(): schema = AsyncAPI( NatsBroker( - ["nats:9092", "nats:9093"], specification_url=["nats:9094", "nats:9095"] + ["nats:9092", "nats:9093"], + specification_url=["nats:9094", "nats:9095"], ), schema_version="2.6.0", ).to_jsonable() diff --git a/tests/asyncapi/nats/v2_6_0/test_naming.py b/tests/asyncapi/nats/v2_6_0/test_naming.py index 4f998b7633..9999446fe9 100644 --- a/tests/asyncapi/nats/v2_6_0/test_naming.py +++ b/tests/asyncapi/nats/v2_6_0/test_naming.py @@ -23,28 +23,30 @@ async def handle(): ... "url": "nats://localhost:4222", "protocol": "nats", "protocolVersion": "custom", - } + }, }, "channels": { "test:Handle": { "servers": ["development"], "bindings": { - "nats": {"subject": "test", "bindingVersion": "custom"} + "nats": {"subject": "test", "bindingVersion": "custom"}, }, "subscribe": { - "message": {"$ref": "#/components/messages/test:Handle:Message"} + "message": { + "$ref": "#/components/messages/test:Handle:Message" + }, }, - } + }, }, "components": { "messages": { "test:Handle:Message": { "title": "test:Handle:Message", "correlationId": { - "location": "$message.header#/correlation_id" + "location": "$message.header#/correlation_id", }, "payload": {"$ref": "#/components/schemas/EmptyPayload"}, - } + }, }, "schemas": {"EmptyPayload": {"title": "EmptyPayload", "type": "null"}}, }, diff --git a/tests/asyncapi/nats/v2_6_0/test_publisher.py b/tests/asyncapi/nats/v2_6_0/test_publisher.py index 2d859f242f..c414603f9c 100644 --- a/tests/asyncapi/nats/v2_6_0/test_publisher.py +++ b/tests/asyncapi/nats/v2_6_0/test_publisher.py @@ -16,5 +16,5 @@ async def handle(msg): ... key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { - "nats": {"bindingVersion": "custom", "subject": "test"} + "nats": {"bindingVersion": "custom", "subject": "test"}, }, schema["channels"][key]["bindings"] diff --git a/tests/asyncapi/nats/v2_6_0/test_router.py b/tests/asyncapi/nats/v2_6_0/test_router.py index 73d8d60e4b..594a79a2ce 100644 --- a/tests/asyncapi/nats/v2_6_0/test_router.py +++ b/tests/asyncapi/nats/v2_6_0/test_router.py @@ -32,35 +32,35 @@ async def handle(msg): ... "url": "nats://localhost:4222", "protocol": "nats", "protocolVersion": "custom", - } + }, }, "channels": { "test_test:Handle": { "servers": ["development"], "bindings": { - "nats": {"subject": "test_test", "bindingVersion": "custom"} + "nats": {"subject": "test_test", "bindingVersion": "custom"}, }, "subscribe": { "message": { - "$ref": "#/components/messages/test_test:Handle:Message" - } + "$ref": "#/components/messages/test_test:Handle:Message", + }, }, - } + }, }, "components": { "messages": { "test_test:Handle:Message": { "title": "test_test:Handle:Message", "correlationId": { - "location": "$message.header#/correlation_id" + "location": "$message.header#/correlation_id", }, "payload": { - "$ref": "#/components/schemas/Handle:Message:Payload" + "$ref": "#/components/schemas/Handle:Message:Payload", }, - } + }, }, "schemas": { - "Handle:Message:Payload": {"title": "Handle:Message:Payload"} + "Handle:Message:Payload": {"title": "Handle:Message:Payload"}, }, }, } diff --git a/tests/asyncapi/nats/v3_0_0/test_arguments.py b/tests/asyncapi/nats/v3_0_0/test_arguments.py index bda50e73ea..31897a0e15 100644 --- a/tests/asyncapi/nats/v3_0_0/test_arguments.py +++ b/tests/asyncapi/nats/v3_0_0/test_arguments.py @@ -16,5 +16,5 @@ async def handle(msg): ... key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { - "nats": {"bindingVersion": "custom", "subject": "test"} + "nats": {"bindingVersion": "custom", "subject": "test"}, } diff --git a/tests/asyncapi/nats/v3_0_0/test_connection.py b/tests/asyncapi/nats/v3_0_0/test_connection.py index 6d825f9513..b15bd1497c 100644 --- a/tests/asyncapi/nats/v3_0_0/test_connection.py +++ b/tests/asyncapi/nats/v3_0_0/test_connection.py @@ -30,7 +30,7 @@ def test_base(): "tags": [{"description": "experimental", "name": "some-tag"}], "host": "nats:9092", "pathname": "", - } + }, }, }, schema diff --git a/tests/asyncapi/nats/v3_0_0/test_naming.py b/tests/asyncapi/nats/v3_0_0/test_naming.py index 0f3fda4a2a..f318c699e9 100644 --- a/tests/asyncapi/nats/v3_0_0/test_naming.py +++ b/tests/asyncapi/nats/v3_0_0/test_naming.py @@ -24,7 +24,7 @@ async def handle(): ... "pathname": "", "protocol": "nats", "protocolVersion": "custom", - } + }, }, "channels": { "test:Handle": { @@ -32,17 +32,17 @@ async def handle(): ... "servers": [ { "$ref": "#/servers/development", - } + }, ], "bindings": { - "nats": {"subject": "test", "bindingVersion": "custom"} + "nats": {"subject": "test", "bindingVersion": "custom"}, }, "messages": { "SubscribeMessage": { "$ref": "#/components/messages/test:Handle:SubscribeMessage", }, }, - } + }, }, "operations": { "test:HandleSubscribe": { @@ -53,19 +53,19 @@ async def handle(): ... "messages": [ { "$ref": "#/channels/test:Handle/messages/SubscribeMessage", - } + }, ], - } + }, }, "components": { "messages": { "test:Handle:SubscribeMessage": { "title": "test:Handle:SubscribeMessage", "correlationId": { - "location": "$message.header#/correlation_id" + "location": "$message.header#/correlation_id", }, "payload": {"$ref": "#/components/schemas/EmptyPayload"}, - } + }, }, "schemas": {"EmptyPayload": {"title": "EmptyPayload", "type": "null"}}, }, diff --git a/tests/asyncapi/nats/v3_0_0/test_publisher.py b/tests/asyncapi/nats/v3_0_0/test_publisher.py index 99f14470ff..ea8b14291d 100644 --- a/tests/asyncapi/nats/v3_0_0/test_publisher.py +++ b/tests/asyncapi/nats/v3_0_0/test_publisher.py @@ -16,5 +16,5 @@ async def handle(msg): ... key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { - "nats": {"bindingVersion": "custom", "subject": "test"} + "nats": {"bindingVersion": "custom", "subject": "test"}, }, schema["channels"][key]["bindings"] diff --git a/tests/asyncapi/nats/v3_0_0/test_router.py b/tests/asyncapi/nats/v3_0_0/test_router.py index 697692d947..69e369b3d7 100644 --- a/tests/asyncapi/nats/v3_0_0/test_router.py +++ b/tests/asyncapi/nats/v3_0_0/test_router.py @@ -33,7 +33,7 @@ async def handle(msg): ... "pathname": "", "protocol": "nats", "protocolVersion": "custom", - } + }, }, "channels": { "test_test:Handle": { @@ -41,39 +41,39 @@ async def handle(msg): ... "servers": [{"$ref": "#/servers/development"}], "messages": { "SubscribeMessage": { - "$ref": "#/components/messages/test_test:Handle:SubscribeMessage" - } + "$ref": "#/components/messages/test_test:Handle:SubscribeMessage", + }, }, "bindings": { - "nats": {"subject": "test_test", "bindingVersion": "custom"} + "nats": {"subject": "test_test", "bindingVersion": "custom"}, }, - } + }, }, "operations": { "test_test:HandleSubscribe": { "action": "receive", "messages": [ { - "$ref": "#/channels/test_test:Handle/messages/SubscribeMessage" - } + "$ref": "#/channels/test_test:Handle/messages/SubscribeMessage", + }, ], "channel": {"$ref": "#/channels/test_test:Handle"}, - } + }, }, "components": { "messages": { "test_test:Handle:SubscribeMessage": { "title": "test_test:Handle:SubscribeMessage", "correlationId": { - "location": "$message.header#/correlation_id" + "location": "$message.header#/correlation_id", }, "payload": { - "$ref": "#/components/schemas/Handle:Message:Payload" + "$ref": "#/components/schemas/Handle:Message:Payload", }, - } + }, }, "schemas": { - "Handle:Message:Payload": {"title": "Handle:Message:Payload"} + "Handle:Message:Payload": {"title": "Handle:Message:Payload"}, }, }, } diff --git a/tests/asyncapi/rabbit/v2_6_0/test_arguments.py b/tests/asyncapi/rabbit/v2_6_0/test_arguments.py index 7f1782e5f4..56cce5e711 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_arguments.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_arguments.py @@ -36,7 +36,7 @@ async def handle(msg): ... "name": "test", "vhost": "/", }, - } + }, } def test_subscriber_fanout_bindings(self): @@ -62,7 +62,7 @@ async def handle(msg): ... "vhost": "/", }, "is": "routingKey", - } + }, } def test_subscriber_headers_bindings(self): @@ -88,7 +88,7 @@ async def handle(msg): ... "vhost": "/", }, "is": "routingKey", - } + }, } def test_subscriber_xdelay_bindings(self): @@ -114,7 +114,7 @@ async def handle(msg): ... "vhost": "/", }, "is": "routingKey", - } + }, } def test_subscriber_consistent_hash_bindings(self): @@ -140,7 +140,7 @@ async def handle(msg): ... "vhost": "/", }, "is": "routingKey", - } + }, } def test_subscriber_modules_hash_bindings(self): @@ -166,5 +166,5 @@ async def handle(msg): ... "vhost": "/", }, "is": "routingKey", - } + }, } diff --git a/tests/asyncapi/rabbit/v2_6_0/test_connection.py b/tests/asyncapi/rabbit/v2_6_0/test_connection.py index 2682bc6b77..9761e16df0 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_connection.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_connection.py @@ -28,7 +28,7 @@ def test_base(): "protocolVersion": "0.9.0", "tags": [{"description": "experimental", "name": "some-tag"}], "url": "amqps://guest:guest@localhost:5673/", # pragma: allowlist secret - } + }, }, } @@ -72,7 +72,7 @@ def test_custom(): "name": "test", "vhost": "/vh", }, - } + }, }, "publish": { "bindings": { @@ -82,26 +82,26 @@ def test_custom(): "cc": "test", "deliveryMode": 1, "mandatory": True, - } + }, }, "message": { - "$ref": "#/components/messages/test:_:Publisher:Message" + "$ref": "#/components/messages/test:_:Publisher:Message", }, }, "servers": ["development"], - } + }, }, "components": { "messages": { "test:_:Publisher:Message": { "correlationId": { - "location": "$message.header#/correlation_id" + "location": "$message.header#/correlation_id", }, "payload": { - "$ref": "#/components/schemas/test:_:PublisherPayload" + "$ref": "#/components/schemas/test:_:PublisherPayload", }, "title": "test:_:Publisher:Message", - } + }, }, "schemas": {"test:_:PublisherPayload": {}}, }, @@ -112,7 +112,7 @@ def test_custom(): "protocol": "amqp", "protocolVersion": "0.9.1", "url": "amqp://guest:guest@127.0.0.1:5672/vh", # pragma: allowlist secret - } + }, }, } ) diff --git a/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py b/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py index 69465e5b82..111542319c 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_fastapi.py @@ -37,5 +37,5 @@ def test_fastapi_security_schema(): "url": "amqp://user:pass@localhost:5672/", # pragma: allowlist secret } assert schema["components"]["securitySchemes"] == { - "user-password": {"type": "userPassword"} + "user-password": {"type": "userPassword"}, } diff --git a/tests/asyncapi/rabbit/v2_6_0/test_naming.py b/tests/asyncapi/rabbit/v2_6_0/test_naming.py index 4625ddae09..3c0efd008e 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_naming.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_naming.py @@ -19,7 +19,7 @@ async def handle(): ... assert list(schema["channels"].keys()) == ["test:exchange:Handle"] assert list(schema["components"]["messages"].keys()) == [ - "test:exchange:Handle:Message" + "test:exchange:Handle:Message", ] def test_publisher_with_exchange(self): @@ -33,7 +33,7 @@ async def handle(): ... assert list(schema["channels"].keys()) == ["test:exchange:Publisher"] assert list(schema["components"]["messages"].keys()) == [ - "test:exchange:Publisher:Message" + "test:exchange:Publisher:Message", ] def test_base(self): @@ -55,7 +55,7 @@ async def handle(): ... "url": "amqp://guest:guest@localhost:5672/", # pragma: allowlist secret "protocol": "amqp", "protocolVersion": "0.9.1", - } + }, }, "channels": { "test:_:Handle": { @@ -72,7 +72,7 @@ async def handle(): ... "vhost": "/", }, "exchange": {"type": "default", "vhost": "/"}, - } + }, }, "subscribe": { "bindings": { @@ -80,26 +80,26 @@ async def handle(): ... "cc": "test", "ack": True, "bindingVersion": "0.2.0", - } + }, }, "message": { - "$ref": "#/components/messages/test:_:Handle:Message" + "$ref": "#/components/messages/test:_:Handle:Message", }, }, - } + }, }, "components": { "messages": { "test:_:Handle:Message": { "title": "test:_:Handle:Message", "correlationId": { - "location": "$message.header#/correlation_id" + "location": "$message.header#/correlation_id", }, "payload": {"$ref": "#/components/schemas/EmptyPayload"}, - } + }, }, "schemas": { - "EmptyPayload": {"title": "EmptyPayload", "type": "null"} + "EmptyPayload": {"title": "EmptyPayload", "type": "null"}, }, }, } diff --git a/tests/asyncapi/rabbit/v2_6_0/test_publisher.py b/tests/asyncapi/rabbit/v2_6_0/test_publisher.py index 87b8d5d13a..b9f6fbfe90 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_publisher.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_publisher.py @@ -27,7 +27,7 @@ async def handle(msg): ... "vhost": "/vhost", }, "is": "routingKey", - } + }, }, "publish": { "bindings": { @@ -36,14 +36,14 @@ async def handle(msg): ... "bindingVersion": "0.2.0", "deliveryMode": 1, "mandatory": True, - } + }, }, "message": { - "$ref": "#/components/messages/_:test-ex:Publisher:Message" + "$ref": "#/components/messages/_:test-ex:Publisher:Message", }, }, "servers": ["development"], - } + }, }, schema["channels"] def test_publisher_bindings(self): @@ -76,7 +76,7 @@ async def handle(msg): ... "name": "test", "vhost": "/", }, - } + }, } def test_useless_queue_bindings(self): @@ -103,15 +103,15 @@ async def handle(msg): ... "vhost": "/", }, "is": "routingKey", - } + }, }, "publish": { "message": { - "$ref": "#/components/messages/_:test-ex:Publisher:Message" - } + "$ref": "#/components/messages/_:test-ex:Publisher:Message", + }, }, "servers": ["development"], - } + }, } def test_reusable_exchange(self): @@ -136,7 +136,7 @@ async def handle(msg): ... "vhost": "/vhost", }, "is": "routingKey", - } + }, }, "publish": { "bindings": { @@ -146,10 +146,10 @@ async def handle(msg): ... "cc": "key1", "deliveryMode": 1, "mandatory": True, - } + }, }, "message": { - "$ref": "#/components/messages/key1:test-ex:Publisher:Message" + "$ref": "#/components/messages/key1:test-ex:Publisher:Message", }, }, "servers": ["development"], @@ -166,7 +166,7 @@ async def handle(msg): ... "vhost": "/vhost", }, "is": "routingKey", - } + }, }, "publish": { "bindings": { @@ -177,10 +177,10 @@ async def handle(msg): ... "deliveryMode": 1, "priority": 10, "mandatory": True, - } + }, }, "message": { - "$ref": "#/components/messages/key2:test-ex:Publisher:Message" + "$ref": "#/components/messages/key2:test-ex:Publisher:Message", }, }, "servers": ["development"], diff --git a/tests/asyncapi/rabbit/v2_6_0/test_router.py b/tests/asyncapi/rabbit/v2_6_0/test_router.py index 9ed97f1c4b..c7eaf52d3b 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_router.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_router.py @@ -40,7 +40,7 @@ async def handle(msg): ... "url": "amqp://guest:guest@localhost:5672/", # pragma: allowlist secret "protocol": "amqp", "protocolVersion": "0.9.1", - } + }, }, "channels": { "test_test:_:Handle": { @@ -57,7 +57,7 @@ async def handle(msg): ... "vhost": "/", }, "exchange": {"type": "default", "vhost": "/"}, - } + }, }, "subscribe": { "bindings": { @@ -65,28 +65,28 @@ async def handle(msg): ... "cc": "test_key", "ack": True, "bindingVersion": "0.2.0", - } + }, }, "message": { - "$ref": "#/components/messages/test_test:_:Handle:Message" + "$ref": "#/components/messages/test_test:_:Handle:Message", }, }, - } + }, }, "components": { "messages": { "test_test:_:Handle:Message": { "title": "test_test:_:Handle:Message", "correlationId": { - "location": "$message.header#/correlation_id" + "location": "$message.header#/correlation_id", }, "payload": { - "$ref": "#/components/schemas/Handle:Message:Payload" + "$ref": "#/components/schemas/Handle:Message:Payload", }, - } + }, }, "schemas": { - "Handle:Message:Payload": {"title": "Handle:Message:Payload"} + "Handle:Message:Payload": {"title": "Handle:Message:Payload"}, }, }, } diff --git a/tests/asyncapi/rabbit/v2_6_0/test_security.py b/tests/asyncapi/rabbit/v2_6_0/test_security.py index a23ad59cad..688932ea20 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_security.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_security.py @@ -33,7 +33,7 @@ def test_base_security_schema(): "protocolVersion": "0.9.1", "security": [], "url": "amqps://guest:guest@localhost:5672/", # pragma: allowlist secret - } + }, }, } @@ -74,7 +74,7 @@ def test_plaintext_security_schema(): "protocolVersion": "0.9.1", "security": [{"user-password": []}], "url": "amqps://admin:password@localhost:5671/", # pragma: allowlist secret - } + }, }, } ) @@ -112,7 +112,7 @@ def test_plaintext_security_schema_without_ssl(): "protocolVersion": "0.9.1", "security": [{"user-password": []}], "url": "amqp://admin:password@localhost:5672/", # pragma: allowlist secret - } + }, }, } ) diff --git a/tests/asyncapi/rabbit/v3_0_0/test_arguments.py b/tests/asyncapi/rabbit/v3_0_0/test_arguments.py index 1dea5c8635..cb61be36ce 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_arguments.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_arguments.py @@ -36,7 +36,7 @@ async def handle(msg): ... "name": "test", "vhost": "/", }, - } + }, } def test_subscriber_fanout_bindings(self): @@ -62,5 +62,5 @@ async def handle(msg): ... "vhost": "/", }, "is": "routingKey", - } + }, } diff --git a/tests/asyncapi/rabbit/v3_0_0/test_connection.py b/tests/asyncapi/rabbit/v3_0_0/test_connection.py index 1b4b9e0431..85259fb162 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_connection.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_connection.py @@ -30,7 +30,7 @@ def test_base(): "tags": [{"description": "experimental", "name": "some-tag"}], "host": "guest:guest@localhost:5673", # pragma: allowlist secret "pathname": "/", - } + }, }, } @@ -73,19 +73,19 @@ def test_custom(): "name": "test", "vhost": "/vh", }, - } + }, }, "servers": [ { "$ref": "#/servers/development", - } + }, ], "messages": { "Message": { "$ref": "#/components/messages/test:_:Publisher:Message", }, }, - } + }, }, "operations": { "test:_:Publisher": { @@ -116,10 +116,10 @@ def test_custom(): "test:_:Publisher:Message": { "correlationId": {"location": "$message.header#/correlation_id"}, "payload": { - "$ref": "#/components/schemas/test:_:Publisher:Message:Payload" + "$ref": "#/components/schemas/test:_:Publisher:Message:Payload", }, "title": "test:_:Publisher:Message", - } + }, }, "schemas": {"test:_:Publisher:Message:Payload": {}}, }, @@ -131,6 +131,6 @@ def test_custom(): "protocolVersion": "0.9.1", "host": "guest:guest@127.0.0.1:5672", # pragma: allowlist secret "pathname": "/vh", # pragma: allowlist secret - } + }, }, } diff --git a/tests/asyncapi/rabbit/v3_0_0/test_fastapi.py b/tests/asyncapi/rabbit/v3_0_0/test_fastapi.py index 0e6d707218..cd2b2407b5 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_fastapi.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_fastapi.py @@ -38,5 +38,5 @@ def test_fastapi_security_schema(): "pathname": "/", } assert schema["components"]["securitySchemes"] == { - "user-password": {"type": "userPassword"} + "user-password": {"type": "userPassword"}, } diff --git a/tests/asyncapi/rabbit/v3_0_0/test_naming.py b/tests/asyncapi/rabbit/v3_0_0/test_naming.py index ebdf2004aa..444fe1a12a 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_naming.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_naming.py @@ -22,7 +22,7 @@ async def handle(): ... assert list(schema["channels"].keys()) == ["test:exchange:Handle"] assert list(schema["components"]["messages"].keys()) == [ - "test:exchange:Handle:SubscribeMessage" + "test:exchange:Handle:SubscribeMessage", ] def test_publisher_with_exchange(self): @@ -39,7 +39,7 @@ async def handle(): ... assert list(schema["channels"].keys()) == ["test:exchange:Publisher"] assert list(schema["components"]["messages"].keys()) == [ - "test:exchange:Publisher:Message" + "test:exchange:Publisher:Message", ] def test_base(self): @@ -63,7 +63,7 @@ async def handle(): ... "pathname": "/", "protocol": "amqp", "protocolVersion": "0.9.1", - } + }, }, "channels": { "test:_:Handle": { @@ -71,7 +71,7 @@ async def handle(): ... "servers": [ { "$ref": "#/servers/development", - } + }, ], "bindings": { "amqp": { @@ -85,14 +85,14 @@ async def handle(): ... "vhost": "/", }, "exchange": {"type": "default", "vhost": "/"}, - } + }, }, "messages": { "SubscribeMessage": { - "$ref": "#/components/messages/test:_:Handle:SubscribeMessage" - } + "$ref": "#/components/messages/test:_:Handle:SubscribeMessage", + }, }, - } + }, }, "operations": { "test:_:HandleSubscribe": { @@ -121,10 +121,10 @@ async def handle(): ... "test:_:Handle:SubscribeMessage": { "title": "test:_:Handle:SubscribeMessage", "correlationId": { - "location": "$message.header#/correlation_id" + "location": "$message.header#/correlation_id", }, "payload": {"$ref": "#/components/schemas/EmptyPayload"}, - } + }, }, "schemas": {"EmptyPayload": {"title": "EmptyPayload", "type": "null"}}, }, diff --git a/tests/asyncapi/rabbit/v3_0_0/test_publisher.py b/tests/asyncapi/rabbit/v3_0_0/test_publisher.py index 1aebc660c6..5e43d45f33 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_publisher.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_publisher.py @@ -28,19 +28,19 @@ async def handle(msg): ... "vhost": "/vhost", }, "is": "routingKey", - } + }, }, "servers": [ { "$ref": "#/servers/development", - } + }, ], "messages": { "Message": { "$ref": "#/components/messages/_:test-ex:Publisher:Message", }, }, - } + }, }, schema["channels"] assert schema["operations"] == { @@ -52,7 +52,7 @@ async def handle(msg): ... "bindingVersion": "0.3.0", "deliveryMode": 1, "mandatory": True, - } + }, }, "channel": { "$ref": "#/channels/_:test-ex:Publisher", @@ -95,7 +95,7 @@ async def handle(msg): ... "name": "test", "vhost": "/", }, - } + }, } def test_useless_queue_bindings(self): @@ -123,19 +123,19 @@ async def handle(msg): ... "vhost": "/", }, "is": "routingKey", - } + }, }, "messages": { "Message": { - "$ref": "#/components/messages/_:test-ex:Publisher:Message" - } + "$ref": "#/components/messages/_:test-ex:Publisher:Message", + }, }, "servers": [ { "$ref": "#/servers/development", - } + }, ], - } + }, } assert schema["operations"] == { @@ -145,9 +145,9 @@ async def handle(msg): ... "$ref": "#/channels/_:test-ex:Publisher", }, "messages": [ - {"$ref": "#/channels/_:test-ex:Publisher/messages/Message"} + {"$ref": "#/channels/_:test-ex:Publisher/messages/Message"}, ], - } + }, } def test_reusable_exchange(self): @@ -173,12 +173,12 @@ async def handle(msg): ... "vhost": "/vhost", }, "is": "routingKey", - } + }, }, "servers": [ { "$ref": "#/servers/development", - } + }, ], "messages": { "Message": { @@ -199,12 +199,12 @@ async def handle(msg): ... "vhost": "/vhost", }, "is": "routingKey", - } + }, }, "servers": [ { "$ref": "#/servers/development", - } + }, ], "messages": { "Message": { @@ -229,10 +229,10 @@ async def handle(msg): ... ], "deliveryMode": 1, "mandatory": True, - } + }, }, "messages": [ - {"$ref": "#/channels/key1:test-ex:Publisher/messages/Message"} + {"$ref": "#/channels/key1:test-ex:Publisher/messages/Message"}, ], }, "key2:test-ex:Publisher": { @@ -250,10 +250,10 @@ async def handle(msg): ... "deliveryMode": 1, "priority": 10, "mandatory": True, - } + }, }, "messages": [ - {"$ref": "#/channels/key2:test-ex:Publisher/messages/Message"} + {"$ref": "#/channels/key2:test-ex:Publisher/messages/Message"}, ], }, } diff --git a/tests/asyncapi/rabbit/v3_0_0/test_router.py b/tests/asyncapi/rabbit/v3_0_0/test_router.py index d0848a2d25..684e07953a 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_router.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_router.py @@ -42,7 +42,7 @@ async def handle(msg): ... "pathname": "/", "protocol": "amqp", "protocolVersion": "0.9.1", - } + }, }, "channels": { "test_test:_:Handle": { @@ -50,8 +50,8 @@ async def handle(msg): ... "servers": [{"$ref": "#/servers/development"}], "messages": { "SubscribeMessage": { - "$ref": "#/components/messages/test_test:_:Handle:SubscribeMessage" - } + "$ref": "#/components/messages/test_test:_:Handle:SubscribeMessage", + }, }, "bindings": { "amqp": { @@ -65,9 +65,9 @@ async def handle(msg): ... "vhost": "/", }, "exchange": {"type": "default", "vhost": "/"}, - } + }, }, - } + }, }, "operations": { "test_test:_:HandleSubscribe": { @@ -79,30 +79,30 @@ async def handle(msg): ... ], "ack": True, "bindingVersion": "0.3.0", - } + }, }, "messages": [ { - "$ref": "#/channels/test_test:_:Handle/messages/SubscribeMessage" - } + "$ref": "#/channels/test_test:_:Handle/messages/SubscribeMessage", + }, ], "channel": {"$ref": "#/channels/test_test:_:Handle"}, - } + }, }, "components": { "messages": { "test_test:_:Handle:SubscribeMessage": { "title": "test_test:_:Handle:SubscribeMessage", "correlationId": { - "location": "$message.header#/correlation_id" + "location": "$message.header#/correlation_id", }, "payload": { - "$ref": "#/components/schemas/Handle:Message:Payload" + "$ref": "#/components/schemas/Handle:Message:Payload", }, - } + }, }, "schemas": { - "Handle:Message:Payload": {"title": "Handle:Message:Payload"} + "Handle:Message:Payload": {"title": "Handle:Message:Payload"}, }, }, }, schema diff --git a/tests/asyncapi/rabbit/v3_0_0/test_security.py b/tests/asyncapi/rabbit/v3_0_0/test_security.py index 55e68288b2..d1e937e92a 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_security.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_security.py @@ -38,7 +38,7 @@ def test_base_security_schema(): "security": [], "host": "guest:guest@localhost:5672", # pragma: allowlist secret "pathname": "/", - } + }, }, } @@ -82,7 +82,7 @@ def test_plaintext_security_schema(): "security": [{"user-password": []}], "host": "admin:password@localhost:5671", # pragma: allowlist secret "pathname": "/", - } + }, }, } @@ -122,6 +122,6 @@ def test_plaintext_security_schema_without_ssl(): "security": [{"user-password": []}], "host": "admin:password@localhost:5672", # pragma: allowlist secret "pathname": "/", # pragma: allowlist secret - } + }, }, } diff --git a/tests/asyncapi/redis/v2_6_0/test_arguments.py b/tests/asyncapi/redis/v2_6_0/test_arguments.py index 6989305e85..cf347b2ab7 100644 --- a/tests/asyncapi/redis/v2_6_0/test_arguments.py +++ b/tests/asyncapi/redis/v2_6_0/test_arguments.py @@ -20,7 +20,7 @@ async def handle(msg): ... "bindingVersion": "custom", "channel": "test", "method": "subscribe", - } + }, } def test_channel_pattern_subscriber(self): @@ -37,7 +37,7 @@ async def handle(msg): ... "bindingVersion": "custom", "channel": "test.*", "method": "psubscribe", - } + }, } def test_list_subscriber(self): @@ -50,7 +50,7 @@ async def handle(msg): ... key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { - "redis": {"bindingVersion": "custom", "channel": "test", "method": "lpop"} + "redis": {"bindingVersion": "custom", "channel": "test", "method": "lpop"}, } def test_stream_subscriber(self): @@ -63,7 +63,7 @@ async def handle(msg): ... key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { - "redis": {"bindingVersion": "custom", "channel": "test", "method": "xread"} + "redis": {"bindingVersion": "custom", "channel": "test", "method": "xread"}, } def test_stream_group_subscriber(self): @@ -82,5 +82,5 @@ async def handle(msg): ... "consumer_name": "consumer", "group_name": "group", "method": "xreadgroup", - } + }, } diff --git a/tests/asyncapi/redis/v2_6_0/test_connection.py b/tests/asyncapi/redis/v2_6_0/test_connection.py index 7a507e2a2a..40a0ee5292 100644 --- a/tests/asyncapi/redis/v2_6_0/test_connection.py +++ b/tests/asyncapi/redis/v2_6_0/test_connection.py @@ -28,7 +28,7 @@ def test_base(): "protocolVersion": "0.9.0", "tags": [{"description": "experimental", "name": "some-tag"}], "url": "redis://localhost:6379", - } + }, }, }, schema @@ -36,7 +36,8 @@ def test_base(): def test_custom(): schema = AsyncAPI( RedisBroker( - "redis://localhost:6379", specification_url="rediss://127.0.0.1:8000" + "redis://localhost:6379", + specification_url="rediss://127.0.0.1:8000", ), schema_version="2.6.0", ).to_jsonable() @@ -52,6 +53,6 @@ def test_custom(): "protocol": "rediss", "protocolVersion": "custom", "url": "rediss://127.0.0.1:8000", - } + }, }, } diff --git a/tests/asyncapi/redis/v2_6_0/test_naming.py b/tests/asyncapi/redis/v2_6_0/test_naming.py index 8371c5986f..c7d45a8464 100644 --- a/tests/asyncapi/redis/v2_6_0/test_naming.py +++ b/tests/asyncapi/redis/v2_6_0/test_naming.py @@ -25,23 +25,25 @@ async def handle(): ... "bindingVersion": "custom", "channel": "test", "method": "subscribe", - } + }, }, "servers": ["development"], "subscribe": { - "message": {"$ref": "#/components/messages/test:Handle:Message"} + "message": { + "$ref": "#/components/messages/test:Handle:Message" + }, }, - } + }, }, "components": { "messages": { "test:Handle:Message": { "correlationId": { - "location": "$message.header#/correlation_id" + "location": "$message.header#/correlation_id", }, "payload": {"$ref": "#/components/schemas/EmptyPayload"}, "title": "test:Handle:Message", - } + }, }, "schemas": {"EmptyPayload": {"title": "EmptyPayload", "type": "null"}}, }, @@ -52,7 +54,7 @@ async def handle(): ... "protocol": "redis", "protocolVersion": "custom", "url": "redis://localhost:6379", - } + }, }, }, schema diff --git a/tests/asyncapi/redis/v2_6_0/test_publisher.py b/tests/asyncapi/redis/v2_6_0/test_publisher.py index 873116b2cb..88a4e3bca3 100644 --- a/tests/asyncapi/redis/v2_6_0/test_publisher.py +++ b/tests/asyncapi/redis/v2_6_0/test_publisher.py @@ -20,7 +20,7 @@ async def handle(msg): ... "bindingVersion": "custom", "channel": "test", "method": "publish", - } + }, } def test_list_publisher(self): @@ -33,7 +33,7 @@ async def handle(msg): ... key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { - "redis": {"bindingVersion": "custom", "channel": "test", "method": "rpush"} + "redis": {"bindingVersion": "custom", "channel": "test", "method": "rpush"}, } def test_stream_publisher(self): @@ -46,5 +46,5 @@ async def handle(msg): ... key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { - "redis": {"bindingVersion": "custom", "channel": "test", "method": "xadd"} + "redis": {"bindingVersion": "custom", "channel": "test", "method": "xadd"}, } diff --git a/tests/asyncapi/redis/v2_6_0/test_router.py b/tests/asyncapi/redis/v2_6_0/test_router.py index c607713a4f..b8eddafe0c 100644 --- a/tests/asyncapi/redis/v2_6_0/test_router.py +++ b/tests/asyncapi/redis/v2_6_0/test_router.py @@ -32,30 +32,30 @@ async def handle(msg): ... "bindingVersion": "custom", "channel": "test_test", "method": "subscribe", - } + }, }, "servers": ["development"], "subscribe": { "message": { - "$ref": "#/components/messages/test_test:Handle:Message" - } + "$ref": "#/components/messages/test_test:Handle:Message", + }, }, - } + }, }, "components": { "messages": { "test_test:Handle:Message": { "correlationId": { - "location": "$message.header#/correlation_id" + "location": "$message.header#/correlation_id", }, "payload": { - "$ref": "#/components/schemas/Handle:Message:Payload" + "$ref": "#/components/schemas/Handle:Message:Payload", }, "title": "test_test:Handle:Message", - } + }, }, "schemas": { - "Handle:Message:Payload": {"title": "Handle:Message:Payload"} + "Handle:Message:Payload": {"title": "Handle:Message:Payload"}, }, }, "defaultContentType": "application/json", @@ -65,7 +65,7 @@ async def handle(msg): ... "protocol": "redis", "protocolVersion": "custom", "url": "redis://localhost:6379", - } + }, }, } diff --git a/tests/asyncapi/redis/v2_6_0/test_security.py b/tests/asyncapi/redis/v2_6_0/test_security.py index ac981ddfd9..0d57bb171f 100644 --- a/tests/asyncapi/redis/v2_6_0/test_security.py +++ b/tests/asyncapi/redis/v2_6_0/test_security.py @@ -32,7 +32,7 @@ def test_base_security_schema(): "protocolVersion": "custom", "security": [], "url": "rediss://localhost:6379/", - } + }, }, } @@ -70,7 +70,7 @@ def test_plaintext_security_schema(): "protocolVersion": "custom", "security": [{"user-password": []}], "url": "redis://localhost:6379/", - } + }, }, } @@ -105,6 +105,6 @@ def test_plaintext_security_schema_without_ssl(): "protocolVersion": "custom", "security": [{"user-password": []}], "url": "redis://localhost:6379/", - } + }, }, } diff --git a/tests/asyncapi/redis/v3_0_0/test_arguments.py b/tests/asyncapi/redis/v3_0_0/test_arguments.py index 546544b1cd..51ec973625 100644 --- a/tests/asyncapi/redis/v3_0_0/test_arguments.py +++ b/tests/asyncapi/redis/v3_0_0/test_arguments.py @@ -20,7 +20,7 @@ async def handle(msg): ... "bindingVersion": "custom", "channel": "test", "method": "subscribe", - } + }, } def test_channel_pattern_subscriber(self): @@ -37,7 +37,7 @@ async def handle(msg): ... "bindingVersion": "custom", "channel": "test.*", "method": "psubscribe", - } + }, } def test_list_subscriber(self): @@ -50,7 +50,7 @@ async def handle(msg): ... key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { - "redis": {"bindingVersion": "custom", "channel": "test", "method": "lpop"} + "redis": {"bindingVersion": "custom", "channel": "test", "method": "lpop"}, } def test_stream_subscriber(self): @@ -63,7 +63,7 @@ async def handle(msg): ... key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { - "redis": {"bindingVersion": "custom", "channel": "test", "method": "xread"} + "redis": {"bindingVersion": "custom", "channel": "test", "method": "xread"}, } def test_stream_group_subscriber(self): @@ -82,5 +82,5 @@ async def handle(msg): ... "consumer_name": "consumer", "group_name": "group", "method": "xreadgroup", - } + }, } diff --git a/tests/asyncapi/redis/v3_0_0/test_connection.py b/tests/asyncapi/redis/v3_0_0/test_connection.py index a14f2eb737..bf31f4f815 100644 --- a/tests/asyncapi/redis/v3_0_0/test_connection.py +++ b/tests/asyncapi/redis/v3_0_0/test_connection.py @@ -30,7 +30,7 @@ def test_base(): "tags": [{"description": "experimental", "name": "some-tag"}], "host": "localhost:6379", "pathname": "", - } + }, }, }, schema @@ -38,7 +38,8 @@ def test_base(): def test_custom(): schema = AsyncAPI( RedisBroker( - "redis://localhost:6379", specification_url="rediss://127.0.0.1:8000" + "redis://localhost:6379", + specification_url="rediss://127.0.0.1:8000", ), schema_version="3.0.0", ).to_jsonable() @@ -56,6 +57,6 @@ def test_custom(): "protocolVersion": "custom", "host": "127.0.0.1:8000", "pathname": "", - } + }, }, } diff --git a/tests/asyncapi/redis/v3_0_0/test_naming.py b/tests/asyncapi/redis/v3_0_0/test_naming.py index 13088411c2..98d503116a 100644 --- a/tests/asyncapi/redis/v3_0_0/test_naming.py +++ b/tests/asyncapi/redis/v3_0_0/test_naming.py @@ -29,15 +29,15 @@ async def handle(): ... "bindingVersion": "custom", "channel": "test", "method": "subscribe", - } + }, }, "servers": [{"$ref": "#/servers/development"}], "messages": { "SubscribeMessage": { - "$ref": "#/components/messages/test:Handle:SubscribeMessage" - } + "$ref": "#/components/messages/test:Handle:SubscribeMessage", + }, }, - } + }, }, "operations": { "test:HandleSubscribe": { @@ -46,19 +46,19 @@ async def handle(): ... "$ref": "#/channels/test:Handle", }, "messages": [ - {"$ref": "#/channels/test:Handle/messages/SubscribeMessage"} + {"$ref": "#/channels/test:Handle/messages/SubscribeMessage"}, ], - } + }, }, "components": { "messages": { "test:Handle:SubscribeMessage": { "correlationId": { - "location": "$message.header#/correlation_id" + "location": "$message.header#/correlation_id", }, "payload": {"$ref": "#/components/schemas/EmptyPayload"}, "title": "test:Handle:SubscribeMessage", - } + }, }, "schemas": {"EmptyPayload": {"title": "EmptyPayload", "type": "null"}}, }, @@ -70,7 +70,7 @@ async def handle(): ... "protocolVersion": "custom", "host": "localhost:6379", "pathname": "", - } + }, }, }, schema diff --git a/tests/asyncapi/redis/v3_0_0/test_publisher.py b/tests/asyncapi/redis/v3_0_0/test_publisher.py index 2ab2e819de..d57472ad85 100644 --- a/tests/asyncapi/redis/v3_0_0/test_publisher.py +++ b/tests/asyncapi/redis/v3_0_0/test_publisher.py @@ -20,7 +20,7 @@ async def handle(msg): ... "bindingVersion": "custom", "channel": "test", "method": "publish", - } + }, } def test_list_publisher(self): @@ -33,7 +33,7 @@ async def handle(msg): ... key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { - "redis": {"bindingVersion": "custom", "channel": "test", "method": "rpush"} + "redis": {"bindingVersion": "custom", "channel": "test", "method": "rpush"}, } def test_stream_publisher(self): @@ -46,5 +46,5 @@ async def handle(msg): ... key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key]["bindings"] == { - "redis": {"bindingVersion": "custom", "channel": "test", "method": "xadd"} + "redis": {"bindingVersion": "custom", "channel": "test", "method": "xadd"}, } diff --git a/tests/asyncapi/redis/v3_0_0/test_router.py b/tests/asyncapi/redis/v3_0_0/test_router.py index c98e8c6f13..d8b9ce4f58 100644 --- a/tests/asyncapi/redis/v3_0_0/test_router.py +++ b/tests/asyncapi/redis/v3_0_0/test_router.py @@ -36,7 +36,7 @@ async def handle(msg): ... "pathname": "", "protocol": "redis", "protocolVersion": "custom", - } + }, }, "channels": { "test_test:Handle": { @@ -44,43 +44,43 @@ async def handle(msg): ... "servers": [{"$ref": "#/servers/development"}], "messages": { "SubscribeMessage": { - "$ref": "#/components/messages/test_test:Handle:SubscribeMessage" - } + "$ref": "#/components/messages/test_test:Handle:SubscribeMessage", + }, }, "bindings": { "redis": { "channel": "test_test", "method": "subscribe", "bindingVersion": "custom", - } + }, }, - } + }, }, "operations": { "test_test:HandleSubscribe": { "action": "receive", "messages": [ { - "$ref": "#/channels/test_test:Handle/messages/SubscribeMessage" - } + "$ref": "#/channels/test_test:Handle/messages/SubscribeMessage", + }, ], "channel": {"$ref": "#/channels/test_test:Handle"}, - } + }, }, "components": { "messages": { "test_test:Handle:SubscribeMessage": { "title": "test_test:Handle:SubscribeMessage", "correlationId": { - "location": "$message.header#/correlation_id" + "location": "$message.header#/correlation_id", }, "payload": { - "$ref": "#/components/schemas/Handle:Message:Payload" + "$ref": "#/components/schemas/Handle:Message:Payload", }, - } + }, }, "schemas": { - "Handle:Message:Payload": {"title": "Handle:Message:Payload"} + "Handle:Message:Payload": {"title": "Handle:Message:Payload"}, }, }, } diff --git a/tests/asyncapi/redis/v3_0_0/test_security.py b/tests/asyncapi/redis/v3_0_0/test_security.py index db7b3a131a..4a903c930c 100644 --- a/tests/asyncapi/redis/v3_0_0/test_security.py +++ b/tests/asyncapi/redis/v3_0_0/test_security.py @@ -37,7 +37,7 @@ def test_base_security_schema(): "security": [], "host": "localhost:6379", "pathname": "/", - } + }, }, } @@ -80,7 +80,7 @@ def test_plaintext_security_schema(): "security": [{"user-password": []}], "host": "localhost:6379", "pathname": "/", - } + }, }, } @@ -120,6 +120,6 @@ def test_plaintext_security_schema_without_ssl(): "security": [{"user-password": []}], "host": "localhost:6379", "pathname": "/", - } + }, }, } diff --git a/tests/brokers/base/fastapi.py b/tests/brokers/base/fastapi.py index b9a227346c..ae95286e50 100644 --- a/tests/brokers/base/fastapi.py +++ b/tests/brokers/base/fastapi.py @@ -438,9 +438,12 @@ async def lifespan(app): app = FastAPI() app.include_router(router) - async with self.patch_broker(router.broker), router.lifespan_context( - app - ) as context: + async with ( + self.patch_broker(router.broker), + router.lifespan_context( + app, + ) as context, + ): assert context["lifespan"] mock.start.assert_called_once() @@ -521,7 +524,6 @@ async def test_dependency_overrides(self, mock: Mock, queue: str): def dep1(): mock.not_call() - pass app = FastAPI() app.dependency_overrides[dep1] = lambda: mock() diff --git a/tests/brokers/base/middlewares.py b/tests/brokers/base/middlewares.py index b4de99b6d4..2ce458af40 100644 --- a/tests/brokers/base/middlewares.py +++ b/tests/brokers/base/middlewares.py @@ -92,7 +92,9 @@ async def handler(m): assert mock.end.call_count == 2 async def test_local_middleware_not_shared_between_subscribers( - self, queue: str, mock: Mock + self, + queue: str, + mock: Mock, ): event1 = asyncio.Event() event2 = asyncio.Event() @@ -208,7 +210,7 @@ async def mid(call_next, msg): @broker.subscriber(*args, **kwargs) async def handler2(m): event.set() - raise ValueError() + raise ValueError async with self.patch_broker(broker) as br: await br.start() @@ -565,7 +567,10 @@ async def subscriber2(msg=Context("message")): assert mock.call_count == 0 async def test_exception_middleware_different_handler( - self, event: asyncio.Event, queue: str, mock: Mock + self, + event: asyncio.Event, + queue: str, + mock: Mock, ): mid = ExceptionMiddleware() @@ -642,7 +647,10 @@ async def value_error_handler(exc): ] async def test_exception_middleware_decoder_error( - self, event: asyncio.Event, queue: str, mock: Mock + self, + event: asyncio.Event, + queue: str, + mock: Mock, ): async def decoder( msg, diff --git a/tests/brokers/base/publish.py b/tests/brokers/base/publish.py index c3828c43d4..72cdcdb3b9 100644 --- a/tests/brokers/base/publish.py +++ b/tests/brokers/base/publish.py @@ -242,7 +242,7 @@ async def m(a: int, b: int): { "a": 1, "b": 1, - } + }, ) @pytest.mark.asyncio @@ -515,7 +515,7 @@ async def handler(m): await asyncio.wait( ( asyncio.create_task( - br.publish("Hello!", queue, reply_to=queue + "reply") + br.publish("Hello!", queue, reply_to=queue + "reply"), ), asyncio.create_task(event.wait()), ), @@ -559,7 +559,7 @@ async def handler(m): await asyncio.wait( ( asyncio.create_task( - br.publish("Hello!", queue, reply_to=queue + "reply") + br.publish("Hello!", queue, reply_to=queue + "reply"), ), asyncio.create_task(event.wait()), ), diff --git a/tests/brokers/base/router.py b/tests/brokers/base/router.py index afb647d2cf..ced3ce5aa2 100644 --- a/tests/brokers/base/router.py +++ b/tests/brokers/base/router.py @@ -356,7 +356,7 @@ def subscriber(m): return "hi" args2, kwargs2 = self.get_subscriber_params( - "test1_" + "test2_" + queue + "resp" + "test1_" + "test2_" + queue + "resp", ) @pub_broker.subscriber(*args2, **kwargs2) @@ -390,7 +390,8 @@ async def test_router_dependencies( router2 = type(router)(dependencies=(Depends(lambda: 2),)) args, kwargs = self.get_subscriber_params( - queue, dependencies=(Depends(lambda: 3),) + queue, + dependencies=(Depends(lambda: 3),), ) @router2.subscriber(*args, **kwargs) diff --git a/tests/brokers/base/testclient.py b/tests/brokers/base/testclient.py index f6d45d7cc7..1cc36fc22a 100644 --- a/tests/brokers/base/testclient.py +++ b/tests/brokers/base/testclient.py @@ -117,7 +117,7 @@ async def test_exception_raises(self, queue: str): @test_broker.subscriber(*args, **kwargs) async def m(msg): # pragma: no cover - raise ValueError() + raise ValueError async with self.patch_broker(test_broker) as br: await br.start() @@ -153,7 +153,8 @@ async def test_broker_with_real_doesnt_get_patched(self): assert br._producer is not None async def test_broker_with_real_patches_publishers_and_subscribers( - self, queue: str + self, + queue: str, ): test_broker = self.get_broker() diff --git a/tests/brokers/confluent/basic.py b/tests/brokers/confluent/basic.py index 6fffc1c976..070360c548 100644 --- a/tests/brokers/confluent/basic.py +++ b/tests/brokers/confluent/basic.py @@ -8,7 +8,9 @@ class ConfluentTestcaseConfig(_Base): timeout: float = 10.0 def get_subscriber_params( - self, *topics: Any, **kwargs: Any + self, + *topics: Any, + **kwargs: Any, ) -> Tuple[ Tuple[Any, ...], Dict[str, Any], diff --git a/tests/brokers/confluent/test_connect.py b/tests/brokers/confluent/test_connect.py index 0861c8f9d5..d2182309e1 100644 --- a/tests/brokers/confluent/test_connect.py +++ b/tests/brokers/confluent/test_connect.py @@ -18,7 +18,7 @@ def test_correct_config(): "builtin.features": config.BuiltinFeatures.gzip, "debug": config.Debug.broker, "group.protocol": config.GroupProtocol.classic, - } + }, ) assert broker.config.as_config_dict() == { diff --git a/tests/brokers/confluent/test_consume.py b/tests/brokers/confluent/test_consume.py index 0e07d3cbbb..bb36b46936 100644 --- a/tests/brokers/confluent/test_consume.py +++ b/tests/brokers/confluent/test_consume.py @@ -63,7 +63,7 @@ def subscriber(m, msg: KafkaMessage): msg.headers, [msg.headers] == msg.batch_headers, msg.headers.get("custom") == "1", - ) + ), ) mock(check) event.set() @@ -92,7 +92,9 @@ async def test_consume_ack( consume_broker = self.get_broker(apply_types=True) args, kwargs = self.get_subscriber_params( - queue, group_id="test", auto_commit=False + queue, + group_id="test", + auto_commit=False, ) @consume_broker.subscriber(*args, **kwargs) @@ -113,7 +115,7 @@ async def handler(msg: KafkaMessage): br.publish( "hello", queue, - ) + ), ), asyncio.create_task(event.wait()), ), @@ -133,7 +135,9 @@ async def test_consume_ack_manual( consume_broker = self.get_broker(apply_types=True) args, kwargs = self.get_subscriber_params( - queue, group_id="test", auto_commit=False + queue, + group_id="test", + auto_commit=False, ) @consume_broker.subscriber(*args, **kwargs) @@ -170,7 +174,9 @@ async def test_consume_ack_raise( consume_broker = self.get_broker(apply_types=True) args, kwargs = self.get_subscriber_params( - queue, group_id="test", auto_commit=False + queue, + group_id="test", + auto_commit=False, ) @consume_broker.subscriber(*args, **kwargs) @@ -207,7 +213,9 @@ async def test_nack( consume_broker = self.get_broker(apply_types=True) args, kwargs = self.get_subscriber_params( - queue, group_id="test", auto_commit=False + queue, + group_id="test", + auto_commit=False, ) @consume_broker.subscriber(*args, **kwargs) @@ -263,7 +271,7 @@ async def handler(msg: KafkaMessage): br.publish( "hello", queue, - ) + ), ), asyncio.create_task(event.wait()), ), @@ -283,7 +291,9 @@ async def test_consume_with_no_auto_commit( consume_broker = self.get_broker(apply_types=True) args, kwargs = self.get_subscriber_params( - queue, auto_commit=False, group_id="test" + queue, + auto_commit=False, + group_id="test", ) @consume_broker.subscriber(*args, **kwargs) @@ -295,7 +305,9 @@ async def subscriber_no_auto_commit(msg: KafkaMessage): event2 = asyncio.Event() args, kwargs = self.get_subscriber_params( - queue, auto_commit=True, group_id="test" + queue, + auto_commit=True, + group_id="test", ) @broker2.subscriber(*args, **kwargs) diff --git a/tests/brokers/confluent/test_security.py b/tests/brokers/confluent/test_security.py index 489c95fbe2..11e92e0e41 100644 --- a/tests/brokers/confluent/test_security.py +++ b/tests/brokers/confluent/test_security.py @@ -34,9 +34,13 @@ async def test_base_security_pass_ssl_context(): basic_broker = KafkaBroker("localhost:9092", security=security) - with patch_aio_consumer_and_producer(), pytest.raises( - SetupError, match="not supported" - ) as e: + with ( + patch_aio_consumer_and_producer(), + pytest.raises( + SetupError, + match="not supported", + ) as e, + ): async with basic_broker: pass diff --git a/tests/brokers/confluent/test_test_client.py b/tests/brokers/confluent/test_test_client.py index 26c86c4d68..f1326092ed 100644 --- a/tests/brokers/confluent/test_test_client.py +++ b/tests/brokers/confluent/test_test_client.py @@ -40,7 +40,9 @@ async def m(msg: KafkaMessage): async with self.patch_broker(broker) as br: with patch.object( - FAKE_CONSUMER, "seek", spy_decorator(FAKE_CONSUMER.seek) + FAKE_CONSUMER, + "seek", + spy_decorator(FAKE_CONSUMER.seek), ) as mocked: await br.publish("hello", queue) m.mock.assert_called_once_with("hello") @@ -254,6 +256,7 @@ async def test_broker_with_real_doesnt_get_patched(self): @pytest.mark.confluent async def test_broker_with_real_patches_publishers_and_subscribers( - self, queue: str + self, + queue: str, ): await super().test_broker_with_real_patches_publishers_and_subscribers(queue) diff --git a/tests/brokers/confluent/test_test_reentrancy.py b/tests/brokers/confluent/test_test_reentrancy.py index 6ed219e2ee..6b00598ab1 100644 --- a/tests/brokers/confluent/test_test_reentrancy.py +++ b/tests/brokers/confluent/test_test_reentrancy.py @@ -15,14 +15,16 @@ @to_output_data @broker.subscriber( - partitions=[TopicPartition(first_topic_name, 0)], auto_offset_reset="earliest" + partitions=[TopicPartition(first_topic_name, 0)], + auto_offset_reset="earliest", ) async def on_input_data(msg: int): return msg + 1 @broker.subscriber( - partitions=[TopicPartition(out_topic_name, 0)], auto_offset_reset="earliest" + partitions=[TopicPartition(out_topic_name, 0)], + auto_offset_reset="earliest", ) async def on_output_data(msg: int): pass @@ -72,7 +74,7 @@ async def on_output_data(msg: int): reason=( "Failed due `on_output_data` subscriber creates inside test and doesn't removed after " "https://github.com/airtai/faststream/issues/556" - ) + ), ) async def test_with_temp_subscriber(): await _test_with_temp_subscriber() diff --git a/tests/brokers/kafka/test_consume.py b/tests/brokers/kafka/test_consume.py index 9384ed2db2..8e40d91c14 100644 --- a/tests/brokers/kafka/test_consume.py +++ b/tests/brokers/kafka/test_consume.py @@ -90,7 +90,7 @@ def subscriber(m, msg: KafkaMessage): msg.headers, [msg.headers] == msg.batch_headers, msg.headers.get("custom") == "1", - ) + ), ) mock(check) event.set() @@ -126,7 +126,9 @@ async def handler(msg: KafkaMessage): await br.start() with patch.object( - AIOKafkaConsumer, "commit", spy_decorator(AIOKafkaConsumer.commit) + AIOKafkaConsumer, + "commit", + spy_decorator(AIOKafkaConsumer.commit), ) as m: await asyncio.wait( ( @@ -134,7 +136,7 @@ async def handler(msg: KafkaMessage): consume_broker.publish( "hello", queue, - ) + ), ), asyncio.create_task(event.wait()), ), @@ -189,7 +191,9 @@ async def handler(msg: KafkaMessage): await br.start() with patch.object( - AIOKafkaConsumer, "commit", spy_decorator(AIOKafkaConsumer.commit) + AIOKafkaConsumer, + "commit", + spy_decorator(AIOKafkaConsumer.commit), ) as m: await asyncio.wait( ( @@ -197,7 +201,7 @@ async def handler(msg: KafkaMessage): br.publish( "hello", queue, - ) + ), ), asyncio.create_task(event.wait()), ), @@ -225,7 +229,9 @@ async def handler(msg: KafkaMessage): await br.start() with patch.object( - AIOKafkaConsumer, "commit", spy_decorator(AIOKafkaConsumer.commit) + AIOKafkaConsumer, + "commit", + spy_decorator(AIOKafkaConsumer.commit), ) as m: await asyncio.wait( ( @@ -233,7 +239,7 @@ async def handler(msg: KafkaMessage): br.publish( "hello", queue, - ) + ), ), asyncio.create_task(event.wait()), ), @@ -261,7 +267,9 @@ async def handler(msg: KafkaMessage): await br.start() with patch.object( - AIOKafkaConsumer, "commit", spy_decorator(AIOKafkaConsumer.commit) + AIOKafkaConsumer, + "commit", + spy_decorator(AIOKafkaConsumer.commit), ) as m: await asyncio.wait( ( @@ -269,7 +277,7 @@ async def handler(msg: KafkaMessage): br.publish( "hello", queue, - ) + ), ), asyncio.create_task(event.wait()), ), @@ -296,7 +304,9 @@ async def handler(msg: KafkaMessage): await br.start() with patch.object( - AIOKafkaConsumer, "commit", spy_decorator(AIOKafkaConsumer.commit) + AIOKafkaConsumer, + "commit", + spy_decorator(AIOKafkaConsumer.commit), ) as m: await asyncio.wait( ( @@ -304,7 +314,7 @@ async def handler(msg: KafkaMessage): br.publish( "hello", queue, - ) + ), ), asyncio.create_task(event.wait()), ), diff --git a/tests/brokers/kafka/test_test_client.py b/tests/brokers/kafka/test_test_client.py index ce439a1df4..c838184abc 100644 --- a/tests/brokers/kafka/test_test_client.py +++ b/tests/brokers/kafka/test_test_client.py @@ -83,7 +83,9 @@ async def m(msg: KafkaMessage): async with self.patch_broker(broker) as br: with patch.object( - FAKE_CONSUMER, "seek", spy_decorator(FAKE_CONSUMER.seek) + FAKE_CONSUMER, + "seek", + spy_decorator(FAKE_CONSUMER.seek), ) as mocked: await br.publish("hello", queue) mocked.mock.assert_called_once() @@ -290,6 +292,7 @@ async def test_broker_with_real_doesnt_get_patched(self): @pytest.mark.kafka async def test_broker_with_real_patches_publishers_and_subscribers( - self, queue: str + self, + queue: str, ): await super().test_broker_with_real_patches_publishers_and_subscribers(queue) diff --git a/tests/brokers/kafka/test_test_reentrancy.py b/tests/brokers/kafka/test_test_reentrancy.py index 5e15ecd171..d769dbee54 100644 --- a/tests/brokers/kafka/test_test_reentrancy.py +++ b/tests/brokers/kafka/test_test_reentrancy.py @@ -63,7 +63,7 @@ async def on_output_data(msg: int): reason=( "Failed due `on_output_data` subscriber creates inside test and doesn't removed after " "https://github.com/airtai/faststream/issues/556" - ) + ), ) async def test_with_temp_subscriber(): await _test_with_temp_subscriber() diff --git a/tests/brokers/nats/test_consume.py b/tests/brokers/nats/test_consume.py index 103cda134b..01588a6360 100644 --- a/tests/brokers/nats/test_consume.py +++ b/tests/brokers/nats/test_consume.py @@ -317,7 +317,7 @@ def subscriber(m, msg: NatsMessage): msg.headers, [msg.headers] == msg.batch_headers, msg.headers.get("custom") == "1", - ) + ), ) mock(check) event.set() @@ -359,7 +359,7 @@ async def handler(m): bucket.put( queue, b"world", - ) + ), ), asyncio.create_task(event.wait()), ), @@ -393,7 +393,7 @@ async def handler(filename: str): bucket.put( "hello", b"world", - ) + ), ), asyncio.create_task(event.wait()), ), diff --git a/tests/brokers/nats/test_fastapi.py b/tests/brokers/nats/test_fastapi.py index b286bdbe93..7ec47022ef 100644 --- a/tests/brokers/nats/test_fastapi.py +++ b/tests/brokers/nats/test_fastapi.py @@ -32,7 +32,7 @@ def subscriber(msg: str, name: str): await asyncio.wait( ( asyncio.create_task( - router.broker.publish("hello", f"{queue}.john") + router.broker.publish("hello", f"{queue}.john"), ), asyncio.create_task(event.wait()), ), diff --git a/tests/brokers/nats/test_router.py b/tests/brokers/nats/test_router.py index 341c6f35be..e5c1b153e8 100644 --- a/tests/brokers/nats/test_router.py +++ b/tests/brokers/nats/test_router.py @@ -138,7 +138,8 @@ def response(m): event.set() r = type(router)( - prefix="test.", handlers=(self.route_class(response, subject=queue),) + prefix="test.", + handlers=(self.route_class(response, subject=queue),), ) pub_broker.include_router(r) diff --git a/tests/brokers/nats/test_test_client.py b/tests/brokers/nats/test_test_client.py index 8046e85ad3..25c43f537e 100644 --- a/tests/brokers/nats/test_test_client.py +++ b/tests/brokers/nats/test_test_client.py @@ -256,6 +256,7 @@ async def test_broker_with_real_doesnt_get_patched(self): @pytest.mark.nats async def test_broker_with_real_patches_publishers_and_subscribers( - self, queue: str + self, + queue: str, ): await super().test_broker_with_real_patches_publishers_and_subscribers(queue) diff --git a/tests/brokers/rabbit/specific/test_nested_exchange.py b/tests/brokers/rabbit/specific/test_nested_exchange.py index 2b830f3e17..e33c040dbd 100644 --- a/tests/brokers/rabbit/specific/test_nested_exchange.py +++ b/tests/brokers/rabbit/specific/test_nested_exchange.py @@ -15,11 +15,14 @@ async def test_bind_to(queue: str): async with broker: meta_parent = RabbitExchange("meta", type=ExchangeType.FANOUT) parent_exch = RabbitExchange( - "main", type=ExchangeType.FANOUT, bind_to=meta_parent + "main", + type=ExchangeType.FANOUT, + bind_to=meta_parent, ) @broker.subscriber( - queue, exchange=RabbitExchange("nested", bind_to=parent_exch) + queue, + exchange=RabbitExchange("nested", bind_to=parent_exch), ) async def handler(m): consume.set() diff --git a/tests/brokers/rabbit/test_consume.py b/tests/brokers/rabbit/test_consume.py index 774af65d8c..588d5e9098 100644 --- a/tests/brokers/rabbit/test_consume.py +++ b/tests/brokers/rabbit/test_consume.py @@ -35,7 +35,7 @@ def h(m): await asyncio.wait( ( asyncio.create_task( - br.publish("hello", queue=queue, exchange=exchange) + br.publish("hello", queue=queue, exchange=exchange), ), asyncio.create_task(event.wait()), ), @@ -74,7 +74,7 @@ def h(m): Message(b"hello"), queue=queue, exchange=exchange.name, - ) + ), ), asyncio.create_task(event.wait()), ), @@ -100,12 +100,14 @@ async def handler(msg: RabbitMessage): await br.start() with patch.object( - IncomingMessage, "ack", spy_decorator(IncomingMessage.ack) + IncomingMessage, + "ack", + spy_decorator(IncomingMessage.ack), ) as m: await asyncio.wait( ( asyncio.create_task( - br.publish("hello", queue=queue, exchange=exchange) + br.publish("hello", queue=queue, exchange=exchange), ), asyncio.create_task(event.wait()), ), @@ -133,12 +135,14 @@ async def handler(msg: RabbitMessage): await br.start() with patch.object( - IncomingMessage, "ack", spy_decorator(IncomingMessage.ack) + IncomingMessage, + "ack", + spy_decorator(IncomingMessage.ack), ) as m: await asyncio.wait( ( asyncio.create_task( - br.publish("hello", queue=queue, exchange=exchange) + br.publish("hello", queue=queue, exchange=exchange), ), asyncio.create_task(event.wait()), ), @@ -167,12 +171,14 @@ async def handler(msg: RabbitMessage): await br.start() with patch.object( - IncomingMessage, "ack", spy_decorator(IncomingMessage.ack) + IncomingMessage, + "ack", + spy_decorator(IncomingMessage.ack), ) as m: await asyncio.wait( ( asyncio.create_task( - br.publish("hello", queue=queue, exchange=exchange) + br.publish("hello", queue=queue, exchange=exchange), ), asyncio.create_task(event.wait()), ), @@ -194,18 +200,20 @@ async def test_consume_manual_nack( async def handler(msg: RabbitMessage): await msg.nack() event.set() - raise ValueError() + raise ValueError async with self.patch_broker(consume_broker) as br: await br.start() with patch.object( - IncomingMessage, "nack", spy_decorator(IncomingMessage.nack) + IncomingMessage, + "nack", + spy_decorator(IncomingMessage.nack), ) as m: await asyncio.wait( ( asyncio.create_task( - br.publish("hello", queue=queue, exchange=exchange) + br.publish("hello", queue=queue, exchange=exchange), ), asyncio.create_task(event.wait()), ), @@ -234,12 +242,14 @@ async def handler(msg: RabbitMessage): await br.start() with patch.object( - IncomingMessage, "nack", spy_decorator(IncomingMessage.nack) + IncomingMessage, + "nack", + spy_decorator(IncomingMessage.nack), ) as m: await asyncio.wait( ( asyncio.create_task( - br.publish("hello", queue=queue, exchange=exchange) + br.publish("hello", queue=queue, exchange=exchange), ), asyncio.create_task(event.wait()), ), @@ -261,18 +271,20 @@ async def test_consume_manual_reject( async def handler(msg: RabbitMessage): await msg.reject() event.set() - raise ValueError() + raise ValueError async with self.patch_broker(consume_broker) as br: await br.start() with patch.object( - IncomingMessage, "reject", spy_decorator(IncomingMessage.reject) + IncomingMessage, + "reject", + spy_decorator(IncomingMessage.reject), ) as m: await asyncio.wait( ( asyncio.create_task( - br.publish("hello", queue=queue, exchange=exchange) + br.publish("hello", queue=queue, exchange=exchange), ), asyncio.create_task(event.wait()), ), @@ -301,12 +313,14 @@ async def handler(msg: RabbitMessage): await br.start() with patch.object( - IncomingMessage, "reject", spy_decorator(IncomingMessage.reject) + IncomingMessage, + "reject", + spy_decorator(IncomingMessage.reject), ) as m: await asyncio.wait( ( asyncio.create_task( - br.publish("hello", queue=queue, exchange=exchange) + br.publish("hello", queue=queue, exchange=exchange), ), asyncio.create_task(event.wait()), ), @@ -333,13 +347,23 @@ async def handler(msg: RabbitMessage): async with self.patch_broker(consume_broker) as br: await br.start() - with patch.object( - IncomingMessage, "reject", spy_decorator(IncomingMessage.reject) - ) as m, patch.object( - IncomingMessage, "reject", spy_decorator(IncomingMessage.reject) - ) as m1, patch.object( - IncomingMessage, "reject", spy_decorator(IncomingMessage.reject) - ) as m2: + with ( + patch.object( + IncomingMessage, + "reject", + spy_decorator(IncomingMessage.reject), + ) as m, + patch.object( + IncomingMessage, + "reject", + spy_decorator(IncomingMessage.reject), + ) as m1, + patch.object( + IncomingMessage, + "reject", + spy_decorator(IncomingMessage.reject), + ) as m2, + ): await asyncio.wait( ( asyncio.create_task(br.publish("hello", queue)), @@ -370,12 +394,14 @@ async def handler(msg: RabbitMessage): await br.start() with patch.object( - IncomingMessage, "ack", spy_decorator(IncomingMessage.ack) + IncomingMessage, + "ack", + spy_decorator(IncomingMessage.ack), ) as m: await asyncio.wait( ( asyncio.create_task( - br.publish("hello", queue=queue, exchange=exchange) + br.publish("hello", queue=queue, exchange=exchange), ), asyncio.create_task(event.wait()), ), diff --git a/tests/brokers/rabbit/test_fastapi.py b/tests/brokers/rabbit/test_fastapi.py index 747e2c5610..54a94ef81d 100644 --- a/tests/brokers/rabbit/test_fastapi.py +++ b/tests/brokers/rabbit/test_fastapi.py @@ -42,7 +42,7 @@ def subscriber(msg: str, name: str): await asyncio.wait( ( asyncio.create_task( - router.broker.publish("hello", "in.john", queue + "1") + router.broker.publish("hello", "in.john", queue + "1"), ), asyncio.create_task(event.wait()), ), diff --git a/tests/brokers/rabbit/test_publish.py b/tests/brokers/rabbit/test_publish.py index d049b71267..17b2e0f9cb 100644 --- a/tests/brokers/rabbit/test_publish.py +++ b/tests/brokers/rabbit/test_publish.py @@ -47,7 +47,7 @@ async def handler(m): await asyncio.wait( ( asyncio.create_task( - br.publish("Hello!", queue, reply_to=reply_queue) + br.publish("Hello!", queue, reply_to=reply_queue), ), asyncio.create_task(event.wait()), ), diff --git a/tests/brokers/rabbit/test_router.py b/tests/brokers/rabbit/test_router.py index 1cde6673df..d2fbbf3f53 100644 --- a/tests/brokers/rabbit/test_router.py +++ b/tests/brokers/rabbit/test_router.py @@ -91,7 +91,7 @@ async def h( type=ExchangeType.TOPIC, ), ), - ) + ), ) pub_broker = self.get_broker(apply_types=True) @@ -132,7 +132,7 @@ def subscriber(m): await asyncio.wait( ( asyncio.create_task( - broker.publish("hello", f"test/{r_queue.name}") + broker.publish("hello", f"test/{r_queue.name}"), ), asyncio.create_task(event.wait()), ), @@ -166,7 +166,7 @@ def subscriber(m): await asyncio.wait( ( asyncio.create_task( - broker.publish("hello", f"test/{queue}1", exchange=exchange) + broker.publish("hello", f"test/{queue}1", exchange=exchange), ), asyncio.create_task(event.wait()), ), @@ -187,7 +187,8 @@ def response(m): r_queue = RabbitQueue(queue) r = type(router)( - prefix="test/", handlers=(self.route_class(response, queue=r_queue),) + prefix="test/", + handlers=(self.route_class(response, queue=r_queue),), ) pub_broker = self.get_broker() @@ -199,7 +200,7 @@ def response(m): await asyncio.wait( ( asyncio.create_task( - pub_broker.publish("hello", f"test/{r_queue.name}") + pub_broker.publish("hello", f"test/{r_queue.name}"), ), asyncio.create_task(event.wait()), ), diff --git a/tests/brokers/rabbit/test_schemas.py b/tests/brokers/rabbit/test_schemas.py index da8e4914cb..467ff954b6 100644 --- a/tests/brokers/rabbit/test_schemas.py +++ b/tests/brokers/rabbit/test_schemas.py @@ -7,7 +7,7 @@ def test_same_queue(): { RabbitQueue("test"): 0, RabbitQueue("test"): 1, - } + }, ) == 1 ) @@ -19,7 +19,7 @@ def test_different_queue_routing_key(): { RabbitQueue("test", routing_key="binding-1"): 0, RabbitQueue("test", routing_key="binding-2"): 1, - } + }, ) == 1 ) diff --git a/tests/brokers/rabbit/test_test_client.py b/tests/brokers/rabbit/test_test_client.py index ad0317eba5..a07a4b0f3e 100644 --- a/tests/brokers/rabbit/test_test_client.py +++ b/tests/brokers/rabbit/test_test_client.py @@ -54,7 +54,8 @@ async def test_respect_routing_key(self): broker = self.get_broker() publisher = broker.publisher( - exchange=RabbitExchange("test", type=ExchangeType.TOPIC), routing_key="up" + exchange=RabbitExchange("test", type=ExchangeType.TOPIC), + routing_key="up", ) async with self.patch_broker(broker): @@ -215,25 +216,25 @@ async def handler(msg: RabbitMessage): async def handler2(msg: RabbitMessage): await msg.raw_message.nack() consume2.set() - raise ValueError() + raise ValueError @broker.subscriber(queue=queue + "2", exchange=exchange, retry=1) async def handler3(msg: RabbitMessage): await msg.raw_message.reject() consume3.set() - raise ValueError() + raise ValueError async with self.patch_broker(broker) as br: await asyncio.wait( ( asyncio.create_task( - br.publish("hello", queue=queue, exchange=exchange) + br.publish("hello", queue=queue, exchange=exchange), ), asyncio.create_task( - br.publish("hello", queue=queue + "1", exchange=exchange) + br.publish("hello", queue=queue + "1", exchange=exchange), ), asyncio.create_task( - br.publish("hello", queue=queue + "2", exchange=exchange) + br.publish("hello", queue=queue + "2", exchange=exchange), ), asyncio.create_task(consume.wait()), asyncio.create_task(consume2.wait()), @@ -303,7 +304,8 @@ async def test_broker_with_real_doesnt_get_patched(self): @pytest.mark.rabbit async def test_broker_with_real_patches_publishers_and_subscribers( - self, queue: str + self, + queue: str, ): await super().test_broker_with_real_patches_publishers_and_subscribers(queue) @@ -321,7 +323,10 @@ async def test_broker_with_real_patches_publishers_and_subscribers( pytest.param("#.test.*.*", "1.2.test.1.2", True, id="#.test.*."), pytest.param("#.test.*.*.*", "1.2.test.1.2", False, id="#.test.*.*.* - broken"), pytest.param( - "#.test.*.test.#", "1.2.test.1.test.1.2", True, id="#.test.*.test.#" + "#.test.*.test.#", + "1.2.test.1.test.1.2", + True, + id="#.test.*.test.#", ), pytest.param("#.*.test", "1.2.2.test", True, id="#.*.test"), pytest.param("#.2.*.test", "1.2.2.test", True, id="#.2.*.test"), diff --git a/tests/brokers/rabbit/test_test_reentrancy.py b/tests/brokers/rabbit/test_test_reentrancy.py index 5cc6bd3e77..4e4225eb80 100644 --- a/tests/brokers/rabbit/test_test_reentrancy.py +++ b/tests/brokers/rabbit/test_test_reentrancy.py @@ -63,7 +63,7 @@ async def on_output_data(msg: int): reason=( "Failed due `on_output_data` subscriber creates inside test and doesn't removed after " "https://github.com/airtai/faststream/issues/556" - ) + ), ) async def test_with_temp_subscriber(): await _test_with_temp_subscriber() diff --git a/tests/brokers/redis/test_consume.py b/tests/brokers/redis/test_consume.py index a0256969a3..5894bbbe4d 100644 --- a/tests/brokers/redis/test_consume.py +++ b/tests/brokers/redis/test_consume.py @@ -164,7 +164,7 @@ async def test_consume_list_batch_with_one( consume_broker = self.get_broker() @consume_broker.subscriber( - list=ListSub(queue, batch=True, polling_interval=0.01) + list=ListSub(queue, batch=True, polling_interval=0.01), ) async def handler(msg): mock(msg) @@ -193,7 +193,7 @@ async def test_consume_list_batch_headers( consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber( - list=ListSub(queue, batch=True, polling_interval=0.01) + list=ListSub(queue, batch=True, polling_interval=0.01), ) def subscriber(m, msg: RedisMessage): check = all( @@ -202,7 +202,7 @@ def subscriber(m, msg: RedisMessage): msg.headers["correlation_id"] == msg.batch_headers[0]["correlation_id"], msg.headers.get("custom") == "1", - ) + ), ) mock(check) event.set() @@ -212,7 +212,7 @@ def subscriber(m, msg: RedisMessage): await asyncio.wait( ( asyncio.create_task( - br.publish("", list=queue, headers={"custom": "1"}) + br.publish("", list=queue, headers={"custom": "1"}), ), asyncio.create_task(event.wait()), ), @@ -232,7 +232,7 @@ async def test_consume_list_batch( msgs_queue = asyncio.Queue(maxsize=1) @consume_broker.subscriber( - list=ListSub(queue, batch=True, polling_interval=0.01) + list=ListSub(queue, batch=True, polling_interval=0.01), ) async def handler(msg): await msgs_queue.put(msg) @@ -267,7 +267,7 @@ def __hash__(self): msgs_queue = asyncio.Queue(maxsize=1) @consume_broker.subscriber( - list=ListSub(queue, batch=True, polling_interval=0.01) + list=ListSub(queue, batch=True, polling_interval=0.01), ) async def handler(msg: List[Data]): await msgs_queue.put(msg) @@ -294,7 +294,7 @@ async def test_consume_list_batch_native( msgs_queue = asyncio.Queue(maxsize=1) @consume_broker.subscriber( - list=ListSub(queue, batch=True, polling_interval=0.01) + list=ListSub(queue, batch=True, polling_interval=0.01), ) async def handler(msg): await msgs_queue.put(msg) @@ -413,7 +413,7 @@ async def handler(msg): await asyncio.wait( ( asyncio.create_task( - br._connection.xadd(queue, {"message": "hello"}) + br._connection.xadd(queue, {"message": "hello"}), ), asyncio.create_task(event.wait()), ), @@ -432,7 +432,7 @@ async def test_consume_stream_batch( consume_broker = self.get_broker() @consume_broker.subscriber( - stream=StreamSub(queue, polling_interval=10, batch=True) + stream=StreamSub(queue, polling_interval=10, batch=True), ) async def handler(msg): mock(msg) @@ -461,7 +461,7 @@ async def test_consume_stream_batch_headers( consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber( - stream=StreamSub(queue, polling_interval=10, batch=True) + stream=StreamSub(queue, polling_interval=10, batch=True), ) def subscriber(m, msg: RedisMessage): check = all( @@ -470,7 +470,7 @@ def subscriber(m, msg: RedisMessage): msg.headers["correlation_id"] == msg.batch_headers[0]["correlation_id"], msg.headers.get("custom") == "1", - ) + ), ) mock(check) event.set() @@ -480,7 +480,7 @@ def subscriber(m, msg: RedisMessage): await asyncio.wait( ( asyncio.create_task( - br.publish("", stream=queue, headers={"custom": "1"}) + br.publish("", stream=queue, headers={"custom": "1"}), ), asyncio.create_task(event.wait()), ), @@ -505,7 +505,7 @@ class Data(BaseModel): msgs_queue = asyncio.Queue(maxsize=1) @consume_broker.subscriber( - stream=StreamSub(queue, polling_interval=10, batch=True) + stream=StreamSub(queue, polling_interval=10, batch=True), ) async def handler(msg: List[Data]): await msgs_queue.put(msg) @@ -532,7 +532,7 @@ async def test_consume_stream_batch_native( consume_broker = self.get_broker() @consume_broker.subscriber( - stream=StreamSub(queue, polling_interval=10, batch=True) + stream=StreamSub(queue, polling_interval=10, batch=True), ) async def handler(msg): mock(msg) @@ -544,7 +544,7 @@ async def handler(msg): await asyncio.wait( ( asyncio.create_task( - br._connection.xadd(queue, {"message": "hello"}) + br._connection.xadd(queue, {"message": "hello"}), ), asyncio.create_task(event.wait()), ), @@ -560,7 +560,7 @@ async def test_consume_group( consume_broker = self.get_broker() @consume_broker.subscriber( - stream=StreamSub(queue, group="group", consumer=queue) + stream=StreamSub(queue, group="group", consumer=queue), ) async def handler(msg: RedisMessage): ... @@ -573,7 +573,7 @@ async def test_consume_group_with_last_id( consume_broker = self.get_broker() @consume_broker.subscriber( - stream=StreamSub(queue, group="group", consumer=queue, last_id="0") + stream=StreamSub(queue, group="group", consumer=queue, last_id="0"), ) async def handler(msg: RedisMessage): ... @@ -587,7 +587,7 @@ async def test_consume_nack( consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber( - stream=StreamSub(queue, group="group", consumer=queue) + stream=StreamSub(queue, group="group", consumer=queue), ) async def handler(msg: RedisMessage): event.set() @@ -617,7 +617,7 @@ async def test_consume_ack( consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber( - stream=StreamSub(queue, group="group", consumer=queue) + stream=StreamSub(queue, group="group", consumer=queue), ) async def handler(msg: RedisMessage): event.set() diff --git a/tests/brokers/redis/test_fastapi.py b/tests/brokers/redis/test_fastapi.py index 6e36a8c69e..b9aefbcb2a 100644 --- a/tests/brokers/redis/test_fastapi.py +++ b/tests/brokers/redis/test_fastapi.py @@ -43,7 +43,8 @@ def subscriber(msg: str, name: str): async def test_connection_params(self, settings): broker = self.router_class( - host="fake-host", port=6377 + host="fake-host", + port=6377, ).broker # kwargs will be ignored await broker.connect( host=settings.host, diff --git a/tests/brokers/redis/test_test_client.py b/tests/brokers/redis/test_test_client.py index e38c3e3445..7da78ca450 100644 --- a/tests/brokers/redis/test_test_client.py +++ b/tests/brokers/redis/test_test_client.py @@ -228,6 +228,7 @@ async def test_broker_with_real_doesnt_get_patched(self): @pytest.mark.redis async def test_broker_with_real_patches_publishers_and_subscribers( - self, queue: str + self, + queue: str, ): await super().test_broker_with_real_patches_publishers_and_subscribers(queue) diff --git a/tests/cli/rabbit/test_app.py b/tests/cli/rabbit/test_app.py index a2a7657372..69461368f9 100644 --- a/tests/cli/rabbit/test_app.py +++ b/tests/cli/rabbit/test_app.py @@ -122,8 +122,13 @@ async def call2(): test_app = FastStream(broker, after_startup=[call1, call2]) - with patch.object(test_app.broker, "start", async_mock.broker_start), patch.object( - test_app.broker, "connect", async_mock.broker_connect + with ( + patch.object(test_app.broker, "start", async_mock.broker_start), + patch.object( + test_app.broker, + "connect", + async_mock.broker_connect, + ), ): await test_app.start() @@ -133,7 +138,8 @@ async def call2(): @pytest.mark.asyncio async def test_startup_lifespan_before_broker_started( - async_mock: AsyncMock, app: FastStream + async_mock: AsyncMock, + app: FastStream, ): @app.on_startup async def call(): @@ -146,8 +152,13 @@ async def call_after(): async_mock.before.assert_awaited_once() async_mock.broker_start.assert_called_once() - with patch.object(app.broker, "start", async_mock.broker_start), patch.object( - app.broker, "connect", async_mock.broker_connect + with ( + patch.object(app.broker, "start", async_mock.broker_start), + patch.object( + app.broker, + "connect", + async_mock.broker_connect, + ), ): await app.start() @@ -168,8 +179,13 @@ async def call2(): test_app = FastStream(broker, after_shutdown=[call1, call2]) - with patch.object(test_app.broker, "start", async_mock.broker_start), patch.object( - test_app.broker, "connect", async_mock.broker_connect + with ( + patch.object(test_app.broker, "start", async_mock.broker_start), + patch.object( + test_app.broker, + "connect", + async_mock.broker_connect, + ), ): await test_app.stop() @@ -179,7 +195,9 @@ async def call2(): @pytest.mark.asyncio async def test_shutdown_lifespan_after_broker_stopped( - mock, async_mock: AsyncMock, app: FastStream + mock, + async_mock: AsyncMock, + app: FastStream, ): @app.after_shutdown async def call(): @@ -203,9 +221,15 @@ async def call_before(): async def test_running(async_mock: AsyncMock, app: FastStream): app.exit() - with patch.object(app.broker, "start", async_mock.broker_run), patch.object( - app.broker, "connect", async_mock.broker_connect - ), patch.object(app.broker, "close", async_mock.broker_stopped): + with ( + patch.object(app.broker, "start", async_mock.broker_run), + patch.object( + app.broker, + "connect", + async_mock.broker_connect, + ), + patch.object(app.broker, "close", async_mock.broker_stopped), + ): await app.run() async_mock.broker_connect.assert_called_once() @@ -227,7 +251,9 @@ async def f(): @pytest.mark.asyncio async def test_running_lifespan_contextmanager( - async_mock: AsyncMock, mock: Mock, app: FastStream + async_mock: AsyncMock, + mock: Mock, + app: FastStream, ): @asynccontextmanager async def lifespan(env: str): @@ -238,9 +264,15 @@ async def lifespan(env: str): app = FastStream(app.broker, lifespan=lifespan) app.exit() - with patch.object(app.broker, "start", async_mock.broker_run), patch.object( - app.broker, "connect", async_mock.broker_connect - ), patch.object(app.broker, "close", async_mock.broker_stopped): + with ( + patch.object(app.broker, "start", async_mock.broker_run), + patch.object( + app.broker, + "connect", + async_mock.broker_connect, + ), + patch.object(app.broker, "close", async_mock.broker_stopped), + ): await app.run(run_extra_options={"env": "test"}) async_mock.broker_connect.assert_called_once() @@ -274,7 +306,7 @@ async def test_test_app_with_excp(mock: Mock): with pytest.raises(ValueError): # noqa: PT011 async with TestApp(app): - raise ValueError() + raise ValueError mock.on.assert_called_once() mock.off.assert_called_once() @@ -300,7 +332,7 @@ def test_sync_test_app_with_excp(mock: Mock): app.on_shutdown(mock.off) with pytest.raises(ValueError), TestApp(app): # noqa: PT011 - raise ValueError() + raise ValueError mock.on.assert_called_once() mock.off.assert_called_once() @@ -316,9 +348,15 @@ async def lifespan(env: str): app = FastStream(app.broker, lifespan=lifespan) - with patch.object(app.broker, "start", async_mock.broker_run), patch.object( - app.broker, "connect", async_mock.broker_connect - ), patch.object(app.broker, "close", async_mock.broker_stopped): + with ( + patch.object(app.broker, "start", async_mock.broker_run), + patch.object( + app.broker, + "connect", + async_mock.broker_connect, + ), + patch.object(app.broker, "close", async_mock.broker_stopped), + ): async with TestApp(app, {"env": "test"}): pass @@ -338,10 +376,18 @@ async def lifespan(env: str): app = FastStream(app.broker, lifespan=lifespan) - with patch.object(app.broker, "start", async_mock.broker_run), patch.object( - app.broker, "close", async_mock.broker_stopped - ), patch.object(app.broker, "connect", async_mock.broker_connect), TestApp( - app, {"env": "test"} + with ( + patch.object(app.broker, "start", async_mock.broker_run), + patch.object( + app.broker, + "close", + async_mock.broker_stopped, + ), + patch.object(app.broker, "connect", async_mock.broker_connect), + TestApp( + app, + {"env": "test"}, + ), ): pass @@ -355,9 +401,15 @@ async def lifespan(env: str): @pytest.mark.asyncio @pytest.mark.skipif(IS_WINDOWS, reason="does not run on windows") async def test_stop_with_sigint(async_mock, app: FastStream): - with patch.object(app.broker, "start", async_mock.broker_run_sigint), patch.object( - app.broker, "connect", async_mock.broker_connect - ), patch.object(app.broker, "close", async_mock.broker_stopped_sigint): + with ( + patch.object(app.broker, "start", async_mock.broker_run_sigint), + patch.object( + app.broker, + "connect", + async_mock.broker_connect, + ), + patch.object(app.broker, "close", async_mock.broker_stopped_sigint), + ): async with anyio.create_task_group() as tg: tg.start_soon(app.run) tg.start_soon(_kill, signal.SIGINT) @@ -370,9 +422,15 @@ async def test_stop_with_sigint(async_mock, app: FastStream): @pytest.mark.asyncio @pytest.mark.skipif(IS_WINDOWS, reason="does not run on windows") async def test_stop_with_sigterm(async_mock, app: FastStream): - with patch.object(app.broker, "start", async_mock.broker_run_sigterm), patch.object( - app.broker, "connect", async_mock.broker_connect - ), patch.object(app.broker, "close", async_mock.broker_stopped_sigterm): + with ( + patch.object(app.broker, "start", async_mock.broker_run_sigterm), + patch.object( + app.broker, + "connect", + async_mock.broker_connect, + ), + patch.object(app.broker, "close", async_mock.broker_stopped_sigterm), + ): async with anyio.create_task_group() as tg: tg.start_soon(app.run) tg.start_soon(_kill, signal.SIGTERM) @@ -396,9 +454,15 @@ async def test_run_asgi(async_mock: AsyncMock, app: FastStream): assert asgi_app._after_shutdown_calling is app._after_shutdown_calling assert asgi_app.routes == asgi_routes - with patch.object(app.broker, "start", async_mock.broker_run), patch.object( - app.broker, "connect", async_mock.broker_connect - ), patch.object(app.broker, "close", async_mock.broker_stopped): + with ( + patch.object(app.broker, "start", async_mock.broker_run), + patch.object( + app.broker, + "connect", + async_mock.broker_connect, + ), + patch.object(app.broker, "close", async_mock.broker_stopped), + ): async with anyio.create_task_group() as tg: tg.start_soon(app.run) tg.start_soon(_kill, signal.SIGINT) diff --git a/tests/cli/test_asyncapi_docs.py b/tests/cli/test_asyncapi_docs.py index 42b24a2c08..3994339065 100644 --- a/tests/cli/test_asyncapi_docs.py +++ b/tests/cli/test_asyncapi_docs.py @@ -24,7 +24,8 @@ @require_aiokafka def test_gen_asyncapi_json_for_kafka_app(runner: CliRunner, kafka_basic_project: Path): r = runner.invoke( - cli, [*GEN_JSON_CMD, "--out", "schema.json", str(kafka_basic_project)] + cli, + [*GEN_JSON_CMD, "--out", "schema.json", str(kafka_basic_project)], ) assert r.exit_code == 0 diff --git a/tests/cli/test_publish.py b/tests/cli/test_publish.py index d73382a771..00100a5373 100644 --- a/tests/cli/test_publish.py +++ b/tests/cli/test_publish.py @@ -197,7 +197,7 @@ def test_publish_command_with_rabbit_options(runner): assert producer_mock.publish.call_args.kwargs == IsPartialDict( { "correlation_id": "someId", - } + }, ) diff --git a/tests/cli/test_run.py b/tests/cli/test_run.py index 12ea46747a..881948b105 100644 --- a/tests/cli/test_run.py +++ b/tests/cli/test_run.py @@ -13,7 +13,8 @@ def test_run_as_asgi(runner: CliRunner): app.run = AsyncMock() with patch( - "faststream._internal.cli.main.import_from_string", return_value=(None, app) + "faststream._internal.cli.main.import_from_string", + return_value=(None, app), ): result = runner.invoke( faststream_app, @@ -27,7 +28,8 @@ def test_run_as_asgi(runner: CliRunner): ], ) app.run.assert_awaited_once_with( - logging.INFO, {"host": "0.0.0.0", "port": "8000"} + logging.INFO, + {"host": "0.0.0.0", "port": "8000"}, ) assert result.exit_code == 0 @@ -38,7 +40,8 @@ def test_run_as_asgi_with_workers(runner: CliRunner, workers: int): app.run = AsyncMock() with patch( - "faststream._internal.cli.main.import_from_string", return_value=(None, app) + "faststream._internal.cli.main.import_from_string", + return_value=(None, app), ): result = runner.invoke( faststream_app, @@ -56,7 +59,8 @@ def test_run_as_asgi_with_workers(runner: CliRunner, workers: int): extra = {"workers": workers} if workers > 1 else {} app.run.assert_awaited_once_with( - logging.INFO, {"host": "0.0.0.0", "port": "8000", **extra} + logging.INFO, + {"host": "0.0.0.0", "port": "8000", **extra}, ) assert result.exit_code == 0 @@ -85,6 +89,7 @@ def test_run_as_asgi_callable(runner: CliRunner): ) app_factory.assert_called_once() app.run.assert_awaited_once_with( - logging.INFO, {"host": "0.0.0.0", "port": "8000"} + logging.INFO, + {"host": "0.0.0.0", "port": "8000"}, ) assert result.exit_code == 0 diff --git a/tests/mocks.py b/tests/mocks.py index 3482444b68..b6b50e78b6 100644 --- a/tests/mocks.py +++ b/tests/mocks.py @@ -11,6 +11,7 @@ def mock_pydantic_settings_env(env_mapping: Mapping[str, Any]): mock = Mock() mock.return_value = env_mapping c.setattr( - "pydantic_settings.sources.DotEnvSettingsSource._read_env_files", mock + "pydantic_settings.sources.DotEnvSettingsSource._read_env_files", + mock, ) yield diff --git a/tests/mypy/kafka.py b/tests/mypy/kafka.py index 043639ddb2..c689d33a92 100644 --- a/tests/mypy/kafka.py +++ b/tests/mypy/kafka.py @@ -16,7 +16,8 @@ async def async_decoder(msg: KafkaMessage) -> DecodedMessage: async def custom_decoder( - msg: KafkaMessage, original: Callable[[KafkaMessage], Awaitable[DecodedMessage]] + msg: KafkaMessage, + original: Callable[[KafkaMessage], Awaitable[DecodedMessage]], ) -> DecodedMessage: return await original(msg) @@ -35,7 +36,8 @@ async def async_parser(msg: ConsumerRecord) -> KafkaMessage: async def custom_parser( - msg: ConsumerRecord, original: Callable[[ConsumerRecord], Awaitable[KafkaMessage]] + msg: ConsumerRecord, + original: Callable[[ConsumerRecord], Awaitable[KafkaMessage]], ) -> KafkaMessage: return await original(msg) @@ -197,7 +199,7 @@ def async_handler() -> None: ... parser=custom_parser, decoder=custom_decoder, ), - ) + ), ) diff --git a/tests/mypy/nats.py b/tests/mypy/nats.py index 7330ca4b1f..7df320fb44 100644 --- a/tests/mypy/nats.py +++ b/tests/mypy/nats.py @@ -16,7 +16,8 @@ async def async_decoder(msg: NatsMessage) -> DecodedMessage: async def custom_decoder( - msg: NatsMessage, original: Callable[[NatsMessage], Awaitable[DecodedMessage]] + msg: NatsMessage, + original: Callable[[NatsMessage], Awaitable[DecodedMessage]], ) -> DecodedMessage: return await original(msg) @@ -35,7 +36,8 @@ async def async_parser(msg: Msg) -> NatsMessage: async def custom_parser( - msg: Msg, original: Callable[[Msg], Awaitable[NatsMessage]] + msg: Msg, + original: Callable[[Msg], Awaitable[NatsMessage]], ) -> NatsMessage: return await original(msg) @@ -198,7 +200,7 @@ def async_handler() -> None: ... parser=custom_parser, decoder=custom_decoder, ), - ) + ), ) diff --git a/tests/mypy/rabbit.py b/tests/mypy/rabbit.py index 6c79509136..c8e3a35535 100644 --- a/tests/mypy/rabbit.py +++ b/tests/mypy/rabbit.py @@ -16,7 +16,8 @@ async def async_decoder(msg: RabbitMessage) -> DecodedMessage: async def custom_decoder( - msg: RabbitMessage, original: Callable[[RabbitMessage], Awaitable[DecodedMessage]] + msg: RabbitMessage, + original: Callable[[RabbitMessage], Awaitable[DecodedMessage]], ) -> DecodedMessage: return await original(msg) @@ -198,7 +199,7 @@ def async_handler() -> None: ... parser=custom_parser, decoder=custom_decoder, ), - ) + ), ) diff --git a/tests/mypy/redis.py b/tests/mypy/redis.py index 3ee2088f89..a926408759 100644 --- a/tests/mypy/redis.py +++ b/tests/mypy/redis.py @@ -18,7 +18,8 @@ async def async_decoder(msg: Message) -> DecodedMessage: async def custom_decoder( - msg: Message, original: Callable[[Message], Awaitable[DecodedMessage]] + msg: Message, + original: Callable[[Message], Awaitable[DecodedMessage]], ) -> DecodedMessage: return await original(msg) @@ -37,7 +38,8 @@ async def async_parser(msg: Msg) -> Message: async def custom_parser( - msg: Msg, original: Callable[[Msg], Awaitable[Message]] + msg: Msg, + original: Callable[[Msg], Awaitable[Message]], ) -> Message: return await original(msg) @@ -201,7 +203,7 @@ def async_handler() -> None: ... parser=custom_parser, decoder=custom_decoder, ), - ) + ), ) diff --git a/tests/opentelemetry/basic.py b/tests/opentelemetry/basic.py index 5cd8b6b0ad..44462b901d 100644 --- a/tests/opentelemetry/basic.py +++ b/tests/opentelemetry/basic.py @@ -123,7 +123,7 @@ def assert_span( if action == Action.PROCESS: assert attrs[SpanAttr.MESSAGING_MESSAGE_PAYLOAD_SIZE_BYTES] == len( - msg + msg, ), attrs[SpanAttr.MESSAGING_MESSAGE_PAYLOAD_SIZE_BYTES] assert attrs[SpanAttr.MESSAGING_OPERATION] == action, attrs[ SpanAttr.MESSAGING_OPERATION @@ -439,8 +439,10 @@ async def handler1(m, baggage: CurrentBaggage): tasks = ( asyncio.create_task( broker.publish( - msg, queue, headers=Baggage({"foo": "bar"}).to_headers() - ) + msg, + queue, + headers=Baggage({"foo": "bar"}).to_headers(), + ), ), asyncio.create_task(event.wait()), ) @@ -486,8 +488,10 @@ async def handler2(m, baggage: CurrentBaggage): tasks = ( asyncio.create_task( broker.publish( - msg, first_queue, headers=Baggage({"foo": "bar"}).to_headers() - ) + msg, + first_queue, + headers=Baggage({"foo": "bar"}).to_headers(), + ), ), asyncio.create_task(event.wait()), ) @@ -535,8 +539,10 @@ async def handler2(m, baggage: CurrentBaggage): tasks = ( asyncio.create_task( broker.publish( - msg, first_queue, headers=Baggage({"foo": "bar"}).to_headers() - ) + msg, + first_queue, + headers=Baggage({"foo": "bar"}).to_headers(), + ), ), asyncio.create_task(event.wait()), ) diff --git a/tests/opentelemetry/confluent/test_confluent.py b/tests/opentelemetry/confluent/test_confluent.py index 4d9844a6e6..195ee10e50 100644 --- a/tests/opentelemetry/confluent/test_confluent.py +++ b/tests/opentelemetry/confluent/test_confluent.py @@ -73,7 +73,8 @@ async def test_batch( trace_exporter: InMemorySpanExporter, ): mid = self.telemetry_middleware_class( - meter_provider=meter_provider, tracer_provider=tracer_provider + meter_provider=meter_provider, + tracer_provider=tracer_provider, ) broker = self.get_broker(middlewares=(mid,), apply_types=True) expected_msg_count = 3 @@ -81,7 +82,7 @@ async def test_batch( expected_link_attrs = {"messaging.batch.message_count": 3} expected_baggage = {"with_batch": "True", "foo": "bar"} expected_baggage_batch = [ - {"with_batch": "True", "foo": "bar"} + {"with_batch": "True", "foo": "bar"}, ] * expected_msg_count args, kwargs = self.get_subscriber_params(queue, batch=True) @@ -103,7 +104,7 @@ async def handler(m, baggage: CurrentBaggage): 3, topic=queue, headers=Baggage({"foo": "bar"}).to_headers(), - ) + ), ), asyncio.create_task(event.wait()), ) @@ -137,7 +138,8 @@ async def test_batch_publish_with_single_consume( trace_exporter: InMemorySpanExporter, ): mid = self.telemetry_middleware_class( - meter_provider=meter_provider, tracer_provider=tracer_provider + meter_provider=meter_provider, + tracer_provider=tracer_provider, ) broker = self.get_broker(middlewares=(mid,), apply_types=True) msgs_queue = asyncio.Queue(maxsize=3) @@ -158,7 +160,11 @@ async def handler(msg, baggage: CurrentBaggage): async with self.patch_broker(broker) as br: await br.start() await br.publish_batch( - 1, "hi", 3, topic=queue, headers=Baggage({"foo": "bar"}).to_headers() + 1, + "hi", + 3, + topic=queue, + headers=Baggage({"foo": "bar"}).to_headers(), ) result, _ = await asyncio.wait( ( @@ -201,7 +207,8 @@ async def test_single_publish_with_batch_consume( trace_exporter: InMemorySpanExporter, ): mid = self.telemetry_middleware_class( - meter_provider=meter_provider, tracer_provider=tracer_provider + meter_provider=meter_provider, + tracer_provider=tracer_provider, ) broker = self.get_broker(middlewares=(mid,), apply_types=True) expected_msg_count = 2 @@ -225,13 +232,17 @@ async def handler(m, baggage: CurrentBaggage): tasks = ( asyncio.create_task( br.publish( - "hi", topic=queue, headers=Baggage({"foo": "bar"}).to_headers() - ) + "hi", + topic=queue, + headers=Baggage({"foo": "bar"}).to_headers(), + ), ), asyncio.create_task( br.publish( - "buy", topic=queue, headers=Baggage({"bar": "baz"}).to_headers() - ) + "buy", + topic=queue, + headers=Baggage({"bar": "baz"}).to_headers(), + ), ), asyncio.create_task(event.wait()), ) diff --git a/tests/opentelemetry/kafka/test_kafka.py b/tests/opentelemetry/kafka/test_kafka.py index db2249c1a2..3e50fc329c 100644 --- a/tests/opentelemetry/kafka/test_kafka.py +++ b/tests/opentelemetry/kafka/test_kafka.py @@ -74,7 +74,8 @@ async def test_batch( trace_exporter: InMemorySpanExporter, ): mid = self.telemetry_middleware_class( - meter_provider=meter_provider, tracer_provider=tracer_provider + meter_provider=meter_provider, + tracer_provider=tracer_provider, ) broker = self.get_broker(middlewares=(mid,), apply_types=True) expected_msg_count = 3 @@ -82,7 +83,7 @@ async def test_batch( expected_link_attrs = {"messaging.batch.message_count": 3} expected_baggage = {"with_batch": "True", "foo": "bar"} expected_baggage_batch = [ - {"with_batch": "True", "foo": "bar"} + {"with_batch": "True", "foo": "bar"}, ] * expected_msg_count args, kwargs = self.get_subscriber_params(queue, batch=True) @@ -104,7 +105,7 @@ async def handler(m, baggage: CurrentBaggage): 3, topic=queue, headers=Baggage({"foo": "bar"}).to_headers(), - ) + ), ), asyncio.create_task(event.wait()), ) @@ -138,7 +139,8 @@ async def test_batch_publish_with_single_consume( trace_exporter: InMemorySpanExporter, ): mid = self.telemetry_middleware_class( - meter_provider=meter_provider, tracer_provider=tracer_provider + meter_provider=meter_provider, + tracer_provider=tracer_provider, ) broker = self.get_broker(middlewares=(mid,), apply_types=True) msgs_queue = asyncio.Queue(maxsize=3) @@ -159,7 +161,11 @@ async def handler(msg, baggage: CurrentBaggage): async with self.patch_broker(broker) as br: await br.start() await br.publish_batch( - 1, "hi", 3, topic=queue, headers=Baggage({"foo": "bar"}).to_headers() + 1, + "hi", + 3, + topic=queue, + headers=Baggage({"foo": "bar"}).to_headers(), ) result, _ = await asyncio.wait( ( @@ -202,7 +208,8 @@ async def test_single_publish_with_batch_consume( trace_exporter: InMemorySpanExporter, ): mid = self.telemetry_middleware_class( - meter_provider=meter_provider, tracer_provider=tracer_provider + meter_provider=meter_provider, + tracer_provider=tracer_provider, ) broker = self.get_broker(middlewares=(mid,), apply_types=True) expected_msg_count = 2 @@ -226,13 +233,17 @@ async def handler(m, baggage: CurrentBaggage): tasks = ( asyncio.create_task( br.publish( - "hi", topic=queue, headers=Baggage({"foo": "bar"}).to_headers() - ) + "hi", + topic=queue, + headers=Baggage({"foo": "bar"}).to_headers(), + ), ), asyncio.create_task( br.publish( - "buy", topic=queue, headers=Baggage({"bar": "baz"}).to_headers() - ) + "buy", + topic=queue, + headers=Baggage({"bar": "baz"}).to_headers(), + ), ), asyncio.create_task(event.wait()), ) diff --git a/tests/opentelemetry/nats/test_nats.py b/tests/opentelemetry/nats/test_nats.py index 6d03d901c8..c34e648e7b 100644 --- a/tests/opentelemetry/nats/test_nats.py +++ b/tests/opentelemetry/nats/test_nats.py @@ -42,7 +42,8 @@ async def test_batch( trace_exporter: InMemorySpanExporter, ): mid = self.telemetry_middleware_class( - meter_provider=meter_provider, tracer_provider=tracer_provider + meter_provider=meter_provider, + tracer_provider=tracer_provider, ) broker = self.get_broker(middlewares=(mid,)) expected_msg_count = 1 diff --git a/tests/opentelemetry/redis/test_redis.py b/tests/opentelemetry/redis/test_redis.py index 871e347a2b..7913cc818c 100644 --- a/tests/opentelemetry/redis/test_redis.py +++ b/tests/opentelemetry/redis/test_redis.py @@ -41,7 +41,8 @@ async def test_batch( trace_exporter: InMemorySpanExporter, ): mid = self.telemetry_middleware_class( - meter_provider=meter_provider, tracer_provider=tracer_provider + meter_provider=meter_provider, + tracer_provider=tracer_provider, ) broker = self.get_broker(middlewares=(mid,), apply_types=True) expected_msg_count = 3 @@ -95,7 +96,8 @@ async def test_batch_publish_with_single_consume( trace_exporter: InMemorySpanExporter, ): mid = self.telemetry_middleware_class( - meter_provider=meter_provider, tracer_provider=tracer_provider + meter_provider=meter_provider, + tracer_provider=tracer_provider, ) broker = self.get_broker(middlewares=(mid,), apply_types=True) msgs_queue = asyncio.Queue(maxsize=3) @@ -158,7 +160,8 @@ async def test_single_publish_with_batch_consume( trace_exporter: InMemorySpanExporter, ): mid = self.telemetry_middleware_class( - meter_provider=meter_provider, tracer_provider=tracer_provider + meter_provider=meter_provider, + tracer_provider=tracer_provider, ) broker = self.get_broker(middlewares=(mid,), apply_types=True) expected_msg_count = 2 @@ -181,19 +184,24 @@ async def handler(m, baggage: CurrentBaggage): tasks = ( asyncio.create_task( br.publish( - "hi", list=queue, headers=Baggage({"foo": "bar"}).to_headers() - ) + "hi", + list=queue, + headers=Baggage({"foo": "bar"}).to_headers(), + ), ), asyncio.create_task( br.publish( - "buy", list=queue, headers=Baggage({"bar": "baz"}).to_headers() - ) + "buy", + list=queue, + headers=Baggage({"bar": "baz"}).to_headers(), + ), ), ) await asyncio.wait(tasks, timeout=self.timeout) await broker.start() await asyncio.wait( - (asyncio.create_task(event.wait()),), timeout=self.timeout + (asyncio.create_task(event.wait()),), + timeout=self.timeout, ) metrics = self.get_metrics(metric_reader) diff --git a/tests/tools.py b/tests/tools.py index 3ff9f57186..6d56d3a5ab 100644 --- a/tests/tools.py +++ b/tests/tools.py @@ -13,6 +13,7 @@ def spy_decorator(method): async def wrapper(*args, **kwargs): mock(*args, **kwargs) return await method(*args, **kwargs) + else: @wraps(method) diff --git a/tests/utils/context/test_main.py b/tests/utils/context/test_main.py index 6f9b889452..43d27416e8 100644 --- a/tests/utils/context/test_main.py +++ b/tests/utils/context/test_main.py @@ -149,8 +149,13 @@ def use( assert key4 == 1 assert key5 is False - with context.scope("key", 0), context.scope("key2", True), context.scope( - "key5", {"key6": False} + with ( + context.scope("key", 0), + context.scope("key2", True), + context.scope( + "key5", + {"key6": False}, + ), ): use() diff --git a/tests/utils/test_ast.py b/tests/utils/test_ast.py index 6f226c4acc..905ae67b9f 100644 --- a/tests/utils/test_ast.py +++ b/tests/utils/test_ast.py @@ -79,4 +79,4 @@ def test_not_broken(): # test ast processes another context correctly with pytest.raises(ValueError): # noqa: PT011 - raise ValueError() + raise ValueError From 50af9e340c779d1bdd4126c08cd431cbcef83270 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Thu, 10 Oct 2024 14:02:28 +0300 Subject: [PATCH 175/245] add: NATS HowTO --- docs/docs/en/getting-started/asgi.md | 2 +- docs/docs/en/howto/nats/dynaconf.md | 94 ++++++++++++++++++++++++++++ docs/docs/en/howto/nats/index.md | 17 +++++ docs/docs/navigation_template.txt | 2 + ruff.toml | 6 +- 5 files changed, 117 insertions(+), 4 deletions(-) create mode 100644 docs/docs/en/howto/nats/dynaconf.md create mode 100644 docs/docs/en/howto/nats/index.md diff --git a/docs/docs/en/getting-started/asgi.md b/docs/docs/en/getting-started/asgi.md index 68828d9ce6..008c56741b 100644 --- a/docs/docs/en/getting-started/asgi.md +++ b/docs/docs/en/getting-started/asgi.md @@ -111,7 +111,7 @@ Now, your **AsyncAPI HTML** representation can be found by the `/docs` url. You may also use regular `FastStream` application object for similar result. -```python linenums="1" hl_lines="2 10" +```python linenums="1" hl_lines="2 11" from faststream import FastStream from faststream.nats import NatsBroker from faststream.asgi import make_ping_asgi, AsgiResponse diff --git a/docs/docs/en/howto/nats/dynaconf.md b/docs/docs/en/howto/nats/dynaconf.md new file mode 100644 index 0000000000..5c68913c80 --- /dev/null +++ b/docs/docs/en/howto/nats/dynaconf.md @@ -0,0 +1,94 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 10 +--- + +# Dynamic Config with Nats + +As **NATS** has key-value storage, you can use it as a configuration storage solution. Here is an example of how to use it with **FastStream**. + +## Subscribing to Key-Value Changes + +To subscribe to key-value changes, you can use the `KvWatch` class. The key to watch must be passed as a parameter to the class, which corresponds to a key in the storage. + +When a message is received, the global context can be updated with the new value. + +```python linenums="1" hl_lines="7-9" +from faststream import FastStream +from faststream.nats import NatsBroker, KvWatch + +broker = NatsBroker() +app = FastStream(broker) + +@broker.subscriber("create_sell", kv_watch=KvWatch("order_service")) +async def watch_kv_order_service(new_value: bool): + app.context.set_global("create_sell", new_value) +``` + +## Checking the Parameter in the Subscriber + +You can use `faststream.Context` to retrieve the parameter from the global context. + +```python linenums="1" hl_lines="10" +from faststream import FastStream, Context +from faststream.nats import NatsBroker, NatsMessage + +broker = NatsBroker() +app = FastStream(broker) + +@broker.subscriber("order_service.order.filled.buy") +async def handle_filled_buy( + message: NatsMessage, + create_sell: bool = Context("create_sell"), +): + if create_sell: + await broker.publish(b"", "order_service.order.create.sell") +``` + +!!! note + The KeyValue watcher will receive the latest value on startup. + +??? example "Full Example" + ```python linenums="1" + from uuid import uuid4 + + from faststream import FastStream, Context + from faststream.nats import NatsMessage, NatsBroker, KvWatch + + broker = NatsBroker() + app = FastStream(broker) + + @broker.subscriber("create_sell", kv_watch=KvWatch("order_service")) + async def watch_kv_order_service(new_value: bool): + app.context.set_global("create_sell", new_value) + + @broker.subscriber("order_service.order.filled.buy") + async def handle_filled_buy( + message: NatsMessage, + create_sell: bool = Context("create_sell"), + ): + if create_sell: + await broker.publish(b"", "order_service.order.create.sell") + + @broker.subscriber("order_service.order.create.sell") + async def handle_create_sell(message: NatsMessage): ... + + @app.on_startup + async def on_startup(): + await broker.connect() + + order_service_kv = await broker.key_value("order_service") + + initial_create_sell_value = b"1" + await order_service_kv.put("create_sell", initial_create_sell_value) + app.context.set_global("create_sell", bool(initial_create_sell_value)) + + @app.after_startup + async def after_startup(): + await broker.publish({"order_id": str(uuid4())}, "order_service.order.filled.buy") + ``` \ No newline at end of file diff --git a/docs/docs/en/howto/nats/index.md b/docs/docs/en/howto/nats/index.md new file mode 100644 index 0000000000..4e24c17ab2 --- /dev/null +++ b/docs/docs/en/howto/nats/index.md @@ -0,0 +1,17 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 10 +--- + +# How To + +**Nats** is a highly complex tool, so the **FastStream** `NatsBroker` API can be complicated and confusing in specific cases. Our main documentation sections cover only the primary **FastStream** and **Nats** concepts. Therefore, this section provides concrete **FastStream - Nats** examples that you can use in your regular services as copy-paste code or, at the very least, as a reference. + +We (**airt** team) hope that this section will be maintained by the community. Please feel free to add any examples/sections or edit existing ones. If you haven't found the solution in the docs yet, this is a great opportunity to add a new article here! + +To add a new page to this section, simply add a new **Markdown** file to the [`docs/docs/en/howto/nats`](https://github.com/airtai/faststream/tree/main/docs/docs/en/howto/nats){.external-link target="_blank"} directory and update the [`navigation_template.txt`](https://github.com/airtai/faststream/blob/main/docs/docs/navigation_template.txt){.external-link target="_blank"} file. \ No newline at end of file diff --git a/docs/docs/navigation_template.txt b/docs/docs/navigation_template.txt index 34104970ee..4cd45d0874 100644 --- a/docs/docs/navigation_template.txt +++ b/docs/docs/navigation_template.txt @@ -95,6 +95,8 @@ search: - [Publishing](nats/publishing/index.md) - [RPC](nats/rpc.md) - [Message Information](nats/message.md) + - [How-To](howto/nats/index.md) + - [DynaConf](howto/nats/dynaconf.md) - [Redis](redis/index.md) - [Pub/Sub](redis/pubsub/index.md) - [Subscription](redis/pubsub/subscription.md) diff --git a/ruff.toml b/ruff.toml index 561f2d7f54..5cf4479d4e 100644 --- a/ruff.toml +++ b/ruff.toml @@ -39,7 +39,7 @@ ignore = [ "SLOT", "ARG", "EXE", - + "ASYNC109", "ANN401", "COM812", @@ -57,7 +57,7 @@ ignore = [ "E501", # line too long, handled by formatter later "C901", # too complex - + # preview "CPY", "PLC0415", @@ -156,4 +156,4 @@ fixture-parentheses = true mark-parentheses = true parametrize-names-type = "tuple" parametrize-values-type = "tuple" -parametrize-values-row-type = "tuple" \ No newline at end of file +parametrize-values-row-type = "tuple" From aa6dc13c723f6c482dfca325b309fd89189d1985 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Thu, 17 Oct 2024 22:00:43 +0300 Subject: [PATCH 176/245] rm useless change --- faststream/_internal/application.py | 1 - 1 file changed, 1 deletion(-) diff --git a/faststream/_internal/application.py b/faststream/_internal/application.py index 2355f0e918..15c389b6e8 100644 --- a/faststream/_internal/application.py +++ b/faststream/_internal/application.py @@ -101,7 +101,6 @@ def __init__( context.set_global("app", self) - self.broker = broker self.logger = logger self.context = context From f63df92fee629ac1a3285026182ff6c9c3a2b93b Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Fri, 18 Oct 2024 17:22:04 +0300 Subject: [PATCH 177/245] refactor: create publisher factory --- faststream/_internal/publisher/proto.py | 6 - faststream/_internal/publisher/usecase.py | 4 +- faststream/confluent/broker/registrator.py | 9 +- faststream/confluent/fastapi/__init__.py | 3 +- faststream/confluent/fastapi/fastapi.py | 4 +- faststream/confluent/publisher/factory.py | 139 +++++++++++++ faststream/confluent/publisher/publisher.py | 190 ------------------ faststream/confluent/publisher/specified.py | 58 ++++++ faststream/confluent/subscriber/factory.py | 2 +- .../{subscriber.py => specified.py} | 0 faststream/confluent/testing.py | 16 +- faststream/kafka/broker/registrator.py | 8 +- faststream/kafka/fastapi/__init__.py | 3 +- faststream/kafka/fastapi/fastapi.py | 4 +- faststream/kafka/publisher/factory.py | 138 +++++++++++++ faststream/kafka/publisher/publisher.py | 190 ------------------ faststream/kafka/publisher/specified.py | 56 ++++++ faststream/kafka/subscriber/factory.py | 2 +- .../{subscriber.py => specified.py} | 0 faststream/kafka/testing.py | 16 +- faststream/nats/broker/broker.py | 4 +- faststream/nats/broker/registrator.py | 7 +- faststream/nats/fastapi/__init__.py | 3 +- faststream/nats/fastapi/fastapi.py | 6 +- faststream/nats/publisher/factory.py | 43 ++++ faststream/nats/publisher/publisher.py | 82 -------- faststream/nats/publisher/specified.py | 36 ++++ .../{subscription.py => adapters.py} | 0 faststream/nats/subscriber/factory.py | 2 +- .../{subscriber.py => specified.py} | 0 faststream/nats/subscriber/usecase.py | 2 +- faststream/nats/testing.py | 2 +- faststream/rabbit/broker/registrator.py | 9 +- faststream/rabbit/fastapi/__init__.py | 3 +- .../rabbit/fastapi/{router.py => fastapi.py} | 6 +- faststream/rabbit/publisher/factory.py | 43 ++++ .../publisher/{publisher.py => specified.py} | 45 +---- faststream/rabbit/schemas/proto.py | 2 +- faststream/rabbit/subscriber/factory.py | 2 +- .../{subscriber.py => specified.py} | 0 faststream/rabbit/testing.py | 10 +- faststream/redis/broker/registrator.py | 11 +- faststream/redis/fastapi/__init__.py | 3 +- faststream/redis/fastapi/fastapi.py | 6 +- faststream/redis/publisher/factory.py | 107 ++++++++++ faststream/redis/publisher/publisher.py | 183 ----------------- faststream/redis/publisher/specified.py | 89 ++++++++ faststream/redis/schemas/proto.py | 2 +- faststream/redis/subscriber/factory.py | 2 +- .../{subscriber.py => specified.py} | 4 +- faststream/redis/testing.py | 2 +- 51 files changed, 789 insertions(+), 775 deletions(-) create mode 100644 faststream/confluent/publisher/factory.py delete mode 100644 faststream/confluent/publisher/publisher.py create mode 100644 faststream/confluent/publisher/specified.py rename faststream/confluent/subscriber/{subscriber.py => specified.py} (100%) create mode 100644 faststream/kafka/publisher/factory.py delete mode 100644 faststream/kafka/publisher/publisher.py create mode 100644 faststream/kafka/publisher/specified.py rename faststream/kafka/subscriber/{subscriber.py => specified.py} (100%) create mode 100644 faststream/nats/publisher/factory.py delete mode 100644 faststream/nats/publisher/publisher.py create mode 100644 faststream/nats/publisher/specified.py rename faststream/nats/subscriber/{subscription.py => adapters.py} (100%) rename faststream/nats/subscriber/{subscriber.py => specified.py} (100%) rename faststream/rabbit/fastapi/{router.py => fastapi.py} (99%) create mode 100644 faststream/rabbit/publisher/factory.py rename faststream/rabbit/publisher/{publisher.py => specified.py} (72%) rename faststream/rabbit/subscriber/{subscriber.py => specified.py} (100%) create mode 100644 faststream/redis/publisher/factory.py delete mode 100644 faststream/redis/publisher/publisher.py create mode 100644 faststream/redis/publisher/specified.py rename faststream/redis/subscriber/{subscriber.py => specified.py} (95%) diff --git a/faststream/_internal/publisher/proto.py b/faststream/_internal/publisher/proto.py index 074fe97d97..1cb920b280 100644 --- a/faststream/_internal/publisher/proto.py +++ b/faststream/_internal/publisher/proto.py @@ -87,12 +87,6 @@ class PublisherProto( @abstractmethod def add_middleware(self, middleware: "BrokerMiddleware[MsgType]") -> None: ... - @staticmethod - @abstractmethod - def create() -> "PublisherProto[MsgType]": - """Abstract factory to create a real Publisher.""" - ... - @override @abstractmethod def _setup( # type: ignore[override] diff --git a/faststream/_internal/publisher/usecase.py b/faststream/_internal/publisher/usecase.py index dbff727a29..b52ea7c387 100644 --- a/faststream/_internal/publisher/usecase.py +++ b/faststream/_internal/publisher/usecase.py @@ -32,9 +32,7 @@ ) -class PublisherUsecase( - PublisherProto[MsgType], -): +class PublisherUsecase(PublisherProto[MsgType]): """A base class for publishers in an asynchronous API.""" mock: Optional[MagicMock] diff --git a/faststream/confluent/broker/registrator.py b/faststream/confluent/broker/registrator.py index 823238e587..289ee413ac 100644 --- a/faststream/confluent/broker/registrator.py +++ b/faststream/confluent/broker/registrator.py @@ -13,7 +13,7 @@ from typing_extensions import Doc, override from faststream._internal.broker.abc_broker import ABCBroker -from faststream.confluent.publisher.publisher import SpecificationPublisher +from faststream.confluent.publisher.factory import create_publisher from faststream.confluent.subscriber.factory import create_subscriber from faststream.exceptions import SetupError @@ -27,12 +27,12 @@ SubscriberMiddleware, ) from faststream.confluent.message import KafkaMessage - from faststream.confluent.publisher.publisher import ( + from faststream.confluent.publisher.specified import ( SpecificationBatchPublisher, SpecificationDefaultPublisher, ) from faststream.confluent.schemas import TopicPartition - from faststream.confluent.subscriber.subscriber import ( + from faststream.confluent.subscriber.specified import ( SpecificationBatchSubscriber, SpecificationDefaultSubscriber, ) @@ -1508,7 +1508,7 @@ def publisher( Or you can create a publisher object to call it lately - `broker.publisher(...).publish(...)`. """ - publisher = SpecificationPublisher.create( + publisher = create_publisher( # batch flag batch=batch, # default args @@ -1530,4 +1530,5 @@ def publisher( if batch: return cast("SpecificationBatchPublisher", super().publisher(publisher)) + return cast("SpecificationDefaultPublisher", super().publisher(publisher)) diff --git a/faststream/confluent/fastapi/__init__.py b/faststream/confluent/fastapi/__init__.py index dc7cb73000..21354fcf98 100644 --- a/faststream/confluent/fastapi/__init__.py +++ b/faststream/confluent/fastapi/__init__.py @@ -2,10 +2,11 @@ from faststream._internal.fastapi.context import Context, ContextRepo, Logger from faststream.confluent.broker import KafkaBroker as KB -from faststream.confluent.fastapi.fastapi import KafkaRouter from faststream.confluent.message import KafkaMessage as KM from faststream.confluent.publisher.producer import AsyncConfluentFastProducer +from .fastapi import KafkaRouter + __all__ = ( "Context", "ContextRepo", diff --git a/faststream/confluent/fastapi/fastapi.py b/faststream/confluent/fastapi/fastapi.py index 7ebc3a6b77..73f6972a40 100644 --- a/faststream/confluent/fastapi/fastapi.py +++ b/faststream/confluent/fastapi/fastapi.py @@ -42,12 +42,12 @@ ) from faststream.confluent.config import ConfluentConfig from faststream.confluent.message import KafkaMessage - from faststream.confluent.publisher.publisher import ( + from faststream.confluent.publisher.specified import ( SpecificationBatchPublisher, SpecificationDefaultPublisher, ) from faststream.confluent.schemas import TopicPartition - from faststream.confluent.subscriber.subscriber import ( + from faststream.confluent.subscriber.specified import ( SpecificationBatchSubscriber, SpecificationDefaultSubscriber, ) diff --git a/faststream/confluent/publisher/factory.py b/faststream/confluent/publisher/factory.py new file mode 100644 index 0000000000..284536604d --- /dev/null +++ b/faststream/confluent/publisher/factory.py @@ -0,0 +1,139 @@ +from collections.abc import Iterable +from typing import ( + TYPE_CHECKING, + Any, + Literal, + Optional, + Union, + overload, +) + +from faststream.exceptions import SetupError + +from .specified import SpecificationBatchPublisher, SpecificationDefaultPublisher + +if TYPE_CHECKING: + from confluent_kafka import Message as ConfluentMsg + + from faststream._internal.types import BrokerMiddleware, PublisherMiddleware + + +@overload +def create_publisher( + *, + batch: Literal[True], + key: Optional[bytes], + topic: str, + partition: Optional[int], + headers: Optional[dict[str, str]], + reply_to: str, + # Publisher args + broker_middlewares: Iterable["BrokerMiddleware[tuple[ConfluentMsg, ...]]"], + middlewares: Iterable["PublisherMiddleware"], + # Specification args + schema_: Optional[Any], + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, +) -> "SpecificationBatchPublisher": ... + + +@overload +def create_publisher( + *, + batch: Literal[False], + key: Optional[bytes], + topic: str, + partition: Optional[int], + headers: Optional[dict[str, str]], + reply_to: str, + # Publisher args + broker_middlewares: Iterable["BrokerMiddleware[ConfluentMsg]"], + middlewares: Iterable["PublisherMiddleware"], + # Specification args + schema_: Optional[Any], + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, +) -> "SpecificationDefaultPublisher": ... + + +@overload +def create_publisher( + *, + batch: bool, + key: Optional[bytes], + topic: str, + partition: Optional[int], + headers: Optional[dict[str, str]], + reply_to: str, + # Publisher args + broker_middlewares: Iterable[ + "BrokerMiddleware[Union[tuple[ConfluentMsg, ...], ConfluentMsg]]" + ], + middlewares: Iterable["PublisherMiddleware"], + # Specification args + schema_: Optional[Any], + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, +) -> Union[ + "SpecificationBatchPublisher", + "SpecificationDefaultPublisher", +]: ... + + +def create_publisher( + *, + batch: bool, + key: Optional[bytes], + topic: str, + partition: Optional[int], + headers: Optional[dict[str, str]], + reply_to: str, + # Publisher args + broker_middlewares: Iterable[ + "BrokerMiddleware[Union[tuple[ConfluentMsg, ...], ConfluentMsg]]" + ], + middlewares: Iterable["PublisherMiddleware"], + # Specification args + schema_: Optional[Any], + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, +) -> Union[ + "SpecificationBatchPublisher", + "SpecificationDefaultPublisher", +]: + if batch: + if key: + msg = "You can't setup `key` with batch publisher" + raise SetupError(msg) + + return SpecificationBatchPublisher( + topic=topic, + partition=partition, + headers=headers, + reply_to=reply_to, + broker_middlewares=broker_middlewares, + middlewares=middlewares, + schema_=schema_, + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + ) + + return SpecificationDefaultPublisher( + key=key, + # basic args + topic=topic, + partition=partition, + headers=headers, + reply_to=reply_to, + broker_middlewares=broker_middlewares, + middlewares=middlewares, + schema_=schema_, + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + ) diff --git a/faststream/confluent/publisher/publisher.py b/faststream/confluent/publisher/publisher.py deleted file mode 100644 index 39ed1ac865..0000000000 --- a/faststream/confluent/publisher/publisher.py +++ /dev/null @@ -1,190 +0,0 @@ -from collections.abc import Iterable -from typing import ( - TYPE_CHECKING, - Any, - Literal, - Optional, - Union, - overload, -) - -from typing_extensions import override - -from faststream._internal.types import MsgType -from faststream.confluent.publisher.usecase import ( - BatchPublisher, - DefaultPublisher, - LogicPublisher, -) -from faststream.exceptions import SetupError -from faststream.specification.asyncapi.utils import resolve_payloads -from faststream.specification.schema.bindings import ChannelBinding, kafka -from faststream.specification.schema.channel import Channel -from faststream.specification.schema.message import CorrelationId, Message -from faststream.specification.schema.operation import Operation - -if TYPE_CHECKING: - from confluent_kafka import Message as ConfluentMsg - - from faststream._internal.types import BrokerMiddleware, PublisherMiddleware - - -class SpecificationPublisher(LogicPublisher[MsgType]): - """A class representing a publisher.""" - - def get_name(self) -> str: - return f"{self.topic}:Publisher" - - def get_schema(self) -> dict[str, Channel]: - payloads = self.get_payloads() - - return { - self.name: Channel( - description=self.description, - publish=Operation( - message=Message( - title=f"{self.name}:Message", - payload=resolve_payloads(payloads, "Publisher"), - correlationId=CorrelationId( - location="$message.header#/correlation_id", - ), - ), - ), - bindings=ChannelBinding(kafka=kafka.ChannelBinding(topic=self.topic)), - ), - } - - @overload # type: ignore[override] - @staticmethod - def create( - *, - batch: Literal[True], - key: Optional[bytes], - topic: str, - partition: Optional[int], - headers: Optional[dict[str, str]], - reply_to: str, - # Publisher args - broker_middlewares: Iterable["BrokerMiddleware[tuple[ConfluentMsg, ...]]"], - middlewares: Iterable["PublisherMiddleware"], - # Specification args - schema_: Optional[Any], - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> "SpecificationBatchPublisher": ... - - @overload - @staticmethod - def create( - *, - batch: Literal[False], - key: Optional[bytes], - topic: str, - partition: Optional[int], - headers: Optional[dict[str, str]], - reply_to: str, - # Publisher args - broker_middlewares: Iterable["BrokerMiddleware[ConfluentMsg]"], - middlewares: Iterable["PublisherMiddleware"], - # Specification args - schema_: Optional[Any], - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> "SpecificationDefaultPublisher": ... - - @overload - @staticmethod - def create( - *, - batch: bool, - key: Optional[bytes], - topic: str, - partition: Optional[int], - headers: Optional[dict[str, str]], - reply_to: str, - # Publisher args - broker_middlewares: Iterable[ - "BrokerMiddleware[Union[tuple[ConfluentMsg, ...], ConfluentMsg]]" - ], - middlewares: Iterable["PublisherMiddleware"], - # Specification args - schema_: Optional[Any], - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> Union[ - "SpecificationBatchPublisher", - "SpecificationDefaultPublisher", - ]: ... - - @override - @staticmethod - def create( - *, - batch: bool, - key: Optional[bytes], - topic: str, - partition: Optional[int], - headers: Optional[dict[str, str]], - reply_to: str, - # Publisher args - broker_middlewares: Iterable[ - "BrokerMiddleware[Union[tuple[ConfluentMsg, ...], ConfluentMsg]]" - ], - middlewares: Iterable["PublisherMiddleware"], - # Specification args - schema_: Optional[Any], - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> Union[ - "SpecificationBatchPublisher", - "SpecificationDefaultPublisher", - ]: - if batch: - if key: - msg = "You can't setup `key` with batch publisher" - raise SetupError(msg) - - return SpecificationBatchPublisher( - topic=topic, - partition=partition, - headers=headers, - reply_to=reply_to, - broker_middlewares=broker_middlewares, - middlewares=middlewares, - schema_=schema_, - title_=title_, - description_=description_, - include_in_schema=include_in_schema, - ) - return SpecificationDefaultPublisher( - key=key, - # basic args - topic=topic, - partition=partition, - headers=headers, - reply_to=reply_to, - broker_middlewares=broker_middlewares, - middlewares=middlewares, - schema_=schema_, - title_=title_, - description_=description_, - include_in_schema=include_in_schema, - ) - - -class SpecificationBatchPublisher( - BatchPublisher, - SpecificationPublisher[tuple["ConfluentMsg", ...]], -): - pass - - -class SpecificationDefaultPublisher( - DefaultPublisher, - SpecificationPublisher["ConfluentMsg"], -): - pass diff --git a/faststream/confluent/publisher/specified.py b/faststream/confluent/publisher/specified.py new file mode 100644 index 0000000000..fec0faf183 --- /dev/null +++ b/faststream/confluent/publisher/specified.py @@ -0,0 +1,58 @@ +from typing import ( + TYPE_CHECKING, +) + +from faststream._internal.types import MsgType +from faststream.confluent.publisher.usecase import ( + BatchPublisher, + DefaultPublisher, + LogicPublisher, +) +from faststream.specification.asyncapi.utils import resolve_payloads +from faststream.specification.schema.bindings import ChannelBinding, kafka +from faststream.specification.schema.channel import Channel +from faststream.specification.schema.message import CorrelationId, Message +from faststream.specification.schema.operation import Operation + +if TYPE_CHECKING: + from confluent_kafka import Message as ConfluentMsg + + +class SpecificationPublisher(LogicPublisher[MsgType]): + """A class representing a publisher.""" + + def get_name(self) -> str: + return f"{self.topic}:Publisher" + + def get_schema(self) -> dict[str, Channel]: + payloads = self.get_payloads() + + return { + self.name: Channel( + description=self.description, + publish=Operation( + message=Message( + title=f"{self.name}:Message", + payload=resolve_payloads(payloads, "Publisher"), + correlationId=CorrelationId( + location="$message.header#/correlation_id", + ), + ), + ), + bindings=ChannelBinding(kafka=kafka.ChannelBinding(topic=self.topic)), + ), + } + + +class SpecificationBatchPublisher( + BatchPublisher, + SpecificationPublisher[tuple["ConfluentMsg", ...]], +): + pass + + +class SpecificationDefaultPublisher( + DefaultPublisher, + SpecificationPublisher["ConfluentMsg"], +): + pass diff --git a/faststream/confluent/subscriber/factory.py b/faststream/confluent/subscriber/factory.py index 336e02c159..c1d4a2d444 100644 --- a/faststream/confluent/subscriber/factory.py +++ b/faststream/confluent/subscriber/factory.py @@ -7,7 +7,7 @@ overload, ) -from faststream.confluent.subscriber.subscriber import ( +from faststream.confluent.subscriber.specified import ( SpecificationBatchSubscriber, SpecificationDefaultSubscriber, ) diff --git a/faststream/confluent/subscriber/subscriber.py b/faststream/confluent/subscriber/specified.py similarity index 100% rename from faststream/confluent/subscriber/subscriber.py rename to faststream/confluent/subscriber/specified.py diff --git a/faststream/confluent/testing.py b/faststream/confluent/testing.py index d9c5026298..c0a3cfa7bc 100644 --- a/faststream/confluent/testing.py +++ b/faststream/confluent/testing.py @@ -16,16 +16,16 @@ from faststream.confluent.broker import KafkaBroker from faststream.confluent.parser import AsyncConfluentParser from faststream.confluent.publisher.producer import AsyncConfluentFastProducer -from faststream.confluent.publisher.publisher import SpecificationBatchPublisher +from faststream.confluent.publisher.specified import SpecificationBatchPublisher from faststream.confluent.schemas import TopicPartition -from faststream.confluent.subscriber.subscriber import SpecificationBatchSubscriber +from faststream.confluent.subscriber.usecase import BatchSubscriber from faststream.exceptions import SubscriberNotFound from faststream.message import encode_message, gen_cor_id if TYPE_CHECKING: from faststream._internal.basic_types import SendableMessage from faststream._internal.setup.logger import LoggerState - from faststream.confluent.publisher.publisher import SpecificationPublisher + from faststream.confluent.publisher.specified import SpecificationPublisher from faststream.confluent.subscriber.usecase import LogicSubscriber __all__ = ("TestKafkaBroker",) @@ -133,9 +133,7 @@ async def publish( # type: ignore[override] partition, ): msg_to_send = ( - [incoming] - if isinstance(handler, SpecificationBatchSubscriber) - else incoming + [incoming] if isinstance(handler, BatchSubscriber) else incoming ) await self._execute_handler(msg_to_send, topic, handler) @@ -170,7 +168,7 @@ async def publish_batch( for message in msgs ) - if isinstance(handler, SpecificationBatchSubscriber): + if isinstance(handler, BatchSubscriber): await self._execute_handler(list(messages), topic, handler) else: @@ -206,9 +204,7 @@ async def request( # type: ignore[override] partition, ): msg_to_send = ( - [incoming] - if isinstance(handler, SpecificationBatchSubscriber) - else incoming + [incoming] if isinstance(handler, BatchSubscriber) else incoming ) with anyio.fail_after(timeout): diff --git a/faststream/kafka/broker/registrator.py b/faststream/kafka/broker/registrator.py index ce805e6066..8a7efeff2f 100644 --- a/faststream/kafka/broker/registrator.py +++ b/faststream/kafka/broker/registrator.py @@ -16,7 +16,7 @@ from typing_extensions import Doc, override from faststream._internal.broker.abc_broker import ABCBroker -from faststream.kafka.publisher.publisher import SpecificationPublisher +from faststream.kafka.publisher.factory import create_publisher from faststream.kafka.subscriber.factory import create_subscriber if TYPE_CHECKING: @@ -31,11 +31,11 @@ SubscriberMiddleware, ) from faststream.kafka.message import KafkaMessage - from faststream.kafka.publisher.publisher import ( + from faststream.kafka.publisher.specified import ( SpecificationBatchPublisher, SpecificationDefaultPublisher, ) - from faststream.kafka.subscriber.subscriber import ( + from faststream.kafka.subscriber.specified import ( SpecificationBatchSubscriber, SpecificationDefaultSubscriber, ) @@ -1911,7 +1911,7 @@ def publisher( Or you can create a publisher object to call it lately - `broker.publisher(...).publish(...)`. """ - publisher = SpecificationPublisher.create( + publisher = create_publisher( # batch flag batch=batch, # default args diff --git a/faststream/kafka/fastapi/__init__.py b/faststream/kafka/fastapi/__init__.py index e2a8447ef7..9fda6d07d3 100644 --- a/faststream/kafka/fastapi/__init__.py +++ b/faststream/kafka/fastapi/__init__.py @@ -2,10 +2,11 @@ from faststream._internal.fastapi.context import Context, ContextRepo, Logger from faststream.kafka.broker import KafkaBroker as KB -from faststream.kafka.fastapi.fastapi import KafkaRouter from faststream.kafka.message import KafkaMessage as KM from faststream.kafka.publisher.producer import AioKafkaFastProducer +from .fastapi import KafkaRouter + __all__ = ( "Context", "ContextRepo", diff --git a/faststream/kafka/fastapi/fastapi.py b/faststream/kafka/fastapi/fastapi.py index 0c805aa2dc..1b92a1029c 100644 --- a/faststream/kafka/fastapi/fastapi.py +++ b/faststream/kafka/fastapi/fastapi.py @@ -48,11 +48,11 @@ SubscriberMiddleware, ) from faststream.kafka.message import KafkaMessage - from faststream.kafka.publisher.publisher import ( + from faststream.kafka.publisher.specified import ( SpecificationBatchPublisher, SpecificationDefaultPublisher, ) - from faststream.kafka.subscriber.subscriber import ( + from faststream.kafka.subscriber.specified import ( SpecificationBatchSubscriber, SpecificationDefaultSubscriber, ) diff --git a/faststream/kafka/publisher/factory.py b/faststream/kafka/publisher/factory.py new file mode 100644 index 0000000000..16c2b69e60 --- /dev/null +++ b/faststream/kafka/publisher/factory.py @@ -0,0 +1,138 @@ +from collections.abc import Iterable +from typing import ( + TYPE_CHECKING, + Any, + Literal, + Optional, + Union, + overload, +) + +from faststream.exceptions import SetupError + +from .specified import SpecificationBatchPublisher, SpecificationDefaultPublisher + +if TYPE_CHECKING: + from aiokafka import ConsumerRecord + + from faststream._internal.types import BrokerMiddleware, PublisherMiddleware + + +@overload +def create_publisher( + *, + batch: Literal[True], + key: Optional[bytes], + topic: str, + partition: Optional[int], + headers: Optional[dict[str, str]], + reply_to: str, + # Publisher args + broker_middlewares: Iterable["BrokerMiddleware[tuple[ConsumerRecord, ...]]"], + middlewares: Iterable["PublisherMiddleware"], + # Specification args + schema_: Optional[Any], + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, +) -> "SpecificationBatchPublisher": ... + + +@overload +def create_publisher( + *, + batch: Literal[False], + key: Optional[bytes], + topic: str, + partition: Optional[int], + headers: Optional[dict[str, str]], + reply_to: str, + # Publisher args + broker_middlewares: Iterable["BrokerMiddleware[ConsumerRecord]"], + middlewares: Iterable["PublisherMiddleware"], + # Specification args + schema_: Optional[Any], + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, +) -> "SpecificationDefaultPublisher": ... + + +@overload +def create_publisher( + *, + batch: bool, + key: Optional[bytes], + topic: str, + partition: Optional[int], + headers: Optional[dict[str, str]], + reply_to: str, + # Publisher args + broker_middlewares: Iterable[ + "BrokerMiddleware[Union[tuple[ConsumerRecord, ...], ConsumerRecord]]" + ], + middlewares: Iterable["PublisherMiddleware"], + # Specification args + schema_: Optional[Any], + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, +) -> Union[ + "SpecificationBatchPublisher", + "SpecificationDefaultPublisher", +]: ... + + +def create_publisher( + *, + batch: bool, + key: Optional[bytes], + topic: str, + partition: Optional[int], + headers: Optional[dict[str, str]], + reply_to: str, + # Publisher args + broker_middlewares: Iterable[ + "BrokerMiddleware[Union[tuple[ConsumerRecord, ...], ConsumerRecord]]" + ], + middlewares: Iterable["PublisherMiddleware"], + # Specification args + schema_: Optional[Any], + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, +) -> Union[ + "SpecificationBatchPublisher", + "SpecificationDefaultPublisher", +]: + if batch: + if key: + msg = "You can't setup `key` with batch publisher" + raise SetupError(msg) + + return SpecificationBatchPublisher( + topic=topic, + partition=partition, + headers=headers, + reply_to=reply_to, + broker_middlewares=broker_middlewares, + middlewares=middlewares, + schema_=schema_, + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + ) + return SpecificationDefaultPublisher( + key=key, + # basic args + topic=topic, + partition=partition, + headers=headers, + reply_to=reply_to, + broker_middlewares=broker_middlewares, + middlewares=middlewares, + schema_=schema_, + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + ) diff --git a/faststream/kafka/publisher/publisher.py b/faststream/kafka/publisher/publisher.py deleted file mode 100644 index db575aac29..0000000000 --- a/faststream/kafka/publisher/publisher.py +++ /dev/null @@ -1,190 +0,0 @@ -from collections.abc import Iterable -from typing import ( - TYPE_CHECKING, - Any, - Literal, - Optional, - Union, - overload, -) - -from typing_extensions import override - -from faststream._internal.types import MsgType -from faststream.exceptions import SetupError -from faststream.kafka.publisher.usecase import ( - BatchPublisher, - DefaultPublisher, - LogicPublisher, -) -from faststream.specification.asyncapi.utils import resolve_payloads -from faststream.specification.schema.bindings import ChannelBinding, kafka -from faststream.specification.schema.channel import Channel -from faststream.specification.schema.message import CorrelationId, Message -from faststream.specification.schema.operation import Operation - -if TYPE_CHECKING: - from aiokafka import ConsumerRecord - - from faststream._internal.types import BrokerMiddleware, PublisherMiddleware - - -class SpecificationPublisher(LogicPublisher[MsgType]): - """A class representing a publisher.""" - - def get_name(self) -> str: - return f"{self.topic}:Publisher" - - def get_schema(self) -> dict[str, Channel]: - payloads = self.get_payloads() - - return { - self.name: Channel( - description=self.description, - publish=Operation( - message=Message( - title=f"{self.name}:Message", - payload=resolve_payloads(payloads, "Publisher"), - correlationId=CorrelationId( - location="$message.header#/correlation_id", - ), - ), - ), - bindings=ChannelBinding(kafka=kafka.ChannelBinding(topic=self.topic)), - ), - } - - @overload # type: ignore[override] - @staticmethod - def create( - *, - batch: Literal[True], - key: Optional[bytes], - topic: str, - partition: Optional[int], - headers: Optional[dict[str, str]], - reply_to: str, - # Publisher args - broker_middlewares: Iterable["BrokerMiddleware[tuple[ConsumerRecord, ...]]"], - middlewares: Iterable["PublisherMiddleware"], - # Specification args - schema_: Optional[Any], - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> "SpecificationBatchPublisher": ... - - @overload - @staticmethod - def create( - *, - batch: Literal[False], - key: Optional[bytes], - topic: str, - partition: Optional[int], - headers: Optional[dict[str, str]], - reply_to: str, - # Publisher args - broker_middlewares: Iterable["BrokerMiddleware[ConsumerRecord]"], - middlewares: Iterable["PublisherMiddleware"], - # Specification args - schema_: Optional[Any], - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> "SpecificationDefaultPublisher": ... - - @overload - @staticmethod - def create( - *, - batch: bool, - key: Optional[bytes], - topic: str, - partition: Optional[int], - headers: Optional[dict[str, str]], - reply_to: str, - # Publisher args - broker_middlewares: Iterable[ - "BrokerMiddleware[Union[tuple[ConsumerRecord, ...], ConsumerRecord]]" - ], - middlewares: Iterable["PublisherMiddleware"], - # Specification args - schema_: Optional[Any], - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> Union[ - "SpecificationBatchPublisher", - "SpecificationDefaultPublisher", - ]: ... - - @override - @staticmethod - def create( - *, - batch: bool, - key: Optional[bytes], - topic: str, - partition: Optional[int], - headers: Optional[dict[str, str]], - reply_to: str, - # Publisher args - broker_middlewares: Iterable[ - "BrokerMiddleware[Union[tuple[ConsumerRecord, ...], ConsumerRecord]]" - ], - middlewares: Iterable["PublisherMiddleware"], - # Specification args - schema_: Optional[Any], - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> Union[ - "SpecificationBatchPublisher", - "SpecificationDefaultPublisher", - ]: - if batch: - if key: - msg = "You can't setup `key` with batch publisher" - raise SetupError(msg) - - return SpecificationBatchPublisher( - topic=topic, - partition=partition, - headers=headers, - reply_to=reply_to, - broker_middlewares=broker_middlewares, - middlewares=middlewares, - schema_=schema_, - title_=title_, - description_=description_, - include_in_schema=include_in_schema, - ) - return SpecificationDefaultPublisher( - key=key, - # basic args - topic=topic, - partition=partition, - headers=headers, - reply_to=reply_to, - broker_middlewares=broker_middlewares, - middlewares=middlewares, - schema_=schema_, - title_=title_, - description_=description_, - include_in_schema=include_in_schema, - ) - - -class SpecificationBatchPublisher( - BatchPublisher, - SpecificationPublisher[tuple["ConsumerRecord", ...]], -): - pass - - -class SpecificationDefaultPublisher( - DefaultPublisher, - SpecificationPublisher["ConsumerRecord"], -): - pass diff --git a/faststream/kafka/publisher/specified.py b/faststream/kafka/publisher/specified.py new file mode 100644 index 0000000000..d765cc8f8b --- /dev/null +++ b/faststream/kafka/publisher/specified.py @@ -0,0 +1,56 @@ +from typing import TYPE_CHECKING + +from faststream._internal.types import MsgType +from faststream.kafka.publisher.usecase import ( + BatchPublisher, + DefaultPublisher, + LogicPublisher, +) +from faststream.specification.asyncapi.utils import resolve_payloads +from faststream.specification.schema.bindings import ChannelBinding, kafka +from faststream.specification.schema.channel import Channel +from faststream.specification.schema.message import CorrelationId, Message +from faststream.specification.schema.operation import Operation + +if TYPE_CHECKING: + from aiokafka import ConsumerRecord + + +class SpecificationPublisher(LogicPublisher[MsgType]): + """A class representing a publisher.""" + + def get_name(self) -> str: + return f"{self.topic}:Publisher" + + def get_schema(self) -> dict[str, Channel]: + payloads = self.get_payloads() + + return { + self.name: Channel( + description=self.description, + publish=Operation( + message=Message( + title=f"{self.name}:Message", + payload=resolve_payloads(payloads, "Publisher"), + correlationId=CorrelationId( + location="$message.header#/correlation_id", + ), + ), + ), + bindings=ChannelBinding(kafka=kafka.ChannelBinding(topic=self.topic)), + ), + } + + +class SpecificationBatchPublisher( + BatchPublisher, + SpecificationPublisher[tuple["ConsumerRecord", ...]], +): + pass + + +class SpecificationDefaultPublisher( + DefaultPublisher, + SpecificationPublisher["ConsumerRecord"], +): + pass diff --git a/faststream/kafka/subscriber/factory.py b/faststream/kafka/subscriber/factory.py index a31a5fde93..b4ae8638f1 100644 --- a/faststream/kafka/subscriber/factory.py +++ b/faststream/kafka/subscriber/factory.py @@ -8,7 +8,7 @@ ) from faststream.exceptions import SetupError -from faststream.kafka.subscriber.subscriber import ( +from faststream.kafka.subscriber.specified import ( SpecificationBatchSubscriber, SpecificationDefaultSubscriber, ) diff --git a/faststream/kafka/subscriber/subscriber.py b/faststream/kafka/subscriber/specified.py similarity index 100% rename from faststream/kafka/subscriber/subscriber.py rename to faststream/kafka/subscriber/specified.py diff --git a/faststream/kafka/testing.py b/faststream/kafka/testing.py index a0135e9083..ce35bbd1b5 100755 --- a/faststream/kafka/testing.py +++ b/faststream/kafka/testing.py @@ -21,13 +21,13 @@ from faststream.kafka.message import KafkaMessage from faststream.kafka.parser import AioKafkaParser from faststream.kafka.publisher.producer import AioKafkaFastProducer -from faststream.kafka.publisher.publisher import SpecificationBatchPublisher -from faststream.kafka.subscriber.subscriber import SpecificationBatchSubscriber +from faststream.kafka.publisher.specified import SpecificationBatchPublisher +from faststream.kafka.subscriber.usecase import BatchSubscriber from faststream.message import encode_message, gen_cor_id if TYPE_CHECKING: from faststream._internal.basic_types import SendableMessage - from faststream.kafka.publisher.publisher import SpecificationPublisher + from faststream.kafka.publisher.specified import SpecificationPublisher from faststream.kafka.subscriber.usecase import LogicSubscriber __all__ = ("TestKafkaBroker",) @@ -128,9 +128,7 @@ async def publish( # type: ignore[override] partition, ): msg_to_send = ( - [incoming] - if isinstance(handler, SpecificationBatchSubscriber) - else incoming + [incoming] if isinstance(handler, BatchSubscriber) else incoming ) await self._execute_handler(msg_to_send, topic, handler) @@ -164,9 +162,7 @@ async def request( # type: ignore[override] partition, ): msg_to_send = ( - [incoming] - if isinstance(handler, SpecificationBatchSubscriber) - else incoming + [incoming] if isinstance(handler, BatchSubscriber) else incoming ) with anyio.fail_after(timeout): @@ -204,7 +200,7 @@ async def publish_batch( for message in msgs ) - if isinstance(handler, SpecificationBatchSubscriber): + if isinstance(handler, BatchSubscriber): await self._execute_handler(list(messages), topic, handler) else: diff --git a/faststream/nats/broker/broker.py b/faststream/nats/broker/broker.py index ee91cc291e..b9ef1afdfb 100644 --- a/faststream/nats/broker/broker.py +++ b/faststream/nats/broker/broker.py @@ -36,7 +36,7 @@ from faststream.nats.helpers import KVBucketDeclarer, OSBucketDeclarer from faststream.nats.publisher.producer import NatsFastProducer, NatsJSFastProducer from faststream.nats.security import parse_security -from faststream.nats.subscriber.subscriber import SpecificationSubscriber +from faststream.nats.subscriber.specified import SpecificationSubscriber from .logging import make_nats_logger_state from .registrator import NatsRegistrator @@ -71,7 +71,7 @@ CustomCallable, ) from faststream.nats.message import NatsMessage - from faststream.nats.publisher.publisher import SpecificationPublisher + from faststream.nats.publisher.specified import SpecificationPublisher from faststream.security import BaseSecurity from faststream.specification.schema.tag import Tag, TagDict diff --git a/faststream/nats/broker/registrator.py b/faststream/nats/broker/registrator.py index 580501f2e8..811f1ab847 100644 --- a/faststream/nats/broker/registrator.py +++ b/faststream/nats/broker/registrator.py @@ -6,10 +6,11 @@ from faststream._internal.broker.abc_broker import ABCBroker from faststream.nats.helpers import StreamBuilder -from faststream.nats.publisher.publisher import SpecificationPublisher +from faststream.nats.publisher.factory import create_publisher +from faststream.nats.publisher.specified import SpecificationPublisher from faststream.nats.schemas import JStream, KvWatch, ObjWatch, PullSub from faststream.nats.subscriber.factory import create_subscriber -from faststream.nats.subscriber.subscriber import SpecificationSubscriber +from faststream.nats.subscriber.specified import SpecificationSubscriber if TYPE_CHECKING: from fast_depends.dependencies import Depends @@ -314,7 +315,7 @@ def publisher( # type: ignore[override] publisher = cast( SpecificationPublisher, super().publisher( - publisher=SpecificationPublisher.create( + publisher=create_publisher( subject=subject, headers=headers, # Core diff --git a/faststream/nats/fastapi/__init__.py b/faststream/nats/fastapi/__init__.py index 7351e313a2..18a28e4e8d 100644 --- a/faststream/nats/fastapi/__init__.py +++ b/faststream/nats/fastapi/__init__.py @@ -5,10 +5,11 @@ from faststream._internal.fastapi.context import Context, ContextRepo, Logger from faststream.nats.broker import NatsBroker as NB -from faststream.nats.fastapi.fastapi import NatsRouter from faststream.nats.message import NatsMessage as NM from faststream.nats.publisher.producer import NatsFastProducer, NatsJSFastProducer +from .fastapi import NatsRouter + NatsMessage = Annotated[NM, Context("message")] NatsBroker = Annotated[NB, Context("broker")] Client = Annotated[NatsClient, Context("broker._connection")] diff --git a/faststream/nats/fastapi/fastapi.py b/faststream/nats/fastapi/fastapi.py index ad910b71b6..e2c5ae3d98 100644 --- a/faststream/nats/fastapi/fastapi.py +++ b/faststream/nats/fastapi/fastapi.py @@ -33,8 +33,7 @@ from faststream._internal.constants import EMPTY from faststream._internal.fastapi.router import StreamRouter from faststream.nats.broker import NatsBroker -from faststream.nats.publisher.publisher import SpecificationPublisher -from faststream.nats.subscriber.subscriber import SpecificationSubscriber +from faststream.nats.subscriber.specified import SpecificationSubscriber if TYPE_CHECKING: import ssl @@ -61,6 +60,7 @@ SubscriberMiddleware, ) from faststream.nats.message import NatsMessage + from faststream.nats.publisher.specified import SpecificationPublisher from faststream.nats.schemas import JStream, KvWatch, ObjWatch, PullSub from faststream.security import BaseSecurity from faststream.specification.schema.tag import Tag, TagDict @@ -945,7 +945,7 @@ def publisher( # type: ignore[override] bool, Doc("Whetever to include operation in AsyncAPI schema or not."), ] = True, - ) -> SpecificationPublisher: + ) -> "SpecificationPublisher": return self.broker.publisher( subject, headers=headers, diff --git a/faststream/nats/publisher/factory.py b/faststream/nats/publisher/factory.py new file mode 100644 index 0000000000..8f03f94b9d --- /dev/null +++ b/faststream/nats/publisher/factory.py @@ -0,0 +1,43 @@ +from collections.abc import Iterable +from typing import TYPE_CHECKING, Any, Optional + +from .specified import SpecificationPublisher + +if TYPE_CHECKING: + from nats.aio.msg import Msg + + from faststream._internal.types import BrokerMiddleware, PublisherMiddleware + from faststream.nats.schemas.js_stream import JStream + + +def create_publisher( + *, + subject: str, + reply_to: str, + headers: Optional[dict[str, str]], + stream: Optional["JStream"], + timeout: Optional[float], + # Publisher args + broker_middlewares: Iterable["BrokerMiddleware[Msg]"], + middlewares: Iterable["PublisherMiddleware"], + # AsyncAPI args + schema_: Optional[Any], + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, +) -> SpecificationPublisher: + return SpecificationPublisher( + subject=subject, + reply_to=reply_to, + headers=headers, + stream=stream, + timeout=timeout, + # Publisher args + broker_middlewares=broker_middlewares, + middlewares=middlewares, + # AsyncAPI args + schema_=schema_, + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + ) diff --git a/faststream/nats/publisher/publisher.py b/faststream/nats/publisher/publisher.py deleted file mode 100644 index f80cd8dccb..0000000000 --- a/faststream/nats/publisher/publisher.py +++ /dev/null @@ -1,82 +0,0 @@ -from collections.abc import Iterable -from typing import TYPE_CHECKING, Any, Optional - -from typing_extensions import override - -from faststream.nats.publisher.usecase import LogicPublisher -from faststream.specification.asyncapi.utils import resolve_payloads -from faststream.specification.schema.bindings import ChannelBinding, nats -from faststream.specification.schema.channel import Channel -from faststream.specification.schema.message import CorrelationId, Message -from faststream.specification.schema.operation import Operation - -if TYPE_CHECKING: - from nats.aio.msg import Msg - - from faststream._internal.types import BrokerMiddleware, PublisherMiddleware - from faststream.nats.schemas.js_stream import JStream - - -class SpecificationPublisher(LogicPublisher): - """A class to represent a NATS publisher.""" - - def get_name(self) -> str: - return f"{self.subject}:Publisher" - - def get_schema(self) -> dict[str, Channel]: - payloads = self.get_payloads() - - return { - self.name: Channel( - description=self.description, - publish=Operation( - message=Message( - title=f"{self.name}:Message", - payload=resolve_payloads(payloads, "Publisher"), - correlationId=CorrelationId( - location="$message.header#/correlation_id", - ), - ), - ), - bindings=ChannelBinding( - nats=nats.ChannelBinding( - subject=self.subject, - ), - ), - ), - } - - @override - @classmethod - def create( # type: ignore[override] - cls, - *, - subject: str, - reply_to: str, - headers: Optional[dict[str, str]], - stream: Optional["JStream"], - timeout: Optional[float], - # Publisher args - broker_middlewares: Iterable["BrokerMiddleware[Msg]"], - middlewares: Iterable["PublisherMiddleware"], - # AsyncAPI args - schema_: Optional[Any], - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> "SpecificationPublisher": - return cls( - subject=subject, - reply_to=reply_to, - headers=headers, - stream=stream, - timeout=timeout, - # Publisher args - broker_middlewares=broker_middlewares, - middlewares=middlewares, - # AsyncAPI args - schema_=schema_, - title_=title_, - description_=description_, - include_in_schema=include_in_schema, - ) diff --git a/faststream/nats/publisher/specified.py b/faststream/nats/publisher/specified.py new file mode 100644 index 0000000000..41cfdc27b9 --- /dev/null +++ b/faststream/nats/publisher/specified.py @@ -0,0 +1,36 @@ +from faststream.nats.publisher.usecase import LogicPublisher +from faststream.specification.asyncapi.utils import resolve_payloads +from faststream.specification.schema.bindings import ChannelBinding, nats +from faststream.specification.schema.channel import Channel +from faststream.specification.schema.message import CorrelationId, Message +from faststream.specification.schema.operation import Operation + + +class SpecificationPublisher(LogicPublisher): + """A class to represent a NATS publisher.""" + + def get_name(self) -> str: + return f"{self.subject}:Publisher" + + def get_schema(self) -> dict[str, Channel]: + payloads = self.get_payloads() + + return { + self.name: Channel( + description=self.description, + publish=Operation( + message=Message( + title=f"{self.name}:Message", + payload=resolve_payloads(payloads, "Publisher"), + correlationId=CorrelationId( + location="$message.header#/correlation_id", + ), + ), + ), + bindings=ChannelBinding( + nats=nats.ChannelBinding( + subject=self.subject, + ), + ), + ), + } diff --git a/faststream/nats/subscriber/subscription.py b/faststream/nats/subscriber/adapters.py similarity index 100% rename from faststream/nats/subscriber/subscription.py rename to faststream/nats/subscriber/adapters.py diff --git a/faststream/nats/subscriber/factory.py b/faststream/nats/subscriber/factory.py index b3170988b8..f2853f06b9 100644 --- a/faststream/nats/subscriber/factory.py +++ b/faststream/nats/subscriber/factory.py @@ -12,7 +12,7 @@ ) from faststream.exceptions import SetupError -from faststream.nats.subscriber.subscriber import ( +from faststream.nats.subscriber.specified import ( SpecificationBatchPullStreamSubscriber, SpecificationConcurrentCoreSubscriber, SpecificationConcurrentPullStreamSubscriber, diff --git a/faststream/nats/subscriber/subscriber.py b/faststream/nats/subscriber/specified.py similarity index 100% rename from faststream/nats/subscriber/subscriber.py rename to faststream/nats/subscriber/specified.py diff --git a/faststream/nats/subscriber/usecase.py b/faststream/nats/subscriber/usecase.py index 457db20587..be75b89776 100644 --- a/faststream/nats/subscriber/usecase.py +++ b/faststream/nats/subscriber/usecase.py @@ -34,7 +34,7 @@ ObjParser, ) from faststream.nats.schemas.js_stream import compile_nats_wildcard -from faststream.nats.subscriber.subscription import ( +from faststream.nats.subscriber.adapters import ( UnsubscribeAdapter, Unsubscriptable, ) diff --git a/faststream/nats/testing.py b/faststream/nats/testing.py index 4df82ae989..7765df0181 100644 --- a/faststream/nats/testing.py +++ b/faststream/nats/testing.py @@ -22,7 +22,7 @@ if TYPE_CHECKING: from faststream._internal.basic_types import SendableMessage - from faststream.nats.publisher.publisher import SpecificationPublisher + from faststream.nats.publisher.specified import SpecificationPublisher from faststream.nats.subscriber.usecase import LogicSubscriber __all__ = ("TestNatsBroker",) diff --git a/faststream/rabbit/broker/registrator.py b/faststream/rabbit/broker/registrator.py index 32aedfcfec..5b6ffbb606 100644 --- a/faststream/rabbit/broker/registrator.py +++ b/faststream/rabbit/broker/registrator.py @@ -4,14 +4,15 @@ from typing_extensions import Doc, override from faststream._internal.broker.abc_broker import ABCBroker -from faststream.rabbit.publisher.publisher import SpecificationPublisher +from faststream.rabbit.publisher.factory import create_publisher +from faststream.rabbit.publisher.specified import SpecificationPublisher from faststream.rabbit.publisher.usecase import PublishKwargs from faststream.rabbit.schemas import ( RabbitExchange, RabbitQueue, ) from faststream.rabbit.subscriber.factory import create_subscriber -from faststream.rabbit.subscriber.subscriber import SpecificationSubscriber +from faststream.rabbit.subscriber.specified import SpecificationSubscriber if TYPE_CHECKING: from aio_pika import IncomingMessage # noqa: F401 @@ -240,7 +241,7 @@ def publisher( # type: ignore[override] Optional[str], Doc("Publisher connection User ID, validated if set."), ] = None, - ) -> SpecificationPublisher: + ) -> "SpecificationPublisher": """Creates long-living and AsyncAPI-documented publisher object. You can use it as a handler decorator (handler should be decorated by `@broker.subscriber(...)` too) - `@broker.publisher(...)`. @@ -266,7 +267,7 @@ def publisher( # type: ignore[override] return cast( SpecificationPublisher, super().publisher( - SpecificationPublisher.create( + create_publisher( routing_key=routing_key, queue=RabbitQueue.validate(queue), exchange=RabbitExchange.validate(exchange), diff --git a/faststream/rabbit/fastapi/__init__.py b/faststream/rabbit/fastapi/__init__.py index da296cd366..cb7c7c26d4 100644 --- a/faststream/rabbit/fastapi/__init__.py +++ b/faststream/rabbit/fastapi/__init__.py @@ -2,10 +2,11 @@ from faststream._internal.fastapi.context import Context, ContextRepo, Logger from faststream.rabbit.broker import RabbitBroker as RB -from faststream.rabbit.fastapi.router import RabbitRouter from faststream.rabbit.message import RabbitMessage as RM from faststream.rabbit.publisher.producer import AioPikaFastProducer +from .fastapi import RabbitRouter + RabbitMessage = Annotated[RM, Context("message")] RabbitBroker = Annotated[RB, Context("broker")] RabbitProducer = Annotated[AioPikaFastProducer, Context("broker._producer")] diff --git a/faststream/rabbit/fastapi/router.py b/faststream/rabbit/fastapi/fastapi.py similarity index 99% rename from faststream/rabbit/fastapi/router.py rename to faststream/rabbit/fastapi/fastapi.py index 69a7a23d73..9240380079 100644 --- a/faststream/rabbit/fastapi/router.py +++ b/faststream/rabbit/fastapi/fastapi.py @@ -21,12 +21,11 @@ from faststream._internal.constants import EMPTY from faststream._internal.fastapi.router import StreamRouter from faststream.rabbit.broker.broker import RabbitBroker as RB -from faststream.rabbit.publisher.publisher import SpecificationPublisher from faststream.rabbit.schemas import ( RabbitExchange, RabbitQueue, ) -from faststream.rabbit.subscriber.subscriber import SpecificationSubscriber +from faststream.rabbit.subscriber.specified import SpecificationSubscriber if TYPE_CHECKING: from enum import Enum @@ -48,6 +47,7 @@ SubscriberMiddleware, ) from faststream.rabbit.message import RabbitMessage + from faststream.rabbit.publisher.specified import SpecificationPublisher from faststream.security import BaseSecurity from faststream.specification.schema.tag import Tag, TagDict @@ -800,7 +800,7 @@ def publisher( Optional[str], Doc("Publisher connection User ID, validated if set."), ] = None, - ) -> SpecificationPublisher: + ) -> "SpecificationPublisher": return self.broker.publisher( queue=queue, exchange=exchange, diff --git a/faststream/rabbit/publisher/factory.py b/faststream/rabbit/publisher/factory.py new file mode 100644 index 0000000000..cf2bc27c86 --- /dev/null +++ b/faststream/rabbit/publisher/factory.py @@ -0,0 +1,43 @@ +from collections.abc import Iterable +from typing import TYPE_CHECKING, Any, Optional + +from .specified import SpecificationPublisher + +if TYPE_CHECKING: + from aio_pika import IncomingMessage + + from faststream._internal.types import BrokerMiddleware, PublisherMiddleware + from faststream.rabbit.schemas import RabbitExchange, RabbitQueue + + from .usecase import PublishKwargs + + +def create_publisher( + *, + routing_key: str, + queue: "RabbitQueue", + exchange: "RabbitExchange", + message_kwargs: "PublishKwargs", + # Publisher args + broker_middlewares: Iterable["BrokerMiddleware[IncomingMessage]"], + middlewares: Iterable["PublisherMiddleware"], + # AsyncAPI args + schema_: Optional[Any], + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, +) -> SpecificationPublisher: + return SpecificationPublisher( + routing_key=routing_key, + queue=queue, + exchange=exchange, + message_kwargs=message_kwargs, + # Publisher args + broker_middlewares=broker_middlewares, + middlewares=middlewares, + # AsyncAPI args + schema_=schema_, + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + ) diff --git a/faststream/rabbit/publisher/publisher.py b/faststream/rabbit/publisher/specified.py similarity index 72% rename from faststream/rabbit/publisher/publisher.py rename to faststream/rabbit/publisher/specified.py index 18796b92b4..fce0411752 100644 --- a/faststream/rabbit/publisher/publisher.py +++ b/faststream/rabbit/publisher/specified.py @@ -1,9 +1,3 @@ -from collections.abc import Iterable -from typing import TYPE_CHECKING, Any, Optional - -from typing_extensions import override - -from faststream.rabbit.publisher.usecase import LogicPublisher, PublishKwargs from faststream.rabbit.utils import is_routing_exchange from faststream.specification.asyncapi.utils import resolve_payloads from faststream.specification.schema.bindings import ( @@ -15,11 +9,7 @@ from faststream.specification.schema.message import CorrelationId, Message from faststream.specification.schema.operation import Operation -if TYPE_CHECKING: - from aio_pika import IncomingMessage - - from faststream._internal.types import BrokerMiddleware, PublisherMiddleware - from faststream.rabbit.schemas import RabbitExchange, RabbitQueue +from .usecase import LogicPublisher class SpecificationPublisher(LogicPublisher): @@ -104,36 +94,3 @@ def get_schema(self) -> dict[str, Channel]: ), ), } - - @override - @classmethod - def create( # type: ignore[override] - cls, - *, - routing_key: str, - queue: "RabbitQueue", - exchange: "RabbitExchange", - message_kwargs: "PublishKwargs", - # Publisher args - broker_middlewares: Iterable["BrokerMiddleware[IncomingMessage]"], - middlewares: Iterable["PublisherMiddleware"], - # AsyncAPI args - schema_: Optional[Any], - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> "SpecificationPublisher": - return cls( - routing_key=routing_key, - queue=queue, - exchange=exchange, - message_kwargs=message_kwargs, - # Publisher args - broker_middlewares=broker_middlewares, - middlewares=middlewares, - # AsyncAPI args - schema_=schema_, - title_=title_, - description_=description_, - include_in_schema=include_in_schema, - ) diff --git a/faststream/rabbit/schemas/proto.py b/faststream/rabbit/schemas/proto.py index 226840925e..ca00168745 100644 --- a/faststream/rabbit/schemas/proto.py +++ b/faststream/rabbit/schemas/proto.py @@ -5,7 +5,7 @@ class BaseRMQInformation(Protocol): - """Base class to store AsyncAPI RMQ bindings.""" + """Base class to store Specification RMQ bindings.""" virtual_host: str queue: RabbitQueue diff --git a/faststream/rabbit/subscriber/factory.py b/faststream/rabbit/subscriber/factory.py index c69884503a..23b190b13e 100644 --- a/faststream/rabbit/subscriber/factory.py +++ b/faststream/rabbit/subscriber/factory.py @@ -1,7 +1,7 @@ from collections.abc import Iterable from typing import TYPE_CHECKING, Optional, Union -from faststream.rabbit.subscriber.subscriber import SpecificationSubscriber +from faststream.rabbit.subscriber.specified import SpecificationSubscriber if TYPE_CHECKING: from aio_pika import IncomingMessage diff --git a/faststream/rabbit/subscriber/subscriber.py b/faststream/rabbit/subscriber/specified.py similarity index 100% rename from faststream/rabbit/subscriber/subscriber.py rename to faststream/rabbit/subscriber/specified.py diff --git a/faststream/rabbit/testing.py b/faststream/rabbit/testing.py index 5831fc903c..7d45ed786b 100644 --- a/faststream/rabbit/testing.py +++ b/faststream/rabbit/testing.py @@ -18,7 +18,6 @@ from faststream.rabbit.broker.broker import RabbitBroker from faststream.rabbit.parser import AioPikaParser from faststream.rabbit.publisher.producer import AioPikaFastProducer -from faststream.rabbit.publisher.publisher import SpecificationPublisher from faststream.rabbit.schemas import ( ExchangeType, RabbitExchange, @@ -28,6 +27,7 @@ if TYPE_CHECKING: from aio_pika.abc import DateType, HeadersType, TimeoutType + from faststream.rabbit.publisher.specified import SpecificationPublisher from faststream.rabbit.subscriber.usecase import LogicSubscriber from faststream.rabbit.types import AioPikaSendableMessage @@ -39,7 +39,7 @@ class TestRabbitBroker(TestBroker[RabbitBroker]): """A class to test RabbitMQ brokers.""" @contextmanager - def _patch_broker(self, broker: RabbitBroker) -> Generator[None, None, None]: + def _patch_broker(self, broker: "RabbitBroker") -> Generator[None, None, None]: with ( mock.patch.object( broker, @@ -56,13 +56,13 @@ def _patch_broker(self, broker: RabbitBroker) -> Generator[None, None, None]: yield @staticmethod - async def _fake_connect(broker: RabbitBroker, *args: Any, **kwargs: Any) -> None: + async def _fake_connect(broker: "RabbitBroker", *args: Any, **kwargs: Any) -> None: broker._producer = FakeProducer(broker) @staticmethod def create_publisher_fake_subscriber( - broker: RabbitBroker, - publisher: SpecificationPublisher, + broker: "RabbitBroker", + publisher: "SpecificationPublisher", ) -> tuple["LogicSubscriber", bool]: sub: Optional[LogicSubscriber] = None for handler in broker._subscribers: diff --git a/faststream/redis/broker/registrator.py b/faststream/redis/broker/registrator.py index da6759f03a..9f852284d3 100644 --- a/faststream/redis/broker/registrator.py +++ b/faststream/redis/broker/registrator.py @@ -5,9 +5,10 @@ from faststream._internal.broker.abc_broker import ABCBroker from faststream.redis.message import UnifyRedisDict -from faststream.redis.publisher.publisher import SpecificationPublisher +from faststream.redis.publisher.factory import create_publisher +from faststream.redis.publisher.specified import SpecificationPublisher from faststream.redis.subscriber.factory import SubsciberType, create_subscriber -from faststream.redis.subscriber.subscriber import SpecificationSubscriber +from faststream.redis.subscriber.specified import SpecificationSubscriber if TYPE_CHECKING: from fast_depends.dependencies import Depends @@ -19,7 +20,7 @@ SubscriberMiddleware, ) from faststream.redis.message import UnifyRedisMessage - from faststream.redis.publisher.publisher import PublisherType + from faststream.redis.publisher.specified import PublisherType from faststream.redis.schemas import ListSub, PubSub, StreamSub @@ -174,7 +175,7 @@ def publisher( # type: ignore[override] bool, Doc("Whetever to include operation in AsyncAPI schema or not."), ] = True, - ) -> SpecificationPublisher: + ) -> "SpecificationPublisher": """Creates long-living and AsyncAPI-documented publisher object. You can use it as a handler decorator (handler should be decorated by `@broker.subscriber(...)` too) - `@broker.publisher(...)`. @@ -185,7 +186,7 @@ def publisher( # type: ignore[override] return cast( SpecificationPublisher, super().publisher( - SpecificationPublisher.create( + create_publisher( channel=channel, list=list, stream=stream, diff --git a/faststream/redis/fastapi/__init__.py b/faststream/redis/fastapi/__init__.py index da6dfd1c85..117c03aae2 100644 --- a/faststream/redis/fastapi/__init__.py +++ b/faststream/redis/fastapi/__init__.py @@ -4,9 +4,10 @@ from faststream._internal.fastapi.context import Context, ContextRepo, Logger from faststream.redis.broker.broker import RedisBroker as RB -from faststream.redis.fastapi.fastapi import RedisRouter from faststream.redis.message import BaseMessage as RM # noqa: N814 +from .fastapi import RedisRouter + __all__ = ( "Context", "ContextRepo", diff --git a/faststream/redis/fastapi/fastapi.py b/faststream/redis/fastapi/fastapi.py index 0a1a93e441..ed97300b87 100644 --- a/faststream/redis/fastapi/fastapi.py +++ b/faststream/redis/fastapi/fastapi.py @@ -27,9 +27,8 @@ from faststream._internal.fastapi.router import StreamRouter from faststream.redis.broker.broker import RedisBroker as RB from faststream.redis.message import UnifyRedisDict -from faststream.redis.publisher.publisher import SpecificationPublisher from faststream.redis.schemas import ListSub, PubSub, StreamSub -from faststream.redis.subscriber.subscriber import SpecificationSubscriber +from faststream.redis.subscriber.specified import SpecificationSubscriber if TYPE_CHECKING: from enum import Enum @@ -48,6 +47,7 @@ SubscriberMiddleware, ) from faststream.redis.message import UnifyRedisMessage + from faststream.redis.publisher.specified import SpecificationPublisher from faststream.security import BaseSecurity from faststream.specification.schema.tag import Tag, TagDict @@ -692,7 +692,7 @@ def publisher( bool, Doc("Whetever to include operation in AsyncAPI schema or not."), ] = True, - ) -> SpecificationPublisher: + ) -> "SpecificationPublisher": return self.broker.publisher( channel, list=list, diff --git a/faststream/redis/publisher/factory.py b/faststream/redis/publisher/factory.py new file mode 100644 index 0000000000..2174a0b4c8 --- /dev/null +++ b/faststream/redis/publisher/factory.py @@ -0,0 +1,107 @@ +from collections.abc import Iterable +from typing import TYPE_CHECKING, Any, Optional, Union + +from typing_extensions import TypeAlias + +from faststream.exceptions import SetupError +from faststream.redis.schemas import INCORRECT_SETUP_MSG, ListSub, PubSub, StreamSub +from faststream.redis.schemas.proto import validate_options + +from .specified import ( + SpecificationChannelPublisher, + SpecificationListBatchPublisher, + SpecificationListPublisher, + SpecificationStreamPublisher, +) + +if TYPE_CHECKING: + from faststream._internal.basic_types import AnyDict + from faststream._internal.types import BrokerMiddleware, PublisherMiddleware + from faststream.redis.message import UnifyRedisDict + + +PublisherType: TypeAlias = Union[ + "SpecificationChannelPublisher", + "SpecificationStreamPublisher", + "SpecificationListPublisher", + "SpecificationListBatchPublisher", +] + + +def create_publisher( + *, + channel: Union["PubSub", str, None], + list: Union["ListSub", str, None], + stream: Union["StreamSub", str, None], + headers: Optional["AnyDict"], + reply_to: str, + broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], + middlewares: Iterable["PublisherMiddleware"], + # AsyncAPI args + title_: Optional[str], + description_: Optional[str], + schema_: Optional[Any], + include_in_schema: bool, +) -> PublisherType: + validate_options(channel=channel, list=list, stream=stream) + + if (channel := PubSub.validate(channel)) is not None: + return SpecificationChannelPublisher( + channel=channel, + # basic args + headers=headers, + reply_to=reply_to, + broker_middlewares=broker_middlewares, + middlewares=middlewares, + # AsyncAPI args + title_=title_, + description_=description_, + schema_=schema_, + include_in_schema=include_in_schema, + ) + + if (stream := StreamSub.validate(stream)) is not None: + return SpecificationStreamPublisher( + stream=stream, + # basic args + headers=headers, + reply_to=reply_to, + broker_middlewares=broker_middlewares, + middlewares=middlewares, + # AsyncAPI args + title_=title_, + description_=description_, + schema_=schema_, + include_in_schema=include_in_schema, + ) + + if (list := ListSub.validate(list)) is not None: + if list.batch: + return SpecificationListBatchPublisher( + list=list, + # basic args + headers=headers, + reply_to=reply_to, + broker_middlewares=broker_middlewares, + middlewares=middlewares, + # AsyncAPI args + title_=title_, + description_=description_, + schema_=schema_, + include_in_schema=include_in_schema, + ) + return SpecificationListPublisher( + list=list, + # basic args + headers=headers, + reply_to=reply_to, + broker_middlewares=broker_middlewares, + middlewares=middlewares, + # AsyncAPI args + title_=title_, + description_=description_, + schema_=schema_, + include_in_schema=include_in_schema, + ) + + raise SetupError(INCORRECT_SETUP_MSG) diff --git a/faststream/redis/publisher/publisher.py b/faststream/redis/publisher/publisher.py deleted file mode 100644 index 11b7e5f4c4..0000000000 --- a/faststream/redis/publisher/publisher.py +++ /dev/null @@ -1,183 +0,0 @@ -from collections.abc import Iterable -from typing import TYPE_CHECKING, Any, Optional, Union - -from typing_extensions import TypeAlias, override - -from faststream.exceptions import SetupError -from faststream.redis.publisher.usecase import ( - ChannelPublisher, - ListBatchPublisher, - ListPublisher, - LogicPublisher, - StreamPublisher, -) -from faststream.redis.schemas import INCORRECT_SETUP_MSG, ListSub, PubSub, StreamSub -from faststream.redis.schemas.proto import RedisAsyncAPIProtocol, validate_options -from faststream.specification.asyncapi.utils import resolve_payloads -from faststream.specification.schema.bindings import ChannelBinding, redis -from faststream.specification.schema.channel import Channel -from faststream.specification.schema.message import CorrelationId, Message -from faststream.specification.schema.operation import Operation - -if TYPE_CHECKING: - from faststream._internal.basic_types import AnyDict - from faststream._internal.types import BrokerMiddleware, PublisherMiddleware - from faststream.redis.message import UnifyRedisDict - -PublisherType: TypeAlias = Union[ - "AsyncAPIChannelPublisher", - "AsyncAPIStreamPublisher", - "AsyncAPIListPublisher", - "AsyncAPIListBatchPublisher", -] - - -class SpecificationPublisher(LogicPublisher, RedisAsyncAPIProtocol): - """A class to represent a Redis publisher.""" - - def get_schema(self) -> dict[str, Channel]: - payloads = self.get_payloads() - - return { - self.name: Channel( - description=self.description, - publish=Operation( - message=Message( - title=f"{self.name}:Message", - payload=resolve_payloads(payloads, "Publisher"), - correlationId=CorrelationId( - location="$message.header#/correlation_id", - ), - ), - ), - bindings=ChannelBinding( - redis=self.channel_binding, - ), - ), - } - - @override - @staticmethod - def create( # type: ignore[override] - *, - channel: Union["PubSub", str, None], - list: Union["ListSub", str, None], - stream: Union["StreamSub", str, None], - headers: Optional["AnyDict"], - reply_to: str, - broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], - middlewares: Iterable["PublisherMiddleware"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - schema_: Optional[Any], - include_in_schema: bool, - ) -> PublisherType: - validate_options(channel=channel, list=list, stream=stream) - - if (channel := PubSub.validate(channel)) is not None: - return AsyncAPIChannelPublisher( - channel=channel, - # basic args - headers=headers, - reply_to=reply_to, - broker_middlewares=broker_middlewares, - middlewares=middlewares, - # AsyncAPI args - title_=title_, - description_=description_, - schema_=schema_, - include_in_schema=include_in_schema, - ) - - if (stream := StreamSub.validate(stream)) is not None: - return AsyncAPIStreamPublisher( - stream=stream, - # basic args - headers=headers, - reply_to=reply_to, - broker_middlewares=broker_middlewares, - middlewares=middlewares, - # AsyncAPI args - title_=title_, - description_=description_, - schema_=schema_, - include_in_schema=include_in_schema, - ) - - if (list := ListSub.validate(list)) is not None: - if list.batch: - return AsyncAPIListBatchPublisher( - list=list, - # basic args - headers=headers, - reply_to=reply_to, - broker_middlewares=broker_middlewares, - middlewares=middlewares, - # AsyncAPI args - title_=title_, - description_=description_, - schema_=schema_, - include_in_schema=include_in_schema, - ) - return AsyncAPIListPublisher( - list=list, - # basic args - headers=headers, - reply_to=reply_to, - broker_middlewares=broker_middlewares, - middlewares=middlewares, - # AsyncAPI args - title_=title_, - description_=description_, - schema_=schema_, - include_in_schema=include_in_schema, - ) - - raise SetupError(INCORRECT_SETUP_MSG) - - -class AsyncAPIChannelPublisher(ChannelPublisher, SpecificationPublisher): - def get_name(self) -> str: - return f"{self.channel.name}:Publisher" - - @property - def channel_binding(self) -> "redis.ChannelBinding": - return redis.ChannelBinding( - channel=self.channel.name, - method="publish", - ) - - -class _ListPublisherMixin(SpecificationPublisher): - list: "ListSub" - - def get_name(self) -> str: - return f"{self.list.name}:Publisher" - - @property - def channel_binding(self) -> "redis.ChannelBinding": - return redis.ChannelBinding( - channel=self.list.name, - method="rpush", - ) - - -class AsyncAPIListPublisher(ListPublisher, _ListPublisherMixin): - pass - - -class AsyncAPIListBatchPublisher(ListBatchPublisher, _ListPublisherMixin): - pass - - -class AsyncAPIStreamPublisher(StreamPublisher, SpecificationPublisher): - def get_name(self) -> str: - return f"{self.stream.name}:Publisher" - - @property - def channel_binding(self) -> "redis.ChannelBinding": - return redis.ChannelBinding( - channel=self.stream.name, - method="xadd", - ) diff --git a/faststream/redis/publisher/specified.py b/faststream/redis/publisher/specified.py new file mode 100644 index 0000000000..f0598834c6 --- /dev/null +++ b/faststream/redis/publisher/specified.py @@ -0,0 +1,89 @@ +from typing import TYPE_CHECKING + +from faststream.redis.publisher.usecase import ( + ChannelPublisher, + ListBatchPublisher, + ListPublisher, + LogicPublisher, + StreamPublisher, +) +from faststream.redis.schemas.proto import RedisSpecificationProtocol +from faststream.specification.asyncapi.utils import resolve_payloads +from faststream.specification.schema.bindings import ChannelBinding, redis +from faststream.specification.schema.channel import Channel +from faststream.specification.schema.message import CorrelationId, Message +from faststream.specification.schema.operation import Operation + +if TYPE_CHECKING: + from faststream.redis.schemas import ListSub + + +class SpecificationPublisher(LogicPublisher, RedisSpecificationProtocol): + """A class to represent a Redis publisher.""" + + def get_schema(self) -> dict[str, Channel]: + payloads = self.get_payloads() + + return { + self.name: Channel( + description=self.description, + publish=Operation( + message=Message( + title=f"{self.name}:Message", + payload=resolve_payloads(payloads, "Publisher"), + correlationId=CorrelationId( + location="$message.header#/correlation_id", + ), + ), + ), + bindings=ChannelBinding( + redis=self.channel_binding, + ), + ), + } + + +class SpecificationChannelPublisher(ChannelPublisher, SpecificationPublisher): + def get_name(self) -> str: + return f"{self.channel.name}:Publisher" + + @property + def channel_binding(self) -> "redis.ChannelBinding": + return redis.ChannelBinding( + channel=self.channel.name, + method="publish", + ) + + +class _ListPublisherMixin(SpecificationPublisher): + list: "ListSub" + + def get_name(self) -> str: + return f"{self.list.name}:Publisher" + + @property + def channel_binding(self) -> "redis.ChannelBinding": + return redis.ChannelBinding( + channel=self.list.name, + method="rpush", + ) + + +class SpecificationListPublisher(ListPublisher, _ListPublisherMixin): + pass + + +class SpecificationListBatchPublisher(ListBatchPublisher, _ListPublisherMixin): + pass + + +class SpecificationStreamPublisher(StreamPublisher, SpecificationPublisher): + def get_name(self) -> str: + return f"{self.stream.name}:Publisher" + + @property + def channel_binding(self) -> "redis.ChannelBinding": + return redis.ChannelBinding( + channel=self.stream.name, + method="xadd", + ) diff --git a/faststream/redis/schemas/proto.py b/faststream/redis/schemas/proto.py index 0e1d929211..1b4a5526f6 100644 --- a/faststream/redis/schemas/proto.py +++ b/faststream/redis/schemas/proto.py @@ -9,7 +9,7 @@ from faststream.specification.schema.bindings import redis -class RedisAsyncAPIProtocol(EndpointProto): +class RedisSpecificationProtocol(EndpointProto): @property @abstractmethod def channel_binding(self) -> "redis.ChannelBinding": ... diff --git a/faststream/redis/subscriber/factory.py b/faststream/redis/subscriber/factory.py index 8cd414f278..248ce141cf 100644 --- a/faststream/redis/subscriber/factory.py +++ b/faststream/redis/subscriber/factory.py @@ -6,7 +6,7 @@ from faststream.exceptions import SetupError from faststream.redis.schemas import INCORRECT_SETUP_MSG, ListSub, PubSub, StreamSub from faststream.redis.schemas.proto import validate_options -from faststream.redis.subscriber.subscriber import ( +from faststream.redis.subscriber.specified import ( AsyncAPIChannelSubscriber, AsyncAPIListBatchSubscriber, AsyncAPIListSubscriber, diff --git a/faststream/redis/subscriber/subscriber.py b/faststream/redis/subscriber/specified.py similarity index 95% rename from faststream/redis/subscriber/subscriber.py rename to faststream/redis/subscriber/specified.py index eba6c89f40..3c62aa3168 100644 --- a/faststream/redis/subscriber/subscriber.py +++ b/faststream/redis/subscriber/specified.py @@ -1,5 +1,5 @@ from faststream.redis.schemas import ListSub, StreamSub -from faststream.redis.schemas.proto import RedisAsyncAPIProtocol +from faststream.redis.schemas.proto import RedisSpecificationProtocol from faststream.redis.subscriber.usecase import ( BatchListSubscriber, BatchStreamSubscriber, @@ -15,7 +15,7 @@ from faststream.specification.schema.operation import Operation -class SpecificationSubscriber(LogicSubscriber, RedisAsyncAPIProtocol): +class SpecificationSubscriber(LogicSubscriber, RedisSpecificationProtocol): """A class to represent a Redis handler.""" def get_schema(self) -> dict[str, Channel]: diff --git a/faststream/redis/testing.py b/faststream/redis/testing.py index 8f065bf5a7..48205dbe08 100644 --- a/faststream/redis/testing.py +++ b/faststream/redis/testing.py @@ -38,7 +38,7 @@ if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict, SendableMessage - from faststream.redis.publisher.publisher import SpecificationPublisher + from faststream.redis.publisher.specified import SpecificationPublisher __all__ = ("TestRedisBroker",) From 9a6461d80ae7eae192514968d92423a585d4fa25 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Fri, 18 Oct 2024 17:33:24 +0300 Subject: [PATCH 178/245] refactor: split publish to private --- faststream/_internal/publisher/fake.py | 13 ++- faststream/_internal/publisher/proto.py | 19 +++- faststream/_internal/subscriber/usecase.py | 2 +- faststream/confluent/publisher/usecase.py | 53 +++++++++++ faststream/kafka/publisher/usecase.py | 63 +++++++++++-- faststream/nats/publisher/usecase.py | 29 +++++- faststream/rabbit/publisher/usecase.py | 32 ++++++- faststream/redis/publisher/usecase.py | 102 +++++++++++++++++---- 8 files changed, 278 insertions(+), 35 deletions(-) diff --git a/faststream/_internal/publisher/fake.py b/faststream/_internal/publisher/fake.py index 3fb3b1e074..2c5a4eaa7e 100644 --- a/faststream/_internal/publisher/fake.py +++ b/faststream/_internal/publisher/fake.py @@ -3,10 +3,11 @@ from itertools import chain from typing import TYPE_CHECKING, Any, Optional +from faststream._internal.basic_types import SendableMessage from faststream._internal.publisher.proto import BasePublisherProto if TYPE_CHECKING: - from faststream._internal.basic_types import AnyDict, AsyncFunc, SendableMessage + from faststream._internal.basic_types import AnyDict, AsyncFunc from faststream._internal.types import PublisherMiddleware @@ -26,6 +27,16 @@ def __init__( self.middlewares = middlewares async def publish( + self, + message: SendableMessage, + /, + *, + correlation_id: Optional[str] = None, + ) -> Optional[Any]: + msg = "You can't use `FakePublisher` directly." + raise NotImplementedError(msg) + + async def _publish( self, message: "SendableMessage", *, diff --git a/faststream/_internal/publisher/proto.py b/faststream/_internal/publisher/proto.py index 1cb920b280..d2094b0e46 100644 --- a/faststream/_internal/publisher/proto.py +++ b/faststream/_internal/publisher/proto.py @@ -54,9 +54,26 @@ async def publish( /, *, correlation_id: Optional[str] = None, + ) -> Optional[Any]: + """Public method to publish a message. + + Should be called by user only `broker.publisher(...).publish(...)`. + """ + ... + + @abstractmethod + async def _publish( + self, + message: "SendableMessage", + /, + *, + correlation_id: Optional[str] = None, _extra_middlewares: Iterable["PublisherMiddleware"] = (), ) -> Optional[Any]: - """Publishes a message asynchronously.""" + """Private method to publish a message. + + Should be called inside `publish` method or as a step of `consume` scope. + """ ... @abstractmethod diff --git a/faststream/_internal/subscriber/usecase.py b/faststream/_internal/subscriber/usecase.py index 54d5a9250c..75f4063a10 100644 --- a/faststream/_internal/subscriber/usecase.py +++ b/faststream/_internal/subscriber/usecase.py @@ -376,7 +376,7 @@ async def process_message(self, msg: MsgType) -> "Response": self.__get_response_publisher(message), h.handler._publishers, ): - await p.publish( + await p._publish( result_msg.body, **result_msg.as_publish_kwargs(), # publisher middlewares diff --git a/faststream/confluent/publisher/usecase.py b/faststream/confluent/publisher/usecase.py index 6b7fcf101c..120928b68f 100644 --- a/faststream/confluent/publisher/usecase.py +++ b/faststream/confluent/publisher/usecase.py @@ -165,6 +165,33 @@ async def publish( correlation_id: Optional[str] = None, reply_to: str = "", no_confirm: bool = False, + ) -> None: + return await self._publish( + message, + topic=topic, + key=key, + partition=partition, + timestamp_ms=timestamp_ms, + headers=headers, + correlation_id=correlation_id, + reply_to=reply_to, + no_confirm=no_confirm, + _extra_middlewares=(), + ) + + @override + async def _publish( + self, + message: "SendableMessage", + topic: str = "", + *, + key: Optional[bytes] = None, + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + correlation_id: Optional[str] = None, + reply_to: str = "", + no_confirm: bool = False, # publisher specific _extra_middlewares: Iterable["PublisherMiddleware"] = (), ) -> None: @@ -236,6 +263,32 @@ async def publish( correlation_id: Optional[str] = None, reply_to: str = "", no_confirm: bool = False, + ) -> None: + return await self._publish( + message, + *extra_messages, + topic=topic, + partition=partition, + timestamp_ms=timestamp_ms, + headers=headers, + correlation_id=correlation_id, + reply_to=reply_to, + no_confirm=no_confirm, + _extra_middlewares=(), + ) + + @override + async def _publish( + self, + message: Union["SendableMessage", Iterable["SendableMessage"]], + *extra_messages: "SendableMessage", + topic: str = "", + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + correlation_id: Optional[str] = None, + reply_to: str = "", + no_confirm: bool = False, # publisher specific _extra_middlewares: Iterable["PublisherMiddleware"] = (), ) -> None: diff --git a/faststream/kafka/publisher/usecase.py b/faststream/kafka/publisher/usecase.py index de0094033e..3c09c32dd8 100644 --- a/faststream/kafka/publisher/usecase.py +++ b/faststream/kafka/publisher/usecase.py @@ -269,11 +269,35 @@ async def publish( bool, Doc("Do not wait for Kafka publish confirmation."), ] = False, + ) -> None: + return await self._publish( + message, + topic=topic, + key=key, + partition=partition, + timestamp_ms=timestamp_ms, + headers=headers, + correlation_id=correlation_id, + reply_to=reply_to, + no_confirm=no_confirm, + _extra_middlewares=(), + ) + + @override + async def _publish( + self, + message: "SendableMessage", + topic: str = "", + *, + key: Union[bytes, Any, None] = None, + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + correlation_id: Optional[str] = None, + reply_to: str = "", + no_confirm: bool = False, # publisher specific - _extra_middlewares: Annotated[ - Iterable["PublisherMiddleware"], - Doc("Extra middlewares to wrap publishing process."), - ] = (), + _extra_middlewares: Iterable["PublisherMiddleware"] = (), ) -> None: assert self._producer, NOT_CONNECTED_YET # nosec B101 @@ -438,11 +462,34 @@ async def publish( bool, Doc("Do not wait for Kafka publish confirmation."), ] = False, + ) -> None: + return await self._publish( + message, + *extra_messages, + topic=topic, + partition=partition, + timestamp_ms=timestamp_ms, + headers=headers, + reply_to=reply_to, + correlation_id=correlation_id, + no_confirm=no_confirm, + _extra_middlewares=(), + ) + + @override + async def _publish( + self, + message: Union["SendableMessage", Iterable["SendableMessage"]], + *extra_messages: "SendableMessage", + topic: str = "", + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + reply_to: str = "", + correlation_id: Optional[str] = None, + no_confirm: bool = False, # publisher specific - _extra_middlewares: Annotated[ - Iterable["PublisherMiddleware"], - Doc("Extra middlewares to wrap publishing process."), - ] = (), + _extra_middlewares: Iterable["PublisherMiddleware"] = (), ) -> None: assert self._producer, NOT_CONNECTED_YET # nosec B101 diff --git a/faststream/nats/publisher/usecase.py b/faststream/nats/publisher/usecase.py index f76e24d070..b3317e4be9 100644 --- a/faststream/nats/publisher/usecase.py +++ b/faststream/nats/publisher/usecase.py @@ -76,8 +76,6 @@ async def publish( correlation_id: Optional[str] = None, stream: Optional[str] = None, timeout: Optional[float] = None, - # publisher specific - _extra_middlewares: Iterable["PublisherMiddleware"] = (), ) -> None: """Publish message directly. @@ -95,9 +93,32 @@ async def publish( stream (str, optional): This option validates that the target subject is in presented stream (default is `None`). Can be omitted without any effect. timeout (float, optional): Timeout to send message to NATS in seconds (default is `None`). - - _extra_middlewares (:obj:`Iterable` of :obj:`PublisherMiddleware`): Extra middlewares to wrap publishing process (default is `()`). """ + return await self._publish( + message, + subject=subject, + headers=headers, + reply_to=reply_to, + correlation_id=correlation_id, + stream=stream, + timeout=timeout, + _extra_middlewares=(), + ) + + @override + async def _publish( + self, + message: "SendableMessage", + subject: str = "", + *, + headers: Optional[dict[str, str]] = None, + reply_to: str = "", + correlation_id: Optional[str] = None, + stream: Optional[str] = None, + timeout: Optional[float] = None, + # publisher specific + _extra_middlewares: Iterable["PublisherMiddleware"] = (), + ) -> None: assert self._producer, NOT_CONNECTED_YET # nosec B101 kwargs: AnyDict = { diff --git a/faststream/rabbit/publisher/usecase.py b/faststream/rabbit/publisher/usecase.py index 49cdf71f14..6a01bdbdac 100644 --- a/faststream/rabbit/publisher/usecase.py +++ b/faststream/rabbit/publisher/usecase.py @@ -211,10 +211,34 @@ async def publish( Doc("Message publish timestamp. Generated automatically if not presented."), ] = None, # publisher specific - _extra_middlewares: Annotated[ - Iterable["PublisherMiddleware"], - Doc("Extra middlewares to wrap publishing process."), - ] = (), + **publish_kwargs: "Unpack[PublishKwargs]", + ) -> Optional["aiormq.abc.ConfirmationFrameType"]: + return await self._publish( + message, + queue=queue, + exchange=exchange, + routing_key=routing_key, + correlation_id=correlation_id, + message_id=message_id, + timestamp=timestamp, + _extra_middlewares=(), + **publish_kwargs, + ) + + @override + async def _publish( + self, + message: "AioPikaSendableMessage", + queue: Union["RabbitQueue", str, None] = None, + exchange: Union["RabbitExchange", str, None] = None, + *, + routing_key: str = "", + # message args + correlation_id: Optional[str] = None, + message_id: Optional[str] = None, + timestamp: Optional["DateType"] = None, + # publisher specific + _extra_middlewares: Iterable["PublisherMiddleware"] = (), **publish_kwargs: "Unpack[PublishKwargs]", ) -> Optional["aiormq.abc.ConfirmationFrameType"]: assert self._producer, NOT_CONNECTED_YET # nosec B101 diff --git a/faststream/redis/publisher/usecase.py b/faststream/redis/publisher/usecase.py index 9aae92c837..27ad3a3543 100644 --- a/faststream/redis/publisher/usecase.py +++ b/faststream/redis/publisher/usecase.py @@ -128,11 +128,28 @@ async def publish( "**correlation_id** is a useful option to trace messages.", ), ] = None, + **kwargs: Any, # option to suppress maxlen + ) -> None: + return await self._publish( + message, + channel=channel, + reply_to=reply_to, + headers=headers, + correlation_id=correlation_id, + _extra_middlewares=(), + **kwargs, + ) + + @override + async def _publish( + self, + message: "SendableMessage" = None, + channel: Optional[str] = None, + reply_to: str = "", + headers: Optional["AnyDict"] = None, + correlation_id: Optional[str] = None, # publisher specific - _extra_middlewares: Annotated[ - Iterable["PublisherMiddleware"], - Doc("Extra middlewares to wrap publishing process."), - ] = (), + _extra_middlewares: Iterable["PublisherMiddleware"] = (), **kwargs: Any, # option to suppress maxlen ) -> None: assert self._producer, NOT_CONNECTED_YET # nosec B101 @@ -298,10 +315,28 @@ async def publish( ), ] = None, # publisher specific - _extra_middlewares: Annotated[ - Iterable["PublisherMiddleware"], - Doc("Extra middlewares to wrap publishing process."), - ] = (), + **kwargs: Any, # option to suppress maxlen + ) -> None: + return await self._publish( + message, + list=list, + reply_to=reply_to, + headers=headers, + correlation_id=correlation_id, + _extra_middlewares=(), + **kwargs, + ) + + @override + async def _publish( + self, + message: "SendableMessage" = None, + list: Optional[str] = None, + reply_to: str = "", + headers: Optional["AnyDict"] = None, + correlation_id: Optional[str] = None, + # publisher specific + _extra_middlewares: Iterable["PublisherMiddleware"] = (), **kwargs: Any, # option to suppress maxlen ) -> None: assert self._producer, NOT_CONNECTED_YET # nosec B101 @@ -420,10 +455,27 @@ async def publish( # type: ignore[override] Doc("Message headers to store metainformation."), ] = None, # publisher specific - _extra_middlewares: Annotated[ - Iterable["PublisherMiddleware"], - Doc("Extra middlewares to wrap publishing process."), - ] = (), + **kwargs: Any, # option to suppress maxlen + ) -> None: + return await self._publish( + message, + list=list, + correlation_id=correlation_id, + headers=headers, + _extra_middlewares=(), + **kwargs, + ) + + @override + async def _publish( # type: ignore[override] + self, + message: "SendableMessage" = (), + list: Optional[str] = None, + *, + correlation_id: Optional[str] = None, + headers: Optional["AnyDict"] = None, + # publisher specific + _extra_middlewares: Iterable["PublisherMiddleware"] = (), **kwargs: Any, # option to suppress maxlen ) -> None: assert self._producer, NOT_CONNECTED_YET # nosec B101 @@ -526,11 +578,29 @@ async def publish( "Remove eldest message if maxlen exceeded.", ), ] = None, + ) -> None: + return await self._publish( + message, + stream=stream, + reply_to=reply_to, + headers=headers, + correlation_id=correlation_id, + maxlen=maxlen, + _extra_middlewares=(), + ) + + @override + async def _publish( + self, + message: "SendableMessage" = None, + stream: Optional[str] = None, + reply_to: str = "", + headers: Optional["AnyDict"] = None, + correlation_id: Optional[str] = None, + *, + maxlen: Optional[int] = None, # publisher specific - _extra_middlewares: Annotated[ - Iterable["PublisherMiddleware"], - Doc("Extra middlewares to wrap publishing process."), - ] = (), + _extra_middlewares: Iterable["PublisherMiddleware"] = (), ) -> None: assert self._producer, NOT_CONNECTED_YET # nosec B101 From be596f0fc41386a0768545a30a5e915bbcca982a Mon Sep 17 00:00:00 2001 From: Pastukhov Nikita Date: Sat, 26 Oct 2024 10:57:21 +0300 Subject: [PATCH 179/245] refactor: use CMD to call publisher (#1857) * refactor: use CMD to call publisher * fix: add missing pre-commit changes * refactor: add an ability to check RPC response * refactor: use PublishType * refactor: new NatsFakePublisher * refactor: use PublishCmd in request * fix: correct publisher.publish * fix: correct Nats JS request * lint: polish annotations * feat: add RabbitPublishCommand * refactor: add basic publish & request publisher methods * refactor: remove add_header Response method * refactor: add KafkaPublishCommand * refactor: pass context to middleware directly * refactor: Confluent, Redis publish commands * refactor: break ISP, add publish_batch to ProducerProto * refactor: create basic fake publisher * refactor: do not call LoggingMiddleware for RPC responses * refactor: new NatsOtelMiddleware * refactor: new RabbitOtelMiddleware * refactor: new RedisOtelMiddleware * refactor: new KafkaOtelMiddleware * refactor: new ConfluentOtelMiddleware * feat: add PublishCmd add_headers method * refactor: actual PrometheusMiddleware * fix: correct AsyncAPI * fix: add missing pre-commit changes * chore: remove 3.8 from CI * docs: generate API References * chore: fix CI * chore: fix CI * fix: set miltilock at start only --------- Co-authored-by: Lancetnik --- .github/workflows/pr_tests.yaml | 5 +- docs/docs/SUMMARY.md | 87 +++- .../prometheus/KafkaPrometheusMiddleware.md} | 2 +- .../middleware/KafkaPrometheusMiddleware.md | 11 + .../BaseConfluentMetricsSettingsProvider.md | 11 + .../BatchConfluentMetricsSettingsProvider.md | 11 + .../ConfluentMetricsSettingsProvider.md | 11 + .../provider/settings_provider_factory.md | 11 + .../publisher/fake/KafkaFakePublisher.md} | 2 +- .../confluent/response/KafkaPublishCommand.md | 11 + .../FeatureNotSupportedException.md | 11 + .../prometheus/KafkaPrometheusMiddleware.md | 11 + .../middleware/KafkaPrometheusMiddleware.md | 11 + .../BaseKafkaMetricsSettingsProvider.md | 11 + .../BatchKafkaMetricsSettingsProvider.md | 11 + .../provider/KafkaMetricsSettingsProvider.md | 11 + .../provider/settings_provider_factory.md | 11 + .../publisher/fake/KafkaFakePublisher.md | 11 + .../response/KafkaPublishCommand.md} | 2 +- .../prometheus/NatsPrometheusMiddleware.md | 11 + .../middleware/NatsPrometheusMiddleware.md | 11 + .../BaseNatsMetricsSettingsProvider.md | 11 + .../BatchNatsMetricsSettingsProvider.md | 11 + .../provider/NatsMetricsSettingsProvider.md | 11 + .../provider/settings_provider_factory.md | 11 + .../publisher/fake/NatsFakePublisher.md} | 2 +- .../nats/response/NatsPublishCommand.md | 11 + .../api/faststream/prometheus/ConsumeAttrs.md | 11 + .../prometheus/MetricsSettingsProvider.md | 11 + .../prometheus/PrometheusMiddleware.md | 11 + .../prometheus/container/MetricsContainer.md | 11 + .../prometheus/manager/MetricsManager.md | 11 + .../middleware/PrometheusMiddleware.md | 11 + .../provider/MetricsSettingsProvider.md | 11 + .../prometheus/types/ConsumeAttrs.md | 11 + .../prometheus/types/ProcessingStatus.md | 11 + .../prometheus/types/PublishingStatus.md | 11 + .../prometheus/RabbitPrometheusMiddleware.md | 11 + .../middleware/RabbitPrometheusMiddleware.md | 11 + .../provider/RabbitMetricsSettingsProvider.md | 11 + .../publisher/fake/RabbitFakePublisher.md | 11 + .../publisher/options/MessageOptions.md | 11 + .../publisher/options/PublishOptions.md | 11 + .../rabbit/response/RabbitPublishCommand.md | 11 + .../prometheus/RedisPrometheusMiddleware.md | 11 + .../middleware/RedisPrometheusMiddleware.md | 11 + .../BaseRedisMetricsSettingsProvider.md | 11 + .../BatchRedisMetricsSettingsProvider.md | 11 + .../provider/RedisMetricsSettingsProvider.md | 11 + .../provider/settings_provider_factory.md | 11 + .../publisher/fake/RedisFakePublisher.md | 11 + .../redis/response/DestinationType.md | 11 + .../redis/response/RedisPublishCommand.md | 11 + .../api/faststream/response/PublishCommand.md | 11 + .../en/api/faststream/response/PublishType.md | 11 + .../response/publish_type/PublishType.md | 11 + .../response/response/PublishCommand.md | 11 + docs/docs/en/howto/nats/dynaconf.md | 2 +- docs/docs/en/howto/nats/index.md | 2 +- faststream/_internal/broker/broker.py | 48 ++- faststream/_internal/publisher/fake.py | 68 ++- faststream/_internal/publisher/proto.py | 32 +- faststream/_internal/publisher/usecase.py | 76 +++- faststream/_internal/subscriber/usecase.py | 10 +- faststream/_internal/subscriber/utils.py | 8 +- faststream/_internal/testing/broker.py | 2 + faststream/_internal/types.py | 22 +- faststream/confluent/annotations.py | 2 - faststream/confluent/broker/broker.py | 94 +++-- .../confluent/opentelemetry/provider.py | 21 +- faststream/confluent/prometheus/middleware.py | 6 +- faststream/confluent/prometheus/provider.py | 10 +- faststream/confluent/publisher/fake.py | 27 ++ faststream/confluent/publisher/producer.py | 78 ++-- faststream/confluent/publisher/usecase.py | 202 +++------ faststream/confluent/response.py | 100 ++++- faststream/confluent/subscriber/usecase.py | 14 +- faststream/confluent/testing.py | 103 ++--- faststream/exceptions.py | 2 +- faststream/kafka/annotations.py | 2 - faststream/kafka/broker/broker.py | 49 +-- faststream/kafka/opentelemetry/provider.py | 21 +- faststream/kafka/prometheus/middleware.py | 6 +- faststream/kafka/prometheus/provider.py | 10 +- faststream/kafka/publisher/fake.py | 27 ++ faststream/kafka/publisher/producer.py | 85 ++-- faststream/kafka/publisher/usecase.py | 217 +++------- faststream/kafka/response.py | 104 ++++- faststream/kafka/subscriber/usecase.py | 14 +- faststream/kafka/testing.py | 99 ++--- faststream/middlewares/base.py | 34 +- faststream/middlewares/exception.py | 124 +++--- faststream/middlewares/logging.py | 92 +++-- faststream/nats/annotations.py | 8 - faststream/nats/broker/broker.py | 63 ++- faststream/nats/opentelemetry/provider.py | 15 +- faststream/nats/prometheus/middleware.py | 6 +- faststream/nats/prometheus/provider.py | 12 +- faststream/nats/publisher/fake.py | 27 ++ faststream/nats/publisher/producer.py | 96 ++--- faststream/nats/publisher/usecase.py | 118 ++---- faststream/nats/response.py | 77 +++- faststream/nats/subscriber/usecase.py | 26 +- faststream/nats/testing.py | 52 +-- faststream/opentelemetry/middleware.py | 127 +++--- faststream/opentelemetry/provider.py | 7 +- faststream/prometheus/__init__.py | 4 +- faststream/prometheus/consts.py | 2 +- faststream/prometheus/middleware.py | 110 ++--- faststream/prometheus/provider.py | 9 +- faststream/rabbit/annotations.py | 2 - faststream/rabbit/broker/broker.py | 36 +- faststream/rabbit/opentelemetry/provider.py | 27 +- faststream/rabbit/parser.py | 26 +- faststream/rabbit/prometheus/middleware.py | 6 +- faststream/rabbit/prometheus/provider.py | 18 +- faststream/rabbit/publisher/fake.py | 30 ++ faststream/rabbit/publisher/options.py | 28 ++ faststream/rabbit/publisher/producer.py | 151 ++----- faststream/rabbit/publisher/specified.py | 10 +- faststream/rabbit/publisher/usecase.py | 255 ++++-------- faststream/rabbit/response.py | 121 ++++-- faststream/rabbit/schemas/proto.py | 2 +- faststream/rabbit/subscriber/usecase.py | 15 +- faststream/rabbit/testing.py | 101 +---- faststream/redis/annotations.py | 2 - faststream/redis/broker/broker.py | 43 +- faststream/redis/opentelemetry/provider.py | 13 +- faststream/redis/prometheus/middleware.py | 6 +- faststream/redis/prometheus/provider.py | 23 +- faststream/redis/publisher/fake.py | 27 ++ faststream/redis/publisher/producer.py | 113 ++--- faststream/redis/publisher/usecase.py | 388 +++++------------- faststream/redis/response.py | 124 +++++- faststream/redis/schemas/proto.py | 3 +- faststream/redis/subscriber/usecase.py | 14 +- faststream/redis/testing.py | 80 ++-- faststream/response/__init__.py | 5 +- faststream/response/publish_type.py | 12 + faststream/response/response.py | 51 ++- .../subscription/test_annotated.py | 3 +- .../asyncapi/rabbit/v2_6_0/test_publisher.py | 2 +- tests/brokers/base/consume.py | 3 +- tests/brokers/base/middlewares.py | 36 +- tests/brokers/base/requests.py | 6 +- tests/brokers/base/testclient.py | 3 +- tests/brokers/confluent/test_consume.py | 4 +- .../brokers/confluent/test_publish_command.py | 46 +++ tests/brokers/kafka/test_consume.py | 4 +- tests/brokers/kafka/test_publish_command.py | 46 +++ tests/brokers/nats/test_consume.py | 4 +- tests/brokers/rabbit/test_consume.py | 6 +- tests/brokers/rabbit/test_publish.py | 18 +- tests/brokers/rabbit/test_test_client.py | 6 +- tests/brokers/redis/test_publish_command.py | 46 +++ tests/brokers/test_pushback.py | 5 +- tests/brokers/test_response.py | 19 +- tests/cli/rabbit/test_app.py | 5 +- tests/cli/test_publish.py | 81 ++-- tests/prometheus/basic.py | 2 +- tests/tools.py | 4 +- tests/utils/test_ast.py | 4 +- 162 files changed, 3014 insertions(+), 2304 deletions(-) rename docs/docs/en/api/faststream/{opentelemetry/middleware/BaseTelemetryMiddleware.md => confluent/prometheus/KafkaPrometheusMiddleware.md} (63%) create mode 100644 docs/docs/en/api/faststream/confluent/prometheus/middleware/KafkaPrometheusMiddleware.md create mode 100644 docs/docs/en/api/faststream/confluent/prometheus/provider/BaseConfluentMetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/confluent/prometheus/provider/BatchConfluentMetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/confluent/prometheus/provider/ConfluentMetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/confluent/prometheus/provider/settings_provider_factory.md rename docs/docs/en/api/faststream/{middlewares/exception/BaseExceptionMiddleware.md => confluent/publisher/fake/KafkaFakePublisher.md} (64%) create mode 100644 docs/docs/en/api/faststream/confluent/response/KafkaPublishCommand.md create mode 100644 docs/docs/en/api/faststream/exceptions/FeatureNotSupportedException.md create mode 100644 docs/docs/en/api/faststream/kafka/prometheus/KafkaPrometheusMiddleware.md create mode 100644 docs/docs/en/api/faststream/kafka/prometheus/middleware/KafkaPrometheusMiddleware.md create mode 100644 docs/docs/en/api/faststream/kafka/prometheus/provider/BaseKafkaMetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/kafka/prometheus/provider/BatchKafkaMetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/kafka/prometheus/provider/KafkaMetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/kafka/prometheus/provider/settings_provider_factory.md create mode 100644 docs/docs/en/api/faststream/kafka/publisher/fake/KafkaFakePublisher.md rename docs/docs/en/api/faststream/{exceptions/OperationForbiddenError.md => kafka/response/KafkaPublishCommand.md} (68%) create mode 100644 docs/docs/en/api/faststream/nats/prometheus/NatsPrometheusMiddleware.md create mode 100644 docs/docs/en/api/faststream/nats/prometheus/middleware/NatsPrometheusMiddleware.md create mode 100644 docs/docs/en/api/faststream/nats/prometheus/provider/BaseNatsMetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/nats/prometheus/provider/BatchNatsMetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/nats/prometheus/provider/NatsMetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/nats/prometheus/provider/settings_provider_factory.md rename docs/docs/en/api/faststream/{middlewares/logging/LoggingMiddleware.md => nats/publisher/fake/NatsFakePublisher.md} (67%) create mode 100644 docs/docs/en/api/faststream/nats/response/NatsPublishCommand.md create mode 100644 docs/docs/en/api/faststream/prometheus/ConsumeAttrs.md create mode 100644 docs/docs/en/api/faststream/prometheus/MetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/prometheus/PrometheusMiddleware.md create mode 100644 docs/docs/en/api/faststream/prometheus/container/MetricsContainer.md create mode 100644 docs/docs/en/api/faststream/prometheus/manager/MetricsManager.md create mode 100644 docs/docs/en/api/faststream/prometheus/middleware/PrometheusMiddleware.md create mode 100644 docs/docs/en/api/faststream/prometheus/provider/MetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/prometheus/types/ConsumeAttrs.md create mode 100644 docs/docs/en/api/faststream/prometheus/types/ProcessingStatus.md create mode 100644 docs/docs/en/api/faststream/prometheus/types/PublishingStatus.md create mode 100644 docs/docs/en/api/faststream/rabbit/prometheus/RabbitPrometheusMiddleware.md create mode 100644 docs/docs/en/api/faststream/rabbit/prometheus/middleware/RabbitPrometheusMiddleware.md create mode 100644 docs/docs/en/api/faststream/rabbit/prometheus/provider/RabbitMetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/rabbit/publisher/fake/RabbitFakePublisher.md create mode 100644 docs/docs/en/api/faststream/rabbit/publisher/options/MessageOptions.md create mode 100644 docs/docs/en/api/faststream/rabbit/publisher/options/PublishOptions.md create mode 100644 docs/docs/en/api/faststream/rabbit/response/RabbitPublishCommand.md create mode 100644 docs/docs/en/api/faststream/redis/prometheus/RedisPrometheusMiddleware.md create mode 100644 docs/docs/en/api/faststream/redis/prometheus/middleware/RedisPrometheusMiddleware.md create mode 100644 docs/docs/en/api/faststream/redis/prometheus/provider/BaseRedisMetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/redis/prometheus/provider/BatchRedisMetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/redis/prometheus/provider/RedisMetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/redis/prometheus/provider/settings_provider_factory.md create mode 100644 docs/docs/en/api/faststream/redis/publisher/fake/RedisFakePublisher.md create mode 100644 docs/docs/en/api/faststream/redis/response/DestinationType.md create mode 100644 docs/docs/en/api/faststream/redis/response/RedisPublishCommand.md create mode 100644 docs/docs/en/api/faststream/response/PublishCommand.md create mode 100644 docs/docs/en/api/faststream/response/PublishType.md create mode 100644 docs/docs/en/api/faststream/response/publish_type/PublishType.md create mode 100644 docs/docs/en/api/faststream/response/response/PublishCommand.md create mode 100644 faststream/confluent/publisher/fake.py create mode 100644 faststream/kafka/publisher/fake.py create mode 100644 faststream/nats/publisher/fake.py create mode 100644 faststream/rabbit/publisher/fake.py create mode 100644 faststream/rabbit/publisher/options.py create mode 100644 faststream/redis/publisher/fake.py create mode 100644 faststream/response/publish_type.py create mode 100644 tests/brokers/confluent/test_publish_command.py create mode 100644 tests/brokers/kafka/test_publish_command.py create mode 100644 tests/brokers/redis/test_publish_command.py diff --git a/.github/workflows/pr_tests.yaml b/.github/workflows/pr_tests.yaml index e9282d496c..58e75a252b 100644 --- a/.github/workflows/pr_tests.yaml +++ b/.github/workflows/pr_tests.yaml @@ -31,7 +31,6 @@ jobs: - uses: actions/setup-python@v5 with: python-version: | - 3.8 3.9 3.10 - name: Set $PY environment variable @@ -55,7 +54,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] pydantic-version: ["pydantic-v1", "pydantic-v2"] fail-fast: false @@ -491,7 +490,7 @@ jobs: version: "latest" - uses: actions/setup-python@v5 with: - python-version: "3.8" + python-version: "3.12" - name: Get coverage files uses: actions/download-artifact@v4 diff --git a/docs/docs/SUMMARY.md b/docs/docs/SUMMARY.md index e7018afc71..8f8c5f0cba 100644 --- a/docs/docs/SUMMARY.md +++ b/docs/docs/SUMMARY.md @@ -294,9 +294,20 @@ search: - [telemetry_attributes_provider_factory](api/faststream/confluent/opentelemetry/provider/telemetry_attributes_provider_factory.md) - parser - [AsyncConfluentParser](api/faststream/confluent/parser/AsyncConfluentParser.md) + - prometheus + - [KafkaPrometheusMiddleware](api/faststream/confluent/prometheus/KafkaPrometheusMiddleware.md) + - middleware + - [KafkaPrometheusMiddleware](api/faststream/confluent/prometheus/middleware/KafkaPrometheusMiddleware.md) + - provider + - [BaseConfluentMetricsSettingsProvider](api/faststream/confluent/prometheus/provider/BaseConfluentMetricsSettingsProvider.md) + - [BatchConfluentMetricsSettingsProvider](api/faststream/confluent/prometheus/provider/BatchConfluentMetricsSettingsProvider.md) + - [ConfluentMetricsSettingsProvider](api/faststream/confluent/prometheus/provider/ConfluentMetricsSettingsProvider.md) + - [settings_provider_factory](api/faststream/confluent/prometheus/provider/settings_provider_factory.md) - publisher - factory - [create_publisher](api/faststream/confluent/publisher/factory/create_publisher.md) + - fake + - [KafkaFakePublisher](api/faststream/confluent/publisher/fake/KafkaFakePublisher.md) - producer - [AsyncConfluentFastProducer](api/faststream/confluent/publisher/producer/AsyncConfluentFastProducer.md) - specified @@ -308,6 +319,7 @@ search: - [DefaultPublisher](api/faststream/confluent/publisher/usecase/DefaultPublisher.md) - [LogicPublisher](api/faststream/confluent/publisher/usecase/LogicPublisher.md) - response + - [KafkaPublishCommand](api/faststream/confluent/response/KafkaPublishCommand.md) - [KafkaResponse](api/faststream/confluent/response/KafkaResponse.md) - router - [KafkaPublisher](api/faststream/confluent/router/KafkaPublisher.md) @@ -341,11 +353,11 @@ search: - [AckMessage](api/faststream/exceptions/AckMessage.md) - [ContextError](api/faststream/exceptions/ContextError.md) - [FastStreamException](api/faststream/exceptions/FastStreamException.md) + - [FeatureNotSupportedException](api/faststream/exceptions/FeatureNotSupportedException.md) - [HandlerException](api/faststream/exceptions/HandlerException.md) - [IgnoredException](api/faststream/exceptions/IgnoredException.md) - [IncorrectState](api/faststream/exceptions/IncorrectState.md) - [NackMessage](api/faststream/exceptions/NackMessage.md) - - [OperationForbiddenError](api/faststream/exceptions/OperationForbiddenError.md) - [RejectMessage](api/faststream/exceptions/RejectMessage.md) - [SetupError](api/faststream/exceptions/SetupError.md) - [SkipMessage](api/faststream/exceptions/SkipMessage.md) @@ -392,9 +404,20 @@ search: - parser - [AioKafkaBatchParser](api/faststream/kafka/parser/AioKafkaBatchParser.md) - [AioKafkaParser](api/faststream/kafka/parser/AioKafkaParser.md) + - prometheus + - [KafkaPrometheusMiddleware](api/faststream/kafka/prometheus/KafkaPrometheusMiddleware.md) + - middleware + - [KafkaPrometheusMiddleware](api/faststream/kafka/prometheus/middleware/KafkaPrometheusMiddleware.md) + - provider + - [BaseKafkaMetricsSettingsProvider](api/faststream/kafka/prometheus/provider/BaseKafkaMetricsSettingsProvider.md) + - [BatchKafkaMetricsSettingsProvider](api/faststream/kafka/prometheus/provider/BatchKafkaMetricsSettingsProvider.md) + - [KafkaMetricsSettingsProvider](api/faststream/kafka/prometheus/provider/KafkaMetricsSettingsProvider.md) + - [settings_provider_factory](api/faststream/kafka/prometheus/provider/settings_provider_factory.md) - publisher - factory - [create_publisher](api/faststream/kafka/publisher/factory/create_publisher.md) + - fake + - [KafkaFakePublisher](api/faststream/kafka/publisher/fake/KafkaFakePublisher.md) - producer - [AioKafkaFastProducer](api/faststream/kafka/publisher/producer/AioKafkaFastProducer.md) - specified @@ -406,6 +429,7 @@ search: - [DefaultPublisher](api/faststream/kafka/publisher/usecase/DefaultPublisher.md) - [LogicPublisher](api/faststream/kafka/publisher/usecase/LogicPublisher.md) - response + - [KafkaPublishCommand](api/faststream/kafka/response/KafkaPublishCommand.md) - [KafkaResponse](api/faststream/kafka/response/KafkaResponse.md) - router - [KafkaPublisher](api/faststream/kafka/router/KafkaPublisher.md) @@ -453,12 +477,10 @@ search: - base - [BaseMiddleware](api/faststream/middlewares/base/BaseMiddleware.md) - exception - - [BaseExceptionMiddleware](api/faststream/middlewares/exception/BaseExceptionMiddleware.md) - [ExceptionMiddleware](api/faststream/middlewares/exception/ExceptionMiddleware.md) - [ignore_handler](api/faststream/middlewares/exception/ignore_handler.md) - logging - [CriticalLogMiddleware](api/faststream/middlewares/logging/CriticalLogMiddleware.md) - - [LoggingMiddleware](api/faststream/middlewares/logging/LoggingMiddleware.md) - nats - [AckPolicy](api/faststream/nats/AckPolicy.md) - [ConsumerConfig](api/faststream/nats/ConsumerConfig.md) @@ -527,9 +549,20 @@ search: - [NatsBaseParser](api/faststream/nats/parser/NatsBaseParser.md) - [NatsParser](api/faststream/nats/parser/NatsParser.md) - [ObjParser](api/faststream/nats/parser/ObjParser.md) + - prometheus + - [NatsPrometheusMiddleware](api/faststream/nats/prometheus/NatsPrometheusMiddleware.md) + - middleware + - [NatsPrometheusMiddleware](api/faststream/nats/prometheus/middleware/NatsPrometheusMiddleware.md) + - provider + - [BaseNatsMetricsSettingsProvider](api/faststream/nats/prometheus/provider/BaseNatsMetricsSettingsProvider.md) + - [BatchNatsMetricsSettingsProvider](api/faststream/nats/prometheus/provider/BatchNatsMetricsSettingsProvider.md) + - [NatsMetricsSettingsProvider](api/faststream/nats/prometheus/provider/NatsMetricsSettingsProvider.md) + - [settings_provider_factory](api/faststream/nats/prometheus/provider/settings_provider_factory.md) - publisher - factory - [create_publisher](api/faststream/nats/publisher/factory/create_publisher.md) + - fake + - [NatsFakePublisher](api/faststream/nats/publisher/fake/NatsFakePublisher.md) - producer - [NatsFastProducer](api/faststream/nats/publisher/producer/NatsFastProducer.md) - [NatsJSFastProducer](api/faststream/nats/publisher/producer/NatsJSFastProducer.md) @@ -538,6 +571,7 @@ search: - usecase - [LogicPublisher](api/faststream/nats/publisher/usecase/LogicPublisher.md) - response + - [NatsPublishCommand](api/faststream/nats/response/NatsPublishCommand.md) - [NatsResponse](api/faststream/nats/response/NatsResponse.md) - router - [NatsPublisher](api/faststream/nats/router/NatsPublisher.md) @@ -603,7 +637,6 @@ search: - consts - [MessageAction](api/faststream/opentelemetry/consts/MessageAction.md) - middleware - - [BaseTelemetryMiddleware](api/faststream/opentelemetry/middleware/BaseTelemetryMiddleware.md) - [TelemetryMiddleware](api/faststream/opentelemetry/middleware/TelemetryMiddleware.md) - provider - [TelemetrySettingsProvider](api/faststream/opentelemetry/provider/TelemetrySettingsProvider.md) @@ -618,6 +651,22 @@ search: - [Context](api/faststream/params/params/Context.md) - [Header](api/faststream/params/params/Header.md) - [Path](api/faststream/params/params/Path.md) + - prometheus + - [ConsumeAttrs](api/faststream/prometheus/ConsumeAttrs.md) + - [MetricsSettingsProvider](api/faststream/prometheus/MetricsSettingsProvider.md) + - [PrometheusMiddleware](api/faststream/prometheus/PrometheusMiddleware.md) + - container + - [MetricsContainer](api/faststream/prometheus/container/MetricsContainer.md) + - manager + - [MetricsManager](api/faststream/prometheus/manager/MetricsManager.md) + - middleware + - [PrometheusMiddleware](api/faststream/prometheus/middleware/PrometheusMiddleware.md) + - provider + - [MetricsSettingsProvider](api/faststream/prometheus/provider/MetricsSettingsProvider.md) + - types + - [ConsumeAttrs](api/faststream/prometheus/types/ConsumeAttrs.md) + - [ProcessingStatus](api/faststream/prometheus/types/ProcessingStatus.md) + - [PublishingStatus](api/faststream/prometheus/types/PublishingStatus.md) - rabbit - [ExchangeType](api/faststream/rabbit/ExchangeType.md) - [RabbitBroker](api/faststream/rabbit/RabbitBroker.md) @@ -655,9 +704,20 @@ search: - [RabbitTelemetrySettingsProvider](api/faststream/rabbit/opentelemetry/provider/RabbitTelemetrySettingsProvider.md) - parser - [AioPikaParser](api/faststream/rabbit/parser/AioPikaParser.md) + - prometheus + - [RabbitPrometheusMiddleware](api/faststream/rabbit/prometheus/RabbitPrometheusMiddleware.md) + - middleware + - [RabbitPrometheusMiddleware](api/faststream/rabbit/prometheus/middleware/RabbitPrometheusMiddleware.md) + - provider + - [RabbitMetricsSettingsProvider](api/faststream/rabbit/prometheus/provider/RabbitMetricsSettingsProvider.md) - publisher - factory - [create_publisher](api/faststream/rabbit/publisher/factory/create_publisher.md) + - fake + - [RabbitFakePublisher](api/faststream/rabbit/publisher/fake/RabbitFakePublisher.md) + - options + - [MessageOptions](api/faststream/rabbit/publisher/options/MessageOptions.md) + - [PublishOptions](api/faststream/rabbit/publisher/options/PublishOptions.md) - producer - [AioPikaFastProducer](api/faststream/rabbit/publisher/producer/AioPikaFastProducer.md) - specified @@ -667,6 +727,7 @@ search: - [PublishKwargs](api/faststream/rabbit/publisher/usecase/PublishKwargs.md) - [RequestPublishKwargs](api/faststream/rabbit/publisher/usecase/RequestPublishKwargs.md) - response + - [RabbitPublishCommand](api/faststream/rabbit/response/RabbitPublishCommand.md) - [RabbitResponse](api/faststream/rabbit/response/RabbitResponse.md) - router - [RabbitPublisher](api/faststream/rabbit/router/RabbitPublisher.md) @@ -755,9 +816,20 @@ search: - [RedisPubSubParser](api/faststream/redis/parser/RedisPubSubParser.md) - [RedisStreamParser](api/faststream/redis/parser/RedisStreamParser.md) - [SimpleParser](api/faststream/redis/parser/SimpleParser.md) + - prometheus + - [RedisPrometheusMiddleware](api/faststream/redis/prometheus/RedisPrometheusMiddleware.md) + - middleware + - [RedisPrometheusMiddleware](api/faststream/redis/prometheus/middleware/RedisPrometheusMiddleware.md) + - provider + - [BaseRedisMetricsSettingsProvider](api/faststream/redis/prometheus/provider/BaseRedisMetricsSettingsProvider.md) + - [BatchRedisMetricsSettingsProvider](api/faststream/redis/prometheus/provider/BatchRedisMetricsSettingsProvider.md) + - [RedisMetricsSettingsProvider](api/faststream/redis/prometheus/provider/RedisMetricsSettingsProvider.md) + - [settings_provider_factory](api/faststream/redis/prometheus/provider/settings_provider_factory.md) - publisher - factory - [create_publisher](api/faststream/redis/publisher/factory/create_publisher.md) + - fake + - [RedisFakePublisher](api/faststream/redis/publisher/fake/RedisFakePublisher.md) - producer - [RedisFastProducer](api/faststream/redis/publisher/producer/RedisFastProducer.md) - specified @@ -773,6 +845,8 @@ search: - [LogicPublisher](api/faststream/redis/publisher/usecase/LogicPublisher.md) - [StreamPublisher](api/faststream/redis/publisher/usecase/StreamPublisher.md) - response + - [DestinationType](api/faststream/redis/response/DestinationType.md) + - [RedisPublishCommand](api/faststream/redis/response/RedisPublishCommand.md) - [RedisResponse](api/faststream/redis/response/RedisResponse.md) - router - [RedisPublisher](api/faststream/redis/router/RedisPublisher.md) @@ -819,9 +893,14 @@ search: - [Visitor](api/faststream/redis/testing/Visitor.md) - [build_message](api/faststream/redis/testing/build_message.md) - response + - [PublishCommand](api/faststream/response/PublishCommand.md) + - [PublishType](api/faststream/response/PublishType.md) - [Response](api/faststream/response/Response.md) - [ensure_response](api/faststream/response/ensure_response.md) + - publish_type + - [PublishType](api/faststream/response/publish_type/PublishType.md) - response + - [PublishCommand](api/faststream/response/response/PublishCommand.md) - [Response](api/faststream/response/response/Response.md) - utils - [ensure_response](api/faststream/response/utils/ensure_response.md) diff --git a/docs/docs/en/api/faststream/opentelemetry/middleware/BaseTelemetryMiddleware.md b/docs/docs/en/api/faststream/confluent/prometheus/KafkaPrometheusMiddleware.md similarity index 63% rename from docs/docs/en/api/faststream/opentelemetry/middleware/BaseTelemetryMiddleware.md rename to docs/docs/en/api/faststream/confluent/prometheus/KafkaPrometheusMiddleware.md index 64a7b4a501..e84e84acc3 100644 --- a/docs/docs/en/api/faststream/opentelemetry/middleware/BaseTelemetryMiddleware.md +++ b/docs/docs/en/api/faststream/confluent/prometheus/KafkaPrometheusMiddleware.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.opentelemetry.middleware.BaseTelemetryMiddleware +::: faststream.confluent.prometheus.KafkaPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/confluent/prometheus/middleware/KafkaPrometheusMiddleware.md b/docs/docs/en/api/faststream/confluent/prometheus/middleware/KafkaPrometheusMiddleware.md new file mode 100644 index 0000000000..6603893f74 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/prometheus/middleware/KafkaPrometheusMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.prometheus.middleware.KafkaPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/confluent/prometheus/provider/BaseConfluentMetricsSettingsProvider.md b/docs/docs/en/api/faststream/confluent/prometheus/provider/BaseConfluentMetricsSettingsProvider.md new file mode 100644 index 0000000000..27c186c098 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/prometheus/provider/BaseConfluentMetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.prometheus.provider.BaseConfluentMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/confluent/prometheus/provider/BatchConfluentMetricsSettingsProvider.md b/docs/docs/en/api/faststream/confluent/prometheus/provider/BatchConfluentMetricsSettingsProvider.md new file mode 100644 index 0000000000..f784a64e9f --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/prometheus/provider/BatchConfluentMetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.prometheus.provider.BatchConfluentMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/confluent/prometheus/provider/ConfluentMetricsSettingsProvider.md b/docs/docs/en/api/faststream/confluent/prometheus/provider/ConfluentMetricsSettingsProvider.md new file mode 100644 index 0000000000..65f0a8348e --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/prometheus/provider/ConfluentMetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.prometheus.provider.ConfluentMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/confluent/prometheus/provider/settings_provider_factory.md b/docs/docs/en/api/faststream/confluent/prometheus/provider/settings_provider_factory.md new file mode 100644 index 0000000000..78358f46e3 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/prometheus/provider/settings_provider_factory.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.prometheus.provider.settings_provider_factory diff --git a/docs/docs/en/api/faststream/middlewares/exception/BaseExceptionMiddleware.md b/docs/docs/en/api/faststream/confluent/publisher/fake/KafkaFakePublisher.md similarity index 64% rename from docs/docs/en/api/faststream/middlewares/exception/BaseExceptionMiddleware.md rename to docs/docs/en/api/faststream/confluent/publisher/fake/KafkaFakePublisher.md index 54f8031f0a..019fbf855f 100644 --- a/docs/docs/en/api/faststream/middlewares/exception/BaseExceptionMiddleware.md +++ b/docs/docs/en/api/faststream/confluent/publisher/fake/KafkaFakePublisher.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.middlewares.exception.BaseExceptionMiddleware +::: faststream.confluent.publisher.fake.KafkaFakePublisher diff --git a/docs/docs/en/api/faststream/confluent/response/KafkaPublishCommand.md b/docs/docs/en/api/faststream/confluent/response/KafkaPublishCommand.md new file mode 100644 index 0000000000..2a4efcf180 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/response/KafkaPublishCommand.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.response.KafkaPublishCommand diff --git a/docs/docs/en/api/faststream/exceptions/FeatureNotSupportedException.md b/docs/docs/en/api/faststream/exceptions/FeatureNotSupportedException.md new file mode 100644 index 0000000000..bbf1f32d2b --- /dev/null +++ b/docs/docs/en/api/faststream/exceptions/FeatureNotSupportedException.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.exceptions.FeatureNotSupportedException diff --git a/docs/docs/en/api/faststream/kafka/prometheus/KafkaPrometheusMiddleware.md b/docs/docs/en/api/faststream/kafka/prometheus/KafkaPrometheusMiddleware.md new file mode 100644 index 0000000000..c2ffd5356a --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/prometheus/KafkaPrometheusMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.prometheus.KafkaPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/kafka/prometheus/middleware/KafkaPrometheusMiddleware.md b/docs/docs/en/api/faststream/kafka/prometheus/middleware/KafkaPrometheusMiddleware.md new file mode 100644 index 0000000000..451b7080c0 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/prometheus/middleware/KafkaPrometheusMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.prometheus.middleware.KafkaPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/kafka/prometheus/provider/BaseKafkaMetricsSettingsProvider.md b/docs/docs/en/api/faststream/kafka/prometheus/provider/BaseKafkaMetricsSettingsProvider.md new file mode 100644 index 0000000000..0fd044f694 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/prometheus/provider/BaseKafkaMetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.prometheus.provider.BaseKafkaMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/kafka/prometheus/provider/BatchKafkaMetricsSettingsProvider.md b/docs/docs/en/api/faststream/kafka/prometheus/provider/BatchKafkaMetricsSettingsProvider.md new file mode 100644 index 0000000000..9bd01d5e71 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/prometheus/provider/BatchKafkaMetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.prometheus.provider.BatchKafkaMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/kafka/prometheus/provider/KafkaMetricsSettingsProvider.md b/docs/docs/en/api/faststream/kafka/prometheus/provider/KafkaMetricsSettingsProvider.md new file mode 100644 index 0000000000..ae7c490da8 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/prometheus/provider/KafkaMetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.prometheus.provider.KafkaMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/kafka/prometheus/provider/settings_provider_factory.md b/docs/docs/en/api/faststream/kafka/prometheus/provider/settings_provider_factory.md new file mode 100644 index 0000000000..1393fd9065 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/prometheus/provider/settings_provider_factory.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.prometheus.provider.settings_provider_factory diff --git a/docs/docs/en/api/faststream/kafka/publisher/fake/KafkaFakePublisher.md b/docs/docs/en/api/faststream/kafka/publisher/fake/KafkaFakePublisher.md new file mode 100644 index 0000000000..6bacca904e --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/publisher/fake/KafkaFakePublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.publisher.fake.KafkaFakePublisher diff --git a/docs/docs/en/api/faststream/exceptions/OperationForbiddenError.md b/docs/docs/en/api/faststream/kafka/response/KafkaPublishCommand.md similarity index 68% rename from docs/docs/en/api/faststream/exceptions/OperationForbiddenError.md rename to docs/docs/en/api/faststream/kafka/response/KafkaPublishCommand.md index e34e86542b..4852098fcc 100644 --- a/docs/docs/en/api/faststream/exceptions/OperationForbiddenError.md +++ b/docs/docs/en/api/faststream/kafka/response/KafkaPublishCommand.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.exceptions.OperationForbiddenError +::: faststream.kafka.response.KafkaPublishCommand diff --git a/docs/docs/en/api/faststream/nats/prometheus/NatsPrometheusMiddleware.md b/docs/docs/en/api/faststream/nats/prometheus/NatsPrometheusMiddleware.md new file mode 100644 index 0000000000..d9b179b0c4 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/prometheus/NatsPrometheusMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.prometheus.NatsPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/nats/prometheus/middleware/NatsPrometheusMiddleware.md b/docs/docs/en/api/faststream/nats/prometheus/middleware/NatsPrometheusMiddleware.md new file mode 100644 index 0000000000..7202731048 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/prometheus/middleware/NatsPrometheusMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.prometheus.middleware.NatsPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/nats/prometheus/provider/BaseNatsMetricsSettingsProvider.md b/docs/docs/en/api/faststream/nats/prometheus/provider/BaseNatsMetricsSettingsProvider.md new file mode 100644 index 0000000000..80742833bc --- /dev/null +++ b/docs/docs/en/api/faststream/nats/prometheus/provider/BaseNatsMetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.prometheus.provider.BaseNatsMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/nats/prometheus/provider/BatchNatsMetricsSettingsProvider.md b/docs/docs/en/api/faststream/nats/prometheus/provider/BatchNatsMetricsSettingsProvider.md new file mode 100644 index 0000000000..163ebb7bc6 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/prometheus/provider/BatchNatsMetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.prometheus.provider.BatchNatsMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/nats/prometheus/provider/NatsMetricsSettingsProvider.md b/docs/docs/en/api/faststream/nats/prometheus/provider/NatsMetricsSettingsProvider.md new file mode 100644 index 0000000000..e5515a4cc5 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/prometheus/provider/NatsMetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.prometheus.provider.NatsMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/nats/prometheus/provider/settings_provider_factory.md b/docs/docs/en/api/faststream/nats/prometheus/provider/settings_provider_factory.md new file mode 100644 index 0000000000..aeaa7b26e0 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/prometheus/provider/settings_provider_factory.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.prometheus.provider.settings_provider_factory diff --git a/docs/docs/en/api/faststream/middlewares/logging/LoggingMiddleware.md b/docs/docs/en/api/faststream/nats/publisher/fake/NatsFakePublisher.md similarity index 67% rename from docs/docs/en/api/faststream/middlewares/logging/LoggingMiddleware.md rename to docs/docs/en/api/faststream/nats/publisher/fake/NatsFakePublisher.md index 62e6dfa604..df23cc8045 100644 --- a/docs/docs/en/api/faststream/middlewares/logging/LoggingMiddleware.md +++ b/docs/docs/en/api/faststream/nats/publisher/fake/NatsFakePublisher.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.middlewares.logging.LoggingMiddleware +::: faststream.nats.publisher.fake.NatsFakePublisher diff --git a/docs/docs/en/api/faststream/nats/response/NatsPublishCommand.md b/docs/docs/en/api/faststream/nats/response/NatsPublishCommand.md new file mode 100644 index 0000000000..148119ba8a --- /dev/null +++ b/docs/docs/en/api/faststream/nats/response/NatsPublishCommand.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.response.NatsPublishCommand diff --git a/docs/docs/en/api/faststream/prometheus/ConsumeAttrs.md b/docs/docs/en/api/faststream/prometheus/ConsumeAttrs.md new file mode 100644 index 0000000000..ad8e536b7a --- /dev/null +++ b/docs/docs/en/api/faststream/prometheus/ConsumeAttrs.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.prometheus.ConsumeAttrs diff --git a/docs/docs/en/api/faststream/prometheus/MetricsSettingsProvider.md b/docs/docs/en/api/faststream/prometheus/MetricsSettingsProvider.md new file mode 100644 index 0000000000..0f7405e44d --- /dev/null +++ b/docs/docs/en/api/faststream/prometheus/MetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.prometheus.MetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/prometheus/PrometheusMiddleware.md b/docs/docs/en/api/faststream/prometheus/PrometheusMiddleware.md new file mode 100644 index 0000000000..c340a0cb23 --- /dev/null +++ b/docs/docs/en/api/faststream/prometheus/PrometheusMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.prometheus.PrometheusMiddleware diff --git a/docs/docs/en/api/faststream/prometheus/container/MetricsContainer.md b/docs/docs/en/api/faststream/prometheus/container/MetricsContainer.md new file mode 100644 index 0000000000..009d88d263 --- /dev/null +++ b/docs/docs/en/api/faststream/prometheus/container/MetricsContainer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.prometheus.container.MetricsContainer diff --git a/docs/docs/en/api/faststream/prometheus/manager/MetricsManager.md b/docs/docs/en/api/faststream/prometheus/manager/MetricsManager.md new file mode 100644 index 0000000000..b1a897c717 --- /dev/null +++ b/docs/docs/en/api/faststream/prometheus/manager/MetricsManager.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.prometheus.manager.MetricsManager diff --git a/docs/docs/en/api/faststream/prometheus/middleware/PrometheusMiddleware.md b/docs/docs/en/api/faststream/prometheus/middleware/PrometheusMiddleware.md new file mode 100644 index 0000000000..2902586e38 --- /dev/null +++ b/docs/docs/en/api/faststream/prometheus/middleware/PrometheusMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.prometheus.middleware.PrometheusMiddleware diff --git a/docs/docs/en/api/faststream/prometheus/provider/MetricsSettingsProvider.md b/docs/docs/en/api/faststream/prometheus/provider/MetricsSettingsProvider.md new file mode 100644 index 0000000000..3511a21a5b --- /dev/null +++ b/docs/docs/en/api/faststream/prometheus/provider/MetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.prometheus.provider.MetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/prometheus/types/ConsumeAttrs.md b/docs/docs/en/api/faststream/prometheus/types/ConsumeAttrs.md new file mode 100644 index 0000000000..d9196cab8d --- /dev/null +++ b/docs/docs/en/api/faststream/prometheus/types/ConsumeAttrs.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.prometheus.types.ConsumeAttrs diff --git a/docs/docs/en/api/faststream/prometheus/types/ProcessingStatus.md b/docs/docs/en/api/faststream/prometheus/types/ProcessingStatus.md new file mode 100644 index 0000000000..98b6710bcd --- /dev/null +++ b/docs/docs/en/api/faststream/prometheus/types/ProcessingStatus.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.prometheus.types.ProcessingStatus diff --git a/docs/docs/en/api/faststream/prometheus/types/PublishingStatus.md b/docs/docs/en/api/faststream/prometheus/types/PublishingStatus.md new file mode 100644 index 0000000000..4e7435fbea --- /dev/null +++ b/docs/docs/en/api/faststream/prometheus/types/PublishingStatus.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.prometheus.types.PublishingStatus diff --git a/docs/docs/en/api/faststream/rabbit/prometheus/RabbitPrometheusMiddleware.md b/docs/docs/en/api/faststream/rabbit/prometheus/RabbitPrometheusMiddleware.md new file mode 100644 index 0000000000..2c4308fabd --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/prometheus/RabbitPrometheusMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.prometheus.RabbitPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/rabbit/prometheus/middleware/RabbitPrometheusMiddleware.md b/docs/docs/en/api/faststream/rabbit/prometheus/middleware/RabbitPrometheusMiddleware.md new file mode 100644 index 0000000000..45163c998a --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/prometheus/middleware/RabbitPrometheusMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.prometheus.middleware.RabbitPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/rabbit/prometheus/provider/RabbitMetricsSettingsProvider.md b/docs/docs/en/api/faststream/rabbit/prometheus/provider/RabbitMetricsSettingsProvider.md new file mode 100644 index 0000000000..6d63301b34 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/prometheus/provider/RabbitMetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.prometheus.provider.RabbitMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/rabbit/publisher/fake/RabbitFakePublisher.md b/docs/docs/en/api/faststream/rabbit/publisher/fake/RabbitFakePublisher.md new file mode 100644 index 0000000000..60879c8e3a --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/publisher/fake/RabbitFakePublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.publisher.fake.RabbitFakePublisher diff --git a/docs/docs/en/api/faststream/rabbit/publisher/options/MessageOptions.md b/docs/docs/en/api/faststream/rabbit/publisher/options/MessageOptions.md new file mode 100644 index 0000000000..eaa454588a --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/publisher/options/MessageOptions.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.publisher.options.MessageOptions diff --git a/docs/docs/en/api/faststream/rabbit/publisher/options/PublishOptions.md b/docs/docs/en/api/faststream/rabbit/publisher/options/PublishOptions.md new file mode 100644 index 0000000000..c80cc9e937 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/publisher/options/PublishOptions.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.publisher.options.PublishOptions diff --git a/docs/docs/en/api/faststream/rabbit/response/RabbitPublishCommand.md b/docs/docs/en/api/faststream/rabbit/response/RabbitPublishCommand.md new file mode 100644 index 0000000000..4c4bb224b6 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/response/RabbitPublishCommand.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.response.RabbitPublishCommand diff --git a/docs/docs/en/api/faststream/redis/prometheus/RedisPrometheusMiddleware.md b/docs/docs/en/api/faststream/redis/prometheus/RedisPrometheusMiddleware.md new file mode 100644 index 0000000000..01b23fe4f1 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/prometheus/RedisPrometheusMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.prometheus.RedisPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/redis/prometheus/middleware/RedisPrometheusMiddleware.md b/docs/docs/en/api/faststream/redis/prometheus/middleware/RedisPrometheusMiddleware.md new file mode 100644 index 0000000000..c29cc91130 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/prometheus/middleware/RedisPrometheusMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.prometheus.middleware.RedisPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/redis/prometheus/provider/BaseRedisMetricsSettingsProvider.md b/docs/docs/en/api/faststream/redis/prometheus/provider/BaseRedisMetricsSettingsProvider.md new file mode 100644 index 0000000000..243414331b --- /dev/null +++ b/docs/docs/en/api/faststream/redis/prometheus/provider/BaseRedisMetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.prometheus.provider.BaseRedisMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/redis/prometheus/provider/BatchRedisMetricsSettingsProvider.md b/docs/docs/en/api/faststream/redis/prometheus/provider/BatchRedisMetricsSettingsProvider.md new file mode 100644 index 0000000000..33d1d2d3a1 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/prometheus/provider/BatchRedisMetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.prometheus.provider.BatchRedisMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/redis/prometheus/provider/RedisMetricsSettingsProvider.md b/docs/docs/en/api/faststream/redis/prometheus/provider/RedisMetricsSettingsProvider.md new file mode 100644 index 0000000000..a7f5f3abe8 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/prometheus/provider/RedisMetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.prometheus.provider.RedisMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/redis/prometheus/provider/settings_provider_factory.md b/docs/docs/en/api/faststream/redis/prometheus/provider/settings_provider_factory.md new file mode 100644 index 0000000000..aa4812f1e2 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/prometheus/provider/settings_provider_factory.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.prometheus.provider.settings_provider_factory diff --git a/docs/docs/en/api/faststream/redis/publisher/fake/RedisFakePublisher.md b/docs/docs/en/api/faststream/redis/publisher/fake/RedisFakePublisher.md new file mode 100644 index 0000000000..eb00559657 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/publisher/fake/RedisFakePublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.publisher.fake.RedisFakePublisher diff --git a/docs/docs/en/api/faststream/redis/response/DestinationType.md b/docs/docs/en/api/faststream/redis/response/DestinationType.md new file mode 100644 index 0000000000..4eda1ad154 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/response/DestinationType.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.response.DestinationType diff --git a/docs/docs/en/api/faststream/redis/response/RedisPublishCommand.md b/docs/docs/en/api/faststream/redis/response/RedisPublishCommand.md new file mode 100644 index 0000000000..14e21c799e --- /dev/null +++ b/docs/docs/en/api/faststream/redis/response/RedisPublishCommand.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.response.RedisPublishCommand diff --git a/docs/docs/en/api/faststream/response/PublishCommand.md b/docs/docs/en/api/faststream/response/PublishCommand.md new file mode 100644 index 0000000000..8ca17ac376 --- /dev/null +++ b/docs/docs/en/api/faststream/response/PublishCommand.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.response.PublishCommand diff --git a/docs/docs/en/api/faststream/response/PublishType.md b/docs/docs/en/api/faststream/response/PublishType.md new file mode 100644 index 0000000000..57d3cbddd7 --- /dev/null +++ b/docs/docs/en/api/faststream/response/PublishType.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.response.PublishType diff --git a/docs/docs/en/api/faststream/response/publish_type/PublishType.md b/docs/docs/en/api/faststream/response/publish_type/PublishType.md new file mode 100644 index 0000000000..2ac2fcd51c --- /dev/null +++ b/docs/docs/en/api/faststream/response/publish_type/PublishType.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.response.publish_type.PublishType diff --git a/docs/docs/en/api/faststream/response/response/PublishCommand.md b/docs/docs/en/api/faststream/response/response/PublishCommand.md new file mode 100644 index 0000000000..b247a7e5d8 --- /dev/null +++ b/docs/docs/en/api/faststream/response/response/PublishCommand.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.response.response.PublishCommand diff --git a/docs/docs/en/howto/nats/dynaconf.md b/docs/docs/en/howto/nats/dynaconf.md index 5c68913c80..a618b0b67f 100644 --- a/docs/docs/en/howto/nats/dynaconf.md +++ b/docs/docs/en/howto/nats/dynaconf.md @@ -91,4 +91,4 @@ async def handle_filled_buy( @app.after_startup async def after_startup(): await broker.publish({"order_id": str(uuid4())}, "order_service.order.filled.buy") - ``` \ No newline at end of file + ``` diff --git a/docs/docs/en/howto/nats/index.md b/docs/docs/en/howto/nats/index.md index 4e24c17ab2..74c92279ed 100644 --- a/docs/docs/en/howto/nats/index.md +++ b/docs/docs/en/howto/nats/index.md @@ -14,4 +14,4 @@ search: We (**airt** team) hope that this section will be maintained by the community. Please feel free to add any examples/sections or edit existing ones. If you haven't found the solution in the docs yet, this is a great opportunity to add a new article here! -To add a new page to this section, simply add a new **Markdown** file to the [`docs/docs/en/howto/nats`](https://github.com/airtai/faststream/tree/main/docs/docs/en/howto/nats){.external-link target="_blank"} directory and update the [`navigation_template.txt`](https://github.com/airtai/faststream/blob/main/docs/docs/navigation_template.txt){.external-link target="_blank"} file. \ No newline at end of file +To add a new page to this section, simply add a new **Markdown** file to the [`docs/docs/en/howto/nats`](https://github.com/airtai/faststream/tree/main/docs/docs/en/howto/nats){.external-link target="_blank"} directory and update the [`navigation_template.txt`](https://github.com/airtai/faststream/blob/main/docs/docs/navigation_template.txt){.external-link target="_blank"} file. diff --git a/faststream/_internal/broker/broker.py b/faststream/_internal/broker/broker.py index f0b73b5be8..03d7887cba 100644 --- a/faststream/_internal/broker/broker.py +++ b/faststream/_internal/broker/broker.py @@ -15,6 +15,7 @@ from typing_extensions import Doc, Self from faststream._internal._compat import is_test_env +from faststream._internal.context.repository import context from faststream._internal.setup import ( EmptyState, FastDependsData, @@ -49,6 +50,7 @@ ProducerProto, PublisherProto, ) + from faststream.response.response import PublishCommand from faststream.security import BaseSecurity from faststream.specification.schema.tag import Tag, TagDict @@ -317,13 +319,11 @@ async def close( self.running = False - async def publish( + async def _basic_publish( self, - msg: Any, + cmd: "PublishCommand", *, producer: Optional["ProducerProto"], - correlation_id: Optional[str] = None, - **kwargs: Any, ) -> Optional[Any]: """Publish message directly.""" assert producer, NOT_CONNECTED_YET # nosec B101 @@ -331,39 +331,49 @@ async def publish( publish = producer.publish for m in self._middlewares: - publish = partial(m(None).publish_scope, publish) + publish = partial(m(None, context=context).publish_scope, publish) - return await publish(msg, correlation_id=correlation_id, **kwargs) + return await publish(cmd) - async def request( + async def _basic_publish_batch( self, - msg: Any, + cmd: "PublishCommand", + *, + producer: Optional["ProducerProto"], + ) -> None: + """Publish a messages batch directly.""" + assert producer, NOT_CONNECTED_YET # nosec B101 + + publish = producer.publish_batch + + for m in self._middlewares: + publish = partial(m(None, context=context).publish_scope, publish) + + await publish(cmd) + + async def _basic_request( + self, + cmd: "PublishCommand", *, producer: Optional["ProducerProto"], - correlation_id: Optional[str] = None, - **kwargs: Any, ) -> Any: """Publish message directly.""" assert producer, NOT_CONNECTED_YET # nosec B101 request = producer.request for m in self._middlewares: - request = partial(m(None).publish_scope, request) + request = partial(m(None, context=context).publish_scope, request) - published_msg = await request( - msg, - correlation_id=correlation_id, - **kwargs, - ) + published_msg = await request(cmd) - message: Any = await process_msg( + response_msg: Any = await process_msg( msg=published_msg, middlewares=self._middlewares, parser=producer._parser, decoder=producer._decoder, + source_type=SourceType.Response, ) - message._source_type = SourceType.Response - return message + return response_msg @abstractmethod async def ping(self, timeout: Optional[float]) -> bool: diff --git a/faststream/_internal/publisher/fake.py b/faststream/_internal/publisher/fake.py index 2c5a4eaa7e..e1d498d86c 100644 --- a/faststream/_internal/publisher/fake.py +++ b/faststream/_internal/publisher/fake.py @@ -1,61 +1,60 @@ +from abc import abstractmethod from collections.abc import Iterable from functools import partial -from itertools import chain from typing import TYPE_CHECKING, Any, Optional from faststream._internal.basic_types import SendableMessage from faststream._internal.publisher.proto import BasePublisherProto if TYPE_CHECKING: - from faststream._internal.basic_types import AnyDict, AsyncFunc + from faststream._internal.basic_types import AsyncFunc + from faststream._internal.publisher.proto import ProducerProto from faststream._internal.types import PublisherMiddleware + from faststream.response.response import PublishCommand class FakePublisher(BasePublisherProto): - """Publisher Interface implementation to use as RPC or REPLY TO publisher.""" + """Publisher Interface implementation to use as RPC or REPLY TO answer publisher.""" def __init__( self, - method: "AsyncFunc", *, - publish_kwargs: "AnyDict", - middlewares: Iterable["PublisherMiddleware"] = (), + producer: "ProducerProto", ) -> None: """Initialize an object.""" - self.method = method - self.publish_kwargs = publish_kwargs - self.middlewares = middlewares + self._producer = producer - async def publish( - self, - message: SendableMessage, - /, - *, - correlation_id: Optional[str] = None, - ) -> Optional[Any]: - msg = "You can't use `FakePublisher` directly." - raise NotImplementedError(msg) + @abstractmethod + def patch_command(self, cmd: "PublishCommand") -> "PublishCommand": + raise NotImplementedError async def _publish( self, - message: "SendableMessage", + cmd: "PublishCommand", *, - correlation_id: Optional[str] = None, - _extra_middlewares: Iterable["PublisherMiddleware"] = (), - **kwargs: Any, + _extra_middlewares: Iterable["PublisherMiddleware"], ) -> Any: - """Publish a message.""" - publish_kwargs = { - "correlation_id": correlation_id, - **self.publish_kwargs, - **kwargs, - } + """This method should be called in subscriber flow only.""" + cmd = self.patch_command(cmd) - call: AsyncFunc = self.method - for m in chain(_extra_middlewares, self.middlewares): + call: AsyncFunc = self._producer.publish + for m in _extra_middlewares: call = partial(m, call) - return await call(message, **publish_kwargs) + return await call(cmd) + + async def publish( + self, + message: SendableMessage, + /, + *, + correlation_id: Optional[str] = None, + ) -> Optional[Any]: + msg = ( + f"`{self.__class__.__name__}` can be used only to publish " + "a response for `reply-to` or `RPC` messages." + ) + raise NotImplementedError(msg) async def request( self, @@ -63,12 +62,9 @@ async def request( /, *, correlation_id: Optional[str] = None, - _extra_middlewares: Iterable["PublisherMiddleware"] = (), ) -> Any: msg = ( - "`FakePublisher` can be used only to publish " + f"`{self.__class__.__name__}` can be used only to publish " "a response for `reply-to` or `RPC` messages." ) - raise NotImplementedError( - msg, - ) + raise NotImplementedError(msg) diff --git a/faststream/_internal/publisher/proto.py b/faststream/_internal/publisher/proto.py index d2094b0e46..4037e1d285 100644 --- a/faststream/_internal/publisher/proto.py +++ b/faststream/_internal/publisher/proto.py @@ -6,6 +6,7 @@ from faststream._internal.proto import Endpoint from faststream._internal.types import MsgType +from faststream.response.response import PublishCommand from faststream.specification.base.proto import EndpointProto if TYPE_CHECKING: @@ -17,6 +18,7 @@ PublisherMiddleware, T_HandlerReturn, ) + from faststream.response.response import PublishCommand class ProducerProto(Protocol): @@ -24,27 +26,20 @@ class ProducerProto(Protocol): _decoder: "AsyncCallable" @abstractmethod - async def publish( - self, - message: "SendableMessage", - /, - *, - correlation_id: Optional[str] = None, - ) -> Optional[Any]: + async def publish(self, cmd: "PublishCommand") -> Optional[Any]: """Publishes a message asynchronously.""" ... @abstractmethod - async def request( - self, - message: "SendableMessage", - /, - *, - correlation_id: Optional[str] = None, - ) -> Any: + async def request(self, cmd: "PublishCommand") -> Any: """Publishes a message synchronously.""" ... + @abstractmethod + async def publish_batch(self, cmd: "PublishCommand") -> None: + """Publishes a messages batch asynchronously.""" + ... + class BasePublisherProto(Protocol): @abstractmethod @@ -64,12 +59,10 @@ async def publish( @abstractmethod async def _publish( self, - message: "SendableMessage", - /, + cmd: "PublishCommand", *, - correlation_id: Optional[str] = None, - _extra_middlewares: Iterable["PublisherMiddleware"] = (), - ) -> Optional[Any]: + _extra_middlewares: Iterable["PublisherMiddleware"], + ) -> None: """Private method to publish a message. Should be called inside `publish` method or as a step of `consume` scope. @@ -83,7 +76,6 @@ async def request( /, *, correlation_id: Optional[str] = None, - _extra_middlewares: Iterable["PublisherMiddleware"] = (), ) -> Optional[Any]: """Publishes a message synchronously.""" ... diff --git a/faststream/_internal/publisher/usecase.py b/faststream/_internal/publisher/usecase.py index b52ea7c387..fbd735a783 100644 --- a/faststream/_internal/publisher/usecase.py +++ b/faststream/_internal/publisher/usecase.py @@ -1,5 +1,7 @@ -from collections.abc import Iterable +from collections.abc import Awaitable, Iterable +from functools import partial from inspect import unwrap +from itertools import chain from typing import ( TYPE_CHECKING, Annotated, @@ -13,13 +15,17 @@ from fast_depends.core import CallModel, build_call_model from typing_extensions import Doc, override +from faststream._internal.context.repository import context from faststream._internal.publisher.proto import PublisherProto from faststream._internal.subscriber.call_wrapper.call import HandlerCallWrapper +from faststream._internal.subscriber.utils import process_msg from faststream._internal.types import ( MsgType, P_HandlerParams, T_HandlerReturn, ) +from faststream.exceptions import NOT_CONNECTED_YET +from faststream.message.source_type import SourceType from faststream.specification.asyncapi.message import get_response_schema from faststream.specification.asyncapi.utils import to_camelcase @@ -30,6 +36,7 @@ BrokerMiddleware, PublisherMiddleware, ) + from faststream.response.response import PublishCommand class PublisherUsecase(PublisherProto[MsgType]): @@ -130,6 +137,73 @@ def __call__( self.calls.append(handler_call._original_call) return handler_call + async def _basic_publish( + self, + cmd: "PublishCommand", + *, + _extra_middlewares: Iterable["PublisherMiddleware"], + ) -> Any: + assert self._producer, NOT_CONNECTED_YET # nosec B101 + + pub: Callable[..., Awaitable[Any]] = self._producer.publish + + for pub_m in chain( + ( + _extra_middlewares + or ( + m(None, context=context).publish_scope + for m in self._broker_middlewares + ) + ), + self._middlewares, + ): + pub = partial(pub_m, pub) + + await pub(cmd) + + async def _basic_request( + self, + cmd: "PublishCommand", + ) -> Optional[Any]: + assert self._producer, NOT_CONNECTED_YET # nosec B101 + + request = self._producer.request + + for pub_m in chain( + (m(None, context=context).publish_scope for m in self._broker_middlewares), + self._middlewares, + ): + request = partial(pub_m, request) + + published_msg = await request(cmd) + + response_msg: Any = await process_msg( + msg=published_msg, + middlewares=self._broker_middlewares, + parser=self._producer._parser, + decoder=self._producer._decoder, + source_type=SourceType.Response, + ) + return response_msg + + async def _basic_publish_batch( + self, + cmd: "PublishCommand", + *, + _extra_middlewares: Iterable["PublisherMiddleware"], + ) -> Optional[Any]: + assert self._producer, NOT_CONNECTED_YET # nosec B101 + + pub = self._producer.publish_batch + + for pub_m in chain( + (m(None, context=context).publish_scope for m in self._broker_middlewares), + self._middlewares, + ): + pub = partial(pub_m, pub) + + await pub(cmd) + def get_payloads(self) -> list[tuple["AnyDict", str]]: payloads: list[tuple[AnyDict, str]] = [] diff --git a/faststream/_internal/subscriber/usecase.py b/faststream/_internal/subscriber/usecase.py index 75f4063a10..6eda9add2e 100644 --- a/faststream/_internal/subscriber/usecase.py +++ b/faststream/_internal/subscriber/usecase.py @@ -151,8 +151,6 @@ def _setup( # type: ignore[override] # dependant args state: "SetupState", ) -> None: - self.lock = MultiLock() - self._producer = producer self.graceful_timeout = graceful_timeout self.extra_context = extra_context @@ -191,6 +189,8 @@ def _setup( # type: ignore[override] @abstractmethod async def start(self) -> None: """Start the handler.""" + self.lock = MultiLock() + self.running = True @abstractmethod @@ -329,7 +329,7 @@ async def process_message(self, msg: MsgType) -> "Response": # enter all middlewares middlewares: list[BaseMiddleware] = [] for base_m in self._broker_middlewares: - middleware = base_m(msg) + middleware = base_m(msg, context=context) middlewares.append(middleware) await middleware.__aenter__() @@ -377,9 +377,7 @@ async def process_message(self, msg: MsgType) -> "Response": h.handler._publishers, ): await p._publish( - result_msg.body, - **result_msg.as_publish_kwargs(), - # publisher middlewares + result_msg.as_publish_command(), _extra_middlewares=(m.publish_scope for m in middlewares), ) diff --git a/faststream/_internal/subscriber/utils.py b/faststream/_internal/subscriber/utils.py index f3099b6490..5b6d0c990e 100644 --- a/faststream/_internal/subscriber/utils.py +++ b/faststream/_internal/subscriber/utils.py @@ -15,12 +15,14 @@ import anyio from typing_extensions import Literal, Self, overload +from faststream._internal.context.repository import context from faststream._internal.subscriber.acknowledgement_watcher import ( WatcherContext, get_watcher, ) from faststream._internal.types import MsgType from faststream._internal.utils.functions import fake_context, return_input, to_async +from faststream.message.source_type import SourceType if TYPE_CHECKING: from types import TracebackType @@ -41,6 +43,7 @@ async def process_msg( middlewares: Iterable["BrokerMiddleware[MsgType]"], parser: Callable[[MsgType], Awaitable["StreamMessage[MsgType]"]], decoder: Callable[["StreamMessage[MsgType]"], "Any"], + source_type: SourceType = SourceType.Consume, ) -> None: ... @@ -50,6 +53,7 @@ async def process_msg( middlewares: Iterable["BrokerMiddleware[MsgType]"], parser: Callable[[MsgType], Awaitable["StreamMessage[MsgType]"]], decoder: Callable[["StreamMessage[MsgType]"], "Any"], + source_type: SourceType = SourceType.Consume, ) -> "StreamMessage[MsgType]": ... @@ -58,6 +62,7 @@ async def process_msg( middlewares: Iterable["BrokerMiddleware[MsgType]"], parser: Callable[[MsgType], Awaitable["StreamMessage[MsgType]"]], decoder: Callable[["StreamMessage[MsgType]"], "Any"], + source_type: SourceType = SourceType.Consume, ) -> Optional["StreamMessage[MsgType]"]: if msg is None: return None @@ -69,11 +74,12 @@ async def process_msg( ] = return_input for m in middlewares: - mid = m(msg) + mid = m(msg, context=context) await stack.enter_async_context(mid) return_msg = partial(mid.consume_scope, return_msg) parsed_msg = await parser(msg) + parsed_msg._source_type = source_type parsed_msg._decoded_body = await decoder(parsed_msg) return await return_msg(parsed_msg) diff --git a/faststream/_internal/testing/broker.py b/faststream/_internal/testing/broker.py index 7e33fd6ab5..f074b55bbc 100644 --- a/faststream/_internal/testing/broker.py +++ b/faststream/_internal/testing/broker.py @@ -14,6 +14,7 @@ from unittest.mock import MagicMock from faststream._internal.broker.broker import BrokerUsecase +from faststream._internal.subscriber.utils import MultiLock from faststream._internal.testing.app import TestApp from faststream._internal.testing.ast import is_contains_context_name from faststream._internal.utils.functions import sync_fake_context @@ -159,6 +160,7 @@ async def publisher_response_subscriber(msg: Any) -> None: for subscriber in broker._subscribers: subscriber.running = True + subscriber.lock = MultiLock() def _fake_close( self, diff --git a/faststream/_internal/types.py b/faststream/_internal/types.py index f7c47c9461..fad8c62f95 100644 --- a/faststream/_internal/types.py +++ b/faststream/_internal/types.py @@ -10,9 +10,11 @@ from typing_extensions import ParamSpec, TypeAlias -from faststream._internal.basic_types import AsyncFunc, AsyncFuncAny +from faststream._internal.basic_types import AsyncFuncAny +from faststream._internal.context.repository import ContextRepo from faststream.message import StreamMessage from faststream.middlewares import BaseMiddleware +from faststream.response.response import PublishCommand MsgType = TypeVar("MsgType") StreamMsg = TypeVar("StreamMsg", bound=StreamMessage[Any]) @@ -64,7 +66,18 @@ ] -BrokerMiddleware: TypeAlias = Callable[[Optional[MsgType]], BaseMiddleware] +class BrokerMiddleware(Protocol[MsgType]): + """Middleware builder interface.""" + + def __call__( + self, + msg: Optional[MsgType], + /, + *, + context: ContextRepo, + ) -> BaseMiddleware: ... + + SubscriberMiddleware: TypeAlias = Callable[ [AsyncFuncAny, MsgType], MsgType, @@ -76,7 +89,6 @@ class PublisherMiddleware(Protocol): def __call__( self, - call_next: AsyncFunc, - *__args: Any, - **__kwargs: Any, + call_next: Callable[[PublishCommand], Awaitable[PublishCommand]], + msg: PublishCommand, ) -> Any: ... diff --git a/faststream/confluent/annotations.py b/faststream/confluent/annotations.py index e3c1f82af9..3ee4a9bf6f 100644 --- a/faststream/confluent/annotations.py +++ b/faststream/confluent/annotations.py @@ -5,7 +5,6 @@ from faststream.confluent.broker import KafkaBroker as KB from faststream.confluent.message import KafkaMessage as KM from faststream.confluent.publisher.producer import AsyncConfluentFastProducer -from faststream.params import NoCast __all__ = ( "ContextRepo", @@ -13,7 +12,6 @@ "KafkaMessage", "KafkaProducer", "Logger", - "NoCast", ) KafkaMessage = Annotated[KM, Context("message")] diff --git a/faststream/confluent/broker/broker.py b/faststream/confluent/broker/broker.py index a2e28a0670..4451d0e8c0 100644 --- a/faststream/confluent/broker/broker.py +++ b/faststream/confluent/broker/broker.py @@ -23,10 +23,11 @@ from faststream.confluent.client import AsyncConfluentConsumer, AsyncConfluentProducer from faststream.confluent.config import ConfluentFastConfig from faststream.confluent.publisher.producer import AsyncConfluentFastProducer +from faststream.confluent.response import KafkaPublishCommand from faststream.confluent.schemas.params import ConsumerConnectionParams from faststream.confluent.security import parse_security -from faststream.exceptions import NOT_CONNECTED_YET from faststream.message import gen_cor_id +from faststream.response.publish_type import PublishType from .logging import make_kafka_logger_state from .registrator import KafkaRegistrator @@ -39,7 +40,6 @@ from faststream._internal.basic_types import ( AnyDict, - AsyncFunc, Decorator, LoggerProto, SendableMessage, @@ -49,6 +49,7 @@ CustomCallable, ) from faststream.confluent.config import ConfluentConfig + from faststream.confluent.message import KafkaMessage from faststream.security import BaseSecurity from faststream.specification.schema.tag import Tag, TagDict @@ -474,64 +475,90 @@ def _subscriber_setup_extra(self) -> "AnyDict": @override async def publish( # type: ignore[override] self, - message: "SendableMessage", - topic: str, - key: Optional[bytes] = None, + message: Annotated[ + "SendableMessage", + Doc("Message body to send."), + ], + topic: Annotated[ + str, + Doc("Topic where the message will be published."), + ], + *, + key: Union[bytes, str, None] = None, partition: Optional[int] = None, timestamp_ms: Optional[int] = None, - headers: Optional[dict[str, str]] = None, - correlation_id: Optional[str] = None, - *, - reply_to: str = "", - no_confirm: bool = False, - # extra options to be compatible with test client - **kwargs: Any, + headers: Annotated[ + Optional[dict[str, str]], + Doc("Message headers to store metainformation."), + ] = None, + correlation_id: Annotated[ + Optional[str], + Doc( + "Manual message **correlation_id** setter. " + "**correlation_id** is a useful option to trace messages.", + ), + ] = None, + reply_to: Annotated[ + str, + Doc("Reply message topic name to send response."), + ] = "", + no_confirm: Annotated[ + bool, + Doc("Do not wait for Kafka publish confirmation."), + ] = False, ) -> None: - correlation_id = correlation_id or gen_cor_id() + """Publish message directly. - await super().publish( + This method allows you to publish message in not AsyncAPI-documented way. You can use it in another frameworks + applications or to publish messages from time to time. + + Please, use `@broker.publisher(...)` or `broker.publisher(...).publish(...)` instead in a regular way. + """ + cmd = KafkaPublishCommand( message, - producer=self._producer, topic=topic, key=key, partition=partition, timestamp_ms=timestamp_ms, headers=headers, - correlation_id=correlation_id, reply_to=reply_to, no_confirm=no_confirm, - **kwargs, + correlation_id=correlation_id or gen_cor_id(), + _publish_type=PublishType.Publish, ) + return await super()._basic_publish(cmd, producer=self._producer) @override async def request( # type: ignore[override] self, message: "SendableMessage", topic: str, - key: Optional[bytes] = None, + *, + key: Union[bytes, str, None] = None, partition: Optional[int] = None, timestamp_ms: Optional[int] = None, headers: Optional[dict[str, str]] = None, correlation_id: Optional[str] = None, timeout: float = 0.5, - ) -> Optional[Any]: - correlation_id = correlation_id or gen_cor_id() - - return await super().request( + ) -> "KafkaMessage": + cmd = KafkaPublishCommand( message, - producer=self._producer, topic=topic, key=key, partition=partition, timestamp_ms=timestamp_ms, headers=headers, - correlation_id=correlation_id, timeout=timeout, + correlation_id=correlation_id or gen_cor_id(), + _publish_type=PublishType.Request, ) + msg: KafkaMessage = await super()._basic_request(cmd, producer=self._producer) + return msg + async def publish_batch( self, - *msgs: "SendableMessage", + *messages: "SendableMessage", topic: str, partition: Optional[int] = None, timestamp_ms: Optional[int] = None, @@ -540,25 +567,20 @@ async def publish_batch( correlation_id: Optional[str] = None, no_confirm: bool = False, ) -> None: - assert self._producer, NOT_CONNECTED_YET # nosec B101 - - correlation_id = correlation_id or gen_cor_id() - - call: AsyncFunc = self._producer.publish_batch - for m in self._middlewares: - call = partial(m(None).publish_scope, call) - - await call( - *msgs, + cmd = KafkaPublishCommand( + *messages, topic=topic, partition=partition, timestamp_ms=timestamp_ms, headers=headers, reply_to=reply_to, - correlation_id=correlation_id, no_confirm=no_confirm, + correlation_id=correlation_id or gen_cor_id(), + _publish_type=PublishType.Publish, ) + await self._basic_publish_batch(cmd, producer=self._producer) + @override async def ping(self, timeout: Optional[float]) -> bool: sleep_time = (timeout or 10) / 10 diff --git a/faststream/confluent/opentelemetry/provider.py b/faststream/confluent/opentelemetry/provider.py index 8ebeea51d7..07031b5449 100644 --- a/faststream/confluent/opentelemetry/provider.py +++ b/faststream/confluent/opentelemetry/provider.py @@ -11,6 +11,7 @@ from confluent_kafka import Message from faststream._internal.basic_types import AnyDict + from faststream.confluent.response import KafkaPublishCommand from faststream.message import StreamMessage @@ -20,29 +21,29 @@ class BaseConfluentTelemetrySettingsProvider(TelemetrySettingsProvider[MsgType]) def __init__(self) -> None: self.messaging_system = "kafka" - def get_publish_attrs_from_kwargs( + def get_publish_attrs_from_cmd( self, - kwargs: "AnyDict", + cmd: "KafkaPublishCommand", ) -> "AnyDict": attrs = { SpanAttributes.MESSAGING_SYSTEM: self.messaging_system, - SpanAttributes.MESSAGING_DESTINATION_NAME: kwargs["topic"], - SpanAttributes.MESSAGING_MESSAGE_CONVERSATION_ID: kwargs["correlation_id"], + SpanAttributes.MESSAGING_DESTINATION_NAME: cmd.destination, + SpanAttributes.MESSAGING_MESSAGE_CONVERSATION_ID: cmd.correlation_id, } - if (partition := kwargs.get("partition")) is not None: - attrs[SpanAttributes.MESSAGING_KAFKA_DESTINATION_PARTITION] = partition + if cmd.partition is not None: + attrs[SpanAttributes.MESSAGING_KAFKA_DESTINATION_PARTITION] = cmd.partition - if (key := kwargs.get("key")) is not None: - attrs[SpanAttributes.MESSAGING_KAFKA_MESSAGE_KEY] = key + if cmd.key is not None: + attrs[SpanAttributes.MESSAGING_KAFKA_MESSAGE_KEY] = cmd.key return attrs def get_publish_destination_name( self, - kwargs: "AnyDict", + cmd: "KafkaPublishCommand", ) -> str: - return cast(str, kwargs["topic"]) + return cmd.destination class ConfluentTelemetrySettingsProvider( diff --git a/faststream/confluent/prometheus/middleware.py b/faststream/confluent/prometheus/middleware.py index 5aed2ce984..d294522330 100644 --- a/faststream/confluent/prometheus/middleware.py +++ b/faststream/confluent/prometheus/middleware.py @@ -1,15 +1,15 @@ from collections.abc import Sequence from typing import TYPE_CHECKING, Optional +from faststream._internal.constants import EMPTY from faststream.confluent.prometheus.provider import settings_provider_factory -from faststream.prometheus.middleware import BasePrometheusMiddleware -from faststream.types import EMPTY +from faststream.prometheus.middleware import PrometheusMiddleware if TYPE_CHECKING: from prometheus_client import CollectorRegistry -class KafkaPrometheusMiddleware(BasePrometheusMiddleware): +class KafkaPrometheusMiddleware(PrometheusMiddleware): def __init__( self, *, diff --git a/faststream/confluent/prometheus/provider.py b/faststream/confluent/prometheus/provider.py index d0e52375a5..e9e91a4587 100644 --- a/faststream/confluent/prometheus/provider.py +++ b/faststream/confluent/prometheus/provider.py @@ -1,7 +1,7 @@ from collections.abc import Sequence from typing import TYPE_CHECKING, Union, cast -from faststream.broker.message import MsgType, StreamMessage +from faststream.message.message import MsgType, StreamMessage from faststream.prometheus import ( ConsumeAttrs, MetricsSettingsProvider, @@ -10,7 +10,7 @@ if TYPE_CHECKING: from confluent_kafka import Message - from faststream.types import AnyDict + from faststream.confluent.response import KafkaPublishCommand class BaseConfluentMetricsSettingsProvider(MetricsSettingsProvider[MsgType]): @@ -19,11 +19,11 @@ class BaseConfluentMetricsSettingsProvider(MetricsSettingsProvider[MsgType]): def __init__(self) -> None: self.messaging_system = "kafka" - def get_publish_destination_name_from_kwargs( + def get_publish_destination_name_from_cmd( self, - kwargs: "AnyDict", + cmd: "KafkaPublishCommand", ) -> str: - return cast(str, kwargs["topic"]) + return cmd.destination class ConfluentMetricsSettingsProvider(BaseConfluentMetricsSettingsProvider["Message"]): diff --git a/faststream/confluent/publisher/fake.py b/faststream/confluent/publisher/fake.py new file mode 100644 index 0000000000..82d97ab682 --- /dev/null +++ b/faststream/confluent/publisher/fake.py @@ -0,0 +1,27 @@ +from typing import TYPE_CHECKING, Union + +from faststream._internal.publisher.fake import FakePublisher +from faststream.confluent.response import KafkaPublishCommand + +if TYPE_CHECKING: + from faststream._internal.publisher.proto import ProducerProto + from faststream.response.response import PublishCommand + + +class KafkaFakePublisher(FakePublisher): + """Publisher Interface implementation to use as RPC or REPLY TO answer publisher.""" + + def __init__( + self, + producer: "ProducerProto", + topic: str, + ) -> None: + super().__init__(producer=producer) + self.topic = topic + + def patch_command( + self, cmd: Union["PublishCommand", "KafkaPublishCommand"] + ) -> "KafkaPublishCommand": + real_cmd = KafkaPublishCommand.from_cmd(cmd) + real_cmd.destination = self.topic + return real_cmd diff --git a/faststream/confluent/publisher/producer.py b/faststream/confluent/publisher/producer.py index a4d9d9cf29..0ca1a00217 100644 --- a/faststream/confluent/publisher/producer.py +++ b/faststream/confluent/publisher/producer.py @@ -5,13 +5,13 @@ from faststream._internal.publisher.proto import ProducerProto from faststream._internal.subscriber.utils import resolve_custom_func from faststream.confluent.parser import AsyncConfluentParser -from faststream.exceptions import OperationForbiddenError +from faststream.exceptions import FeatureNotSupportedException from faststream.message import encode_message if TYPE_CHECKING: - from faststream._internal.basic_types import SendableMessage from faststream._internal.types import CustomCallable from faststream.confluent.client import AsyncConfluentProducer + from faststream.confluent.response import KafkaPublishCommand class AsyncConfluentFastProducer(ProducerProto): @@ -30,71 +30,42 @@ def __init__( self._parser = resolve_custom_func(parser, default.parse_message) self._decoder = resolve_custom_func(decoder, default.decode_message) + async def stop(self) -> None: + await self._producer.stop() + @override async def publish( # type: ignore[override] self, - message: "SendableMessage", - topic: str, - *, - key: Optional[bytes] = None, - partition: Optional[int] = None, - timestamp_ms: Optional[int] = None, - headers: Optional[dict[str, str]] = None, - correlation_id: str = "", - reply_to: str = "", - no_confirm: bool = False, + cmd: "KafkaPublishCommand", ) -> None: """Publish a message to a topic.""" - message, content_type = encode_message(message) + message, content_type = encode_message(cmd.body) headers_to_send = { "content-type": content_type or "", - "correlation_id": correlation_id, - **(headers or {}), + **cmd.headers_to_publish(), } - if reply_to: - headers_to_send["reply_to"] = headers_to_send.get( - "reply_to", - reply_to, - ) - await self._producer.send( - topic=topic, + topic=cmd.destination, value=message, - key=key, - partition=partition, - timestamp_ms=timestamp_ms, + key=cmd.key, + partition=cmd.partition, + timestamp_ms=cmd.timestamp_ms, headers=[(i, (j or "").encode()) for i, j in headers_to_send.items()], - no_confirm=no_confirm, + no_confirm=cmd.no_confirm, ) - async def stop(self) -> None: - await self._producer.stop() - async def publish_batch( self, - *msgs: "SendableMessage", - topic: str, - partition: Optional[int] = None, - timestamp_ms: Optional[int] = None, - headers: Optional[dict[str, str]] = None, - reply_to: str = "", - correlation_id: str = "", - no_confirm: bool = False, + cmd: "KafkaPublishCommand", ) -> None: """Publish a batch of messages to a topic.""" batch = self._producer.create_batch() - headers_to_send = {"correlation_id": correlation_id, **(headers or {})} - - if reply_to: - headers_to_send["reply_to"] = headers_to_send.get( - "reply_to", - reply_to, - ) + headers_to_send = cmd.headers_to_publish() - for msg in msgs: + for msg in cmd.batch_bodies: message, content_type = encode_message(msg) if content_type: @@ -108,20 +79,21 @@ async def publish_batch( batch.append( key=None, value=message, - timestamp=timestamp_ms, + timestamp=cmd.timestamp_ms, headers=[(i, j.encode()) for i, j in final_headers.items()], ) await self._producer.send_batch( batch, - topic, - partition=partition, - no_confirm=no_confirm, + cmd.destination, + partition=cmd.partition, + no_confirm=cmd.no_confirm, ) @override - async def request(self, *args: Any, **kwargs: Any) -> Optional[Any]: + async def request( + self, + cmd: "KafkaPublishCommand", + ) -> Optional[Any]: msg = "Kafka doesn't support `request` method without test client." - raise OperationForbiddenError( - msg, - ) + raise FeatureNotSupportedException(msg) diff --git a/faststream/confluent/publisher/usecase.py b/faststream/confluent/publisher/usecase.py index 26169478ab..c623bba944 100644 --- a/faststream/confluent/publisher/usecase.py +++ b/faststream/confluent/publisher/usecase.py @@ -1,29 +1,26 @@ -from collections.abc import Awaitable, Iterable -from functools import partial -from itertools import chain +from collections.abc import Iterable from typing import ( TYPE_CHECKING, Any, - Callable, Optional, Union, - cast, ) from confluent_kafka import Message from typing_extensions import override from faststream._internal.publisher.usecase import PublisherUsecase -from faststream._internal.subscriber.utils import process_msg from faststream._internal.types import MsgType -from faststream.exceptions import NOT_CONNECTED_YET -from faststream.message import SourceType, gen_cor_id +from faststream.confluent.response import KafkaPublishCommand +from faststream.message import gen_cor_id +from faststream.response.publish_type import PublishType if TYPE_CHECKING: - from faststream._internal.basic_types import AnyDict, AsyncFunc, SendableMessage + from faststream._internal.basic_types import SendableMessage from faststream._internal.types import BrokerMiddleware, PublisherMiddleware from faststream.confluent.message import KafkaMessage from faststream.confluent.publisher.producer import AsyncConfluentFastProducer + from faststream.response.response import PublishCommand class LogicPublisher(PublisherUsecase[MsgType]): @@ -60,7 +57,7 @@ def __init__( self.topic = topic self.partition = partition self.reply_to = reply_to - self.headers = headers + self.headers = headers or {} self._producer = None @@ -79,42 +76,20 @@ async def request( headers: Optional[dict[str, str]] = None, correlation_id: Optional[str] = None, timeout: float = 0.5, - # publisher specific - _extra_middlewares: Iterable["PublisherMiddleware"] = (), ) -> "KafkaMessage": - assert self._producer, NOT_CONNECTED_YET # nosec B101 - - kwargs: AnyDict = { - "key": key, - # basic args - "timeout": timeout, - "timestamp_ms": timestamp_ms, - "topic": topic or self.topic, - "partition": partition or self.partition, - "headers": headers or self.headers, - "correlation_id": correlation_id or gen_cor_id(), - } - - request: Callable[..., Awaitable[Any]] = self._producer.request - - for pub_m in chain( - ( - _extra_middlewares - or (m(None).publish_scope for m in self._broker_middlewares) - ), - self._middlewares, - ): - request = partial(pub_m, request) - - published_msg = await request(message, **kwargs) - - msg: KafkaMessage = await process_msg( - msg=published_msg, - middlewares=self._broker_middlewares, - parser=self._producer._parser, - decoder=self._producer._decoder, + cmd = KafkaPublishCommand( + message, + topic=topic or self.topic, + key=key, + partition=partition or self.partition, + headers=self.headers | (headers or {}), + correlation_id=correlation_id or gen_cor_id(), + timestamp_ms=timestamp_ms, + timeout=timeout, + _publish_type=PublishType.Request, ) - msg._source_type = SourceType.Response + + msg: KafkaMessage = await self._basic_request(cmd) return msg @@ -122,7 +97,7 @@ class DefaultPublisher(LogicPublisher[Message]): def __init__( self, *, - key: Optional[bytes], + key: Union[bytes, str, None], topic: str, partition: Optional[int], headers: Optional[dict[str, str]], @@ -167,61 +142,38 @@ async def publish( reply_to: str = "", no_confirm: bool = False, ) -> None: - return await self._publish( + cmd = KafkaPublishCommand( message, - topic=topic, - key=key, - partition=partition, + topic=topic or self.topic, + key=key or self.key, + partition=partition or self.partition, + reply_to=reply_to or self.reply_to, + headers=self.headers | (headers or {}), + correlation_id=correlation_id or gen_cor_id(), timestamp_ms=timestamp_ms, - headers=headers, - correlation_id=correlation_id, - reply_to=reply_to, no_confirm=no_confirm, - _extra_middlewares=(), + _publish_type=PublishType.Publish, ) + await self._basic_publish(cmd, _extra_middlewares=()) @override async def _publish( self, - message: "SendableMessage", - topic: str = "", + cmd: Union["PublishCommand", "KafkaPublishCommand"], *, - key: Optional[bytes] = None, - partition: Optional[int] = None, - timestamp_ms: Optional[int] = None, - headers: Optional[dict[str, str]] = None, - correlation_id: Optional[str] = None, - reply_to: str = "", - no_confirm: bool = False, - # publisher specific - _extra_middlewares: Iterable["PublisherMiddleware"] = (), + _extra_middlewares: Iterable["PublisherMiddleware"], ) -> None: - assert self._producer, NOT_CONNECTED_YET # nosec B101 + """This method should be called in subscriber flow only.""" + cmd = KafkaPublishCommand.from_cmd(cmd) - kwargs: AnyDict = { - "key": key or self.key, - # basic args - "no_confirm": no_confirm, - "topic": topic or self.topic, - "partition": partition or self.partition, - "timestamp_ms": timestamp_ms, - "headers": headers or self.headers, - "reply_to": reply_to or self.reply_to, - "correlation_id": correlation_id or gen_cor_id(), - } + cmd.destination = self.topic + cmd.add_headers(self.headers, override=False) + cmd.reply_to = cmd.reply_to or self.reply_to - call: Callable[..., Awaitable[None]] = self._producer.publish + cmd.partition = cmd.partition or self.partition + cmd.key = cmd.key or self.key - for m in chain( - ( - _extra_middlewares - or (m(None).publish_scope for m in self._broker_middlewares) - ), - self._middlewares, - ): - call = partial(m, call) - - return await call(message, **kwargs) + await self._basic_publish(cmd, _extra_middlewares=_extra_middlewares) @override async def request( @@ -235,11 +187,9 @@ async def request( headers: Optional[dict[str, str]] = None, correlation_id: Optional[str] = None, timeout: float = 0.5, - # publisher specific - _extra_middlewares: Iterable["PublisherMiddleware"] = (), ) -> "KafkaMessage": return await super().request( - message=message, + message, topic=topic, key=key or self.key, partition=partition, @@ -247,7 +197,6 @@ async def request( headers=headers, correlation_id=correlation_id, timeout=timeout, - _extra_middlewares=_extra_middlewares, ) @@ -255,8 +204,7 @@ class BatchPublisher(LogicPublisher[tuple[Message, ...]]): @override async def publish( self, - message: Union["SendableMessage", Iterable["SendableMessage"]], - *extra_messages: "SendableMessage", + *messages: "SendableMessage", topic: str = "", partition: Optional[int] = None, timestamp_ms: Optional[int] = None, @@ -265,61 +213,35 @@ async def publish( reply_to: str = "", no_confirm: bool = False, ) -> None: - return await self._publish( - message, - *extra_messages, - topic=topic, - partition=partition, + cmd = KafkaPublishCommand( + *messages, + key=None, + topic=topic or self.topic, + partition=partition or self.partition, + reply_to=reply_to or self.reply_to, + headers=self.headers | (headers or {}), + correlation_id=correlation_id or gen_cor_id(), timestamp_ms=timestamp_ms, - headers=headers, - correlation_id=correlation_id, - reply_to=reply_to, no_confirm=no_confirm, - _extra_middlewares=(), + _publish_type=PublishType.Publish, ) + await self._basic_publish_batch(cmd, _extra_middlewares=()) + @override async def _publish( self, - message: Union["SendableMessage", Iterable["SendableMessage"]], - *extra_messages: "SendableMessage", - topic: str = "", - partition: Optional[int] = None, - timestamp_ms: Optional[int] = None, - headers: Optional[dict[str, str]] = None, - correlation_id: Optional[str] = None, - reply_to: str = "", - no_confirm: bool = False, - # publisher specific - _extra_middlewares: Iterable["PublisherMiddleware"] = (), + cmd: Union["PublishCommand", "KafkaPublishCommand"], + *, + _extra_middlewares: Iterable["PublisherMiddleware"], ) -> None: - assert self._producer, NOT_CONNECTED_YET # nosec B101 - - msgs: Iterable[SendableMessage] - if extra_messages: - msgs = (cast("SendableMessage", message), *extra_messages) - else: - msgs = cast(Iterable["SendableMessage"], message) - - kwargs: AnyDict = { - "topic": topic or self.topic, - "no_confirm": no_confirm, - "partition": partition or self.partition, - "timestamp_ms": timestamp_ms, - "headers": headers or self.headers, - "reply_to": reply_to or self.reply_to, - "correlation_id": correlation_id or gen_cor_id(), - } + """This method should be called in subscriber flow only.""" + cmd = KafkaPublishCommand.from_cmd(cmd, batch=True) - call: AsyncFunc = self._producer.publish_batch + cmd.destination = self.topic + cmd.add_headers(self.headers, override=False) + cmd.reply_to = cmd.reply_to or self.reply_to - for m in chain( - ( - _extra_middlewares - or (m(None).publish_scope for m in self._broker_middlewares) - ), - self._middlewares, - ): - call = partial(m, call) + cmd.partition = cmd.partition or self.partition - await call(*msgs, **kwargs) + await self._basic_publish_batch(cmd, _extra_middlewares=_extra_middlewares) diff --git a/faststream/confluent/response.py b/faststream/confluent/response.py index 3d04d6ab35..2a4f84e21a 100644 --- a/faststream/confluent/response.py +++ b/faststream/confluent/response.py @@ -1,8 +1,10 @@ -from typing import TYPE_CHECKING, Optional +from collections.abc import Sequence +from typing import TYPE_CHECKING, Optional, Union from typing_extensions import override -from faststream.response import Response +from faststream.response.publish_type import PublishType +from faststream.response.response import PublishCommand, Response if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict, SendableMessage @@ -34,3 +36,97 @@ def as_publish_kwargs(self) -> "AnyDict": "timestamp_ms": self.timestamp_ms, "key": self.key, } + + @override + def as_publish_command(self) -> "KafkaPublishCommand": + return KafkaPublishCommand( + self.body, + headers=self.headers, + correlation_id=self.correlation_id, + _publish_type=PublishType.Reply, + # Kafka specific + topic="", + key=self.key, + timestamp_ms=self.timestamp_ms, + ) + + +class KafkaPublishCommand(PublishCommand): + def __init__( + self, + message: "SendableMessage", + /, + *messages: "SendableMessage", + topic: str, + _publish_type: PublishType, + key: Union[bytes, str, None] = None, + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + correlation_id: Optional[str] = None, + reply_to: str = "", + no_confirm: bool = False, + timeout: float = 0.5, + ) -> None: + super().__init__( + message, + destination=topic, + reply_to=reply_to, + correlation_id=correlation_id, + headers=headers, + _publish_type=_publish_type, + ) + self.extra_bodies = messages + + self.key = key + self.partition = partition + self.timestamp_ms = timestamp_ms + self.no_confirm = no_confirm + + # request option + self.timeout = timeout + + @property + def batch_bodies(self) -> tuple["SendableMessage", ...]: + if self.body: + return (self.body, *self.extra_bodies) + return self.extra_bodies + + @classmethod + def from_cmd( + cls, + cmd: Union["PublishCommand", "KafkaPublishCommand"], + *, + batch: bool = False, + ) -> "KafkaPublishCommand": + if isinstance(cmd, KafkaPublishCommand): + # NOTE: Should return a copy probably. + return cmd + + body, extra_bodies = cmd.body, [] + if batch and isinstance(body, Sequence) and not isinstance(body, str): + if body: + body, extra_bodies = body[0], body[1:] + else: + body = None + + return cls( + body, + *extra_bodies, + topic=cmd.destination, + correlation_id=cmd.correlation_id, + headers=cmd.headers, + reply_to=cmd.reply_to, + _publish_type=cmd.publish_type, + ) + + def headers_to_publish(self) -> dict[str, str]: + headers = {} + + if self.correlation_id: + headers["correlation_id"] = self.correlation_id + + if self.reply_to: + headers["reply_to"] = self.reply_to + + return headers | self.headers diff --git a/faststream/confluent/subscriber/usecase.py b/faststream/confluent/subscriber/usecase.py index 1f88912fdc..be1ce66dfa 100644 --- a/faststream/confluent/subscriber/usecase.py +++ b/faststream/confluent/subscriber/usecase.py @@ -12,18 +12,18 @@ from confluent_kafka import KafkaException, Message from typing_extensions import override -from faststream._internal.publisher.fake import FakePublisher from faststream._internal.subscriber.usecase import SubscriberUsecase from faststream._internal.subscriber.utils import process_msg from faststream._internal.types import MsgType from faststream.confluent.parser import AsyncConfluentParser +from faststream.confluent.publisher.fake import KafkaFakePublisher from faststream.confluent.schemas import TopicPartition if TYPE_CHECKING: from fast_depends.dependencies import Depends from faststream._internal.basic_types import AnyDict, LoggerProto - from faststream._internal.publisher.proto import ProducerProto + from faststream._internal.publisher.proto import BasePublisherProto, ProducerProto from faststream._internal.setup import SetupState from faststream._internal.types import ( AsyncCallable, @@ -182,16 +182,14 @@ async def get_one( def _make_response_publisher( self, message: "StreamMessage[Any]", - ) -> Sequence[FakePublisher]: + ) -> Sequence["BasePublisherProto"]: if self._producer is None: return () return ( - FakePublisher( - self._producer.publish, - publish_kwargs={ - "topic": message.reply_to, - }, + KafkaFakePublisher( + self._producer, + topic=message.reply_to, ), ) diff --git a/faststream/confluent/testing.py b/faststream/confluent/testing.py index c0a3cfa7bc..973a7fb58d 100644 --- a/faststream/confluent/testing.py +++ b/faststream/confluent/testing.py @@ -26,6 +26,7 @@ from faststream._internal.basic_types import SendableMessage from faststream._internal.setup.logger import LoggerState from faststream.confluent.publisher.specified import SpecificationPublisher + from faststream.confluent.response import KafkaPublishCommand from faststream.confluent.subscriber.usecase import LogicSubscriber __all__ = ("TestKafkaBroker",) @@ -104,111 +105,89 @@ def _setup(self, logger_stater: "LoggerState") -> None: @override async def publish( # type: ignore[override] self, - message: "SendableMessage", - topic: str, - key: Optional[bytes] = None, - partition: Optional[int] = None, - timestamp_ms: Optional[int] = None, - headers: Optional[dict[str, str]] = None, - correlation_id: Optional[str] = None, - *, - no_confirm: bool = False, - reply_to: str = "", + cmd: "KafkaPublishCommand", ) -> None: """Publish a message to the Kafka broker.""" incoming = build_message( - message=message, - topic=topic, - key=key, - partition=partition, - timestamp_ms=timestamp_ms, - headers=headers, - correlation_id=correlation_id or gen_cor_id(), - reply_to=reply_to, + message=cmd.body, + topic=cmd.destination, + key=cmd.key, + partition=cmd.partition, + timestamp_ms=cmd.timestamp_ms, + headers=cmd.headers, + correlation_id=cmd.correlation_id, + reply_to=cmd.reply_to, ) for handler in _find_handler( self.broker._subscribers, - topic, - partition, + cmd.destination, + cmd.partition, ): msg_to_send = ( [incoming] if isinstance(handler, BatchSubscriber) else incoming ) - await self._execute_handler(msg_to_send, topic, handler) + await self._execute_handler(msg_to_send, cmd.destination, handler) async def publish_batch( self, - *msgs: "SendableMessage", - topic: str, - partition: Optional[int] = None, - timestamp_ms: Optional[int] = None, - headers: Optional[dict[str, str]] = None, - reply_to: str = "", - correlation_id: Optional[str] = None, - no_confirm: bool = False, + cmd: "KafkaPublishCommand", ) -> None: """Publish a batch of messages to the Kafka broker.""" for handler in _find_handler( self.broker._subscribers, - topic, - partition, + cmd.destination, + cmd.partition, ): messages = ( build_message( message=message, - topic=topic, - partition=partition, - timestamp_ms=timestamp_ms, - headers=headers, - correlation_id=correlation_id or gen_cor_id(), - reply_to=reply_to, + topic=cmd.destination, + partition=cmd.partition, + timestamp_ms=cmd.timestamp_ms, + headers=cmd.headers, + correlation_id=cmd.correlation_id, + reply_to=cmd.reply_to, ) - for message in msgs + for message in cmd.batch_bodies ) if isinstance(handler, BatchSubscriber): - await self._execute_handler(list(messages), topic, handler) + await self._execute_handler(list(messages), cmd.destination, handler) else: for m in messages: - await self._execute_handler(m, topic, handler) + await self._execute_handler(m, cmd.destination, handler) @override async def request( # type: ignore[override] self, - message: "SendableMessage", - topic: str, - key: Optional[bytes] = None, - partition: Optional[int] = None, - timestamp_ms: Optional[int] = None, - headers: Optional[dict[str, str]] = None, - correlation_id: Optional[str] = None, - *, - timeout: Optional[float] = 0.5, + cmd: "KafkaPublishCommand", ) -> "MockConfluentMessage": incoming = build_message( - message=message, - topic=topic, - key=key, - partition=partition, - timestamp_ms=timestamp_ms, - headers=headers, - correlation_id=correlation_id or gen_cor_id(), + message=cmd.body, + topic=cmd.destination, + key=cmd.key, + partition=cmd.partition, + timestamp_ms=cmd.timestamp_ms, + headers=cmd.headers, + correlation_id=cmd.correlation_id, ) for handler in _find_handler( self.broker._subscribers, - topic, - partition, + cmd.destination, + cmd.partition, ): msg_to_send = ( [incoming] if isinstance(handler, BatchSubscriber) else incoming ) - with anyio.fail_after(timeout): - return await self._execute_handler(msg_to_send, topic, handler) + with anyio.fail_after(cmd.timeout): + return await self._execute_handler( + msg_to_send, cmd.destination, handler + ) raise SubscriberNotFound @@ -282,7 +261,7 @@ def build_message( message: "SendableMessage", topic: str, *, - correlation_id: str, + correlation_id: Optional[str] = None, partition: Optional[int] = None, timestamp_ms: Optional[int] = None, key: Optional[bytes] = None, @@ -294,7 +273,7 @@ def build_message( k = key or b"" headers = { "content-type": content_type or "", - "correlation_id": correlation_id, + "correlation_id": correlation_id or gen_cor_id(), "reply_to": reply_to, **(headers or {}), } diff --git a/faststream/exceptions.py b/faststream/exceptions.py index 4b009adde2..4aabd52ae8 100644 --- a/faststream/exceptions.py +++ b/faststream/exceptions.py @@ -115,7 +115,7 @@ def __str__(self) -> str: ) -class OperationForbiddenError(FastStreamException, NotImplementedError): +class FeatureNotSupportedException(FastStreamException, NotImplementedError): # noqa: N818 """Raises at planned NotImplemented operation call.""" diff --git a/faststream/kafka/annotations.py b/faststream/kafka/annotations.py index 1f5c70d524..607be0ea8e 100644 --- a/faststream/kafka/annotations.py +++ b/faststream/kafka/annotations.py @@ -7,7 +7,6 @@ from faststream.kafka.broker import KafkaBroker as KB from faststream.kafka.message import KafkaMessage as KM from faststream.kafka.publisher.producer import AioKafkaFastProducer -from faststream.params import NoCast __all__ = ( "ContextRepo", @@ -15,7 +14,6 @@ "KafkaMessage", "KafkaProducer", "Logger", - "NoCast", ) Consumer = Annotated[AIOKafkaConsumer, Context("handler_.consumer")] diff --git a/faststream/kafka/broker/broker.py b/faststream/kafka/broker/broker.py index aa77e9c408..ce2969b12b 100644 --- a/faststream/kafka/broker/broker.py +++ b/faststream/kafka/broker/broker.py @@ -24,9 +24,11 @@ from faststream._internal.utils.data import filter_by_dict from faststream.exceptions import NOT_CONNECTED_YET from faststream.kafka.publisher.producer import AioKafkaFastProducer +from faststream.kafka.response import KafkaPublishCommand from faststream.kafka.schemas.params import ConsumerConnectionParams from faststream.kafka.security import parse_security from faststream.message import gen_cor_id +from faststream.response.publish_type import PublishType from .logging import make_kafka_logger_state from .registrator import KafkaRegistrator @@ -44,7 +46,6 @@ from faststream._internal.basic_types import ( AnyDict, - AsyncFunc, Decorator, LoggerProto, SendableMessage, @@ -53,6 +54,7 @@ BrokerMiddleware, CustomCallable, ) + from faststream.kafka.message import KafkaMessage from faststream.security import BaseSecurity from faststream.specification.schema.tag import Tag, TagDict @@ -724,8 +726,6 @@ async def publish( # type: ignore[override] bool, Doc("Do not wait for Kafka publish confirmation."), ] = False, - # extra options to be compatible with test client - **kwargs: Any, ) -> None: """Publish message directly. @@ -734,21 +734,19 @@ async def publish( # type: ignore[override] Please, use `@broker.publisher(...)` or `broker.publisher(...).publish(...)` instead in a regular way. """ - correlation_id = correlation_id or gen_cor_id() - - await super().publish( + cmd = KafkaPublishCommand( message, - producer=self._producer, topic=topic, key=key, partition=partition, timestamp_ms=timestamp_ms, headers=headers, - correlation_id=correlation_id, reply_to=reply_to, no_confirm=no_confirm, - **kwargs, + correlation_id=correlation_id or gen_cor_id(), + _publish_type=PublishType.Publish, ) + return await super()._basic_publish(cmd, producer=self._producer) @override async def request( # type: ignore[override] @@ -809,31 +807,32 @@ async def request( # type: ignore[override] float, Doc("Timeout to send RPC request."), ] = 0.5, - ) -> Optional[Any]: - correlation_id = correlation_id or gen_cor_id() - - return await super().request( + ) -> "KafkaMessage": + cmd = KafkaPublishCommand( message, - producer=self._producer, topic=topic, key=key, partition=partition, timestamp_ms=timestamp_ms, headers=headers, - correlation_id=correlation_id, timeout=timeout, + correlation_id=correlation_id or gen_cor_id(), + _publish_type=PublishType.Request, ) + msg: KafkaMessage = await super()._basic_request(cmd, producer=self._producer) + return msg + async def publish_batch( self, - *msgs: Annotated[ + *messages: Annotated[ "SendableMessage", Doc("Messages bodies to send."), ], topic: Annotated[ str, Doc("Topic where the message will be published."), - ], + ] = "", partition: Annotated[ Optional[int], Doc( @@ -874,24 +873,20 @@ async def publish_batch( ) -> None: assert self._producer, NOT_CONNECTED_YET # nosec B101 - correlation_id = correlation_id or gen_cor_id() - - call: AsyncFunc = self._producer.publish_batch - - for m in self._middlewares: - call = partial(m(None).publish_scope, call) - - await call( - *msgs, + cmd = KafkaPublishCommand( + *messages, topic=topic, partition=partition, timestamp_ms=timestamp_ms, headers=headers, reply_to=reply_to, - correlation_id=correlation_id, no_confirm=no_confirm, + correlation_id=correlation_id or gen_cor_id(), + _publish_type=PublishType.Publish, ) + await self._basic_publish_batch(cmd, producer=self._producer) + @override async def ping(self, timeout: Optional[float]) -> bool: sleep_time = (timeout or 10) / 10 diff --git a/faststream/kafka/opentelemetry/provider.py b/faststream/kafka/opentelemetry/provider.py index f9a43f54f6..cd2118ed33 100644 --- a/faststream/kafka/opentelemetry/provider.py +++ b/faststream/kafka/opentelemetry/provider.py @@ -11,6 +11,7 @@ from aiokafka import ConsumerRecord from faststream._internal.basic_types import AnyDict + from faststream.kafka.response import KafkaPublishCommand from faststream.message import StreamMessage @@ -20,29 +21,29 @@ class BaseKafkaTelemetrySettingsProvider(TelemetrySettingsProvider[MsgType]): def __init__(self) -> None: self.messaging_system = "kafka" - def get_publish_attrs_from_kwargs( + def get_publish_attrs_from_cmd( self, - kwargs: "AnyDict", + cmd: "KafkaPublishCommand", ) -> "AnyDict": attrs = { SpanAttributes.MESSAGING_SYSTEM: self.messaging_system, - SpanAttributes.MESSAGING_DESTINATION_NAME: kwargs["topic"], - SpanAttributes.MESSAGING_MESSAGE_CONVERSATION_ID: kwargs["correlation_id"], + SpanAttributes.MESSAGING_DESTINATION_NAME: cmd.destination, + SpanAttributes.MESSAGING_MESSAGE_CONVERSATION_ID: cmd.correlation_id, } - if (partition := kwargs.get("partition")) is not None: - attrs[SpanAttributes.MESSAGING_KAFKA_DESTINATION_PARTITION] = partition + if cmd.partition is not None: + attrs[SpanAttributes.MESSAGING_KAFKA_DESTINATION_PARTITION] = cmd.partition - if (key := kwargs.get("key")) is not None: - attrs[SpanAttributes.MESSAGING_KAFKA_MESSAGE_KEY] = key + if cmd.key is not None: + attrs[SpanAttributes.MESSAGING_KAFKA_MESSAGE_KEY] = cmd.key return attrs def get_publish_destination_name( self, - kwargs: "AnyDict", + cmd: "KafkaPublishCommand", ) -> str: - return cast(str, kwargs["topic"]) + return cmd.destination class KafkaTelemetrySettingsProvider( diff --git a/faststream/kafka/prometheus/middleware.py b/faststream/kafka/prometheus/middleware.py index 8624b37a0f..fd5948945a 100644 --- a/faststream/kafka/prometheus/middleware.py +++ b/faststream/kafka/prometheus/middleware.py @@ -1,15 +1,15 @@ from collections.abc import Sequence from typing import TYPE_CHECKING, Optional +from faststream._internal.constants import EMPTY from faststream.kafka.prometheus.provider import settings_provider_factory -from faststream.prometheus.middleware import BasePrometheusMiddleware -from faststream.types import EMPTY +from faststream.prometheus.middleware import PrometheusMiddleware if TYPE_CHECKING: from prometheus_client import CollectorRegistry -class KafkaPrometheusMiddleware(BasePrometheusMiddleware): +class KafkaPrometheusMiddleware(PrometheusMiddleware): def __init__( self, *, diff --git a/faststream/kafka/prometheus/provider.py b/faststream/kafka/prometheus/provider.py index 7193745c10..9ea5ffbd3c 100644 --- a/faststream/kafka/prometheus/provider.py +++ b/faststream/kafka/prometheus/provider.py @@ -1,7 +1,7 @@ from collections.abc import Sequence from typing import TYPE_CHECKING, Union, cast -from faststream.broker.message import MsgType, StreamMessage +from faststream.message.message import MsgType, StreamMessage from faststream.prometheus import ( MetricsSettingsProvider, ) @@ -9,8 +9,8 @@ if TYPE_CHECKING: from aiokafka import ConsumerRecord + from faststream.kafka.response import KafkaPublishCommand from faststream.prometheus import ConsumeAttrs - from faststream.types import AnyDict class BaseKafkaMetricsSettingsProvider(MetricsSettingsProvider[MsgType]): @@ -19,11 +19,11 @@ class BaseKafkaMetricsSettingsProvider(MetricsSettingsProvider[MsgType]): def __init__(self) -> None: self.messaging_system = "kafka" - def get_publish_destination_name_from_kwargs( + def get_publish_destination_name_from_cmd( self, - kwargs: "AnyDict", + cmd: "KafkaPublishCommand", ) -> str: - return cast(str, kwargs["topic"]) + return cmd.destination class KafkaMetricsSettingsProvider(BaseKafkaMetricsSettingsProvider["ConsumerRecord"]): diff --git a/faststream/kafka/publisher/fake.py b/faststream/kafka/publisher/fake.py new file mode 100644 index 0000000000..92ecbabcb8 --- /dev/null +++ b/faststream/kafka/publisher/fake.py @@ -0,0 +1,27 @@ +from typing import TYPE_CHECKING, Union + +from faststream._internal.publisher.fake import FakePublisher +from faststream.kafka.response import KafkaPublishCommand + +if TYPE_CHECKING: + from faststream._internal.publisher.proto import ProducerProto + from faststream.response.response import PublishCommand + + +class KafkaFakePublisher(FakePublisher): + """Publisher Interface implementation to use as RPC or REPLY TO answer publisher.""" + + def __init__( + self, + producer: "ProducerProto", + topic: str, + ) -> None: + super().__init__(producer=producer) + self.topic = topic + + def patch_command( + self, cmd: Union["PublishCommand", "KafkaPublishCommand"] + ) -> "KafkaPublishCommand": + real_cmd = KafkaPublishCommand.from_cmd(cmd) + real_cmd.destination = self.topic + return real_cmd diff --git a/faststream/kafka/publisher/producer.py b/faststream/kafka/publisher/producer.py index 93441fb2bd..661d899118 100644 --- a/faststream/kafka/publisher/producer.py +++ b/faststream/kafka/publisher/producer.py @@ -1,10 +1,10 @@ -from typing import TYPE_CHECKING, Any, Optional, Union +from typing import TYPE_CHECKING, Any, Optional from typing_extensions import override from faststream._internal.publisher.proto import ProducerProto from faststream._internal.subscriber.utils import resolve_custom_func -from faststream.exceptions import OperationForbiddenError +from faststream.exceptions import FeatureNotSupportedException from faststream.kafka.message import KafkaMessage from faststream.kafka.parser import AioKafkaParser from faststream.message import encode_message @@ -12,8 +12,8 @@ if TYPE_CHECKING: from aiokafka import AIOKafkaProducer - from faststream._internal.basic_types import SendableMessage from faststream._internal.types import CustomCallable + from faststream.kafka.response import KafkaPublishCommand class AioKafkaFastProducer(ProducerProto): @@ -35,73 +35,45 @@ def __init__( self._parser = resolve_custom_func(parser, default.parse_message) self._decoder = resolve_custom_func(decoder, default.decode_message) + async def stop(self) -> None: + await self._producer.stop() + @override async def publish( # type: ignore[override] self, - message: "SendableMessage", - topic: str, - *, - correlation_id: str, - key: Union[bytes, Any, None] = None, - partition: Optional[int] = None, - timestamp_ms: Optional[int] = None, - headers: Optional[dict[str, str]] = None, - reply_to: str = "", - no_confirm: bool = False, + cmd: "KafkaPublishCommand", ) -> None: """Publish a message to a topic.""" - message, content_type = encode_message(message) + message, content_type = encode_message(cmd.body) headers_to_send = { "content-type": content_type or "", - "correlation_id": correlation_id, - **(headers or {}), + **cmd.headers_to_publish(), } - if reply_to: - headers_to_send["reply_to"] = headers_to_send.get( - "reply_to", - reply_to, - ) - send_future = await self._producer.send( - topic=topic, + topic=cmd.destination, value=message, - key=key, - partition=partition, - timestamp_ms=timestamp_ms, + key=cmd.key, + partition=cmd.partition, + timestamp_ms=cmd.timestamp_ms, headers=[(i, (j or "").encode()) for i, j in headers_to_send.items()], ) - if not no_confirm: - await send_future - async def stop(self) -> None: - await self._producer.stop() + if not cmd.no_confirm: + await send_future async def publish_batch( self, - *msgs: "SendableMessage", - correlation_id: str, - topic: str, - partition: Optional[int] = None, - timestamp_ms: Optional[int] = None, - headers: Optional[dict[str, str]] = None, - reply_to: str = "", - no_confirm: bool = False, + cmd: "KafkaPublishCommand", ) -> None: """Publish a batch of messages to a topic.""" batch = self._producer.create_batch() - headers_to_send = {"correlation_id": correlation_id, **(headers or {})} - - if reply_to: - headers_to_send["reply_to"] = headers_to_send.get( - "reply_to", - reply_to, - ) + headers_to_send = cmd.headers_to_publish() - for msg in msgs: - message, content_type = encode_message(msg) + for body in cmd.batch_bodies: + message, content_type = encode_message(body) if content_type: final_headers = { @@ -114,17 +86,22 @@ async def publish_batch( batch.append( key=None, value=message, - timestamp=timestamp_ms, + timestamp=cmd.timestamp_ms, headers=[(i, j.encode()) for i, j in final_headers.items()], ) - send_future = await self._producer.send_batch(batch, topic, partition=partition) - if not no_confirm: + send_future = await self._producer.send_batch( + batch, + cmd.destination, + partition=cmd.partition, + ) + if not cmd.no_confirm: await send_future @override - async def request(self, *args: Any, **kwargs: Any) -> Optional[Any]: + async def request( + self, + cmd: "KafkaPublishCommand", + ) -> Any: msg = "Kafka doesn't support `request` method without test client." - raise OperationForbiddenError( - msg, - ) + raise FeatureNotSupportedException(msg) diff --git a/faststream/kafka/publisher/usecase.py b/faststream/kafka/publisher/usecase.py index f9c326367f..495d539cea 100644 --- a/faststream/kafka/publisher/usecase.py +++ b/faststream/kafka/publisher/usecase.py @@ -1,30 +1,28 @@ -from collections.abc import Awaitable, Iterable -from functools import partial -from itertools import chain +from collections.abc import Iterable from typing import ( TYPE_CHECKING, Annotated, Any, - Callable, Optional, Union, - cast, ) from aiokafka import ConsumerRecord from typing_extensions import Doc, override from faststream._internal.publisher.usecase import PublisherUsecase -from faststream._internal.subscriber.utils import process_msg from faststream._internal.types import MsgType -from faststream.exceptions import NOT_CONNECTED_YET -from faststream.message import SourceType, gen_cor_id +from faststream.kafka.message import KafkaMessage +from faststream.kafka.response import KafkaPublishCommand +from faststream.message import gen_cor_id +from faststream.response.publish_type import PublishType if TYPE_CHECKING: - from faststream._internal.basic_types import AsyncFunc, SendableMessage + from faststream._internal.basic_types import SendableMessage from faststream._internal.types import BrokerMiddleware, PublisherMiddleware from faststream.kafka.message import KafkaMessage from faststream.kafka.publisher.producer import AioKafkaFastProducer + from faststream.response.response import PublishCommand class LogicPublisher(PublisherUsecase[MsgType]): @@ -61,7 +59,7 @@ def __init__( self.topic = topic self.partition = partition self.reply_to = reply_to - self.headers = headers + self.headers = headers or {} self._producer = None @@ -127,48 +125,20 @@ async def request( float, Doc("Timeout to send RPC request."), ] = 0.5, - # publisher specific - _extra_middlewares: Annotated[ - Iterable["PublisherMiddleware"], - Doc("Extra middlewares to wrap publishing process."), - ] = (), ) -> "KafkaMessage": - assert self._producer, NOT_CONNECTED_YET # nosec B101 - - topic = topic or self.topic - partition = partition or self.partition - headers = headers or self.headers - correlation_id = correlation_id or gen_cor_id() - - request: Callable[..., Awaitable[Any]] = self._producer.request - - for pub_m in chain( - ( - _extra_middlewares - or (m(None).publish_scope for m in self._broker_middlewares) - ), - self._middlewares, - ): - request = partial(pub_m, request) - - published_msg = await request( + cmd = KafkaPublishCommand( message, - topic=topic, + topic=topic or self.topic, key=key, - partition=partition, - headers=headers, - timeout=timeout, - correlation_id=correlation_id, + partition=partition or self.partition, + headers=self.headers | (headers or {}), + correlation_id=correlation_id or gen_cor_id(), timestamp_ms=timestamp_ms, + timeout=timeout, + _publish_type=PublishType.Request, ) - msg: KafkaMessage = await process_msg( - msg=published_msg, - middlewares=self._broker_middlewares, - parser=self._producer._parser, - decoder=self._producer._decoder, - ) - msg._source_type = SourceType.Response + msg: KafkaMessage = await self._basic_request(cmd) return msg @@ -176,7 +146,7 @@ class DefaultPublisher(LogicPublisher[ConsumerRecord]): def __init__( self, *, - key: Optional[bytes], + key: Union[bytes, str, None], topic: str, partition: Optional[int], headers: Optional[dict[str, str]], @@ -271,66 +241,38 @@ async def publish( Doc("Do not wait for Kafka publish confirmation."), ] = False, ) -> None: - return await self._publish( + cmd = KafkaPublishCommand( message, - topic=topic, - key=key, - partition=partition, + topic=topic or self.topic, + key=key or self.key, + partition=partition or self.partition, + reply_to=reply_to or self.reply_to, + headers=self.headers | (headers or {}), + correlation_id=correlation_id or gen_cor_id(), timestamp_ms=timestamp_ms, - headers=headers, - correlation_id=correlation_id, - reply_to=reply_to, no_confirm=no_confirm, - _extra_middlewares=(), + _publish_type=PublishType.Publish, ) + await self._basic_publish(cmd, _extra_middlewares=()) @override async def _publish( self, - message: "SendableMessage", - topic: str = "", + cmd: Union["PublishCommand", "KafkaPublishCommand"], *, - key: Union[bytes, Any, None] = None, - partition: Optional[int] = None, - timestamp_ms: Optional[int] = None, - headers: Optional[dict[str, str]] = None, - correlation_id: Optional[str] = None, - reply_to: str = "", - no_confirm: bool = False, - # publisher specific - _extra_middlewares: Iterable["PublisherMiddleware"] = (), + _extra_middlewares: Iterable["PublisherMiddleware"], ) -> None: - assert self._producer, NOT_CONNECTED_YET # nosec B101 + """This method should be called in subscriber flow only.""" + cmd = KafkaPublishCommand.from_cmd(cmd) - topic = topic or self.topic - key = key or self.key - partition = partition or self.partition - headers = headers or self.headers - reply_to = reply_to or self.reply_to - correlation_id = correlation_id or gen_cor_id() + cmd.destination = self.topic + cmd.add_headers(self.headers, override=False) + cmd.reply_to = cmd.reply_to or self.reply_to - call: Callable[..., Awaitable[None]] = self._producer.publish + cmd.partition = cmd.partition or self.partition + cmd.key = cmd.key or self.key - for m in chain( - ( - _extra_middlewares - or (m(None).publish_scope for m in self._broker_middlewares) - ), - self._middlewares, - ): - call = partial(m, call) - - await call( - message, - topic=topic, - key=key, - partition=partition, - headers=headers, - reply_to=reply_to, - correlation_id=correlation_id, - timestamp_ms=timestamp_ms, - no_confirm=no_confirm, - ) + await self._basic_publish(cmd, _extra_middlewares=_extra_middlewares) @override async def request( @@ -391,14 +333,9 @@ async def request( float, Doc("Timeout to send RPC request."), ] = 0.5, - # publisher specific - _extra_middlewares: Annotated[ - Iterable["PublisherMiddleware"], - Doc("Extra middlewares to wrap publishing process."), - ] = (), ) -> "KafkaMessage": return await super().request( - message=message, + message, topic=topic, key=key or self.key, partition=partition, @@ -406,7 +343,6 @@ async def request( headers=headers, correlation_id=correlation_id, timeout=timeout, - _extra_middlewares=_extra_middlewares, ) @@ -414,11 +350,7 @@ class BatchPublisher(LogicPublisher[tuple["ConsumerRecord", ...]]): @override async def publish( self, - message: Annotated[ - Union["SendableMessage", Iterable["SendableMessage"]], - Doc("One message or iterable messages bodies to send."), - ], - *extra_messages: Annotated[ + *messages: Annotated[ "SendableMessage", Doc("Messages bodies to send."), ], @@ -464,66 +396,35 @@ async def publish( Doc("Do not wait for Kafka publish confirmation."), ] = False, ) -> None: - return await self._publish( - message, - *extra_messages, - topic=topic, - partition=partition, + cmd = KafkaPublishCommand( + *messages, + key=None, + topic=topic or self.topic, + partition=partition or self.partition, + reply_to=reply_to or self.reply_to, + headers=self.headers | (headers or {}), + correlation_id=correlation_id or gen_cor_id(), timestamp_ms=timestamp_ms, - headers=headers, - reply_to=reply_to, - correlation_id=correlation_id, no_confirm=no_confirm, - _extra_middlewares=(), + _publish_type=PublishType.Publish, ) + await self._basic_publish_batch(cmd, _extra_middlewares=()) + @override async def _publish( self, - message: Union["SendableMessage", Iterable["SendableMessage"]], - *extra_messages: "SendableMessage", - topic: str = "", - partition: Optional[int] = None, - timestamp_ms: Optional[int] = None, - headers: Optional[dict[str, str]] = None, - reply_to: str = "", - correlation_id: Optional[str] = None, - no_confirm: bool = False, - # publisher specific - _extra_middlewares: Iterable["PublisherMiddleware"] = (), + cmd: Union["PublishCommand", "KafkaPublishCommand"], + *, + _extra_middlewares: Iterable["PublisherMiddleware"], ) -> None: - assert self._producer, NOT_CONNECTED_YET # nosec B101 + """This method should be called in subscriber flow only.""" + cmd = KafkaPublishCommand.from_cmd(cmd, batch=True) - msgs: Iterable[SendableMessage] - if extra_messages: - msgs = (cast("SendableMessage", message), *extra_messages) - else: - msgs = cast(Iterable["SendableMessage"], message) + cmd.destination = self.topic + cmd.add_headers(self.headers, override=False) + cmd.reply_to = cmd.reply_to or self.reply_to - topic = topic or self.topic - partition = partition or self.partition - headers = headers or self.headers - reply_to = reply_to or self.reply_to - correlation_id = correlation_id or gen_cor_id() + cmd.partition = cmd.partition or self.partition - call: AsyncFunc = self._producer.publish_batch - - for m in chain( - ( - _extra_middlewares - or (m(None).publish_scope for m in self._broker_middlewares) - ), - self._middlewares, - ): - call = partial(m, call) - - await call( - *msgs, - topic=topic, - partition=partition, - headers=headers, - reply_to=reply_to, - correlation_id=correlation_id, - timestamp_ms=timestamp_ms, - no_confirm=no_confirm, - ) + await self._basic_publish_batch(cmd, _extra_middlewares=_extra_middlewares) diff --git a/faststream/kafka/response.py b/faststream/kafka/response.py index 3d04d6ab35..ac3cd1019d 100644 --- a/faststream/kafka/response.py +++ b/faststream/kafka/response.py @@ -1,8 +1,10 @@ -from typing import TYPE_CHECKING, Optional +from collections.abc import Sequence +from typing import TYPE_CHECKING, Any, Optional, Union from typing_extensions import override -from faststream.response import Response +from faststream.response.publish_type import PublishType +from faststream.response.response import PublishCommand, Response if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict, SendableMessage @@ -28,9 +30,95 @@ def __init__( self.key = key @override - def as_publish_kwargs(self) -> "AnyDict": - return { - **super().as_publish_kwargs(), - "timestamp_ms": self.timestamp_ms, - "key": self.key, - } + def as_publish_command(self) -> "KafkaPublishCommand": + return KafkaPublishCommand( + self.body, + headers=self.headers, + correlation_id=self.correlation_id, + _publish_type=PublishType.Reply, + # Kafka specific + topic="", + key=self.key, + timestamp_ms=self.timestamp_ms, + ) + + +class KafkaPublishCommand(PublishCommand): + def __init__( + self, + message: "SendableMessage", + /, + *messages: "SendableMessage", + topic: str, + _publish_type: PublishType, + key: Union[bytes, Any, None] = None, + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + correlation_id: Optional[str] = None, + reply_to: str = "", + no_confirm: bool = False, + timeout: float = 0.5, + ) -> None: + super().__init__( + message, + destination=topic, + reply_to=reply_to, + correlation_id=correlation_id, + headers=headers, + _publish_type=_publish_type, + ) + self.extra_bodies = messages + + self.key = key + self.partition = partition + self.timestamp_ms = timestamp_ms + self.no_confirm = no_confirm + + # request option + self.timeout = timeout + + @property + def batch_bodies(self) -> tuple["SendableMessage", ...]: + if self.body: + return (self.body, *self.extra_bodies) + return self.extra_bodies + + @classmethod + def from_cmd( + cls, + cmd: Union["PublishCommand", "KafkaPublishCommand"], + *, + batch: bool = False, + ) -> "KafkaPublishCommand": + if isinstance(cmd, KafkaPublishCommand): + # NOTE: Should return a copy probably. + return cmd + + body, extra_bodies = cmd.body, [] + if batch and isinstance(body, Sequence) and not isinstance(body, str): + if body: + body, extra_bodies = body[0], body[1:] + else: + body = None + + return cls( + body, + *extra_bodies, + topic=cmd.destination, + correlation_id=cmd.correlation_id, + headers=cmd.headers, + reply_to=cmd.reply_to, + _publish_type=cmd.publish_type, + ) + + def headers_to_publish(self) -> dict[str, str]: + headers = {} + + if self.correlation_id: + headers["correlation_id"] = self.correlation_id + + if self.reply_to: + headers["reply_to"] = self.reply_to + + return headers | self.headers diff --git a/faststream/kafka/subscriber/usecase.py b/faststream/kafka/subscriber/usecase.py index 7a38b79055..4d12aa9abd 100644 --- a/faststream/kafka/subscriber/usecase.py +++ b/faststream/kafka/subscriber/usecase.py @@ -14,7 +14,6 @@ from aiokafka.errors import ConsumerStoppedError, KafkaError from typing_extensions import override -from faststream._internal.publisher.fake import FakePublisher from faststream._internal.subscriber.usecase import SubscriberUsecase from faststream._internal.subscriber.utils import process_msg from faststream._internal.types import ( @@ -26,6 +25,7 @@ from faststream._internal.utils.path import compile_path from faststream.kafka.message import KafkaAckableMessage, KafkaMessage from faststream.kafka.parser import AioKafkaBatchParser, AioKafkaParser +from faststream.kafka.publisher.fake import KafkaFakePublisher if TYPE_CHECKING: from aiokafka import AIOKafkaConsumer, ConsumerRecord @@ -33,7 +33,7 @@ from fast_depends.dependencies import Depends from faststream._internal.basic_types import AnyDict, LoggerProto - from faststream._internal.publisher.proto import ProducerProto + from faststream._internal.publisher.proto import BasePublisherProto, ProducerProto from faststream._internal.setup import SetupState from faststream.message import StreamMessage @@ -203,16 +203,14 @@ async def get_one( def _make_response_publisher( self, message: "StreamMessage[Any]", - ) -> Sequence[FakePublisher]: + ) -> Sequence["BasePublisherProto"]: if self._producer is None: return () return ( - FakePublisher( - self._producer.publish, - publish_kwargs={ - "topic": message.reply_to, - }, + KafkaFakePublisher( + self._producer, + topic=message.reply_to, ), ) diff --git a/faststream/kafka/testing.py b/faststream/kafka/testing.py index ce35bbd1b5..a73e18ade8 100755 --- a/faststream/kafka/testing.py +++ b/faststream/kafka/testing.py @@ -28,6 +28,7 @@ if TYPE_CHECKING: from faststream._internal.basic_types import SendableMessage from faststream.kafka.publisher.specified import SpecificationPublisher + from faststream.kafka.response import KafkaPublishCommand from faststream.kafka.subscriber.usecase import LogicSubscriber __all__ = ("TestKafkaBroker",) @@ -99,113 +100,91 @@ def __init__(self, broker: KafkaBroker) -> None: @override async def publish( # type: ignore[override] self, - message: "SendableMessage", - topic: str, - key: Optional[bytes] = None, - partition: Optional[int] = None, - timestamp_ms: Optional[int] = None, - headers: Optional[dict[str, str]] = None, - correlation_id: Optional[str] = None, - *, - reply_to: str = "", - no_confirm: bool = False, + cmd: "KafkaPublishCommand", ) -> None: """Publish a message to the Kafka broker.""" incoming = build_message( - message=message, - topic=topic, - key=key, - partition=partition, - timestamp_ms=timestamp_ms, - headers=headers, - correlation_id=correlation_id, - reply_to=reply_to, + message=cmd.body, + topic=cmd.destination, + key=cmd.key, + partition=cmd.partition, + timestamp_ms=cmd.timestamp_ms, + headers=cmd.headers, + correlation_id=cmd.correlation_id, + reply_to=cmd.reply_to, ) for handler in _find_handler( self.broker._subscribers, - topic, - partition, + cmd.destination, + cmd.partition, ): msg_to_send = ( [incoming] if isinstance(handler, BatchSubscriber) else incoming ) - await self._execute_handler(msg_to_send, topic, handler) + await self._execute_handler(msg_to_send, cmd.destination, handler) @override async def request( # type: ignore[override] self, - message: "SendableMessage", - topic: str, - key: Optional[bytes] = None, - partition: Optional[int] = None, - timestamp_ms: Optional[int] = None, - headers: Optional[dict[str, str]] = None, - correlation_id: Optional[str] = None, - *, - timeout: Optional[float] = 0.5, + cmd: "KafkaPublishCommand", ) -> "ConsumerRecord": incoming = build_message( - message=message, - topic=topic, - key=key, - partition=partition, - timestamp_ms=timestamp_ms, - headers=headers, - correlation_id=correlation_id, + message=cmd.body, + topic=cmd.destination, + key=cmd.key, + partition=cmd.partition, + timestamp_ms=cmd.timestamp_ms, + headers=cmd.headers, + correlation_id=cmd.correlation_id, ) for handler in _find_handler( self.broker._subscribers, - topic, - partition, + cmd.destination, + cmd.partition, ): msg_to_send = ( [incoming] if isinstance(handler, BatchSubscriber) else incoming ) - with anyio.fail_after(timeout): - return await self._execute_handler(msg_to_send, topic, handler) + with anyio.fail_after(cmd.timeout): + return await self._execute_handler( + msg_to_send, cmd.destination, handler + ) raise SubscriberNotFound async def publish_batch( self, - *msgs: "SendableMessage", - topic: str, - partition: Optional[int] = None, - timestamp_ms: Optional[int] = None, - headers: Optional[dict[str, str]] = None, - reply_to: str = "", - correlation_id: Optional[str] = None, - no_confirm: bool = False, + cmd: "KafkaPublishCommand", ) -> None: """Publish a batch of messages to the Kafka broker.""" for handler in _find_handler( self.broker._subscribers, - topic, - partition, + cmd.destination, + cmd.partition, ): messages = ( build_message( message=message, - topic=topic, - partition=partition, - timestamp_ms=timestamp_ms, - headers=headers, - correlation_id=correlation_id, - reply_to=reply_to, + topic=cmd.destination, + partition=cmd.partition, + timestamp_ms=cmd.timestamp_ms, + headers=cmd.headers, + correlation_id=cmd.correlation_id, + reply_to=cmd.reply_to, ) - for message in msgs + for message in cmd.batch_bodies ) if isinstance(handler, BatchSubscriber): - await self._execute_handler(list(messages), topic, handler) + await self._execute_handler(list(messages), cmd.destination, handler) else: for m in messages: - await self._execute_handler(m, topic, handler) + await self._execute_handler(m, cmd.destination, handler) async def _execute_handler( self, diff --git a/faststream/middlewares/base.py b/faststream/middlewares/base.py index a9ff8642ba..49ea3526d9 100644 --- a/faststream/middlewares/base.py +++ b/faststream/middlewares/base.py @@ -1,19 +1,29 @@ -from typing import TYPE_CHECKING, Any, Optional +from collections.abc import Awaitable +from typing import TYPE_CHECKING, Any, Callable, Optional from typing_extensions import Self if TYPE_CHECKING: from types import TracebackType - from faststream._internal.basic_types import AsyncFunc, AsyncFuncAny + from faststream._internal.basic_types import AsyncFuncAny + from faststream._internal.context.repository import ContextRepo from faststream.message import StreamMessage + from faststream.response.response import PublishCommand class BaseMiddleware: """A base middleware class.""" - def __init__(self, msg: Optional[Any] = None) -> None: + def __init__( + self, + msg: Optional[Any], + /, + *, + context: "ContextRepo", + ) -> None: self.msg = msg + self.context = context async def on_receive(self) -> None: """Hook to call on message receive.""" @@ -73,10 +83,8 @@ async def consume_scope( async def on_publish( self, - msg: Any, - *args: Any, - **kwargs: Any, - ) -> Any: + msg: "PublishCommand", + ) -> "PublishCommand": """Asynchronously handle a publish event.""" return msg @@ -90,19 +98,13 @@ async def after_publish( async def publish_scope( self, - call_next: "AsyncFunc", - msg: Any, - *args: Any, - **kwargs: Any, + call_next: Callable[["PublishCommand"], Awaitable[Any]], + cmd: "PublishCommand", ) -> Any: """Publish a message and return an async iterator.""" err: Optional[Exception] = None try: - result = await call_next( - await self.on_publish(msg, *args, **kwargs), - *args, - **kwargs, - ) + result = await call_next(await self.on_publish(cmd)) except Exception as e: err = e diff --git a/faststream/middlewares/exception.py b/faststream/middlewares/exception.py index 2732037945..8530bb8a77 100644 --- a/faststream/middlewares/exception.py +++ b/faststream/middlewares/exception.py @@ -23,6 +23,7 @@ from types import TracebackType from faststream._internal.basic_types import AsyncFuncAny + from faststream._internal.context.repository import ContextRepo from faststream.message import StreamMessage @@ -48,61 +49,6 @@ ] -class BaseExceptionMiddleware(BaseMiddleware): - def __init__( - self, - handlers: CastedHandlers, - publish_handlers: CastedPublishingHandlers, - msg: Optional[Any] = None, - ) -> None: - super().__init__(msg) - self._handlers = handlers - self._publish_handlers = publish_handlers - - async def consume_scope( - self, - call_next: "AsyncFuncAny", - msg: "StreamMessage[Any]", - ) -> Any: - try: - return await call_next(await self.on_consume(msg)) - - except Exception as exc: - exc_type = type(exc) - - for handler_type, handler in self._publish_handlers: - if issubclass(exc_type, handler_type): - return await handler(exc) - - raise - - async def after_processed( - self, - exc_type: Optional[type[BaseException]] = None, - exc_val: Optional[BaseException] = None, - exc_tb: Optional["TracebackType"] = None, - ) -> Optional[bool]: - if exc_type: - for handler_type, handler in self._handlers: - if issubclass(exc_type, handler_type): - # TODO: remove it after context will be moved to middleware - # In case parser/decoder error occurred - scope: AbstractContextManager[Any] - if not context.get_local("message"): - scope = context.scope("message", self.msg) - else: - scope = sync_fake_context() - - with scope: - await handler(exc_val) - - return True - - return False - - return None - - class ExceptionMiddleware: __slots__ = ("_handlers", "_publish_handlers") @@ -195,14 +141,78 @@ def default_wrapper( return default_wrapper - def __call__(self, msg: Optional[Any]) -> BaseExceptionMiddleware: + def __call__( + self, + msg: Optional[Any], + /, + *, + context: "ContextRepo", + ) -> "_BaseExceptionMiddleware": """Real middleware runtime constructor.""" - return BaseExceptionMiddleware( + return _BaseExceptionMiddleware( handlers=self._handlers, publish_handlers=self._publish_handlers, + context=context, msg=msg, ) +class _BaseExceptionMiddleware(BaseMiddleware): + def __init__( + self, + *, + handlers: CastedHandlers, + publish_handlers: CastedPublishingHandlers, + context: "ContextRepo", + msg: Optional[Any], + ) -> None: + super().__init__(msg, context=context) + self._handlers = handlers + self._publish_handlers = publish_handlers + + async def consume_scope( + self, + call_next: "AsyncFuncAny", + msg: "StreamMessage[Any]", + ) -> Any: + try: + return await call_next(await self.on_consume(msg)) + + except Exception as exc: + exc_type = type(exc) + + for handler_type, handler in self._publish_handlers: + if issubclass(exc_type, handler_type): + return await handler(exc) + + raise + + async def after_processed( + self, + exc_type: Optional[type[BaseException]] = None, + exc_val: Optional[BaseException] = None, + exc_tb: Optional["TracebackType"] = None, + ) -> Optional[bool]: + if exc_type: + for handler_type, handler in self._handlers: + if issubclass(exc_type, handler_type): + # TODO: remove it after context will be moved to middleware + # In case parser/decoder error occurred + scope: AbstractContextManager[Any] + if not context.get_local("message"): + scope = context.scope("message", self.msg) + else: + scope = sync_fake_context() + + with scope: + await handler(exc_val) + + return True + + return False + + return None + + async def ignore_handler(exception: IgnoredException) -> NoReturn: raise exception diff --git a/faststream/middlewares/logging.py b/faststream/middlewares/logging.py index 57ff030a94..f24d507266 100644 --- a/faststream/middlewares/logging.py +++ b/faststream/middlewares/logging.py @@ -2,41 +2,67 @@ from typing import TYPE_CHECKING, Any, Optional from faststream._internal.context.repository import context -from faststream._internal.setup.logger import LoggerState from faststream.exceptions import IgnoredException +from faststream.message.source_type import SourceType from .base import BaseMiddleware if TYPE_CHECKING: from types import TracebackType + from faststream._internal.basic_types import AsyncFuncAny + from faststream._internal.context.repository import ContextRepo + from faststream._internal.setup.logger import LoggerState from faststream.message import StreamMessage class CriticalLogMiddleware: - def __init__(self, logger: LoggerState) -> None: + def __init__(self, logger: "LoggerState") -> None: """Initialize the class.""" self.logger = logger - def __call__(self, msg: Optional[Any] = None) -> Any: - return LoggingMiddleware(logger=self.logger) + def __call__( + self, + msg: Optional[Any], + /, + *, + context: "ContextRepo", + ) -> "_LoggingMiddleware": + return _LoggingMiddleware( + logger=self.logger, + msg=msg, + context=context, + ) -class LoggingMiddleware(BaseMiddleware): +class _LoggingMiddleware(BaseMiddleware): """A middleware class for logging critical errors.""" - def __init__(self, logger: LoggerState) -> None: + def __init__( + self, + *, + logger: "LoggerState", + context: "ContextRepo", + msg: Optional[Any], + ) -> None: + super().__init__(msg, context=context) self.logger = logger + self._source_type = SourceType.Consume - async def on_consume( + async def consume_scope( self, + call_next: "AsyncFuncAny", msg: "StreamMessage[Any]", ) -> "StreamMessage[Any]": - self.logger.log( - "Received", - extra=context.get_local("log_context", {}), - ) - return await super().on_consume(msg) + source_type = self._source_type = msg._source_type + + if source_type is not SourceType.Response: + self.logger.log( + "Received", + extra=context.get_local("log_context", {}), + ) + + return await call_next(msg) async def __aexit__( self, @@ -45,26 +71,28 @@ async def __aexit__( exc_tb: Optional["TracebackType"] = None, ) -> bool: """Asynchronously called after processing.""" - c = context.get_local("log_context", {}) - - if exc_type: - if issubclass(exc_type, IgnoredException): - self.logger.log( - log_level=logging.INFO, - message=exc_val, - extra=c, - ) - else: - self.logger.log( - log_level=logging.ERROR, - message=f"{exc_type.__name__}: {exc_val}", - exc_info=exc_val, - extra=c, - ) - - self.logger.log(message="Processed", extra=c) - - await super().after_processed(exc_type, exc_val, exc_tb) + if self._source_type is not SourceType.Response: + c = context.get_local("log_context", {}) + + if exc_type: + if issubclass(exc_type, IgnoredException): + self.logger.log( + log_level=logging.INFO, + message=exc_val, + extra=c, + ) + + else: + self.logger.log( + log_level=logging.ERROR, + message=f"{exc_type.__name__}: {exc_val}", + exc_info=exc_val, + extra=c, + ) + + self.logger.log(message="Processed", extra=c) + + await super().__aexit__(exc_type, exc_val, exc_tb) # Exception was not processed return False diff --git a/faststream/nats/annotations.py b/faststream/nats/annotations.py index 9bd2e29066..5aa74aa8d0 100644 --- a/faststream/nats/annotations.py +++ b/faststream/nats/annotations.py @@ -8,12 +8,7 @@ from faststream.annotations import ContextRepo, Logger from faststream.nats.broker import NatsBroker as _Broker from faststream.nats.message import NatsMessage as _Message -from faststream.nats.publisher.producer import ( - NatsFastProducer as _CoreProducer, - NatsJSFastProducer as _JsProducer, -) from faststream.nats.subscriber.usecase import OBJECT_STORAGE_CONTEXT_KEY -from faststream.params import NoCast __all__ = ( "Client", @@ -22,7 +17,6 @@ "Logger", "NatsBroker", "NatsMessage", - "NoCast", "ObjectStorage", ) @@ -31,5 +25,3 @@ NatsBroker = Annotated[_Broker, Context("broker")] Client = Annotated[_NatsClient, Context("broker._connection")] JsClient = Annotated[_JetStream, Context("broker._stream")] -NatsProducer = Annotated[_CoreProducer, Context("broker._producer")] -NatsJsProducer = Annotated[_JsProducer, Context("broker._js_producer")] diff --git a/faststream/nats/broker/broker.py b/faststream/nats/broker/broker.py index b9ef1afdfb..09aed61b54 100644 --- a/faststream/nats/broker/broker.py +++ b/faststream/nats/broker/broker.py @@ -35,8 +35,10 @@ from faststream.message import gen_cor_id from faststream.nats.helpers import KVBucketDeclarer, OSBucketDeclarer from faststream.nats.publisher.producer import NatsFastProducer, NatsJSFastProducer +from faststream.nats.response import NatsPublishCommand from faststream.nats.security import parse_security from faststream.nats.subscriber.specified import SpecificationSubscriber +from faststream.response.publish_type import PublishType from .logging import make_nats_logger_state from .registrator import NatsRegistrator @@ -724,30 +726,21 @@ async def publish( # type: ignore[override] Please, use `@broker.publisher(...)` or `broker.publisher(...).publish(...)` instead in a regular way. """ - publish_kwargs: AnyDict = { - "subject": subject, - "headers": headers, - "reply_to": reply_to, - } + cmd = NatsPublishCommand( + message=message, + correlation_id=correlation_id or gen_cor_id(), + subject=subject, + headers=headers, + reply_to=reply_to, + stream=stream, + timeout=timeout, + _publish_type=PublishType.Publish, + ) producer: Optional[ProducerProto] - if stream is None: - producer = self._producer - else: - producer = self._js_producer - publish_kwargs.update( - { - "stream": stream, - "timeout": timeout, - }, - ) + producer = self._producer if stream is None else self._js_producer - await super().publish( - message, - producer=producer, - correlation_id=correlation_id or gen_cor_id(), - **publish_kwargs, - ) + await super()._basic_publish(cmd, producer=producer) @override async def request( # type: ignore[override] @@ -789,26 +782,20 @@ async def request( # type: ignore[override] Doc("Timeout to send message to NATS."), ] = 0.5, ) -> "NatsMessage": - publish_kwargs = { - "subject": subject, - "headers": headers, - "timeout": timeout, - } + cmd = NatsPublishCommand( + message=message, + correlation_id=correlation_id or gen_cor_id(), + subject=subject, + headers=headers, + timeout=timeout, + stream=stream, + _publish_type=PublishType.Request, + ) producer: Optional[ProducerProto] - if stream is None: - producer = self._producer + producer = self._producer if stream is None else self._js_producer - else: - producer = self._js_producer - publish_kwargs.update({"stream": stream}) - - msg: NatsMessage = await super().request( - message, - producer=producer, - correlation_id=correlation_id or gen_cor_id(), - **publish_kwargs, - ) + msg: NatsMessage = await super()._basic_request(cmd, producer=producer) return msg @override diff --git a/faststream/nats/opentelemetry/provider.py b/faststream/nats/opentelemetry/provider.py index 93364d7bb2..32d9d2d4e1 100644 --- a/faststream/nats/opentelemetry/provider.py +++ b/faststream/nats/opentelemetry/provider.py @@ -4,7 +4,6 @@ from nats.aio.msg import Msg from opentelemetry.semconv.trace import SpanAttributes -from faststream.__about__ import SERVICE_NAME from faststream._internal.types import MsgType from faststream.opentelemetry import TelemetrySettingsProvider from faststream.opentelemetry.consts import MESSAGING_DESTINATION_PUBLISH_NAME @@ -12,6 +11,7 @@ if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict from faststream.message import StreamMessage + from faststream.nats.response import NatsPublishCommand class BaseNatsTelemetrySettingsProvider(TelemetrySettingsProvider[MsgType]): @@ -20,22 +20,21 @@ class BaseNatsTelemetrySettingsProvider(TelemetrySettingsProvider[MsgType]): def __init__(self) -> None: self.messaging_system = "nats" - def get_publish_attrs_from_kwargs( + def get_publish_attrs_from_cmd( self, - kwargs: "AnyDict", + cmd: "NatsPublishCommand", ) -> "AnyDict": return { SpanAttributes.MESSAGING_SYSTEM: self.messaging_system, - SpanAttributes.MESSAGING_DESTINATION_NAME: kwargs["subject"], - SpanAttributes.MESSAGING_MESSAGE_CONVERSATION_ID: kwargs["correlation_id"], + SpanAttributes.MESSAGING_DESTINATION_NAME: cmd.destination, + SpanAttributes.MESSAGING_MESSAGE_CONVERSATION_ID: cmd.correlation_id, } def get_publish_destination_name( self, - kwargs: "AnyDict", + cmd: "NatsPublishCommand", ) -> str: - subject: str = kwargs.get("subject", SERVICE_NAME) - return subject + return cmd.destination class NatsTelemetrySettingsProvider(BaseNatsTelemetrySettingsProvider["Msg"]): diff --git a/faststream/nats/prometheus/middleware.py b/faststream/nats/prometheus/middleware.py index e517fa89a7..9620cd651c 100644 --- a/faststream/nats/prometheus/middleware.py +++ b/faststream/nats/prometheus/middleware.py @@ -1,15 +1,15 @@ from collections.abc import Sequence from typing import TYPE_CHECKING, Optional +from faststream._internal.constants import EMPTY from faststream.nats.prometheus.provider import settings_provider_factory -from faststream.prometheus.middleware import BasePrometheusMiddleware -from faststream.types import EMPTY +from faststream.prometheus.middleware import PrometheusMiddleware if TYPE_CHECKING: from prometheus_client import CollectorRegistry -class NatsPrometheusMiddleware(BasePrometheusMiddleware): +class NatsPrometheusMiddleware(PrometheusMiddleware): def __init__( self, *, diff --git a/faststream/nats/prometheus/provider.py b/faststream/nats/prometheus/provider.py index 7e01ce51e8..6b5585eeb9 100644 --- a/faststream/nats/prometheus/provider.py +++ b/faststream/nats/prometheus/provider.py @@ -1,16 +1,16 @@ from collections.abc import Sequence -from typing import TYPE_CHECKING, Union, cast +from typing import TYPE_CHECKING, Union from nats.aio.msg import Msg -from faststream.broker.message import MsgType, StreamMessage +from faststream.message.message import MsgType, StreamMessage from faststream.prometheus import ( ConsumeAttrs, MetricsSettingsProvider, ) if TYPE_CHECKING: - from faststream.types import AnyDict + from faststream.nats.response import NatsPublishCommand class BaseNatsMetricsSettingsProvider(MetricsSettingsProvider[MsgType]): @@ -19,11 +19,11 @@ class BaseNatsMetricsSettingsProvider(MetricsSettingsProvider[MsgType]): def __init__(self) -> None: self.messaging_system = "nats" - def get_publish_destination_name_from_kwargs( + def get_publish_destination_name_from_cmd( self, - kwargs: "AnyDict", + cmd: "NatsPublishCommand", ) -> str: - return cast(str, kwargs["subject"]) + return cmd.destination class NatsMetricsSettingsProvider(BaseNatsMetricsSettingsProvider["Msg"]): diff --git a/faststream/nats/publisher/fake.py b/faststream/nats/publisher/fake.py new file mode 100644 index 0000000000..7c70536e34 --- /dev/null +++ b/faststream/nats/publisher/fake.py @@ -0,0 +1,27 @@ +from typing import TYPE_CHECKING, Union + +from faststream._internal.publisher.fake import FakePublisher +from faststream.nats.response import NatsPublishCommand + +if TYPE_CHECKING: + from faststream._internal.publisher.proto import ProducerProto + from faststream.response.response import PublishCommand + + +class NatsFakePublisher(FakePublisher): + """Publisher Interface implementation to use as RPC or REPLY TO answer publisher.""" + + def __init__( + self, + producer: "ProducerProto", + subject: str, + ) -> None: + super().__init__(producer=producer) + self.subject = subject + + def patch_command( + self, cmd: Union["PublishCommand", "NatsPublishCommand"] + ) -> "NatsPublishCommand": + real_cmd = NatsPublishCommand.from_cmd(cmd) + real_cmd.destination = self.subject + return real_cmd diff --git a/faststream/nats/publisher/producer.py b/faststream/nats/publisher/producer.py index 05d3a81402..2af4fdfc48 100644 --- a/faststream/nats/publisher/producer.py +++ b/faststream/nats/publisher/producer.py @@ -7,6 +7,7 @@ from faststream._internal.publisher.proto import ProducerProto from faststream._internal.subscriber.utils import resolve_custom_func +from faststream.exceptions import FeatureNotSupportedException from faststream.message import encode_message from faststream.nats.parser import NatsParser @@ -15,11 +16,11 @@ from nats.aio.msg import Msg from nats.js import JetStreamContext - from faststream._internal.basic_types import SendableMessage from faststream._internal.types import ( AsyncCallable, CustomCallable, ) + from faststream.nats.response import NatsPublishCommand class NatsFastProducer(ProducerProto): @@ -44,54 +45,49 @@ def __init__( @override async def publish( # type: ignore[override] self, - message: "SendableMessage", - subject: str, - *, - correlation_id: str, - headers: Optional[dict[str, str]] = None, - reply_to: str = "", - **kwargs: Any, # suprress stream option + cmd: "NatsPublishCommand", ) -> None: - payload, content_type = encode_message(message) + payload, content_type = encode_message(cmd.body) headers_to_send = { "content-type": content_type or "", - "correlation_id": correlation_id, - **(headers or {}), + **cmd.headers_to_publish(), } await self._connection.publish( - subject=subject, + subject=cmd.destination, payload=payload, - reply=reply_to, + reply=cmd.reply_to, headers=headers_to_send, ) @override async def request( # type: ignore[override] self, - message: "SendableMessage", - subject: str, - *, - correlation_id: str, - headers: Optional[dict[str, str]] = None, - timeout: float = 0.5, + cmd: "NatsPublishCommand", ) -> "Msg": - payload, content_type = encode_message(message) + payload, content_type = encode_message(cmd.body) headers_to_send = { "content-type": content_type or "", - "correlation_id": correlation_id, - **(headers or {}), + **cmd.headers_to_publish(), } return await self._connection.request( - subject=subject, + subject=cmd.destination, payload=payload, headers=headers_to_send, - timeout=timeout, + timeout=cmd.timeout, ) + @override + async def publish_batch( + self, + cmd: "NatsPublishCommand", + ) -> None: + msg = "NATS doesn't support publishing in batches." + raise FeatureNotSupportedException(msg) + class NatsJSFastProducer(ProducerProto): """A class to represent a NATS JetStream producer.""" @@ -115,32 +111,21 @@ def __init__( @override async def publish( # type: ignore[override] self, - message: "SendableMessage", - subject: str, - *, - correlation_id: str, - headers: Optional[dict[str, str]] = None, - reply_to: str = "", - stream: Optional[str] = None, - timeout: Optional[float] = None, + cmd: "NatsPublishCommand", ) -> Optional[Any]: - payload, content_type = encode_message(message) + payload, content_type = encode_message(cmd.body) headers_to_send = { "content-type": content_type or "", - "correlation_id": correlation_id, - **(headers or {}), + **cmd.headers_to_publish(js=True), } - if reply_to: - headers_to_send.update({"reply_to": reply_to}) - await self._connection.publish( - subject=subject, + subject=cmd.destination, payload=payload, headers=headers_to_send, - stream=stream, - timeout=timeout, + stream=cmd.stream, + timeout=cmd.timeout, ) return None @@ -148,15 +133,9 @@ async def publish( # type: ignore[override] @override async def request( # type: ignore[override] self, - message: "SendableMessage", - subject: str, - *, - correlation_id: str, - headers: Optional[dict[str, str]] = None, - stream: Optional[str] = None, - timeout: float = 0.5, + cmd: "NatsPublishCommand", ) -> "Msg": - payload, content_type = encode_message(message) + payload, content_type = encode_message(cmd.body) reply_to = self._connection._nc.new_inbox() future: asyncio.Future[Msg] = asyncio.Future() @@ -165,18 +144,17 @@ async def request( # type: ignore[override] headers_to_send = { "content-type": content_type or "", - "correlation_id": correlation_id, "reply_to": reply_to, - **(headers or {}), + **cmd.headers_to_publish(js=False), } - with anyio.fail_after(timeout): + with anyio.fail_after(cmd.timeout): await self._connection.publish( - subject=subject, + subject=cmd.destination, payload=payload, headers=headers_to_send, - stream=stream, - timeout=timeout, + stream=cmd.stream, + timeout=cmd.timeout, ) msg = await future @@ -191,3 +169,11 @@ async def request( # type: ignore[override] raise nats.errors.NoRespondersError return msg + + @override + async def publish_batch( + self, + cmd: "NatsPublishCommand", + ) -> None: + msg = "NATS doesn't support publishing in batches." + raise FeatureNotSupportedException(msg) diff --git a/faststream/nats/publisher/usecase.py b/faststream/nats/publisher/usecase.py index 169014e9fc..880479546c 100644 --- a/faststream/nats/publisher/usecase.py +++ b/faststream/nats/publisher/usecase.py @@ -1,11 +1,8 @@ -from collections.abc import Awaitable, Iterable -from functools import partial -from itertools import chain +from collections.abc import Iterable from typing import ( TYPE_CHECKING, Annotated, Any, - Callable, Optional, Union, ) @@ -14,16 +11,17 @@ from typing_extensions import Doc, override from faststream._internal.publisher.usecase import PublisherUsecase -from faststream._internal.subscriber.utils import process_msg -from faststream.exceptions import NOT_CONNECTED_YET -from faststream.message import SourceType, gen_cor_id +from faststream.message import gen_cor_id +from faststream.nats.response import NatsPublishCommand +from faststream.response.publish_type import PublishType if TYPE_CHECKING: - from faststream._internal.basic_types import AnyDict, SendableMessage + from faststream._internal.basic_types import SendableMessage from faststream._internal.types import BrokerMiddleware, PublisherMiddleware from faststream.nats.message import NatsMessage from faststream.nats.publisher.producer import NatsFastProducer, NatsJSFastProducer from faststream.nats.schemas import JStream + from faststream.response.response import PublishCommand class LogicPublisher(PublisherUsecase[Msg]): @@ -62,7 +60,7 @@ def __init__( self.subject = subject self.stream = stream self.timeout = timeout - self.headers = headers + self.headers = headers or {} self.reply_to = reply_to @override @@ -94,55 +92,37 @@ async def publish( Can be omitted without any effect. timeout (float, optional): Timeout to send message to NATS in seconds (default is `None`). """ - return await self._publish( + cmd = NatsPublishCommand( message, - subject=subject, - headers=headers, - reply_to=reply_to, - correlation_id=correlation_id, - stream=stream, - timeout=timeout, - _extra_middlewares=(), + subject=subject or self.subject, + headers=self.headers | (headers or {}), + reply_to=reply_to or self.reply_to, + correlation_id=correlation_id or gen_cor_id(), + stream=stream or getattr(self.stream, "name", None), + timeout=timeout or self.timeout, + _publish_type=PublishType.Publish, ) + return await self._basic_publish(cmd, _extra_middlewares=()) @override async def _publish( self, - message: "SendableMessage", - subject: str = "", + cmd: Union["PublishCommand", "NatsPublishCommand"], *, - headers: Optional[dict[str, str]] = None, - reply_to: str = "", - correlation_id: Optional[str] = None, - stream: Optional[str] = None, - timeout: Optional[float] = None, - # publisher specific - _extra_middlewares: Iterable["PublisherMiddleware"] = (), + _extra_middlewares: Iterable["PublisherMiddleware"], ) -> None: - assert self._producer, NOT_CONNECTED_YET # nosec B101 + """This method should be called in subscriber flow only.""" + cmd = NatsPublishCommand.from_cmd(cmd) - kwargs: AnyDict = { - "subject": subject or self.subject, - "headers": headers or self.headers, - "reply_to": reply_to or self.reply_to, - "correlation_id": correlation_id or gen_cor_id(), - } + cmd.destination = self.subject + cmd.add_headers(self.headers, override=False) + cmd.reply_to = cmd.reply_to or self.reply_to - if stream := stream or getattr(self.stream, "name", None): - kwargs.update({"stream": stream, "timeout": timeout or self.timeout}) + if self.stream: + cmd.stream = self.stream.name + cmd.timeout = self.timeout - call: Callable[..., Awaitable[Any]] = self._producer.publish - - for m in chain( - ( - _extra_middlewares - or (m(None).publish_scope for m in self._broker_middlewares) - ), - self._middlewares, - ): - call = partial(m, call) - - await call(message, **kwargs) + return await self._basic_publish(cmd, _extra_middlewares=_extra_middlewares) @override async def request( @@ -177,44 +157,18 @@ async def request( float, Doc("Timeout to send message to NATS."), ] = 0.5, - # publisher specific - _extra_middlewares: Annotated[ - Iterable["PublisherMiddleware"], - Doc("Extra middlewares to wrap publishing process."), - ] = (), ) -> "NatsMessage": - assert self._producer, NOT_CONNECTED_YET # nosec B101 - - kwargs: AnyDict = { - "subject": subject or self.subject, - "headers": headers or self.headers, - "timeout": timeout or self.timeout, - "correlation_id": correlation_id or gen_cor_id(), - } - - request: Callable[..., Awaitable[Any]] = self._producer.request - - for pub_m in chain( - ( - _extra_middlewares - or (m(None).publish_scope for m in self._broker_middlewares) - ), - self._middlewares, - ): - request = partial(pub_m, request) - - published_msg = await request( - message, - **kwargs, + cmd = NatsPublishCommand( + message=message, + subject=subject or self.subject, + headers=self.headers | (headers or {}), + timeout=timeout or self.timeout, + correlation_id=correlation_id or gen_cor_id(), + stream=getattr(self.stream, "name", None), + _publish_type=PublishType.Request, ) - msg: NatsMessage = await process_msg( - msg=published_msg, - middlewares=self._broker_middlewares, - parser=self._producer._parser, - decoder=self._producer._decoder, - ) - msg._source_type = SourceType.Response + msg: NatsMessage = await self._basic_request(cmd) return msg def add_prefix(self, prefix: str) -> None: diff --git a/faststream/nats/response.py b/faststream/nats/response.py index 625ac866f0..a6fcee1961 100644 --- a/faststream/nats/response.py +++ b/faststream/nats/response.py @@ -1,11 +1,12 @@ -from typing import TYPE_CHECKING, Optional +from typing import TYPE_CHECKING, Optional, Union from typing_extensions import override -from faststream.response import Response +from faststream.response.publish_type import PublishType +from faststream.response.response import PublishCommand, Response if TYPE_CHECKING: - from faststream._internal.basic_types import AnyDict, SendableMessage + from faststream._internal.basic_types import SendableMessage class NatsResponse(Response): @@ -25,8 +26,68 @@ def __init__( self.stream = stream @override - def as_publish_kwargs(self) -> "AnyDict": - return { - **super().as_publish_kwargs(), - "stream": self.stream, - } + def as_publish_command(self) -> "NatsPublishCommand": + return NatsPublishCommand( + message=self.body, + headers=self.headers, + correlation_id=self.correlation_id, + _publish_type=PublishType.Reply, + # Nats specific + subject="", + stream=self.stream, + ) + + +class NatsPublishCommand(PublishCommand): + def __init__( + self, + message: "SendableMessage", + *, + subject: str = "", + correlation_id: Optional[str] = None, + headers: Optional[dict[str, str]] = None, + reply_to: str = "", + stream: Optional[str] = None, + timeout: Optional[float] = None, + _publish_type: PublishType, + ) -> None: + super().__init__( + body=message, + destination=subject, + correlation_id=correlation_id, + headers=headers, + reply_to=reply_to, + _publish_type=_publish_type, + ) + + self.stream = stream + self.timeout = timeout + + def headers_to_publish(self, *, js: bool = False) -> dict[str, str]: + headers = {} + + if self.correlation_id: + headers["correlation_id"] = self.correlation_id + + if js and self.reply_to: + headers["reply_to"] = self.reply_to + + return headers | self.headers + + @classmethod + def from_cmd( + cls, + cmd: Union["PublishCommand", "NatsPublishCommand"], + ) -> "NatsPublishCommand": + if isinstance(cmd, NatsPublishCommand): + # NOTE: Should return a copy probably. + return cmd + + return cls( + message=cmd.body, + subject=cmd.destination, + correlation_id=cmd.correlation_id, + headers=cmd.headers, + reply_to=cmd.reply_to, + _publish_type=cmd.publish_type, + ) diff --git a/faststream/nats/subscriber/usecase.py b/faststream/nats/subscriber/usecase.py index be75b89776..ff2e8c03c0 100644 --- a/faststream/nats/subscriber/usecase.py +++ b/faststream/nats/subscriber/usecase.py @@ -1,6 +1,6 @@ import asyncio from abc import abstractmethod -from collections.abc import Awaitable, Coroutine, Iterable, Sequence +from collections.abc import Awaitable, Coroutine, Iterable from contextlib import suppress from typing import ( TYPE_CHECKING, @@ -21,7 +21,6 @@ from typing_extensions import Doc, override from faststream._internal.context.repository import context -from faststream._internal.publisher.fake import FakePublisher from faststream._internal.subscriber.usecase import SubscriberUsecase from faststream._internal.subscriber.utils import process_msg from faststream._internal.types import MsgType @@ -33,6 +32,7 @@ NatsParser, ObjParser, ) +from faststream.nats.publisher.fake import NatsFakePublisher from faststream.nats.schemas.js_stream import compile_nats_wildcard from faststream.nats.subscriber.adapters import ( UnsubscribeAdapter, @@ -53,7 +53,7 @@ LoggerProto, SendableMessage, ) - from faststream._internal.publisher.proto import ProducerProto + from faststream._internal.publisher.proto import BasePublisherProto, ProducerProto from faststream._internal.setup import SetupState from faststream._internal.types import ( AsyncCallable, @@ -270,17 +270,15 @@ def __init__( def _make_response_publisher( self, message: "StreamMessage[Any]", - ) -> Sequence[FakePublisher]: - """Create FakePublisher object to use it as one of `publishers` in `self.consume` scope.""" + ) -> Iterable["BasePublisherProto"]: + """Create Publisher objects to use it as one of `publishers` in `self.consume` scope.""" if self._producer is None: return () return ( - FakePublisher( - self._producer.publish, - publish_kwargs={ - "subject": message.reply_to, - }, + NatsFakePublisher( + producer=self._producer, + subject=message.reply_to, ), ) @@ -1140,8 +1138,8 @@ def _make_response_publisher( "StreamMessage[KeyValue.Entry]", Doc("Message requiring reply"), ], - ) -> Sequence[FakePublisher]: - """Create FakePublisher object to use it as one of `publishers` in `self.consume` scope.""" + ) -> Iterable["BasePublisherProto"]: + """Create Publisher objects to use it as one of `publishers` in `self.consume` scope.""" return () def get_log_context( @@ -1293,8 +1291,8 @@ def _make_response_publisher( "StreamMessage[ObjectInfo]", Doc("Message requiring reply"), ], - ) -> Sequence[FakePublisher]: - """Create FakePublisher object to use it as one of `publishers` in `self.consume` scope.""" + ) -> Iterable["BasePublisherProto"]: + """Create Publisher objects to use it as one of `publishers` in `self.consume` scope.""" return () def get_log_context( diff --git a/faststream/nats/testing.py b/faststream/nats/testing.py index 7765df0181..80e2b91f7e 100644 --- a/faststream/nats/testing.py +++ b/faststream/nats/testing.py @@ -23,6 +23,7 @@ if TYPE_CHECKING: from faststream._internal.basic_types import SendableMessage from faststream.nats.publisher.specified import SpecificationPublisher + from faststream.nats.response import NatsPublishCommand from faststream.nats.subscriber.usecase import LogicSubscriber __all__ = ("TestNatsBroker",) @@ -74,28 +75,20 @@ def __init__(self, broker: NatsBroker) -> None: @override async def publish( # type: ignore[override] - self, - message: "SendableMessage", - subject: str, - reply_to: str = "", - headers: Optional[dict[str, str]] = None, - correlation_id: Optional[str] = None, - # NatsJSFastProducer compatibility - timeout: Optional[float] = None, - stream: Optional[str] = None, + self, cmd: "NatsPublishCommand" ) -> None: incoming = build_message( - message=message, - subject=subject, - headers=headers, - correlation_id=correlation_id, - reply_to=reply_to, + message=cmd.body, + subject=cmd.destination, + headers=cmd.headers, + correlation_id=cmd.correlation_id, + reply_to=cmd.reply_to, ) for handler in _find_handler( self.broker._subscribers, - subject, - stream, + cmd.destination, + cmd.stream, ): msg: Union[list[PatchedMessage], PatchedMessage] @@ -104,31 +97,24 @@ async def publish( # type: ignore[override] else: msg = incoming - await self._execute_handler(msg, subject, handler) + await self._execute_handler(msg, cmd.destination, handler) @override async def request( # type: ignore[override] self, - message: "SendableMessage", - subject: str, - *, - correlation_id: Optional[str] = None, - headers: Optional[dict[str, str]] = None, - timeout: float = 0.5, - # NatsJSFastProducer compatibility - stream: Optional[str] = None, + cmd: "NatsPublishCommand", ) -> "PatchedMessage": incoming = build_message( - message=message, - subject=subject, - headers=headers, - correlation_id=correlation_id, + message=cmd.body, + subject=cmd.destination, + headers=cmd.headers, + correlation_id=cmd.correlation_id, ) for handler in _find_handler( self.broker._subscribers, - subject, - stream, + cmd.destination, + cmd.stream, ): msg: Union[list[PatchedMessage], PatchedMessage] @@ -137,8 +123,8 @@ async def request( # type: ignore[override] else: msg = incoming - with anyio.fail_after(timeout): - return await self._execute_handler(msg, subject, handler) + with anyio.fail_after(cmd.timeout): + return await self._execute_handler(msg, cmd.destination, handler) raise SubscriberNotFound diff --git a/faststream/opentelemetry/middleware.py b/faststream/opentelemetry/middleware.py index 8305e3457a..853b85ccc7 100644 --- a/faststream/opentelemetry/middleware.py +++ b/faststream/opentelemetry/middleware.py @@ -10,10 +10,7 @@ from opentelemetry.trace import Link, Span from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator -from faststream import ( - BaseMiddleware, - context as fs_context, -) +from faststream import BaseMiddleware from faststream.opentelemetry.baggage import Baggage from faststream.opentelemetry.consts import ( ERROR_TYPE, @@ -22,7 +19,6 @@ WITH_BATCH, MessageAction, ) -from faststream.opentelemetry.provider import TelemetrySettingsProvider if TYPE_CHECKING: from contextvars import Token @@ -33,13 +29,58 @@ from opentelemetry.util.types import Attributes from faststream._internal.basic_types import AnyDict, AsyncFunc, AsyncFuncAny + from faststream._internal.context.repository import ContextRepo from faststream.message import StreamMessage + from faststream.opentelemetry.provider import TelemetrySettingsProvider + from faststream.response.response import PublishCommand _BAGGAGE_PROPAGATOR = W3CBaggagePropagator() _TRACE_PROPAGATOR = TraceContextTextMapPropagator() +class TelemetryMiddleware: + # NOTE: should it be class or function? + __slots__ = ( + "_meter", + "_metrics", + "_settings_provider_factory", + "_tracer", + ) + + def __init__( + self, + *, + settings_provider_factory: Callable[ + [Any], + Optional["TelemetrySettingsProvider[Any]"], + ], + tracer_provider: Optional["TracerProvider"] = None, + meter_provider: Optional["MeterProvider"] = None, + meter: Optional["Meter"] = None, + include_messages_counters: bool = False, + ) -> None: + self._tracer = _get_tracer(tracer_provider) + self._meter = _get_meter(meter_provider, meter) + self._metrics = _MetricsContainer(self._meter, include_messages_counters) + self._settings_provider_factory = settings_provider_factory + + def __call__( + self, + msg: Optional[Any], + /, + *, + context: "ContextRepo", + ) -> "_BaseTelemetryMiddleware": + return _BaseTelemetryMiddleware( + msg, + tracer=self._tracer, + metrics_container=self._metrics, + settings_provider_factory=self._settings_provider_factory, + context=context, + ) + + class _MetricsContainer: __slots__ = ( "include_messages_counters", @@ -112,19 +153,21 @@ def observe_consume( ) -class BaseTelemetryMiddleware(BaseMiddleware): +class _BaseTelemetryMiddleware(BaseMiddleware): def __init__( self, + msg: Optional[Any], + /, *, tracer: "Tracer", settings_provider_factory: Callable[ [Any], - Optional[TelemetrySettingsProvider[Any]], + Optional["TelemetrySettingsProvider[Any]"], ], metrics_container: _MetricsContainer, - msg: Optional[Any] = None, + context: "ContextRepo", ) -> None: - self.msg = msg + super().__init__(msg, context=context) self._tracer = tracer self._metrics = metrics_container @@ -136,29 +179,27 @@ def __init__( async def publish_scope( self, call_next: "AsyncFunc", - msg: Any, - *args: Any, - **kwargs: Any, + msg: "PublishCommand", ) -> Any: if (provider := self.__settings_provider) is None: - return await call_next(msg, *args, **kwargs) + return await call_next(msg) - headers = kwargs.pop("headers", {}) or {} + headers = msg.headers current_context = context.get_current() - destination_name = provider.get_publish_destination_name(kwargs) + destination_name = provider.get_publish_destination_name(msg) - current_baggage: Optional[Baggage] = fs_context.get_local("baggage") + current_baggage: Optional[Baggage] = self.context.get_local("baggage") if current_baggage: headers.update(current_baggage.to_headers()) - trace_attributes = provider.get_publish_attrs_from_kwargs(kwargs) + trace_attributes = provider.get_publish_attrs_from_cmd(msg) metrics_attributes = { SpanAttributes.MESSAGING_SYSTEM: provider.messaging_system, SpanAttributes.MESSAGING_DESTINATION_NAME: destination_name, } # NOTE: if batch with single message? - if (msg_count := len((msg, *args))) > 1: + if (msg_count := len(msg.batch_bodies)) > 1: trace_attributes[SpanAttributes.MESSAGING_BATCH_MESSAGE_COUNT] = msg_count current_context = _BAGGAGE_PROPAGATOR.extract(headers, current_context) _BAGGAGE_PROPAGATOR.inject( @@ -196,7 +237,8 @@ async def publish_scope( SpanAttributes.MESSAGING_OPERATION, MessageAction.PUBLISH, ) - result = await call_next(msg, *args, headers=headers, **kwargs) + msg.headers = headers + result = await call_next(msg) except Exception as e: metrics_attributes[ERROR_TYPE] = type(e).__name__ @@ -207,7 +249,7 @@ async def publish_scope( self._metrics.observe_publish(metrics_attributes, duration, msg_count) for key, token in self._scope_tokens: - fs_context.reset_local(key, token) + self.context.reset_local(key, token) return result @@ -260,9 +302,15 @@ async def consume_scope( ) self._current_span = span - self._scope_tokens.append(("span", fs_context.set_local("span", span))) + self._scope_tokens.append(( + "span", + self.context.set_local("span", span), + )) self._scope_tokens.append( - ("baggage", fs_context.set_local("baggage", Baggage.from_msg(msg))), + ( + "baggage", + self.context.set_local("baggage", Baggage.from_msg(msg)), + ), ) new_context = trace.set_span_in_context(span, current_context) @@ -295,41 +343,6 @@ async def after_processed( return False -class TelemetryMiddleware: - # NOTE: should it be class or function? - __slots__ = ( - "_meter", - "_metrics", - "_settings_provider_factory", - "_tracer", - ) - - def __init__( - self, - *, - settings_provider_factory: Callable[ - [Any], - Optional[TelemetrySettingsProvider[Any]], - ], - tracer_provider: Optional["TracerProvider"] = None, - meter_provider: Optional["MeterProvider"] = None, - meter: Optional["Meter"] = None, - include_messages_counters: bool = False, - ) -> None: - self._tracer = _get_tracer(tracer_provider) - self._meter = _get_meter(meter_provider, meter) - self._metrics = _MetricsContainer(self._meter, include_messages_counters) - self._settings_provider_factory = settings_provider_factory - - def __call__(self, msg: Optional[Any]) -> BaseMiddleware: - return BaseTelemetryMiddleware( - tracer=self._tracer, - metrics_container=self._metrics, - settings_provider_factory=self._settings_provider_factory, - msg=msg, - ) - - def _get_meter( meter_provider: Optional["MeterProvider"] = None, meter: Optional["Meter"] = None, diff --git a/faststream/opentelemetry/provider.py b/faststream/opentelemetry/provider.py index 304f1f332b..6e2aaa90b6 100644 --- a/faststream/opentelemetry/provider.py +++ b/faststream/opentelemetry/provider.py @@ -5,6 +5,7 @@ if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict from faststream.message import StreamMessage + from faststream.response.response import PublishCommand class TelemetrySettingsProvider(Protocol[MsgType]): @@ -20,12 +21,12 @@ def get_consume_destination_name( msg: "StreamMessage[MsgType]", ) -> str: ... - def get_publish_attrs_from_kwargs( + def get_publish_attrs_from_cmd( self, - kwargs: "AnyDict", + cmd: "PublishCommand", ) -> "AnyDict": ... def get_publish_destination_name( self, - kwargs: "AnyDict", + cmd: "PublishCommand", ) -> str: ... diff --git a/faststream/prometheus/__init__.py b/faststream/prometheus/__init__.py index e604b8cef7..a06f158ff3 100644 --- a/faststream/prometheus/__init__.py +++ b/faststream/prometheus/__init__.py @@ -1,9 +1,9 @@ -from faststream.prometheus.middleware import BasePrometheusMiddleware +from faststream.prometheus.middleware import PrometheusMiddleware from faststream.prometheus.provider import MetricsSettingsProvider from faststream.prometheus.types import ConsumeAttrs __all__ = ( - "BasePrometheusMiddleware", "ConsumeAttrs", "MetricsSettingsProvider", + "PrometheusMiddleware", ) diff --git a/faststream/prometheus/consts.py b/faststream/prometheus/consts.py index 3c4648d333..75cb8ba89a 100644 --- a/faststream/prometheus/consts.py +++ b/faststream/prometheus/consts.py @@ -1,5 +1,5 @@ -from faststream.broker.message import AckStatus from faststream.exceptions import AckMessage, NackMessage, RejectMessage, SkipMessage +from faststream.message.message import AckStatus from faststream.prometheus.types import ProcessingStatus PROCESSING_STATUS_BY_HANDLER_EXCEPTION_MAP = { diff --git a/faststream/prometheus/middleware.py b/faststream/prometheus/middleware.py index 9bbaafb79a..3d7f256f05 100644 --- a/faststream/prometheus/middleware.py +++ b/faststream/prometheus/middleware.py @@ -3,6 +3,7 @@ from typing import TYPE_CHECKING, Any, Callable, Optional from faststream import BaseMiddleware +from faststream._internal.constants import EMPTY from faststream.prometheus.consts import ( PROCESSING_STATUS_BY_ACK_STATUS, PROCESSING_STATUS_BY_HANDLER_EXCEPTION_MAP, @@ -11,28 +12,74 @@ from faststream.prometheus.manager import MetricsManager from faststream.prometheus.provider import MetricsSettingsProvider from faststream.prometheus.types import ProcessingStatus, PublishingStatus -from faststream.types import EMPTY if TYPE_CHECKING: from prometheus_client import CollectorRegistry - from faststream.broker.message import StreamMessage + from faststream._internal.context.repository import ContextRepo + from faststream.message.message import StreamMessage + from faststream.response.response import PublishCommand from faststream.types import AsyncFunc, AsyncFuncAny -class PrometheusMiddleware(BaseMiddleware): +class PrometheusMiddleware: + __slots__ = ("_metrics_container", "_metrics_manager", "_settings_provider_factory") + + def __init__( + self, + *, + settings_provider_factory: Callable[ + [Any], Optional[MetricsSettingsProvider[Any]] + ], + registry: "CollectorRegistry", + app_name: str = EMPTY, + metrics_prefix: str = "faststream", + received_messages_size_buckets: Optional[Sequence[float]] = None, + ) -> None: + if app_name is EMPTY: + app_name = metrics_prefix + + self._settings_provider_factory = settings_provider_factory + self._metrics_container = MetricsContainer( + registry, + metrics_prefix=metrics_prefix, + received_messages_size_buckets=received_messages_size_buckets, + ) + self._metrics_manager = MetricsManager( + self._metrics_container, + app_name=app_name, + ) + + def __call__( + self, + msg: Optional[Any], + /, + *, + context: "ContextRepo", + ) -> "_PrometheusMiddleware": + return _PrometheusMiddleware( + msg, + metrics_manager=self._metrics_manager, + settings_provider_factory=self._settings_provider_factory, + context=context, + ) + + +class _PrometheusMiddleware(BaseMiddleware): def __init__( self, - msg: Optional[Any] = None, + msg: Optional[Any], + /, *, settings_provider_factory: Callable[ [Any], Optional[MetricsSettingsProvider[Any]] ], metrics_manager: MetricsManager, + context: "ContextRepo", ) -> None: self._metrics_manager = metrics_manager self._settings_provider = settings_provider_factory(msg) - super().__init__(msg) + super().__init__(msg, context=context) async def consume_scope( self, @@ -114,15 +161,13 @@ async def consume_scope( async def publish_scope( self, call_next: "AsyncFunc", - msg: Any, - *args: Any, - **kwargs: Any, + cmd: "PublishCommand", ) -> Any: if self._settings_provider is None: - return await call_next(msg, *args, **kwargs) + return await call_next(cmd) destination_name = ( - self._settings_provider.get_publish_destination_name_from_kwargs(kwargs) + self._settings_provider.get_publish_destination_name_from_cmd(cmd) ) messaging_system = self._settings_provider.messaging_system @@ -130,11 +175,7 @@ async def publish_scope( start_time = time.perf_counter() try: - result = await call_next( - await self.on_publish(msg, *args, **kwargs), - *args, - **kwargs, - ) + result = await call_next(cmd) except Exception as e: err = e @@ -155,49 +196,12 @@ async def publish_scope( ) status = PublishingStatus.error if err else PublishingStatus.success - messages_count = len((msg, *args)) self._metrics_manager.add_published_message( - amount=messages_count, + amount=len(cmd.batch_bodies), status=status, broker=messaging_system, destination=destination_name, ) return result - - -class BasePrometheusMiddleware: - __slots__ = ("_metrics_container", "_metrics_manager", "_settings_provider_factory") - - def __init__( - self, - *, - settings_provider_factory: Callable[ - [Any], Optional[MetricsSettingsProvider[Any]] - ], - registry: "CollectorRegistry", - app_name: str = EMPTY, - metrics_prefix: str = "faststream", - received_messages_size_buckets: Optional[Sequence[float]] = None, - ) -> None: - if app_name is EMPTY: - app_name = metrics_prefix - - self._settings_provider_factory = settings_provider_factory - self._metrics_container = MetricsContainer( - registry, - metrics_prefix=metrics_prefix, - received_messages_size_buckets=received_messages_size_buckets, - ) - self._metrics_manager = MetricsManager( - self._metrics_container, - app_name=app_name, - ) - - def __call__(self, msg: Optional[Any]) -> BaseMiddleware: - return PrometheusMiddleware( - msg=msg, - metrics_manager=self._metrics_manager, - settings_provider_factory=self._settings_provider_factory, - ) diff --git a/faststream/prometheus/provider.py b/faststream/prometheus/provider.py index 1a543f5b55..acbf68702f 100644 --- a/faststream/prometheus/provider.py +++ b/faststream/prometheus/provider.py @@ -1,11 +1,10 @@ from typing import TYPE_CHECKING, Protocol -from faststream.broker.message import MsgType +from faststream.message.message import MsgType, StreamMessage if TYPE_CHECKING: - from faststream.broker.message import StreamMessage from faststream.prometheus import ConsumeAttrs - from faststream.types import AnyDict + from faststream.response.response import PublishCommand class MetricsSettingsProvider(Protocol[MsgType]): @@ -16,7 +15,7 @@ def get_consume_attrs_from_message( msg: "StreamMessage[MsgType]", ) -> "ConsumeAttrs": ... - def get_publish_destination_name_from_kwargs( + def get_publish_destination_name_from_cmd( self, - kwargs: "AnyDict", + cmd: "PublishCommand", ) -> str: ... diff --git a/faststream/rabbit/annotations.py b/faststream/rabbit/annotations.py index 4a135ecae9..dcbea9d20e 100644 --- a/faststream/rabbit/annotations.py +++ b/faststream/rabbit/annotations.py @@ -4,7 +4,6 @@ from faststream._internal.context import Context from faststream.annotations import ContextRepo, Logger -from faststream.params import NoCast from faststream.rabbit.broker import RabbitBroker as RB from faststream.rabbit.message import RabbitMessage as RM from faststream.rabbit.publisher.producer import AioPikaFastProducer @@ -14,7 +13,6 @@ "Connection", "ContextRepo", "Logger", - "NoCast", "RabbitBroker", "RabbitMessage", "RabbitProducer", diff --git a/faststream/rabbit/broker/broker.py b/faststream/rabbit/broker/broker.py index 7e15392154..80b30305e6 100644 --- a/faststream/rabbit/broker/broker.py +++ b/faststream/rabbit/broker/broker.py @@ -22,6 +22,7 @@ from faststream.message import gen_cor_id from faststream.rabbit.helpers.declarer import RabbitDeclarer from faststream.rabbit.publisher.producer import AioPikaFastProducer +from faststream.rabbit.response import RabbitPublishCommand from faststream.rabbit.schemas import ( RABBIT_REPLY, RabbitExchange, @@ -29,6 +30,7 @@ ) from faststream.rabbit.security import parse_security from faststream.rabbit.utils import build_url +from faststream.response.publish_type import PublishType from .logging import make_rabbit_logger_state from .registrator import RabbitRegistrator @@ -619,32 +621,31 @@ async def publish( # type: ignore[override] Please, use `@broker.publisher(...)` or `broker.publisher(...).publish(...)` instead in a regular way. """ - routing = routing_key or RabbitQueue.validate(queue).routing - correlation_id = correlation_id or gen_cor_id() - - return await super().publish( + cmd = RabbitPublishCommand( message, - producer=self._producer, - routing_key=routing, + routing_key=routing_key or RabbitQueue.validate(queue).routing, + exchange=RabbitExchange.validate(exchange), + correlation_id=correlation_id or gen_cor_id(), app_id=self.app_id, - exchange=exchange, mandatory=mandatory, immediate=immediate, persist=persist, reply_to=reply_to, headers=headers, - correlation_id=correlation_id, content_type=content_type, content_encoding=content_encoding, expiration=expiration, message_id=message_id, - timestamp=timestamp, message_type=message_type, + timestamp=timestamp, user_id=user_id, timeout=timeout, priority=priority, + _publish_type=PublishType.Publish, ) + return await super()._basic_publish(cmd, producer=self._producer) + @override async def request( # type: ignore[override] self, @@ -739,16 +740,12 @@ async def request( # type: ignore[override] Doc("The message priority (0 by default)."), ] = None, ) -> "RabbitMessage": - routing = routing_key or RabbitQueue.validate(queue).routing - correlation_id = correlation_id or gen_cor_id() - - msg: RabbitMessage = await super().request( + cmd = RabbitPublishCommand( message, - producer=self._producer, - correlation_id=correlation_id, - routing_key=routing, + routing_key=routing_key or RabbitQueue.validate(queue).routing, + exchange=RabbitExchange.validate(exchange), + correlation_id=correlation_id or gen_cor_id(), app_id=self.app_id, - exchange=exchange, mandatory=mandatory, immediate=immediate, persist=persist, @@ -757,12 +754,15 @@ async def request( # type: ignore[override] content_encoding=content_encoding, expiration=expiration, message_id=message_id, - timestamp=timestamp, message_type=message_type, + timestamp=timestamp, user_id=user_id, timeout=timeout, priority=priority, + _publish_type=PublishType.Request, ) + + msg: RabbitMessage = await super()._basic_request(cmd, producer=self._producer) return msg async def declare_queue( diff --git a/faststream/rabbit/opentelemetry/provider.py b/faststream/rabbit/opentelemetry/provider.py index ffa14e60e6..e9bd12c7fd 100644 --- a/faststream/rabbit/opentelemetry/provider.py +++ b/faststream/rabbit/opentelemetry/provider.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Union +from typing import TYPE_CHECKING from opentelemetry.semconv.trace import SpanAttributes @@ -10,7 +10,7 @@ from faststream._internal.basic_types import AnyDict from faststream.message import StreamMessage - from faststream.rabbit.schemas.exchange import RabbitExchange + from faststream.rabbit.response import RabbitPublishCommand class RabbitTelemetrySettingsProvider(TelemetrySettingsProvider["IncomingMessage"]): @@ -41,28 +41,19 @@ def get_consume_destination_name( routing_key = msg.raw_message.routing_key return f"{exchange}.{routing_key}" - def get_publish_attrs_from_kwargs( + def get_publish_attrs_from_cmd( self, - kwargs: "AnyDict", + cmd: "RabbitPublishCommand", ) -> "AnyDict": - exchange: Union[None, str, RabbitExchange] = kwargs.get("exchange") return { SpanAttributes.MESSAGING_SYSTEM: self.messaging_system, - SpanAttributes.MESSAGING_DESTINATION_NAME: getattr( - exchange, - "name", - exchange or "", - ), - SpanAttributes.MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY: kwargs[ - "routing_key" - ], - SpanAttributes.MESSAGING_MESSAGE_CONVERSATION_ID: kwargs["correlation_id"], + SpanAttributes.MESSAGING_DESTINATION_NAME: cmd.exchange.name, + SpanAttributes.MESSAGING_RABBITMQ_DESTINATION_ROUTING_KEY: cmd.destination, + SpanAttributes.MESSAGING_MESSAGE_CONVERSATION_ID: cmd.correlation_id, } def get_publish_destination_name( self, - kwargs: "AnyDict", + cmd: "RabbitPublishCommand", ) -> str: - exchange: str = kwargs.get("exchange") or "default" - routing_key: str = kwargs["routing_key"] - return f"{exchange}.{routing_key}" + return f"{cmd.exchange.name or 'default'}.{cmd.destination}" diff --git a/faststream/rabbit/parser.py b/faststream/rabbit/parser.py index 70b2ba5492..de43697e17 100644 --- a/faststream/rabbit/parser.py +++ b/faststream/rabbit/parser.py @@ -61,19 +61,19 @@ async def decode_message( def encode_message( message: "AioPikaSendableMessage", *, - persist: bool, - reply_to: Optional[str], - headers: Optional["HeadersType"], - content_type: Optional[str], - content_encoding: Optional[str], - priority: Optional[int], - correlation_id: Optional[str], - expiration: Optional["DateType"], - message_id: Optional[str], - timestamp: Optional["DateType"], - message_type: Optional[str], - user_id: Optional[str], - app_id: Optional[str], + persist: bool = False, + reply_to: Optional[str] = None, + headers: Optional["HeadersType"] = None, + content_type: Optional[str] = None, + content_encoding: Optional[str] = None, + priority: Optional[int] = None, + correlation_id: Optional[str] = None, + expiration: "DateType" = None, + message_id: Optional[str] = None, + timestamp: "DateType" = None, + message_type: Optional[str] = None, + user_id: Optional[str] = None, + app_id: Optional[str] = None, ) -> Message: """Encodes a message for sending using AioPika.""" if isinstance(message, Message): diff --git a/faststream/rabbit/prometheus/middleware.py b/faststream/rabbit/prometheus/middleware.py index 44f179b66d..78dd498576 100644 --- a/faststream/rabbit/prometheus/middleware.py +++ b/faststream/rabbit/prometheus/middleware.py @@ -1,15 +1,15 @@ from collections.abc import Sequence from typing import TYPE_CHECKING, Optional -from faststream.prometheus.middleware import BasePrometheusMiddleware +from faststream._internal.constants import EMPTY +from faststream.prometheus.middleware import PrometheusMiddleware from faststream.rabbit.prometheus.provider import RabbitMetricsSettingsProvider -from faststream.types import EMPTY if TYPE_CHECKING: from prometheus_client import CollectorRegistry -class RabbitPrometheusMiddleware(BasePrometheusMiddleware): +class RabbitPrometheusMiddleware(PrometheusMiddleware): def __init__( self, *, diff --git a/faststream/rabbit/prometheus/provider.py b/faststream/rabbit/prometheus/provider.py index 48c1bb2541..f4fa0d977f 100644 --- a/faststream/rabbit/prometheus/provider.py +++ b/faststream/rabbit/prometheus/provider.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Union +from typing import TYPE_CHECKING from faststream.prometheus import ( ConsumeAttrs, @@ -8,9 +8,8 @@ if TYPE_CHECKING: from aio_pika import IncomingMessage - from faststream.broker.message import StreamMessage - from faststream.rabbit.schemas.exchange import RabbitExchange - from faststream.types import AnyDict + from faststream.message.message import StreamMessage + from faststream.rabbit.response import RabbitPublishCommand class RabbitMetricsSettingsProvider(MetricsSettingsProvider["IncomingMessage"]): @@ -32,13 +31,8 @@ def get_consume_attrs_from_message( "messages_count": 1, } - def get_publish_destination_name_from_kwargs( + def get_publish_destination_name_from_cmd( self, - kwargs: "AnyDict", + cmd: "RabbitPublishCommand", ) -> str: - exchange: Union[None, str, RabbitExchange] = kwargs.get("exchange") - exchange_prefix = getattr(exchange, "name", exchange or "default") - - routing_key: str = kwargs["routing_key"] - - return f"{exchange_prefix}.{routing_key}" + return f"{cmd.exchange.name or 'default'}.{cmd.destination}" diff --git a/faststream/rabbit/publisher/fake.py b/faststream/rabbit/publisher/fake.py new file mode 100644 index 0000000000..e5c67848e6 --- /dev/null +++ b/faststream/rabbit/publisher/fake.py @@ -0,0 +1,30 @@ +from typing import TYPE_CHECKING, Optional, Union + +from faststream._internal.publisher.fake import FakePublisher +from faststream.rabbit.response import RabbitPublishCommand + +if TYPE_CHECKING: + from faststream._internal.publisher.proto import ProducerProto + from faststream.response.response import PublishCommand + + +class RabbitFakePublisher(FakePublisher): + """Publisher Interface implementation to use as RPC or REPLY TO answer publisher.""" + + def __init__( + self, + producer: "ProducerProto", + routing_key: str, + app_id: Optional[str], + ) -> None: + super().__init__(producer=producer) + self.routing_key = routing_key + self.app_id = str + + def patch_command( + self, cmd: Union["PublishCommand", "RabbitPublishCommand"] + ) -> "RabbitPublishCommand": + real_cmd = RabbitPublishCommand.from_cmd(cmd) + real_cmd.destination = self.routing_key + real_cmd.app_id = self.app_id + return real_cmd diff --git a/faststream/rabbit/publisher/options.py b/faststream/rabbit/publisher/options.py new file mode 100644 index 0000000000..81343b7cf9 --- /dev/null +++ b/faststream/rabbit/publisher/options.py @@ -0,0 +1,28 @@ +from typing import TYPE_CHECKING, Optional + +from typing_extensions import TypedDict + +if TYPE_CHECKING: + from aio_pika.abc import DateType, HeadersType, TimeoutType + + +class PublishOptions(TypedDict, total=False): + mandatory: bool + immediate: bool + timeout: "TimeoutType" + + +class MessageOptions(TypedDict, total=False): + persist: bool + reply_to: Optional[str] + headers: Optional["HeadersType"] + content_type: Optional[str] + content_encoding: Optional[str] + priority: Optional[int] + expiration: "DateType" + message_id: Optional[str] + timestamp: "DateType" + message_type: Optional[str] + user_id: Optional[str] + app_id: Optional[str] + correlation_id: Optional[str] diff --git a/faststream/rabbit/publisher/producer.py b/faststream/rabbit/publisher/producer.py index 780ef16424..ec509842a3 100644 --- a/faststream/rabbit/publisher/producer.py +++ b/faststream/rabbit/publisher/producer.py @@ -1,15 +1,15 @@ from typing import ( TYPE_CHECKING, Optional, - Union, cast, ) import anyio -from typing_extensions import override +from typing_extensions import Unpack, override from faststream._internal.publisher.proto import ProducerProto from faststream._internal.subscriber.utils import resolve_custom_func +from faststream.exceptions import FeatureNotSupportedException from faststream.rabbit.parser import AioPikaParser from faststream.rabbit.schemas import RABBIT_REPLY, RabbitExchange @@ -18,7 +18,7 @@ import aiormq from aio_pika import IncomingMessage, RobustQueue - from aio_pika.abc import AbstractIncomingMessage, DateType, HeadersType, TimeoutType + from aio_pika.abc import AbstractIncomingMessage, TimeoutType from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream from faststream._internal.types import ( @@ -26,6 +26,7 @@ CustomCallable, ) from faststream.rabbit.helpers.declarer import RabbitDeclarer + from faststream.rabbit.response import MessageOptions, RabbitPublishCommand from faststream.rabbit.types import AioPikaSendableMessage @@ -53,99 +54,40 @@ def __init__( @override async def publish( # type: ignore[override] self, - message: "AioPikaSendableMessage", - exchange: Union["RabbitExchange", str, None] = None, - *, - correlation_id: str = "", - routing_key: str = "", - mandatory: bool = True, - immediate: bool = False, - timeout: "TimeoutType" = None, - persist: bool = False, - reply_to: Optional[str] = None, - headers: Optional["HeadersType"] = None, - content_type: Optional[str] = None, - content_encoding: Optional[str] = None, - priority: Optional[int] = None, - expiration: Optional["DateType"] = None, - message_id: Optional[str] = None, - timestamp: Optional["DateType"] = None, - message_type: Optional[str] = None, - user_id: Optional[str] = None, - app_id: Optional[str] = None, + cmd: "RabbitPublishCommand", ) -> Optional["aiormq.abc.ConfirmationFrameType"]: """Publish a message to a RabbitMQ queue.""" return await self._publish( - message=message, - exchange=exchange, - routing_key=routing_key, - mandatory=mandatory, - immediate=immediate, - timeout=timeout, - persist=persist, - reply_to=reply_to, - headers=headers, - content_type=content_type, - content_encoding=content_encoding, - priority=priority, - correlation_id=correlation_id, - expiration=expiration, - message_id=message_id, - timestamp=timestamp, - message_type=message_type, - user_id=user_id, - app_id=app_id, + message=cmd.body, + exchange=cmd.exchange, + routing_key=cmd.destination, + reply_to=cmd.reply_to, + headers=cmd.headers, + correlation_id=cmd.correlation_id, + **cmd.publish_options, + **cmd.message_options, ) @override async def request( # type: ignore[override] self, - message: "AioPikaSendableMessage", - exchange: Union["RabbitExchange", str, None] = None, - *, - correlation_id: str = "", - routing_key: str = "", - mandatory: bool = True, - immediate: bool = False, - timeout: Optional[float] = None, - persist: bool = False, - headers: Optional["HeadersType"] = None, - content_type: Optional[str] = None, - content_encoding: Optional[str] = None, - priority: Optional[int] = None, - expiration: Optional["DateType"] = None, - message_id: Optional[str] = None, - timestamp: Optional["DateType"] = None, - message_type: Optional[str] = None, - user_id: Optional[str] = None, - app_id: Optional[str] = None, + cmd: "RabbitPublishCommand", ) -> "IncomingMessage": """Publish a message to a RabbitMQ queue.""" async with _RPCCallback( self._rpc_lock, await self.declarer.declare_queue(RABBIT_REPLY), ) as response_queue: - with anyio.fail_after(timeout): + with anyio.fail_after(cmd.timeout): await self._publish( - message=message, - exchange=exchange, - routing_key=routing_key, - mandatory=mandatory, - immediate=immediate, - timeout=timeout, - persist=persist, + message=cmd.body, + exchange=cmd.exchange, + routing_key=cmd.destination, reply_to=RABBIT_REPLY.name, - headers=headers, - content_type=content_type, - content_encoding=content_encoding, - priority=priority, - correlation_id=correlation_id, - expiration=expiration, - message_id=message_id, - timestamp=timestamp, - message_type=message_type, - user_id=user_id, - app_id=app_id, + headers=cmd.headers, + correlation_id=cmd.correlation_id, + **cmd.publish_options, + **cmd.message_options, ) return await response_queue.receive() @@ -153,45 +95,18 @@ async def _publish( self, message: "AioPikaSendableMessage", *, - correlation_id: str, - exchange: Union["RabbitExchange", str, None], + exchange: "RabbitExchange", routing_key: str, - mandatory: bool, - immediate: bool, - timeout: "TimeoutType", - persist: bool, - reply_to: Optional[str], - headers: Optional["HeadersType"], - content_type: Optional[str], - content_encoding: Optional[str], - priority: Optional[int], - expiration: Optional["DateType"], - message_id: Optional[str], - timestamp: Optional["DateType"], - message_type: Optional[str], - user_id: Optional[str], - app_id: Optional[str], + mandatory: bool = True, + immediate: bool = False, + timeout: "TimeoutType" = None, + **message_options: Unpack["MessageOptions"], ) -> Optional["aiormq.abc.ConfirmationFrameType"]: """Publish a message to a RabbitMQ exchange.""" - message = AioPikaParser.encode_message( - message=message, - persist=persist, - reply_to=reply_to, - headers=headers, - content_type=content_type, - content_encoding=content_encoding, - priority=priority, - correlation_id=correlation_id, - expiration=expiration, - message_id=message_id, - timestamp=timestamp, - message_type=message_type, - user_id=user_id, - app_id=app_id, - ) + message = AioPikaParser.encode_message(message=message, **message_options) exchange_obj = await self.declarer.declare_exchange( - exchange=RabbitExchange.validate(exchange), + exchange=exchange, passive=True, ) @@ -203,6 +118,14 @@ async def _publish( timeout=timeout, ) + @override + async def publish_batch( + self, + cmd: "RabbitPublishCommand", + ) -> None: + msg = "RabbitMQ doesn't support publishing in batches." + raise FeatureNotSupportedException(msg) + class _RPCCallback: """A class provides an RPC lock.""" diff --git a/faststream/rabbit/publisher/specified.py b/faststream/rabbit/publisher/specified.py index fce0411752..6d16769926 100644 --- a/faststream/rabbit/publisher/specified.py +++ b/faststream/rabbit/publisher/specified.py @@ -47,10 +47,12 @@ def get_schema(self) -> dict[str, Channel]: bindings=OperationBinding( amqp=amqp.OperationBinding( cc=self.routing or None, - deliveryMode=2 if self.message_kwargs.get("persist") else 1, - mandatory=self.message_kwargs.get("mandatory"), # type: ignore[arg-type] - replyTo=self.message_kwargs.get("reply_to"), # type: ignore[arg-type] - priority=self.message_kwargs.get("priority"), # type: ignore[arg-type] + deliveryMode=2 + if self.message_options.get("persist") + else 1, + replyTo=self.message_options.get("reply_to"), # type: ignore[arg-type] + mandatory=self.publish_options.get("mandatory"), # type: ignore[arg-type] + priority=self.message_options.get("priority"), # type: ignore[arg-type] ), ) if is_routing_exchange(self.exchange) diff --git a/faststream/rabbit/publisher/usecase.py b/faststream/rabbit/publisher/usecase.py index c5ff3fb653..d8aafe7df8 100644 --- a/faststream/rabbit/publisher/usecase.py +++ b/faststream/rabbit/publisher/usecase.py @@ -1,102 +1,41 @@ -from collections.abc import Awaitable, Iterable +from collections.abc import Iterable from copy import deepcopy -from functools import partial -from itertools import chain from typing import ( TYPE_CHECKING, Annotated, Any, - Callable, Optional, Union, ) from aio_pika import IncomingMessage -from typing_extensions import Doc, TypedDict, Unpack, override +from typing_extensions import Doc, Unpack, override from faststream._internal.publisher.usecase import PublisherUsecase -from faststream._internal.subscriber.utils import process_msg -from faststream.exceptions import NOT_CONNECTED_YET -from faststream.message import SourceType, gen_cor_id -from faststream.rabbit.schemas import BaseRMQInformation, RabbitQueue +from faststream._internal.utils.data import filter_by_dict +from faststream.message import gen_cor_id +from faststream.rabbit.response import RabbitPublishCommand +from faststream.rabbit.schemas import BaseRMQInformation, RabbitExchange, RabbitQueue +from faststream.response.publish_type import PublishType + +from .options import MessageOptions, PublishOptions if TYPE_CHECKING: import aiormq - from aio_pika.abc import DateType, HeadersType, TimeoutType - from faststream._internal.basic_types import AnyDict from faststream._internal.types import BrokerMiddleware, PublisherMiddleware from faststream.rabbit.message import RabbitMessage from faststream.rabbit.publisher.producer import AioPikaFastProducer - from faststream.rabbit.schemas.exchange import RabbitExchange from faststream.rabbit.types import AioPikaSendableMessage + from faststream.response.response import PublishCommand # should be public to use in imports -class RequestPublishKwargs(TypedDict, total=False): +class RequestPublishKwargs(MessageOptions, PublishOptions, total=False): """Typed dict to annotate RabbitMQ requesters.""" - headers: Annotated[ - Optional["HeadersType"], - Doc( - "Message headers to store metainformation. " - "Can be overridden by `publish.headers` if specified.", - ), - ] - mandatory: Annotated[ - Optional[bool], - Doc( - "Client waits for confirmation that the message is placed to some queue. " - "RabbitMQ returns message to client if there is no suitable queue.", - ), - ] - immediate: Annotated[ - Optional[bool], - Doc( - "Client expects that there is consumer ready to take the message to work. " - "RabbitMQ returns message to client if there is no suitable consumer.", - ), - ] - timeout: Annotated[ - "TimeoutType", - Doc("Send confirmation time from RabbitMQ."), - ] - persist: Annotated[ - Optional[bool], - Doc("Restore the message on RabbitMQ reboot."), - ] - - priority: Annotated[ - Optional[int], - Doc("The message priority (0 by default)."), - ] - message_type: Annotated[ - Optional[str], - Doc("Application-specific message type, e.g. **orders.created**."), - ] - content_type: Annotated[ - Optional[str], - Doc( - "Message **content-type** header. " - "Used by application, not core RabbitMQ. " - "Will be set automatically if not specified.", - ), - ] - user_id: Annotated[ - Optional[str], - Doc("Publisher connection User ID, validated if set."), - ] - expiration: Annotated[ - Optional["DateType"], - Doc("Message expiration (lifetime) in seconds (or datetime or timedelta)."), - ] - content_encoding: Annotated[ - Optional[str], - Doc("Message body content encoding, e.g. **gzip**."), - ] - -class PublishKwargs(RequestPublishKwargs, total=False): +class PublishKwargs(MessageOptions, PublishOptions, total=False): """Typed dict to annotate RabbitMQ publishers.""" reply_to: Annotated[ @@ -123,6 +62,7 @@ def __init__( routing_key: str, queue: "RabbitQueue", exchange: "RabbitExchange", + # PublishCommand options message_kwargs: "PublishKwargs", # Publisher args broker_middlewares: Iterable["BrokerMiddleware[IncomingMessage]"], @@ -145,9 +85,12 @@ def __init__( self.routing_key = routing_key - request_kwargs = dict(message_kwargs) - self.reply_to = request_kwargs.pop("reply_to", None) - self.message_kwargs = request_kwargs + request_options = dict(message_kwargs) + self.headers = request_options.pop("headers") or {} + self.reply_to = request_options.pop("reply_to", "") + self.timeout = request_options.pop("timeout", None) + self.message_options = filter_by_dict(MessageOptions, request_options) + self.publish_options = filter_by_dict(PublishOptions, request_options) # BaseRMQInformation self.queue = queue @@ -165,8 +108,12 @@ def _setup( # type: ignore[override] app_id: Optional[str], virtual_host: str, ) -> None: - self.app_id = app_id + if app_id: + self.message_options["app_id"] = app_id + self.app_id = app_id + self.virtual_host = virtual_host + super()._setup(producer=producer) @property @@ -202,77 +149,52 @@ async def publish( "**correlation_id** is a useful option to trace messages.", ), ] = None, - message_id: Annotated[ - Optional[str], - Doc("Arbitrary message id. Generated automatically if not presented."), - ] = None, - timestamp: Annotated[ - Optional["DateType"], - Doc("Message publish timestamp. Generated automatically if not presented."), - ] = None, # publisher specific **publish_kwargs: "Unpack[PublishKwargs]", ) -> Optional["aiormq.abc.ConfirmationFrameType"]: - return await self._publish( + if not routing_key: + if q := RabbitQueue.validate(queue): + routing_key = q.routing + else: + routing_key = self.routing + + headers = self.headers | publish_kwargs.pop("headers", {}) + cmd = RabbitPublishCommand( message, - queue=queue, - exchange=exchange, routing_key=routing_key, - correlation_id=correlation_id, - message_id=message_id, - timestamp=timestamp, + exchange=RabbitExchange.validate(exchange or self.exchange), + correlation_id=correlation_id or gen_cor_id(), + headers=headers, + _publish_type=PublishType.Publish, + **(self.publish_options | self.message_options | publish_kwargs), + ) + + frame: Optional[aiormq.abc.ConfirmationFrameType] = await self._basic_publish( + cmd, _extra_middlewares=(), - **publish_kwargs, ) + return frame @override async def _publish( self, - message: "AioPikaSendableMessage", - queue: Union["RabbitQueue", str, None] = None, - exchange: Union["RabbitExchange", str, None] = None, + cmd: Union["RabbitPublishCommand", "PublishCommand"], *, - routing_key: str = "", - # message args - correlation_id: Optional[str] = None, - message_id: Optional[str] = None, - timestamp: Optional["DateType"] = None, - # publisher specific - _extra_middlewares: Iterable["PublisherMiddleware"] = (), - **publish_kwargs: "Unpack[PublishKwargs]", - ) -> Optional["aiormq.abc.ConfirmationFrameType"]: - assert self._producer, NOT_CONNECTED_YET # nosec B101 - - kwargs: AnyDict = { - "routing_key": routing_key - or self.routing_key - or RabbitQueue.validate(queue or self.queue).routing, - "exchange": exchange or self.exchange.name, - "app_id": self.app_id, - "correlation_id": correlation_id or gen_cor_id(), - "message_id": message_id, - "timestamp": timestamp, - # specific args - "reply_to": self.reply_to, - **self.message_kwargs, - **publish_kwargs, - } - - call: Callable[ - ..., - Awaitable[Optional[aiormq.abc.ConfirmationFrameType]], - ] = self._producer.publish - - for m in chain( - ( - _extra_middlewares - or (m(None).publish_scope for m in self._broker_middlewares) - ), - self._middlewares, - ): - call = partial(m, call) + _extra_middlewares: Iterable["PublisherMiddleware"], + ) -> None: + """This method should be called in subscriber flow only.""" + cmd = RabbitPublishCommand.from_cmd(cmd) + + cmd.destination = self.routing + cmd.reply_to = cmd.reply_to or self.reply_to + cmd.add_headers(self.headers, override=False) - return await call(message, **kwargs) + cmd.timeout = cmd.timeout or self.timeout + + cmd.message_options = {**self.message_options, **cmd.message_options} + cmd.publish_options = {**self.publish_options, **cmd.publish_options} + + await self._basic_publish(cmd, _extra_middlewares=_extra_middlewares) @override async def request( @@ -302,60 +224,27 @@ async def request( "**correlation_id** is a useful option to trace messages.", ), ] = None, - message_id: Annotated[ - Optional[str], - Doc("Arbitrary message id. Generated automatically if not presented."), - ] = None, - timestamp: Annotated[ - Optional["DateType"], - Doc("Message publish timestamp. Generated automatically if not presented."), - ] = None, # publisher specific - _extra_middlewares: Annotated[ - Iterable["PublisherMiddleware"], - Doc("Extra middlewares to wrap publishing process."), - ] = (), **publish_kwargs: "Unpack[RequestPublishKwargs]", ) -> "RabbitMessage": - assert self._producer, NOT_CONNECTED_YET # nosec B101 - - kwargs: AnyDict = { - "routing_key": routing_key - or self.routing_key - or RabbitQueue.validate(queue or self.queue).routing, - "exchange": exchange or self.exchange.name, - "app_id": self.app_id, - "correlation_id": correlation_id or gen_cor_id(), - "message_id": message_id, - "timestamp": timestamp, - # specific args - **self.message_kwargs, - **publish_kwargs, - } - - request: Callable[..., Awaitable[Any]] = self._producer.request - - for pub_m in chain( - ( - _extra_middlewares - or (m(None).publish_scope for m in self._broker_middlewares) - ), - self._middlewares, - ): - request = partial(pub_m, request) - - published_msg = await request( + if not routing_key: + if q := RabbitQueue.validate(queue): + routing_key = q.routing + else: + routing_key = self.routing + + headers = self.headers | publish_kwargs.pop("headers", {}) + cmd = RabbitPublishCommand( message, - **kwargs, + routing_key=routing_key, + exchange=RabbitExchange.validate(exchange or self.exchange), + correlation_id=correlation_id or gen_cor_id(), + headers=headers, + _publish_type=PublishType.Publish, + **(self.publish_options | self.message_options | publish_kwargs), ) - msg: RabbitMessage = await process_msg( - msg=published_msg, - middlewares=self._broker_middlewares, - parser=self._producer._parser, - decoder=self._producer._decoder, - ) - msg._source_type = SourceType.Response + msg: RabbitMessage = await self._basic_request(cmd) return msg def add_prefix(self, prefix: str) -> None: diff --git a/faststream/rabbit/response.py b/faststream/rabbit/response.py index 756c665c4b..560a45bb57 100644 --- a/faststream/rabbit/response.py +++ b/faststream/rabbit/response.py @@ -1,13 +1,15 @@ -from typing import TYPE_CHECKING, Optional +from typing import TYPE_CHECKING, Optional, Union -from typing_extensions import override +from typing_extensions import Unpack, override -from faststream.response import Response +from faststream.rabbit.schemas.exchange import RabbitExchange +from faststream.response import PublishCommand, Response +from faststream.response.publish_type import PublishType if TYPE_CHECKING: - from aio_pika.abc import DateType, TimeoutType + from aio_pika.abc import TimeoutType - from faststream._internal.basic_types import AnyDict + from faststream.rabbit.publisher.options import MessageOptions from faststream.rabbit.types import AioPikaSendableMessage @@ -16,48 +18,91 @@ def __init__( self, body: "AioPikaSendableMessage", *, - headers: Optional["AnyDict"] = None, - correlation_id: Optional[str] = None, - message_id: Optional[str] = None, + timeout: "TimeoutType" = None, mandatory: bool = True, immediate: bool = False, - timeout: "TimeoutType" = None, - persist: Optional[bool] = None, - priority: Optional[int] = None, - message_type: Optional[str] = None, - content_type: Optional[str] = None, - expiration: Optional["DateType"] = None, - content_encoding: Optional[str] = None, + **message_options: Unpack["MessageOptions"], ) -> None: + headers = message_options.pop("headers", {}) + correlation_id = message_options.pop("correlation_id", None) + super().__init__( body=body, headers=headers, correlation_id=correlation_id, ) - self.message_id = message_id - self.mandatory = mandatory - self.immediate = immediate - self.timeout = timeout - self.persist = persist - self.priority = priority - self.message_type = message_type - self.content_type = content_type - self.expiration = expiration - self.content_encoding = content_encoding + self.message_options = message_options + self.publish_options = { + "mandatory": mandatory, + "immediate": immediate, + "timeout": timeout, + } @override - def as_publish_kwargs(self) -> "AnyDict": - return { - **super().as_publish_kwargs(), - "message_id": self.message_id, - "mandatory": self.mandatory, - "immediate": self.immediate, - "timeout": self.timeout, - "persist": self.persist, - "priority": self.priority, - "message_type": self.message_type, - "content_type": self.content_type, - "expiration": self.expiration, - "content_encoding": self.content_encoding, + def as_publish_command(self) -> "RabbitPublishCommand": + return RabbitPublishCommand( + message=self.body, + headers=self.headers, + correlation_id=self.correlation_id, + _publish_type=PublishType.Reply, + # RMQ specific + routing_key="", + **self.publish_options, + **self.message_options, + ) + + +class RabbitPublishCommand(PublishCommand): + def __init__( + self, + message: "AioPikaSendableMessage", + *, + _publish_type: PublishType, + routing_key: str = "", + exchange: Optional[RabbitExchange] = None, + # publish kwargs + mandatory: bool = True, + immediate: bool = False, + timeout: "TimeoutType" = None, + correlation_id: Optional[str] = None, + **message_options: Unpack["MessageOptions"], + ) -> None: + headers = message_options.pop("headers", {}) + reply_to = message_options.pop("reply_to", "") + + super().__init__( + body=message, + destination=routing_key, + correlation_id=correlation_id, + headers=headers, + reply_to=reply_to, + _publish_type=_publish_type, + ) + self.exchange = exchange or RabbitExchange() + + self.timeout = timeout + + self.message_options = message_options + self.publish_options = { + "mandatory": mandatory, + "immediate": immediate, } + + @classmethod + def from_cmd( + cls, + cmd: Union["PublishCommand", "RabbitPublishCommand"], + ) -> "RabbitPublishCommand": + if isinstance(cmd, RabbitPublishCommand): + # NOTE: Should return a copy probably. + return cmd + + return cls( + message=cmd.body, + routing_key=cmd.destination, + correlation_id=cmd.correlation_id, + headers=cmd.headers, + reply_to=cmd.reply_to, + _publish_type=cmd.publish_type, + ) diff --git a/faststream/rabbit/schemas/proto.py b/faststream/rabbit/schemas/proto.py index ca00168745..41045b94fa 100644 --- a/faststream/rabbit/schemas/proto.py +++ b/faststream/rabbit/schemas/proto.py @@ -9,5 +9,5 @@ class BaseRMQInformation(Protocol): virtual_host: str queue: RabbitQueue - exchange: Optional[RabbitExchange] + exchange: RabbitExchange app_id: Optional[str] diff --git a/faststream/rabbit/subscriber/usecase.py b/faststream/rabbit/subscriber/usecase.py index e7fc7e5205..67566d0fb1 100644 --- a/faststream/rabbit/subscriber/usecase.py +++ b/faststream/rabbit/subscriber/usecase.py @@ -9,11 +9,11 @@ import anyio from typing_extensions import override -from faststream._internal.publisher.fake import FakePublisher from faststream._internal.subscriber.usecase import SubscriberUsecase from faststream._internal.subscriber.utils import process_msg from faststream.exceptions import SetupError from faststream.rabbit.parser import AioPikaParser +from faststream.rabbit.publisher.fake import RabbitFakePublisher from faststream.rabbit.schemas import BaseRMQInformation if TYPE_CHECKING: @@ -21,6 +21,7 @@ from fast_depends.dependencies import Depends from faststream._internal.basic_types import AnyDict, LoggerProto + from faststream._internal.publisher.proto import BasePublisherProto from faststream._internal.setup import SetupState from faststream._internal.types import BrokerMiddleware, CustomCallable from faststream.message import StreamMessage @@ -205,17 +206,15 @@ async def get_one( def _make_response_publisher( self, message: "StreamMessage[Any]", - ) -> Sequence["FakePublisher"]: + ) -> Sequence["BasePublisherProto"]: if self._producer is None: return () return ( - FakePublisher( - self._producer.publish, - publish_kwargs={ - "routing_key": message.reply_to, - "app_id": self.app_id, - }, + RabbitFakePublisher( + self._producer, + routing_key=message.reply_to, + app_id=self.app_id, ), ) diff --git a/faststream/rabbit/testing.py b/faststream/rabbit/testing.py index 7d45ed786b..97472fa5fe 100644 --- a/faststream/rabbit/testing.py +++ b/faststream/rabbit/testing.py @@ -25,9 +25,10 @@ ) if TYPE_CHECKING: - from aio_pika.abc import DateType, HeadersType, TimeoutType + from aio_pika.abc import DateType, HeadersType from faststream.rabbit.publisher.specified import SpecificationPublisher + from faststream.rabbit.response import RabbitPublishCommand from faststream.rabbit.subscriber.usecase import LogicSubscriber from faststream.rabbit.types import AioPikaSendableMessage @@ -131,6 +132,7 @@ def build_message( routing = routing_key or que.routing + correlation_id = correlation_id or gen_cor_id() msg = AioPikaParser.encode_message( message=message, persist=persist, @@ -141,7 +143,7 @@ def build_message( priority=priority, correlation_id=correlation_id, expiration=expiration, - message_id=message_id or gen_cor_id(), + message_id=message_id or correlation_id, timestamp=timestamp, message_type=message_type, user_id=user_id, @@ -194,47 +196,17 @@ def __init__(self, broker: RabbitBroker) -> None: @override async def publish( # type: ignore[override] self, - message: "AioPikaSendableMessage", - exchange: Union["RabbitExchange", str, None] = None, - *, - correlation_id: str = "", - routing_key: str = "", - mandatory: bool = True, - immediate: bool = False, - timeout: "TimeoutType" = None, - persist: bool = False, - reply_to: Optional[str] = None, - headers: Optional["HeadersType"] = None, - content_type: Optional[str] = None, - content_encoding: Optional[str] = None, - priority: Optional[int] = None, - expiration: Optional["DateType"] = None, - message_id: Optional[str] = None, - timestamp: Optional["DateType"] = None, - message_type: Optional[str] = None, - user_id: Optional[str] = None, - app_id: Optional[str] = None, + cmd: "RabbitPublishCommand", ) -> None: """Publish a message to a RabbitMQ queue or exchange.""" - exch = RabbitExchange.validate(exchange) - incoming = build_message( - message=message, - exchange=exch, - routing_key=routing_key, - reply_to=reply_to, - app_id=app_id, - user_id=user_id, - message_type=message_type, - headers=headers, - persist=persist, - message_id=message_id, - priority=priority, - content_encoding=content_encoding, - content_type=content_type, - correlation_id=correlation_id, - expiration=expiration, - timestamp=timestamp, + message=cmd.body, + exchange=cmd.exchange, + routing_key=cmd.destination, + correlation_id=cmd.correlation_id, + headers=cmd.headers, + reply_to=cmd.reply_to, + **cmd.message_options, ) for handler in self.broker._subscribers: # pragma: no branch @@ -242,52 +214,23 @@ async def publish( # type: ignore[override] handler, incoming.routing_key, incoming.headers, - exch, + cmd.exchange, ): await self._execute_handler(incoming, handler) @override async def request( # type: ignore[override] self, - message: "AioPikaSendableMessage" = "", - exchange: Union["RabbitExchange", str, None] = None, - *, - correlation_id: str = "", - routing_key: str = "", - mandatory: bool = True, - immediate: bool = False, - timeout: Optional[float] = None, - persist: bool = False, - headers: Optional["HeadersType"] = None, - content_type: Optional[str] = None, - content_encoding: Optional[str] = None, - priority: Optional[int] = None, - expiration: Optional["DateType"] = None, - message_id: Optional[str] = None, - timestamp: Optional["DateType"] = None, - message_type: Optional[str] = None, - user_id: Optional[str] = None, - app_id: Optional[str] = None, + cmd: "RabbitPublishCommand", ) -> "PatchedMessage": """Publish a message to a RabbitMQ queue or exchange.""" - exch = RabbitExchange.validate(exchange) - incoming = build_message( - message=message, - exchange=exch, - routing_key=routing_key, - app_id=app_id, - user_id=user_id, - message_type=message_type, - headers=headers, - persist=persist, - message_id=message_id, - priority=priority, - content_encoding=content_encoding, - content_type=content_type, - correlation_id=correlation_id, - expiration=expiration, - timestamp=timestamp, + message=cmd.body, + exchange=cmd.exchange, + routing_key=cmd.destination, + correlation_id=cmd.correlation_id, + headers=cmd.headers, + **cmd.message_options, ) for handler in self.broker._subscribers: # pragma: no branch @@ -295,9 +238,9 @@ async def request( # type: ignore[override] handler, incoming.routing_key, incoming.headers, - exch, + cmd.exchange, ): - with anyio.fail_after(timeout): + with anyio.fail_after(cmd.timeout): return await self._execute_handler(incoming, handler) raise SubscriberNotFound diff --git a/faststream/redis/annotations.py b/faststream/redis/annotations.py index 4bbbb9b324..b4db951b54 100644 --- a/faststream/redis/annotations.py +++ b/faststream/redis/annotations.py @@ -4,14 +4,12 @@ from faststream._internal.context import Context from faststream.annotations import ContextRepo, Logger -from faststream.params import NoCast from faststream.redis.broker.broker import RedisBroker as RB from faststream.redis.message import UnifyRedisMessage __all__ = ( "ContextRepo", "Logger", - "NoCast", "Redis", "RedisBroker", "RedisMessage", diff --git a/faststream/redis/broker/broker.py b/faststream/redis/broker/broker.py index 76c4265754..4ddcdeac05 100644 --- a/faststream/redis/broker/broker.py +++ b/faststream/redis/broker/broker.py @@ -27,11 +27,13 @@ from faststream.__about__ import __version__ from faststream._internal.broker.broker import BrokerUsecase from faststream._internal.constants import EMPTY -from faststream.exceptions import NOT_CONNECTED_YET +from faststream._internal.context.repository import context from faststream.message import gen_cor_id from faststream.redis.message import UnifyRedisDict from faststream.redis.publisher.producer import RedisFastProducer +from faststream.redis.response import RedisPublishCommand from faststream.redis.security import parse_security +from faststream.response.publish_type import PublishType from .logging import make_redis_logger_state from .registrator import RedisRegistrator @@ -412,9 +414,8 @@ async def publish( # type: ignore[override] Please, use `@broker.publisher(...)` or `broker.publisher(...).publish(...)` instead in a regular way. """ - await super().publish( + cmd = RedisPublishCommand( message, - producer=self._producer, correlation_id=correlation_id or gen_cor_id(), channel=channel, list=list, @@ -422,7 +423,9 @@ async def publish( # type: ignore[override] maxlen=maxlen, reply_to=reply_to, headers=headers, + _publish_type=PublishType.Publish, ) + await super()._basic_publish(cmd, producer=self._producer) @override async def request( # type: ignore[override] @@ -437,9 +440,8 @@ async def request( # type: ignore[override] headers: Optional["AnyDict"] = None, timeout: Optional[float] = 30.0, ) -> "RedisMessage": - msg: RedisMessage = await super().request( + cmd = RedisPublishCommand( message, - producer=self._producer, correlation_id=correlation_id or gen_cor_id(), channel=channel, list=list, @@ -447,12 +449,14 @@ async def request( # type: ignore[override] maxlen=maxlen, headers=headers, timeout=timeout, + _publish_type=PublishType.Request, ) + msg: RedisMessage = await super()._basic_request(cmd, producer=self._producer) return msg async def publish_batch( self, - *msgs: Annotated[ + *messages: Annotated[ "SendableMessage", Doc("Messages bodies to send."), ], @@ -467,22 +471,31 @@ async def publish_batch( "**correlation_id** is a useful option to trace messages.", ), ] = None, + reply_to: Annotated[ + str, + Doc("Reply message destination PubSub object name."), + ] = "", + headers: Annotated[ + Optional["AnyDict"], + Doc("Message headers to store metainformation."), + ] = None, ) -> None: """Publish multiple messages to Redis List by one request.""" - assert self._producer, NOT_CONNECTED_YET # nosec B101 - - correlation_id = correlation_id or gen_cor_id() + cmd = RedisPublishCommand( + *messages, + list=list, + reply_to=reply_to, + headers=headers, + correlation_id=correlation_id or gen_cor_id(), + _publish_type=PublishType.Publish, + ) call: AsyncFunc = self._producer.publish_batch for m in self._middlewares: - call = partial(m(None).publish_scope, call) + call = partial(m(None, context=context).publish_scope, call) - await call( - *msgs, - list=list, - correlation_id=correlation_id, - ) + await self._basic_publish_batch(cmd, producer=self._producer) @override async def ping(self, timeout: Optional[float]) -> bool: diff --git a/faststream/redis/opentelemetry/provider.py b/faststream/redis/opentelemetry/provider.py index ea8c17462c..852cd8ca5f 100644 --- a/faststream/redis/opentelemetry/provider.py +++ b/faststream/redis/opentelemetry/provider.py @@ -9,6 +9,7 @@ if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict from faststream.message import StreamMessage + from faststream.redis.response import RedisPublishCommand class RedisTelemetrySettingsProvider(TelemetrySettingsProvider["AnyDict"]): @@ -42,21 +43,21 @@ def get_consume_destination_name( ) -> str: return self._get_destination(msg.raw_message) - def get_publish_attrs_from_kwargs( + def get_publish_attrs_from_cmd( self, - kwargs: "AnyDict", + cmd: "RedisPublishCommand", ) -> "AnyDict": return { SpanAttributes.MESSAGING_SYSTEM: self.messaging_system, - SpanAttributes.MESSAGING_DESTINATION_NAME: self._get_destination(kwargs), - SpanAttributes.MESSAGING_MESSAGE_CONVERSATION_ID: kwargs["correlation_id"], + SpanAttributes.MESSAGING_DESTINATION_NAME: cmd.destination, + SpanAttributes.MESSAGING_MESSAGE_CONVERSATION_ID: cmd.correlation_id, } def get_publish_destination_name( self, - kwargs: "AnyDict", + cmd: "RedisPublishCommand", ) -> str: - return self._get_destination(kwargs) + return cmd.destination @staticmethod def _get_destination(kwargs: "AnyDict") -> str: diff --git a/faststream/redis/prometheus/middleware.py b/faststream/redis/prometheus/middleware.py index 9e8f5d811f..8c62c745fd 100644 --- a/faststream/redis/prometheus/middleware.py +++ b/faststream/redis/prometheus/middleware.py @@ -1,15 +1,15 @@ from collections.abc import Sequence from typing import TYPE_CHECKING, Optional -from faststream.prometheus.middleware import BasePrometheusMiddleware +from faststream._internal.constants import EMPTY +from faststream.prometheus.middleware import PrometheusMiddleware from faststream.redis.prometheus.provider import settings_provider_factory -from faststream.types import EMPTY if TYPE_CHECKING: from prometheus_client import CollectorRegistry -class RedisPrometheusMiddleware(BasePrometheusMiddleware): +class RedisPrometheusMiddleware(PrometheusMiddleware): def __init__( self, *, diff --git a/faststream/redis/prometheus/provider.py b/faststream/redis/prometheus/provider.py index 6cee2824a0..d34227a15e 100644 --- a/faststream/redis/prometheus/provider.py +++ b/faststream/redis/prometheus/provider.py @@ -7,8 +7,9 @@ ) if TYPE_CHECKING: - from faststream.broker.message import StreamMessage - from faststream.types import AnyDict + from faststream._internal.basic_types import AnyDict + from faststream.message.message import StreamMessage + from faststream.redis.response import RedisPublishCommand class BaseRedisMetricsSettingsProvider(MetricsSettingsProvider["AnyDict"]): @@ -17,15 +18,11 @@ class BaseRedisMetricsSettingsProvider(MetricsSettingsProvider["AnyDict"]): def __init__(self) -> None: self.messaging_system = "redis" - def get_publish_destination_name_from_kwargs( + def get_publish_destination_name_from_cmd( self, - kwargs: "AnyDict", + cmd: "RedisPublishCommand", ) -> str: - return self._get_destination(kwargs) - - @staticmethod - def _get_destination(kwargs: "AnyDict") -> str: - return kwargs.get("channel") or kwargs.get("list") or kwargs.get("stream") or "" + return cmd.destination class RedisMetricsSettingsProvider(BaseRedisMetricsSettingsProvider): @@ -34,7 +31,7 @@ def get_consume_attrs_from_message( msg: "StreamMessage[AnyDict]", ) -> ConsumeAttrs: return { - "destination_name": self._get_destination(msg.raw_message), + "destination_name": _get_destination(msg.raw_message), "message_size": len(msg.body), "messages_count": 1, } @@ -46,7 +43,7 @@ def get_consume_attrs_from_message( msg: "StreamMessage[AnyDict]", ) -> ConsumeAttrs: return { - "destination_name": self._get_destination(msg.raw_message), + "destination_name": _get_destination(msg.raw_message), "message_size": len(msg.body), "messages_count": len(cast(Sized, msg._decoded_body)), } @@ -61,3 +58,7 @@ def settings_provider_factory( if msg is not None and msg.get("type", "").startswith("b"): return BatchRedisMetricsSettingsProvider() return RedisMetricsSettingsProvider() + + +def _get_destination(kwargs: "AnyDict") -> str: + return kwargs.get("channel") or kwargs.get("list") or kwargs.get("stream") or "" diff --git a/faststream/redis/publisher/fake.py b/faststream/redis/publisher/fake.py new file mode 100644 index 0000000000..2fd055e6f2 --- /dev/null +++ b/faststream/redis/publisher/fake.py @@ -0,0 +1,27 @@ +from typing import TYPE_CHECKING, Union + +from faststream._internal.publisher.fake import FakePublisher +from faststream.redis.response import RedisPublishCommand + +if TYPE_CHECKING: + from faststream._internal.publisher.proto import ProducerProto + from faststream.response.response import PublishCommand + + +class RedisFakePublisher(FakePublisher): + """Publisher Interface implementation to use as RPC or REPLY TO answer publisher.""" + + def __init__( + self, + producer: "ProducerProto", + channel: str, + ) -> None: + super().__init__(producer=producer) + self.channel = channel + + def patch_command( + self, cmd: Union["PublishCommand", "RedisPublishCommand"] + ) -> "RedisPublishCommand": + real_cmd = RedisPublishCommand.from_cmd(cmd) + real_cmd.destination = self.channel + return real_cmd diff --git a/faststream/redis/publisher/producer.py b/faststream/redis/publisher/producer.py index 8c196e1a71..57afef2d31 100644 --- a/faststream/redis/publisher/producer.py +++ b/faststream/redis/publisher/producer.py @@ -6,15 +6,13 @@ from faststream._internal.publisher.proto import ProducerProto from faststream._internal.subscriber.utils import resolve_custom_func from faststream._internal.utils.nuid import NUID -from faststream.exceptions import SetupError from faststream.redis.message import DATA_KEY from faststream.redis.parser import RawMessage, RedisPubSubParser -from faststream.redis.schemas import INCORRECT_SETUP_MSG +from faststream.redis.response import DestinationType, RedisPublishCommand if TYPE_CHECKING: from redis.asyncio.client import Redis - from faststream._internal.basic_types import AnyDict, SendableMessage from faststream._internal.types import ( AsyncCallable, CustomCallable, @@ -49,93 +47,47 @@ def __init__( @override async def publish( # type: ignore[override] self, - message: "SendableMessage", - *, - correlation_id: str, - channel: Optional[str] = None, - list: Optional[str] = None, - stream: Optional[str] = None, - maxlen: Optional[int] = None, - headers: Optional["AnyDict"] = None, - reply_to: str = "", + cmd: "RedisPublishCommand", ) -> None: - if not any((channel, list, stream)): - raise SetupError(INCORRECT_SETUP_MSG) - msg = RawMessage.encode( - message=message, - reply_to=reply_to, - headers=headers, - correlation_id=correlation_id, + message=cmd.body, + reply_to=cmd.reply_to, + headers=cmd.headers, + correlation_id=cmd.correlation_id, ) - if channel is not None: - await self._connection.publish(channel, msg) - elif list is not None: - await self._connection.rpush(list, msg) - elif stream is not None: - await self._connection.xadd( - name=stream, - fields={DATA_KEY: msg}, - maxlen=maxlen, - ) - else: - msg = "unreachable" - raise AssertionError(msg) + await self.__publish(msg, cmd) @override async def request( # type: ignore[override] self, - message: "SendableMessage", - *, - correlation_id: str, - channel: Optional[str] = None, - list: Optional[str] = None, - stream: Optional[str] = None, - maxlen: Optional[int] = None, - headers: Optional["AnyDict"] = None, - timeout: Optional[float] = 30.0, + cmd: "RedisPublishCommand", ) -> "Any": - if not any((channel, list, stream)): - raise SetupError(INCORRECT_SETUP_MSG) - nuid = NUID() reply_to = str(nuid.next(), "utf-8") psub = self._connection.pubsub() await psub.subscribe(reply_to) msg = RawMessage.encode( - message=message, + message=cmd.body, reply_to=reply_to, - headers=headers, - correlation_id=correlation_id, + headers=cmd.headers, + correlation_id=cmd.correlation_id, ) - if channel is not None: - await self._connection.publish(channel, msg) - elif list is not None: - await self._connection.rpush(list, msg) - elif stream is not None: - await self._connection.xadd( - name=stream, - fields={DATA_KEY: msg}, - maxlen=maxlen, - ) - else: - msg = "unreachable" - raise AssertionError(msg) + await self.__publish(msg, cmd) - with anyio.fail_after(timeout) as scope: + with anyio.fail_after(cmd.timeout) as scope: # skip subscribe message await psub.get_message( ignore_subscribe_messages=True, - timeout=timeout or 0.0, + timeout=cmd.timeout or 0.0, ) # get real response response_msg = await psub.get_message( ignore_subscribe_messages=True, - timeout=timeout or 0.0, + timeout=cmd.timeout or 0.0, ) await psub.unsubscribe() @@ -146,20 +98,33 @@ async def request( # type: ignore[override] return response_msg + @override async def publish_batch( self, - *msgs: "SendableMessage", - list: str, - correlation_id: str, - headers: Optional["AnyDict"] = None, + cmd: "RedisPublishCommand", ) -> None: - batch = ( + batch = [ RawMessage.encode( message=msg, - correlation_id=correlation_id, - reply_to=None, - headers=headers, + correlation_id=cmd.correlation_id, + reply_to=cmd.reply_to, + headers=cmd.headers, ) - for msg in msgs - ) - await self._connection.rpush(list, *batch) + for msg in cmd.batch_bodies + ] + await self._connection.rpush(cmd.destination, *batch) + + async def __publish(self, msg: bytes, cmd: "RedisPublishCommand") -> None: + if cmd.destination_type is DestinationType.Channel: + await self._connection.publish(cmd.destination, msg) + elif cmd.destination_type is DestinationType.List: + await self._connection.rpush(cmd.destination, msg) + elif cmd.destination_type is DestinationType.Stream: + await self._connection.xadd( + name=cmd.destination, + fields={DATA_KEY: msg}, + maxlen=cmd.maxlen, + ) + else: + error_msg = "unreachable" + raise AssertionError(error_msg) diff --git a/faststream/redis/publisher/usecase.py b/faststream/redis/publisher/usecase.py index 2012f0a85e..34e6f934c6 100644 --- a/faststream/redis/publisher/usecase.py +++ b/faststream/redis/publisher/usecase.py @@ -1,24 +1,23 @@ from abc import abstractmethod -from collections.abc import Awaitable, Iterable +from collections.abc import Iterable from copy import deepcopy -from functools import partial -from itertools import chain -from typing import TYPE_CHECKING, Annotated, Any, Callable, Optional +from typing import TYPE_CHECKING, Annotated, Any, Optional, Union from typing_extensions import Doc, override from faststream._internal.publisher.usecase import PublisherUsecase -from faststream._internal.subscriber.utils import process_msg -from faststream.exceptions import NOT_CONNECTED_YET -from faststream.message import SourceType, gen_cor_id +from faststream.message import gen_cor_id from faststream.redis.message import UnifyRedisDict -from faststream.redis.schemas import ListSub, PubSub, StreamSub +from faststream.redis.response import RedisPublishCommand +from faststream.response.publish_type import PublishType if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict, SendableMessage from faststream._internal.types import BrokerMiddleware, PublisherMiddleware from faststream.redis.message import RedisMessage from faststream.redis.publisher.producer import RedisFastProducer + from faststream.redis.schemas import ListSub, PubSub, StreamSub + from faststream.response.response import PublishCommand class LogicPublisher(PublisherUsecase[UnifyRedisDict]): @@ -51,7 +50,7 @@ def __init__( ) self.reply_to = reply_to - self.headers = headers + self.headers = headers or {} self._producer = None @@ -128,56 +127,33 @@ async def publish( "**correlation_id** is a useful option to trace messages.", ), ] = None, - **kwargs: Any, # option to suppress maxlen ) -> None: - return await self._publish( + cmd = RedisPublishCommand( message, - channel=channel, - reply_to=reply_to, - headers=headers, - correlation_id=correlation_id, - _extra_middlewares=(), - **kwargs, + channel=channel or self.channel.name, + reply_to=reply_to or self.reply_to, + headers=self.headers | (headers or {}), + correlation_id=correlation_id or gen_cor_id(), + _publish_type=PublishType.Publish, ) + await self._basic_publish(cmd, _extra_middlewares=()) @override async def _publish( self, - message: "SendableMessage" = None, - channel: Optional[str] = None, - reply_to: str = "", - headers: Optional["AnyDict"] = None, - correlation_id: Optional[str] = None, - # publisher specific - _extra_middlewares: Iterable["PublisherMiddleware"] = (), - **kwargs: Any, # option to suppress maxlen + cmd: Union["PublishCommand", "RedisPublishCommand"], + *, + _extra_middlewares: Iterable["PublisherMiddleware"], ) -> None: - assert self._producer, NOT_CONNECTED_YET # nosec B101 + """This method should be called in subscriber flow only.""" + cmd = RedisPublishCommand.from_cmd(cmd) - channel_sub = PubSub.validate(channel or self.channel) - reply_to = reply_to or self.reply_to - headers = headers or self.headers - correlation_id = correlation_id or gen_cor_id() + cmd.set_destination(channel=self.channel.name) - call: Callable[..., Awaitable[None]] = self._producer.publish - - for m in chain( - ( - _extra_middlewares - or (m(None).publish_scope for m in self._broker_middlewares) - ), - self._middlewares, - ): - call = partial(m, call) + cmd.add_headers(self.headers, override=False) + cmd.reply_to = cmd.reply_to or self.reply_to - await call( - message, - channel=channel_sub.name, - # basic args - reply_to=reply_to, - headers=headers, - correlation_id=correlation_id, - ) + await self._basic_publish(cmd, _extra_middlewares=_extra_middlewares) @override async def request( @@ -206,44 +182,17 @@ async def request( Optional[float], Doc("RPC reply waiting time."), ] = 30.0, - # publisher specific - _extra_middlewares: Annotated[ - Iterable["PublisherMiddleware"], - Doc("Extra middlewares to wrap publishing process."), - ] = (), ) -> "RedisMessage": - assert self._producer, NOT_CONNECTED_YET # nosec B101 - - kwargs = { - "channel": PubSub.validate(channel or self.channel).name, - # basic args - "headers": headers or self.headers, - "correlation_id": correlation_id or gen_cor_id(), - "timeout": timeout, - } - request: Callable[..., Awaitable[Any]] = self._producer.request - - for pub_m in chain( - ( - _extra_middlewares - or (m(None).publish_scope for m in self._broker_middlewares) - ), - self._middlewares, - ): - request = partial(pub_m, request) - - published_msg = await request( + cmd = RedisPublishCommand( message, - **kwargs, + channel=channel or self.channel.name, + headers=self.headers | (headers or {}), + correlation_id=correlation_id or gen_cor_id(), + _publish_type=PublishType.Request, + timeout=timeout, ) - msg: RedisMessage = await process_msg( - msg=published_msg, - middlewares=self._broker_middlewares, - parser=self._producer._parser, - decoder=self._producer._decoder, - ) - msg._source_type = SourceType.Response + msg: RedisMessage = await self._basic_request(cmd) return msg @@ -315,56 +264,34 @@ async def publish( "**correlation_id** is a useful option to trace messages.", ), ] = None, - # publisher specific - **kwargs: Any, # option to suppress maxlen ) -> None: - return await self._publish( + cmd = RedisPublishCommand( message, - list=list, - reply_to=reply_to, - headers=headers, - correlation_id=correlation_id, - _extra_middlewares=(), - **kwargs, + list=list or self.list.name, + reply_to=reply_to or self.reply_to, + headers=self.headers | (headers or {}), + correlation_id=correlation_id or gen_cor_id(), + _publish_type=PublishType.Publish, ) + return await self._basic_publish(cmd, _extra_middlewares=()) + @override async def _publish( self, - message: "SendableMessage" = None, - list: Optional[str] = None, - reply_to: str = "", - headers: Optional["AnyDict"] = None, - correlation_id: Optional[str] = None, - # publisher specific - _extra_middlewares: Iterable["PublisherMiddleware"] = (), - **kwargs: Any, # option to suppress maxlen + cmd: Union["PublishCommand", "RedisPublishCommand"], + *, + _extra_middlewares: Iterable["PublisherMiddleware"], ) -> None: - assert self._producer, NOT_CONNECTED_YET # nosec B101 - - list_sub = ListSub.validate(list or self.list) - reply_to = reply_to or self.reply_to - correlation_id = correlation_id or gen_cor_id() + """This method should be called in subscriber flow only.""" + cmd = RedisPublishCommand.from_cmd(cmd) - call: Callable[..., Awaitable[None]] = self._producer.publish + cmd.set_destination(list=self.list.name) - for m in chain( - ( - _extra_middlewares - or (m(None).publish_scope for m in self._broker_middlewares) - ), - self._middlewares, - ): - call = partial(m, call) + cmd.add_headers(self.headers, override=False) + cmd.reply_to = cmd.reply_to or self.reply_to - await call( - message, - list=list_sub.name, - # basic args - reply_to=reply_to, - headers=headers or self.headers, - correlation_id=correlation_id, - ) + await self._basic_publish(cmd, _extra_middlewares=_extra_middlewares) @override async def request( @@ -393,45 +320,17 @@ async def request( Optional[float], Doc("RPC reply waiting time."), ] = 30.0, - # publisher specific - _extra_middlewares: Annotated[ - Iterable["PublisherMiddleware"], - Doc("Extra middlewares to wrap publishing process."), - ] = (), ) -> "RedisMessage": - assert self._producer, NOT_CONNECTED_YET # nosec B101 - - kwargs = { - "list": ListSub.validate(list or self.list).name, - # basic args - "headers": headers or self.headers, - "correlation_id": correlation_id or gen_cor_id(), - "timeout": timeout, - } - - request: Callable[..., Awaitable[Any]] = self._producer.request - - for pub_m in chain( - ( - _extra_middlewares - or (m(None).publish_scope for m in self._broker_middlewares) - ), - self._middlewares, - ): - request = partial(pub_m, request) - - published_msg = await request( + cmd = RedisPublishCommand( message, - **kwargs, + list=list or self.list.name, + headers=self.headers | (headers or {}), + correlation_id=correlation_id or gen_cor_id(), + _publish_type=PublishType.Request, + timeout=timeout, ) - msg: RedisMessage = await process_msg( - msg=published_msg, - middlewares=self._broker_middlewares, - parser=self._producer._parser, - decoder=self._producer._decoder, - ) - msg._source_type = SourceType.Response + msg: RedisMessage = await self._basic_request(cmd) return msg @@ -439,69 +338,57 @@ class ListBatchPublisher(ListPublisher): @override async def publish( # type: ignore[override] self, - message: Annotated[ - Iterable["SendableMessage"], - Doc("Message body to send."), - ] = (), + *messages: Annotated[ + "SendableMessage", + Doc("Messages bodies to send."), + ], list: Annotated[ - Optional[str], - Doc("Redis List object name to send message."), - ] = None, - *, + str, + Doc("Redis List object name to send messages."), + ], correlation_id: Annotated[ Optional[str], - Doc("Has no real effect. Option to be compatible with original protocol."), + Doc( + "Manual message **correlation_id** setter. " + "**correlation_id** is a useful option to trace messages.", + ), ] = None, + reply_to: Annotated[ + str, + Doc("Reply message destination PubSub object name."), + ] = "", headers: Annotated[ Optional["AnyDict"], Doc("Message headers to store metainformation."), ] = None, - # publisher specific - **kwargs: Any, # option to suppress maxlen ) -> None: - return await self._publish( - message, - list=list, - correlation_id=correlation_id, - headers=headers, - _extra_middlewares=(), - **kwargs, + cmd = RedisPublishCommand( + *messages, + list=list or self.list.name, + reply_to=reply_to or self.reply_to, + headers=self.headers | (headers or {}), + correlation_id=correlation_id or gen_cor_id(), + _publish_type=PublishType.Publish, ) + await self._basic_publish_batch(cmd, _extra_middlewares=()) + @override async def _publish( # type: ignore[override] self, - message: "SendableMessage" = (), - list: Optional[str] = None, + cmd: Union["PublishCommand", "RedisPublishCommand"], *, - correlation_id: Optional[str] = None, - headers: Optional["AnyDict"] = None, - # publisher specific - _extra_middlewares: Iterable["PublisherMiddleware"] = (), - **kwargs: Any, # option to suppress maxlen + _extra_middlewares: Iterable["PublisherMiddleware"], ) -> None: - assert self._producer, NOT_CONNECTED_YET # nosec B101 + """This method should be called in subscriber flow only.""" + cmd = RedisPublishCommand.from_cmd(cmd, batch=True) - list_sub = ListSub.validate(list or self.list) - correlation_id = correlation_id or gen_cor_id() + cmd.set_destination(list=self.list.name) - call: Callable[..., Awaitable[None]] = self._producer.publish_batch + cmd.add_headers(self.headers, override=False) + cmd.reply_to = cmd.reply_to or self.reply_to - for m in chain( - ( - _extra_middlewares - or (m(None).publish_scope for m in self._broker_middlewares) - ), - self._middlewares, - ): - call = partial(m, call) - - await call( - *message, - list=list_sub.name, - correlation_id=correlation_id, - headers=headers or self.headers, - ) + await self._basic_publish_batch(cmd, _extra_middlewares=_extra_middlewares) class StreamPublisher(LogicPublisher): @@ -581,57 +468,35 @@ async def publish( ), ] = None, ) -> None: - return await self._publish( + cmd = RedisPublishCommand( message, - stream=stream, - reply_to=reply_to, - headers=headers, - correlation_id=correlation_id, - maxlen=maxlen, - _extra_middlewares=(), + stream=stream or self.stream.name, + reply_to=reply_to or self.reply_to, + headers=self.headers | (headers or {}), + correlation_id=correlation_id or gen_cor_id(), + maxlen=maxlen or self.stream.maxlen, + _publish_type=PublishType.Publish, ) + return await self._basic_publish(cmd, _extra_middlewares=()) + @override async def _publish( self, - message: "SendableMessage" = None, - stream: Optional[str] = None, - reply_to: str = "", - headers: Optional["AnyDict"] = None, - correlation_id: Optional[str] = None, + cmd: Union["PublishCommand", "RedisPublishCommand"], *, - maxlen: Optional[int] = None, - # publisher specific - _extra_middlewares: Iterable["PublisherMiddleware"] = (), + _extra_middlewares: Iterable["PublisherMiddleware"], ) -> None: - assert self._producer, NOT_CONNECTED_YET # nosec B101 + """This method should be called in subscriber flow only.""" + cmd = RedisPublishCommand.from_cmd(cmd) - stream_sub = StreamSub.validate(stream or self.stream) - maxlen = maxlen or stream_sub.maxlen - reply_to = reply_to or self.reply_to - headers = headers or self.headers - correlation_id = correlation_id or gen_cor_id() + cmd.set_destination(stream=self.stream.name) - call: Callable[..., Awaitable[None]] = self._producer.publish + cmd.add_headers(self.headers, override=False) + cmd.reply_to = cmd.reply_to or self.reply_to + cmd.maxlen = self.stream.maxlen - for m in chain( - ( - _extra_middlewares - or (m(None).publish_scope for m in self._broker_middlewares) - ), - self._middlewares, - ): - call = partial(m, call) - - await call( - message, - stream=stream_sub.name, - maxlen=maxlen, - # basic args - reply_to=reply_to, - headers=headers, - correlation_id=correlation_id, - ) + await self._basic_publish(cmd, _extra_middlewares=_extra_middlewares) @override async def request( @@ -667,43 +532,16 @@ async def request( Optional[float], Doc("RPC reply waiting time."), ] = 30.0, - # publisher specific - _extra_middlewares: Annotated[ - Iterable["PublisherMiddleware"], - Doc("Extra middlewares to wrap publishing process."), - ] = (), ) -> "RedisMessage": - assert self._producer, NOT_CONNECTED_YET # nosec B101 - - kwargs = { - "stream": StreamSub.validate(stream or self.stream).name, - # basic args - "headers": headers or self.headers, - "correlation_id": correlation_id or gen_cor_id(), - "timeout": timeout, - } - - request: Callable[..., Awaitable[Any]] = self._producer.request - - for pub_m in chain( - ( - _extra_middlewares - or (m(None).publish_scope for m in self._broker_middlewares) - ), - self._middlewares, - ): - request = partial(pub_m, request) - - published_msg = await request( + cmd = RedisPublishCommand( message, - **kwargs, + stream=stream or self.stream.name, + headers=self.headers | (headers or {}), + correlation_id=correlation_id or gen_cor_id(), + _publish_type=PublishType.Request, + maxlen=maxlen or self.stream.maxlen, + timeout=timeout, ) - msg: RedisMessage = await process_msg( - msg=published_msg, - middlewares=self._broker_middlewares, - parser=self._producer._parser, - decoder=self._producer._decoder, - ) - msg._source_type = SourceType.Response + msg: RedisMessage = await self._basic_request(cmd) return msg diff --git a/faststream/redis/response.py b/faststream/redis/response.py index b5f4a231f9..a0b830b6c9 100644 --- a/faststream/redis/response.py +++ b/faststream/redis/response.py @@ -1,13 +1,24 @@ -from typing import TYPE_CHECKING, Optional +from collections.abc import Sequence +from enum import Enum +from typing import TYPE_CHECKING, Optional, Union from typing_extensions import override -from faststream.response import Response +from faststream.exceptions import SetupError +from faststream.redis.schemas import INCORRECT_SETUP_MSG +from faststream.response.publish_type import PublishType +from faststream.response.response import PublishCommand, Response if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict, SendableMessage +class DestinationType(str, Enum): + Channel = "channel" + List = "list" + Stream = "stream" + + class RedisResponse(Response): def __init__( self, @@ -25,8 +36,107 @@ def __init__( self.maxlen = maxlen @override - def as_publish_kwargs(self) -> "AnyDict": - return { - **super().as_publish_kwargs(), - "maxlen": self.maxlen, - } + def as_publish_command(self) -> "RedisPublishCommand": + return RedisPublishCommand( + self.body, + headers=self.headers, + correlation_id=self.correlation_id, + _publish_type=PublishType.Reply, + # Kafka specific + channel="fake-channel", # it will be replaced by reply-sender + maxlen=self.maxlen, + ) + + +class RedisPublishCommand(PublishCommand): + destination_type: DestinationType + + def __init__( + self, + message: "SendableMessage", + /, + *messages: "SendableMessage", + _publish_type: "PublishType", + correlation_id: Optional[str] = None, + channel: Optional[str] = None, + list: Optional[str] = None, + stream: Optional[str] = None, + maxlen: Optional[int] = None, + headers: Optional["AnyDict"] = None, + reply_to: str = "", + timeout: Optional[float] = 30.0, + ) -> None: + super().__init__( + message, + _publish_type=_publish_type, + correlation_id=correlation_id, + reply_to=reply_to, + destination="", + headers=headers, + ) + self.extra_bodies = messages + + self.set_destination( + channel=channel, + list=list, + stream=stream, + ) + + # Stream option + self.maxlen = maxlen + + # Request option + self.timeout = timeout + + def set_destination( + self, + *, + channel: Optional[str] = None, + list: Optional[str] = None, + stream: Optional[str] = None, + ) -> str: + if channel is not None: + self.destination_type = DestinationType.Channel + self.destination = channel + elif list is not None: + self.destination_type = DestinationType.List + self.destination = list + elif stream is not None: + self.destination_type = DestinationType.Stream + self.destination = stream + else: + raise SetupError(INCORRECT_SETUP_MSG) + + @property + def batch_bodies(self) -> tuple["SendableMessage", ...]: + if self.body: + return (self.body, *self.extra_bodies) + return self.extra_bodies + + @classmethod + def from_cmd( + cls, + cmd: Union["PublishCommand", "RedisPublishCommand"], + *, + batch: bool = False, + ) -> "RedisPublishCommand": + if isinstance(cmd, RedisPublishCommand): + # NOTE: Should return a copy probably. + return cmd + + body, extra_bodies = cmd.body, [] + if batch and isinstance(body, Sequence) and not isinstance(body, str): + if body: + body, extra_bodies = body[0], body[1:] + else: + body = None + + return cls( + body, + *extra_bodies, + channel=cmd.destination, + correlation_id=cmd.correlation_id, + headers=cmd.headers, + reply_to=cmd.reply_to, + _publish_type=cmd.publish_type, + ) diff --git a/faststream/redis/schemas/proto.py b/faststream/redis/schemas/proto.py index 1b4a5526f6..2644432dcd 100644 --- a/faststream/redis/schemas/proto.py +++ b/faststream/redis/schemas/proto.py @@ -23,7 +23,7 @@ def validate_options( channel: Union["PubSub", str, None], list: Union["ListSub", str, None], stream: Union["StreamSub", str, None], -) -> None: +) -> str: if all((channel, list)): msg = "You can't use `PubSub` and `ListSub` both" raise SetupError(msg) @@ -33,3 +33,4 @@ def validate_options( if all((list, stream)): msg = "You can't use `ListSub` and `StreamSub` both" raise SetupError(msg) + return channel or list or stream diff --git a/faststream/redis/subscriber/usecase.py b/faststream/redis/subscriber/usecase.py index 6ecc4793c6..769aaf34e5 100644 --- a/faststream/redis/subscriber/usecase.py +++ b/faststream/redis/subscriber/usecase.py @@ -19,7 +19,6 @@ from redis.exceptions import ResponseError from typing_extensions import TypeAlias, override -from faststream._internal.publisher.fake import FakePublisher from faststream._internal.subscriber.usecase import SubscriberUsecase from faststream._internal.subscriber.utils import process_msg from faststream.redis.message import ( @@ -40,13 +39,14 @@ RedisPubSubParser, RedisStreamParser, ) +from faststream.redis.publisher.fake import RedisFakePublisher from faststream.redis.schemas import ListSub, PubSub, StreamSub if TYPE_CHECKING: from fast_depends.dependencies import Depends from faststream._internal.basic_types import AnyDict, LoggerProto - from faststream._internal.publisher.proto import ProducerProto + from faststream._internal.publisher.proto import BasePublisherProto, ProducerProto from faststream._internal.setup import SetupState from faststream._internal.types import ( AsyncCallable, @@ -130,16 +130,14 @@ def _setup( # type: ignore[override] def _make_response_publisher( self, message: "BrokerStreamMessage[UnifyRedisDict]", - ) -> Sequence[FakePublisher]: + ) -> Sequence["BasePublisherProto"]: if self._producer is None: return () return ( - FakePublisher( - self._producer.publish, - publish_kwargs={ - "channel": message.reply_to, - }, + RedisFakePublisher( + self._producer, + channel=message.reply_to, ), ) diff --git a/faststream/redis/testing.py b/faststream/redis/testing.py index 48205dbe08..2237af768d 100644 --- a/faststream/redis/testing.py +++ b/faststream/redis/testing.py @@ -28,6 +28,7 @@ ) from faststream.redis.parser import RawMessage, RedisPubSubParser from faststream.redis.publisher.producer import RedisFastProducer +from faststream.redis.response import DestinationType, RedisPublishCommand from faststream.redis.schemas import INCORRECT_SETUP_MSG from faststream.redis.subscriber.usecase import ( ChannelSubscriber, @@ -108,26 +109,16 @@ def __init__(self, broker: RedisBroker) -> None: @override async def publish( self, - message: "SendableMessage", - *, - channel: Optional[str] = None, - list: Optional[str] = None, - stream: Optional[str] = None, - maxlen: Optional[int] = None, - headers: Optional["AnyDict"] = None, - reply_to: str = "", - correlation_id: Optional[str] = None, + cmd: "RedisPublishCommand", ) -> None: - correlation_id = correlation_id or gen_cor_id() - body = build_message( - message=message, - reply_to=reply_to, - correlation_id=correlation_id, - headers=headers, + message=cmd.body, + reply_to=cmd.reply_to, + correlation_id=cmd.correlation_id or gen_cor_id(), + headers=cmd.headers, ) - destination = _make_destionation_kwargs(channel, list, stream) + destination = _make_destionation_kwargs(cmd) visitors = (ChannelVisitor(), ListVisitor(), StreamVisitor()) for handler in self.broker._subscribers: # pragma: no branch @@ -144,25 +135,15 @@ async def publish( @override async def request( # type: ignore[override] self, - message: "SendableMessage", - *, - correlation_id: str, - channel: Optional[str] = None, - list: Optional[str] = None, - stream: Optional[str] = None, - maxlen: Optional[int] = None, - headers: Optional["AnyDict"] = None, - timeout: Optional[float] = 30.0, + cmd: "RedisPublishCommand", ) -> "PubSubMessage": - correlation_id = correlation_id or gen_cor_id() - body = build_message( - message=message, - correlation_id=correlation_id, - headers=headers, + message=cmd.body, + correlation_id=cmd.correlation_id or gen_cor_id(), + headers=cmd.headers, ) - destination = _make_destionation_kwargs(channel, list, stream) + destination = _make_destionation_kwargs(cmd) visitors = (ChannelVisitor(), ListVisitor(), StreamVisitor()) for handler in self.broker._subscribers: # pragma: no branch @@ -174,34 +155,33 @@ async def request( # type: ignore[override] handler, # type: ignore[arg-type] ) - with anyio.fail_after(timeout): + with anyio.fail_after(cmd.timeout): return await self._execute_handler(msg, handler) raise SubscriberNotFound async def publish_batch( self, - *msgs: "SendableMessage", - list: str, - headers: Optional["AnyDict"] = None, - correlation_id: Optional[str] = None, + cmd: "RedisPublishCommand", ) -> None: data_to_send = [ build_message( m, - correlation_id=correlation_id or gen_cor_id(), - headers=headers, + correlation_id=cmd.correlation_id or gen_cor_id(), + headers=cmd.headers, ) - for m in msgs + for m in cmd.batch_bodies ] visitor = ListVisitor() for handler in self.broker._subscribers: # pragma: no branch - if visitor.visit(list=list, sub=handler): + if visitor.visit(list=cmd.destination, sub=handler): casted_handler = cast(_ListHandlerMixin, handler) if casted_handler.list_sub.batch: - msg = visitor.get_message(list, data_to_send, casted_handler) + msg = visitor.get_message( + cmd.destination, data_to_send, casted_handler + ) await self._execute_handler(msg, handler) @@ -375,18 +355,14 @@ class _DestinationKwargs(TypedDict, total=False): stream: str -def _make_destionation_kwargs( - channel: Optional[str], - list: Optional[str], - stream: Optional[str], -) -> _DestinationKwargs: +def _make_destionation_kwargs(cmd: RedisPublishCommand) -> _DestinationKwargs: destination: _DestinationKwargs = {} - if channel: - destination["channel"] = channel - if list: - destination["list"] = list - if stream: - destination["stream"] = stream + if cmd.destination_type is DestinationType.Channel: + destination["channel"] = cmd.destination + if cmd.destination_type is DestinationType.List: + destination["list"] = cmd.destination + if cmd.destination_type is DestinationType.Stream: + destination["stream"] = cmd.destination if len(destination) != 1: raise SetupError(INCORRECT_SETUP_MSG) diff --git a/faststream/response/__init__.py b/faststream/response/__init__.py index 686ec1dc50..9a0cc2410e 100644 --- a/faststream/response/__init__.py +++ b/faststream/response/__init__.py @@ -1,7 +1,10 @@ -from .response import Response +from .publish_type import PublishType +from .response import PublishCommand, Response from .utils import ensure_response __all__ = ( + "PublishCommand", + "PublishType", "Response", "ensure_response", ) diff --git a/faststream/response/publish_type.py b/faststream/response/publish_type.py new file mode 100644 index 0000000000..b837b91632 --- /dev/null +++ b/faststream/response/publish_type.py @@ -0,0 +1,12 @@ +from enum import Enum + + +class PublishType(str, Enum): + Publish = "Publish" + """Regular `broker/publisher.publish(...)` call.""" + + Reply = "Reply" + """Response to RPC/Reply-To request.""" + + Request = "Request" + """RPC request call.""" diff --git a/faststream/response/response.py b/faststream/response/response.py index cbb338bed7..09136c8a28 100644 --- a/faststream/response/response.py +++ b/faststream/response/response.py @@ -1,5 +1,7 @@ from typing import TYPE_CHECKING, Any, Optional +from .publish_type import PublishType + if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict @@ -17,19 +19,50 @@ def __init__( self.headers = headers or {} self.correlation_id = correlation_id + def as_publish_command(self) -> "PublishCommand": + return PublishCommand( + body=self.body, + headers=self.headers, + correlation_id=self.correlation_id, + _publish_type=PublishType.Reply, + ) + + +class PublishCommand(Response): + def __init__( + self, + body: Any, + *, + _publish_type: PublishType, + reply_to: str = "", + destination: str = "", + correlation_id: Optional[str] = None, + headers: Optional["AnyDict"] = None, + ) -> None: + super().__init__( + body, + headers=headers, + correlation_id=correlation_id, + ) + + self.destination = destination + self.reply_to = reply_to + + self.publish_type = _publish_type + + @property + def batch_bodies(self) -> tuple["Any", ...]: + if self.body: + return (self.body,) + return () + def add_headers( self, - extra_headers: "AnyDict", + headers: "AnyDict", *, override: bool = True, ) -> None: if override: - self.headers = {**self.headers, **extra_headers} + self.headers |= headers else: - self.headers = {**extra_headers, **self.headers} - - def as_publish_kwargs(self) -> "AnyDict": - return { - "headers": self.headers, - "correlation_id": self.correlation_id, - } + self.headers = headers | self.headers diff --git a/tests/a_docs/getting_started/subscription/test_annotated.py b/tests/a_docs/getting_started/subscription/test_annotated.py index d3b608277c..07c2e841a2 100644 --- a/tests/a_docs/getting_started/subscription/test_annotated.py +++ b/tests/a_docs/getting_started/subscription/test_annotated.py @@ -1,7 +1,8 @@ -from typing import Any, TypeAlias +from typing import Any import pytest from pydantic import ValidationError +from typing_extensions import TypeAlias from faststream._internal.broker.broker import BrokerUsecase from faststream._internal.subscriber.usecase import SubscriberUsecase diff --git a/tests/asyncapi/rabbit/v2_6_0/test_publisher.py b/tests/asyncapi/rabbit/v2_6_0/test_publisher.py index c9c8ff7ea7..b9c17a9d00 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_publisher.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_publisher.py @@ -185,4 +185,4 @@ async def handle(msg) -> None: ... }, "servers": ["development"], }, - } + }, schema["channels"] diff --git a/tests/brokers/base/consume.py b/tests/brokers/base/consume.py index f6d6510a67..9f0acf2806 100644 --- a/tests/brokers/base/consume.py +++ b/tests/brokers/base/consume.py @@ -1,5 +1,4 @@ import asyncio -from typing import NoReturn from unittest.mock import MagicMock import anyio @@ -343,7 +342,7 @@ async def test_stop_consume_exc( args, kwargs = self.get_subscriber_params(queue) @consume_broker.subscriber(*args, **kwargs) - def subscriber(m) -> NoReturn: + def subscriber(m): mock() event.set() raise StopConsume diff --git a/tests/brokers/base/middlewares.py b/tests/brokers/base/middlewares.py index 22111f4ebc..dbde16432f 100644 --- a/tests/brokers/base/middlewares.py +++ b/tests/brokers/base/middlewares.py @@ -1,5 +1,4 @@ import asyncio -from typing import NoReturn from unittest.mock import Mock, call import pytest @@ -8,6 +7,7 @@ from faststream._internal.basic_types import DecodedMessage from faststream.exceptions import SkipMessage from faststream.middlewares import BaseMiddleware, ExceptionMiddleware +from faststream.response import PublishCommand from .basic import BaseTestcaseConfig @@ -209,7 +209,7 @@ async def mid(call_next, msg): args, kwargs = self.get_subscriber_params(queue, middlewares=(mid,)) @broker.subscriber(*args, **kwargs) - async def handler2(m) -> NoReturn: + async def handler2(m): event.set() raise ValueError @@ -331,8 +331,9 @@ async def test_patch_publish( event: asyncio.Event, ) -> None: class Mid(BaseMiddleware): - async def on_publish(self, msg: str, *args, **kwargs) -> str: - return msg * 2 + async def on_publish(self, msg: PublishCommand) -> PublishCommand: + msg.body *= 2 + return msg broker = self.get_broker(middlewares=(Mid,)) @@ -370,11 +371,10 @@ async def test_global_publisher_middleware( mock: Mock, ) -> None: class Mid(BaseMiddleware): - async def on_publish(self, msg: str, *args, **kwargs) -> str: - data = msg * 2 - assert args or kwargs - mock.enter(data) - return data + async def on_publish(self, msg: PublishCommand) -> PublishCommand: + msg.body *= 2 + mock.enter(msg.body) + return msg async def after_publish(self, *args, **kwargs) -> None: mock.end() @@ -429,7 +429,7 @@ async def value_error_handler(exc) -> str: @broker.subscriber(*args, **kwargs) @broker.publisher(queue + "1") - async def subscriber1(m) -> NoReturn: + async def subscriber1(m): raise ValueError args, kwargs = self.get_subscriber_params(queue + "1") @@ -462,7 +462,7 @@ async def test_exception_middleware_skip_msg( mid = ExceptionMiddleware() @mid.add_handler(ValueError, publish=True) - async def value_error_handler(exc) -> NoReturn: + async def value_error_handler(exc): event.set() raise SkipMessage @@ -471,7 +471,7 @@ async def value_error_handler(exc) -> NoReturn: @broker.subscriber(*args, **kwargs) @broker.publisher(queue + "1") - async def subscriber1(m) -> NoReturn: + async def subscriber1(m): raise ValueError args2, kwargs2 = self.get_subscriber_params(queue + "1") @@ -509,7 +509,7 @@ async def value_error_handler(exc) -> None: args, kwargs = self.get_subscriber_params(queue) @broker.subscriber(*args, **kwargs) - async def subscriber(m) -> NoReturn: + async def subscriber(m): event.set() raise SkipMessage @@ -536,7 +536,7 @@ async def test_exception_middleware_reraise( mid = ExceptionMiddleware() @mid.add_handler(ValueError, publish=True) - async def value_error_handler(exc) -> NoReturn: + async def value_error_handler(exc): event.set() raise exc @@ -545,7 +545,7 @@ async def value_error_handler(exc) -> NoReturn: @broker.subscriber(*args, **kwargs) @broker.publisher(queue + "1") - async def subscriber1(m) -> NoReturn: + async def subscriber1(m): raise ValueError args2, kwargs2 = self.get_subscriber_params(queue + "1") @@ -590,14 +590,14 @@ async def value_error_handler(exc) -> str: @broker.subscriber(*args, **kwargs) @publisher - async def subscriber1(m) -> NoReturn: + async def subscriber1(m): raise ZeroDivisionError args2, kwargs2 = self.get_subscriber_params(queue + "1") @broker.subscriber(*args2, **kwargs2) @publisher - async def subscriber2(m) -> NoReturn: + async def subscriber2(m): raise ValueError args3, kwargs3 = self.get_subscriber_params(queue + "2") @@ -670,7 +670,7 @@ async def value_error_handler(exc) -> None: args, kwargs = self.get_subscriber_params(queue) @broker.subscriber(*args, **kwargs) - async def subscriber1(m) -> NoReturn: + async def subscriber1(m): raise ZeroDivisionError async with self.patch_broker(broker) as br: diff --git a/tests/brokers/base/requests.py b/tests/brokers/base/requests.py index a9beb8f764..9cb8296fa9 100644 --- a/tests/brokers/base/requests.py +++ b/tests/brokers/base/requests.py @@ -1,5 +1,3 @@ -from typing import NoReturn - import anyio import pytest @@ -7,10 +5,10 @@ class RequestsTestcase(BaseTestcaseConfig): - def get_middleware(self, **kwargs) -> NoReturn: + def get_middleware(self, **kwargs): raise NotImplementedError - def get_router(self, **kwargs) -> NoReturn: + def get_router(self, **kwargs): raise NotImplementedError async def test_request_timeout(self, queue: str) -> None: diff --git a/tests/brokers/base/testclient.py b/tests/brokers/base/testclient.py index a594eebca4..6326eacdbb 100644 --- a/tests/brokers/base/testclient.py +++ b/tests/brokers/base/testclient.py @@ -1,6 +1,5 @@ import asyncio from abc import abstractmethod -from typing import NoReturn from unittest.mock import Mock import anyio @@ -117,7 +116,7 @@ async def test_exception_raises(self, queue: str) -> None: args, kwargs = self.get_subscriber_params(queue) @test_broker.subscriber(*args, **kwargs) - async def m(msg) -> NoReturn: # pragma: no cover + async def m(msg): # pragma: no cover raise ValueError async with self.patch_broker(test_broker) as br: diff --git a/tests/brokers/confluent/test_consume.py b/tests/brokers/confluent/test_consume.py index 1cbb6889f7..6f61f01d5f 100644 --- a/tests/brokers/confluent/test_consume.py +++ b/tests/brokers/confluent/test_consume.py @@ -1,5 +1,5 @@ import asyncio -from typing import Any, NoReturn +from typing import Any from unittest.mock import patch import pytest @@ -180,7 +180,7 @@ async def test_consume_ack_raise( ) @consume_broker.subscriber(*args, **kwargs) - async def handler(msg: KafkaMessage) -> NoReturn: + async def handler(msg: KafkaMessage): event.set() raise AckMessage diff --git a/tests/brokers/confluent/test_publish_command.py b/tests/brokers/confluent/test_publish_command.py new file mode 100644 index 0000000000..0f21843038 --- /dev/null +++ b/tests/brokers/confluent/test_publish_command.py @@ -0,0 +1,46 @@ +from typing import Any + +import pytest + +from faststream import Response +from faststream.confluent.response import KafkaPublishCommand, KafkaResponse +from faststream.response import ensure_response + + +def test_simple_reponse(): + response = ensure_response(1) + cmd = KafkaPublishCommand.from_cmd(response.as_publish_command()) + assert cmd.body == 1 + + +def test_base_response_class(): + response = ensure_response(Response(body=1, headers={1: 1})) + cmd = KafkaPublishCommand.from_cmd(response.as_publish_command()) + assert cmd.body == 1 + assert cmd.headers == {1: 1} + + +def test_kafka_response_class(): + response = ensure_response(KafkaResponse(body=1, headers={1: 1}, key=b"1")) + cmd = KafkaPublishCommand.from_cmd(response.as_publish_command()) + assert cmd.body == 1 + assert cmd.headers == {1: 1} + assert cmd.key == b"1" + + +@pytest.mark.parametrize( + ("data", "expected_body"), + ( + pytest.param(None, (), id="None Response"), + pytest.param((), (), id="Empty Sequence"), + pytest.param("123", ("123",), id="String Response"), + pytest.param([1, 2, 3], (1, 2, 3), id="Sequence Data"), + ), +) +def test_batch_response(data: Any, expected_body: Any): + response = ensure_response(data) + cmd = KafkaPublishCommand.from_cmd( + response.as_publish_command(), + batch=True, + ) + assert cmd.batch_bodies == expected_body diff --git a/tests/brokers/kafka/test_consume.py b/tests/brokers/kafka/test_consume.py index 84db65b32d..f5e5421fbd 100644 --- a/tests/brokers/kafka/test_consume.py +++ b/tests/brokers/kafka/test_consume.py @@ -1,5 +1,5 @@ import asyncio -from typing import Any, NoReturn +from typing import Any from unittest.mock import patch import pytest @@ -221,7 +221,7 @@ async def test_consume_ack_raise( consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber(queue, group_id="test", auto_commit=False) - async def handler(msg: KafkaMessage) -> NoReturn: + async def handler(msg: KafkaMessage): event.set() raise AckMessage diff --git a/tests/brokers/kafka/test_publish_command.py b/tests/brokers/kafka/test_publish_command.py new file mode 100644 index 0000000000..0c2b43b781 --- /dev/null +++ b/tests/brokers/kafka/test_publish_command.py @@ -0,0 +1,46 @@ +from typing import Any + +import pytest + +from faststream import Response +from faststream.kafka.response import KafkaPublishCommand, KafkaResponse +from faststream.response import ensure_response + + +def test_simple_reponse(): + response = ensure_response(1) + cmd = KafkaPublishCommand.from_cmd(response.as_publish_command()) + assert cmd.body == 1 + + +def test_base_response_class(): + response = ensure_response(Response(body=1, headers={1: 1})) + cmd = KafkaPublishCommand.from_cmd(response.as_publish_command()) + assert cmd.body == 1 + assert cmd.headers == {1: 1} + + +def test_kafka_response_class(): + response = ensure_response(KafkaResponse(body=1, headers={1: 1}, key=b"1")) + cmd = KafkaPublishCommand.from_cmd(response.as_publish_command()) + assert cmd.body == 1 + assert cmd.headers == {1: 1} + assert cmd.key == b"1" + + +@pytest.mark.parametrize( + ("data", "expected_body"), + ( + pytest.param(None, (), id="None Response"), + pytest.param((), (), id="Empty Sequence"), + pytest.param("123", ("123",), id="String Response"), + pytest.param([1, 2, 3], (1, 2, 3), id="Sequence Data"), + ), +) +def test_batch_response(data: Any, expected_body: Any): + response = ensure_response(data) + cmd = KafkaPublishCommand.from_cmd( + response.as_publish_command(), + batch=True, + ) + assert cmd.batch_bodies == expected_body diff --git a/tests/brokers/nats/test_consume.py b/tests/brokers/nats/test_consume.py index cc72c36073..d7200e627f 100644 --- a/tests/brokers/nats/test_consume.py +++ b/tests/brokers/nats/test_consume.py @@ -1,5 +1,5 @@ import asyncio -from typing import Any, NoReturn +from typing import Any from unittest.mock import Mock, patch import pytest @@ -224,7 +224,7 @@ async def test_consume_ack_raise( consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber(queue, stream=stream) - async def handler(msg: NatsMessage) -> NoReturn: + async def handler(msg: NatsMessage): event.set() raise AckMessage diff --git a/tests/brokers/rabbit/test_consume.py b/tests/brokers/rabbit/test_consume.py index 37d79b7728..742daac225 100644 --- a/tests/brokers/rabbit/test_consume.py +++ b/tests/brokers/rabbit/test_consume.py @@ -1,5 +1,5 @@ import asyncio -from typing import Any, NoReturn +from typing import Any from unittest.mock import patch import pytest @@ -197,7 +197,7 @@ async def test_consume_manual_nack( consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber(queue=queue, exchange=exchange, retry=1) - async def handler(msg: RabbitMessage) -> NoReturn: + async def handler(msg: RabbitMessage): await msg.nack() event.set() raise ValueError @@ -268,7 +268,7 @@ async def test_consume_manual_reject( consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber(queue=queue, exchange=exchange, retry=1) - async def handler(msg: RabbitMessage) -> NoReturn: + async def handler(msg: RabbitMessage): await msg.reject() event.set() raise ValueError diff --git a/tests/brokers/rabbit/test_publish.py b/tests/brokers/rabbit/test_publish.py index 92545e6a1b..4e9b7b3121 100644 --- a/tests/brokers/rabbit/test_publish.py +++ b/tests/brokers/rabbit/test_publish.py @@ -1,5 +1,5 @@ import asyncio -from typing import Any +from typing import TYPE_CHECKING, Any from unittest.mock import Mock, patch import pytest @@ -10,6 +10,9 @@ from tests.brokers.base.publish import BrokerPublishTestcase from tests.tools import spy_decorator +if TYPE_CHECKING: + from faststream.rabbit.response import RabbitPublishCommand + @pytest.mark.rabbit() class TestPublish(BrokerPublishTestcase): @@ -54,8 +57,9 @@ async def handler(m): timeout=3, ) - assert m.mock.call_args.kwargs.get("persist") - assert m.mock.call_args.kwargs.get("immediate") is False + cmd: RabbitPublishCommand = m.mock.call_args[0][1] + assert cmd.message_options["persist"] + assert not cmd.publish_options["immediate"] assert event.is_set() mock.assert_called_with("Hello!") @@ -72,10 +76,7 @@ async def test_response( @pub_broker.subscriber(queue) @pub_broker.publisher(queue + "1") async def handle(): - return RabbitResponse( - 1, - persist=True, - ) + return RabbitResponse(1, persist=True) @pub_broker.subscriber(queue + "1") async def handle_next(msg=Context("message")) -> None: @@ -100,7 +101,8 @@ async def handle_next(msg=Context("message")) -> None: assert event.is_set() - assert m.mock.call_args.kwargs.get("persist") + cmd: RabbitPublishCommand = m.mock.call_args[0][1] + assert cmd.message_options["persist"] mock.assert_called_once_with(body=b"1") diff --git a/tests/brokers/rabbit/test_test_client.py b/tests/brokers/rabbit/test_test_client.py index f42fee9d01..856ed80668 100644 --- a/tests/brokers/rabbit/test_test_client.py +++ b/tests/brokers/rabbit/test_test_client.py @@ -1,5 +1,5 @@ import asyncio -from typing import Any, NoReturn +from typing import Any import pytest @@ -213,13 +213,13 @@ async def handler(msg: RabbitMessage) -> None: consume.set() @broker.subscriber(queue=queue + "1", exchange=exchange, retry=1) - async def handler2(msg: RabbitMessage) -> NoReturn: + async def handler2(msg: RabbitMessage): await msg.raw_message.nack() consume2.set() raise ValueError @broker.subscriber(queue=queue + "2", exchange=exchange, retry=1) - async def handler3(msg: RabbitMessage) -> NoReturn: + async def handler3(msg: RabbitMessage): await msg.raw_message.reject() consume3.set() raise ValueError diff --git a/tests/brokers/redis/test_publish_command.py b/tests/brokers/redis/test_publish_command.py new file mode 100644 index 0000000000..78c272e26e --- /dev/null +++ b/tests/brokers/redis/test_publish_command.py @@ -0,0 +1,46 @@ +from typing import Any + +import pytest + +from faststream import Response +from faststream.redis.response import RedisPublishCommand, RedisResponse +from faststream.response import ensure_response + + +def test_simple_reponse(): + response = ensure_response(1) + cmd = RedisPublishCommand.from_cmd(response.as_publish_command()) + assert cmd.body == 1 + + +def test_base_response_class(): + response = ensure_response(Response(body=1, headers={1: 1})) + cmd = RedisPublishCommand.from_cmd(response.as_publish_command()) + assert cmd.body == 1 + assert cmd.headers == {1: 1} + + +def test_kafka_response_class(): + response = ensure_response(RedisResponse(body=1, headers={1: 1}, maxlen=1)) + cmd = RedisPublishCommand.from_cmd(response.as_publish_command()) + assert cmd.body == 1 + assert cmd.headers == {1: 1} + assert cmd.maxlen == 1 + + +@pytest.mark.parametrize( + ("data", "expected_body"), + ( + pytest.param(None, (), id="None Response"), + pytest.param((), (), id="Empty Sequence"), + pytest.param("123", ("123",), id="String Response"), + pytest.param([1, 2, 3], (1, 2, 3), id="Sequence Data"), + ), +) +def test_batch_response(data: Any, expected_body: Any): + response = ensure_response(data) + cmd = RedisPublishCommand.from_cmd( + response.as_publish_command(), + batch=True, + ) + assert cmd.batch_bodies == expected_body diff --git a/tests/brokers/test_pushback.py b/tests/brokers/test_pushback.py index 7dc083a803..afb064ff69 100644 --- a/tests/brokers/test_pushback.py +++ b/tests/brokers/test_pushback.py @@ -1,4 +1,3 @@ -from typing import NoReturn from unittest.mock import AsyncMock import pytest @@ -92,7 +91,7 @@ async def test_push_endless_back_watcher(async_mock: AsyncMock, message) -> None @pytest.mark.asyncio() -async def test_ignore_skip(async_mock: AsyncMock, message) -> NoReturn: +async def test_ignore_skip(async_mock: AsyncMock, message) -> None: watcher = CounterWatcher(3) context = WatcherContext( @@ -111,7 +110,7 @@ async def test_ignore_skip(async_mock: AsyncMock, message) -> NoReturn: @pytest.mark.asyncio() async def test_additional_params_with_handler_exception( async_mock: AsyncMock, message -) -> NoReturn: +) -> None: watcher = EndlessWatcher() context = WatcherContext( diff --git a/tests/brokers/test_response.py b/tests/brokers/test_response.py index 710706d1c3..a8b669cc52 100644 --- a/tests/brokers/test_response.py +++ b/tests/brokers/test_response.py @@ -1,4 +1,5 @@ -from faststream.response import Response, ensure_response +from faststream.response import ensure_response +from faststream.response.response import Response def test_raw_data() -> None: @@ -13,13 +14,13 @@ def test_response_with_response_instance() -> None: assert resp.headers == {"some": 1} -def test_headers_override() -> None: - resp = Response(1, headers={"some": 1}) - resp.add_headers({"some": 2}) - assert resp.headers == {"some": 2} +def test_add_headers_not_overrides() -> None: + publish_cmd = Response(1, headers={1: 1, 2: 2}).as_publish_command() + publish_cmd.add_headers({1: "ignored", 3: 3}, override=False) + assert publish_cmd.headers == {1: 1, 2: 2, 3: 3} -def test_headers_with_default() -> None: - resp = Response(1, headers={"some": 1}) - resp.add_headers({"some": 2}, override=False) - assert resp.headers == {"some": 1} +def test_add_headers_overrides() -> None: + publish_cmd = Response(1, headers={1: "ignored", 2: 2}).as_publish_command() + publish_cmd.add_headers({1: 1, 3: 3}, override=True) + assert publish_cmd.headers == {1: 1, 2: 2, 3: 3} diff --git a/tests/cli/rabbit/test_app.py b/tests/cli/rabbit/test_app.py index c44d5b05d9..2dcfbc29ea 100644 --- a/tests/cli/rabbit/test_app.py +++ b/tests/cli/rabbit/test_app.py @@ -2,7 +2,6 @@ import os import signal from contextlib import asynccontextmanager -from typing import NoReturn from unittest.mock import AsyncMock, Mock, patch import anyio @@ -303,7 +302,7 @@ async def test_test_app(mock: Mock) -> None: @pytest.mark.asyncio() -async def test_test_app_with_excp(mock: Mock) -> NoReturn: +async def test_test_app_with_excp(mock: Mock) -> None: app = FastStream() app.on_startup(mock.on) @@ -330,7 +329,7 @@ def test_sync_test_app(mock: Mock) -> None: mock.off.assert_called_once() -def test_sync_test_app_with_excp(mock: Mock) -> NoReturn: +def test_sync_test_app_with_excp(mock: Mock) -> None: app = FastStream() app.on_startup(mock.on) diff --git a/tests/cli/test_publish.py b/tests/cli/test_publish.py index 383b89c8d1..c545a03a72 100644 --- a/tests/cli/test_publish.py +++ b/tests/cli/test_publish.py @@ -1,10 +1,11 @@ +from typing import TYPE_CHECKING from unittest.mock import AsyncMock, patch -from dirty_equals import IsPartialDict from typer.testing import CliRunner from faststream import FastStream from faststream._internal.cli.main import cli as faststream_app +from faststream.response.publish_type import PublishType from tests.marks import ( require_aiokafka, require_aiopika, @@ -13,6 +14,15 @@ require_redis, ) +if TYPE_CHECKING: + from faststream.confluent.response import ( + KafkaPublishCommand as ConfluentPublishCommand, + ) + from faststream.kafka.response import KafkaPublishCommand + from faststream.nats.response import NatsPublishCommand + from faststream.rabbit.response import RabbitPublishCommand + from faststream.redis.response import RedisPublishCommand + def get_mock_app(broker_type, producer_type) -> tuple[FastStream, AsyncMock]: broker = broker_type() @@ -46,10 +56,6 @@ def test_publish_command_with_redis_options(runner) -> None: "channelname", "--reply_to", "tester", - "--list", - "listname", - "--stream", - "streamname", "--correlation_id", "someId", ], @@ -57,14 +63,11 @@ def test_publish_command_with_redis_options(runner) -> None: assert result.exit_code == 0 - assert producer_mock.publish.call_args.args[0] == "hello world" - assert producer_mock.publish.call_args.kwargs == IsPartialDict( - reply_to="tester", - stream="streamname", - list="listname", - channel="channelname", - correlation_id="someId", - ) + cmd: RedisPublishCommand = producer_mock.publish.call_args.args[0] + assert cmd.body == "hello world" + assert cmd.reply_to == "tester" + assert cmd.destination == "channelname" + assert cmd.correlation_id == "someId" @require_confluent @@ -93,11 +96,10 @@ def test_publish_command_with_confluent_options(runner) -> None: assert result.exit_code == 0 - assert producer_mock.publish.call_args.args[0] == "hello world" - assert producer_mock.publish.call_args.kwargs == IsPartialDict( - topic="topicname", - correlation_id="someId", - ) + cmd: ConfluentPublishCommand = producer_mock.publish.call_args.args[0] + assert cmd.body == "hello world" + assert cmd.destination == "topicname" + assert cmd.correlation_id == "someId" @require_aiokafka @@ -125,11 +127,11 @@ def test_publish_command_with_kafka_options(runner) -> None: ) assert result.exit_code == 0 - assert producer_mock.publish.call_args.args[0] == "hello world" - assert producer_mock.publish.call_args.kwargs == IsPartialDict( - topic="topicname", - correlation_id="someId", - ) + + cmd: KafkaPublishCommand = producer_mock.publish.call_args.args[0] + assert cmd.body == "hello world" + assert cmd.destination == "topicname" + assert cmd.correlation_id == "someId" @require_nats @@ -160,12 +162,11 @@ def test_publish_command_with_nats_options(runner) -> None: assert result.exit_code == 0 - assert producer_mock.publish.call_args.args[0] == "hello world" - assert producer_mock.publish.call_args.kwargs == IsPartialDict( - subject="subjectname", - reply_to="tester", - correlation_id="someId", - ) + cmd: NatsPublishCommand = producer_mock.publish.call_args.args[0] + assert cmd.body == "hello world" + assert cmd.destination == "subjectname" + assert cmd.reply_to == "tester" + assert cmd.correlation_id == "someId" @require_aiopika @@ -185,6 +186,8 @@ def test_publish_command_with_rabbit_options(runner) -> None: "publish", "fastream:app", "hello world", + "--queue", + "queuename", "--correlation_id", "someId", ], @@ -192,12 +195,10 @@ def test_publish_command_with_rabbit_options(runner) -> None: assert result.exit_code == 0 - assert producer_mock.publish.call_args.args[0] == "hello world" - assert producer_mock.publish.call_args.kwargs == IsPartialDict( - { - "correlation_id": "someId", - }, - ) + cmd: RabbitPublishCommand = producer_mock.publish.call_args.args[0] + assert cmd.body == "hello world" + assert cmd.destination == "queuename" + assert cmd.correlation_id == "someId" @require_nats @@ -225,8 +226,8 @@ def test_publish_nats_request_command(runner: CliRunner) -> None: ], ) - assert producer_mock.request.call_args.args[0] == "hello world" - assert producer_mock.request.call_args.kwargs == IsPartialDict( - subject="subjectname", - timeout=1.0, - ) + cmd: NatsPublishCommand = producer_mock.request.call_args.args[0] + + assert cmd.destination == "subjectname" + assert cmd.timeout == 1.0 + assert cmd.publish_type is PublishType.Request diff --git a/tests/prometheus/basic.py b/tests/prometheus/basic.py index 0a7b4bc666..74c55dc4c0 100644 --- a/tests/prometheus/basic.py +++ b/tests/prometheus/basic.py @@ -6,8 +6,8 @@ from prometheus_client import CollectorRegistry from faststream import Context -from faststream.broker.message import AckStatus from faststream.exceptions import RejectMessage +from faststream.message import AckStatus from faststream.prometheus.middleware import ( PROCESSING_STATUS_BY_ACK_STATUS, PROCESSING_STATUS_BY_HANDLER_EXCEPTION_MAP, diff --git a/tests/tools.py b/tests/tools.py index 55d4405c9d..c2682f2455 100644 --- a/tests/tools.py +++ b/tests/tools.py @@ -1,8 +1,10 @@ import inspect from functools import wraps -from typing import Callable, ParamSpec, Protocol, TypeVar +from typing import Callable, Protocol, TypeVar from unittest.mock import MagicMock +from typing_extensions import ParamSpec + P = ParamSpec("P") T = TypeVar("T") diff --git a/tests/utils/test_ast.py b/tests/utils/test_ast.py index a92c6fcd87..d57d29e88f 100644 --- a/tests/utils/test_ast.py +++ b/tests/utils/test_ast.py @@ -1,5 +1,3 @@ -from typing import NoReturn - import pytest from faststream._internal.testing.ast import is_contains_context_name @@ -75,7 +73,7 @@ def test_nested_invalid() -> None: assert not a.contains -def test_not_broken() -> NoReturn: +def test_not_broken() -> None: with A() as a, B(): assert a.contains From e39d0adb3b22745f9ad56e211e3a903af150ba5b Mon Sep 17 00:00:00 2001 From: Pastukhov Nikita Date: Thu, 31 Oct 2024 19:55:58 +0300 Subject: [PATCH 180/245] Feat/fast depends 3 (#1886) * refactor: make context not-global * docs: generate API References * tests: refactor context tests * chore: merge main * fix: correct Context propogation from App to Broker * docs: generate API References * tests: in-memory cli * chore: use python3.9 compatible FastDepends * chore: revert FD version --------- Co-authored-by: Lancetnik --- docs/docs/SUMMARY.md | 13 ++ .../broker/state/BrokerState.md} | 2 +- .../broker/state/ConnectedState.md} | 2 +- .../broker/state/ConnectionBrokenState.md | 11 + .../nats/broker/state/EmptyBrokerState.md | 11 + .../nats/helpers/state/ConnectedState.md | 11 + .../nats/helpers/state/ConnectionState.md | 11 + .../helpers/state/EmptyConnectionState.md | 11 + .../state/ConnectedSubscriberState.md | 11 + .../subscriber/state/EmptySubscriberState.md | 11 + .../nats/subscriber/state/SubscriberState.md | 11 + .../en/getting-started/dependencies/index.md | 2 +- .../en/getting-started/subscription/index.md | 2 +- .../asyncapi/asyncapi_customization/basic.py | 2 +- .../asyncapi_customization/custom_info.py | 4 +- .../getting_started/context/confluent/cast.py | 4 +- .../context/confluent/custom_local_context.py | 2 +- .../context/confluent/manual_local_context.py | 7 +- .../getting_started/context/kafka/cast.py | 4 +- .../context/kafka/custom_local_context.py | 2 +- .../context/kafka/manual_local_context.py | 7 +- .../getting_started/context/nats/cast.py | 4 +- .../context/nats/custom_local_context.py | 2 +- .../context/nats/manual_local_context.py | 8 +- .../getting_started/context/nested.py | 2 +- .../getting_started/context/rabbit/cast.py | 4 +- .../context/rabbit/custom_local_context.py | 2 +- .../context/rabbit/manual_local_context.py | 8 +- .../getting_started/context/redis/cast.py | 4 +- .../context/redis/custom_local_context.py | 2 +- .../context/redis/manual_local_context.py | 8 +- .../getting_started/lifespan/multiple.py | 4 +- .../subscription/confluent/real_testing.py | 2 +- .../subscription/confluent/testing.py | 2 +- .../subscription/kafka/real_testing.py | 2 +- .../subscription/kafka/testing.py | 2 +- .../subscription/nats/real_testing.py | 2 +- .../subscription/nats/testing.py | 2 +- .../subscription/rabbit/real_testing.py | 2 +- .../subscription/rabbit/testing.py | 2 +- .../subscription/redis/real_testing.py | 2 +- .../subscription/redis/testing.py | 2 +- docs/docs_src/index/confluent/test.py | 4 +- docs/docs_src/index/kafka/test.py | 4 +- docs/docs_src/index/nats/test.py | 4 +- docs/docs_src/index/rabbit/test.py | 4 +- docs/docs_src/index/redis/test.py | 4 +- faststream/__init__.py | 3 - faststream/_internal/_compat.py | 7 +- faststream/_internal/application.py | 103 ++++++--- faststream/_internal/broker/abc_broker.py | 6 +- faststream/_internal/broker/broker.py | 74 +++--- faststream/_internal/broker/router.py | 4 +- faststream/_internal/context/__init__.py | 3 +- faststream/_internal/context/context_type.py | 1 + faststream/_internal/context/repository.py | 5 - faststream/_internal/context/resolve.py | 6 +- faststream/_internal/fastapi/context.py | 14 +- faststream/_internal/fastapi/get_dependant.py | 6 +- faststream/_internal/fastapi/route.py | 8 +- faststream/_internal/fastapi/router.py | 31 ++- faststream/_internal/log/logging.py | 13 +- faststream/_internal/publisher/proto.py | 2 + faststream/_internal/publisher/usecase.py | 74 +++--- faststream/_internal/setup/fast_depends.py | 10 +- faststream/_internal/setup/logger.py | 15 +- faststream/_internal/setup/state.py | 2 +- faststream/_internal/subscriber/call_item.py | 20 +- .../_internal/subscriber/call_wrapper/call.py | 30 +-- .../subscriber/call_wrapper/proto.py | 8 +- faststream/_internal/subscriber/proto.py | 23 +- faststream/_internal/subscriber/usecase.py | 29 +-- faststream/_internal/subscriber/utils.py | 14 +- faststream/_internal/utils/functions.py | 21 +- faststream/app.py | 21 +- faststream/asgi/app.py | 11 +- faststream/confluent/broker/broker.py | 12 +- faststream/confluent/broker/logging.py | 4 +- faststream/confluent/broker/registrator.py | 18 +- faststream/confluent/parser.py | 40 ++-- faststream/confluent/publisher/producer.py | 2 +- faststream/confluent/router.py | 10 +- faststream/confluent/subscriber/factory.py | 10 +- faststream/confluent/subscriber/usecase.py | 31 +-- faststream/confluent/testing.py | 2 +- faststream/kafka/broker/broker.py | 12 +- faststream/kafka/broker/logging.py | 4 +- faststream/kafka/broker/registrator.py | 18 +- faststream/kafka/parser.py | 16 +- faststream/kafka/router.py | 10 +- faststream/kafka/subscriber/factory.py | 10 +- faststream/kafka/subscriber/usecase.py | 28 ++- faststream/middlewares/exception.py | 14 +- faststream/middlewares/logging.py | 5 +- faststream/nats/broker/broker.py | 135 +++++------ faststream/nats/broker/logging.py | 4 +- faststream/nats/broker/registrator.py | 8 +- faststream/nats/broker/state.py | 78 +++++++ faststream/nats/fastapi/__init__.py | 5 - faststream/nats/helpers/bucket_declarer.py | 17 +- .../nats/helpers/obj_storage_declarer.py | 17 +- faststream/nats/helpers/state.py | 27 +++ faststream/nats/publisher/producer.py | 41 +++- faststream/nats/router.py | 10 +- faststream/nats/schemas/js_stream.py | 1 + faststream/nats/subscriber/factory.py | 4 +- faststream/nats/subscriber/specified.py | 2 +- faststream/nats/subscriber/state.py | 60 +++++ faststream/nats/subscriber/usecase.py | 211 ++++++++---------- faststream/nats/testing.py | 3 +- faststream/prometheus/middleware.py | 2 +- faststream/rabbit/broker/broker.py | 12 +- faststream/rabbit/broker/logging.py | 4 +- faststream/rabbit/broker/registrator.py | 6 +- faststream/rabbit/publisher/usecase.py | 4 +- faststream/rabbit/router.py | 12 +- faststream/rabbit/subscriber/factory.py | 4 +- faststream/rabbit/subscriber/usecase.py | 9 +- faststream/redis/broker/broker.py | 20 +- faststream/redis/broker/logging.py | 4 +- faststream/redis/broker/registrator.py | 6 +- faststream/redis/router.py | 10 +- faststream/redis/subscriber/factory.py | 4 +- faststream/redis/subscriber/usecase.py | 61 +++-- faststream/specification/asyncapi/factory.py | 7 +- faststream/specification/asyncapi/message.py | 12 +- pyproject.toml | 2 +- .../cli/confluent/test_confluent_context.py | 4 +- .../cli/kafka/test_kafka_context.py | 4 +- .../cli/nats/test_nats_context.py | 4 +- .../cli/rabbit/test_rabbit_context.py | 4 +- .../cli/redis/test_redis_context.py | 4 +- .../getting_started/context/test_initial.py | 21 +- .../getting_started/lifespan/test_basic.py | 12 +- .../getting_started/lifespan/test_multi.py | 4 +- .../subscription/test_annotated.py | 2 +- tests/asgi/testcase.py | 11 +- tests/brokers/base/consume.py | 2 +- tests/brokers/base/fastapi.py | 19 +- tests/cli/conftest.py | 7 +- tests/cli/rabbit/test_app.py | 108 ++------- tests/cli/rabbit/test_logs.py | 9 +- tests/cli/test_asyncapi_docs.py | 6 +- tests/cli/test_run_asgi.py | 6 +- tests/cli/test_run_regular.py | 12 +- tests/conftest.py | 8 +- tests/utils/context/test_alias.py | 8 +- tests/utils/context/test_main.py | 32 +-- 148 files changed, 1226 insertions(+), 902 deletions(-) rename docs/docs/en/api/faststream/{broker/subscriber/mixins/TasksMixin.md => nats/broker/state/BrokerState.md} (68%) rename docs/docs/en/api/faststream/{broker/subscriber/mixins/ConcurrentMixin.md => nats/broker/state/ConnectedState.md} (66%) create mode 100644 docs/docs/en/api/faststream/nats/broker/state/ConnectionBrokenState.md create mode 100644 docs/docs/en/api/faststream/nats/broker/state/EmptyBrokerState.md create mode 100644 docs/docs/en/api/faststream/nats/helpers/state/ConnectedState.md create mode 100644 docs/docs/en/api/faststream/nats/helpers/state/ConnectionState.md create mode 100644 docs/docs/en/api/faststream/nats/helpers/state/EmptyConnectionState.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/state/ConnectedSubscriberState.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/state/EmptySubscriberState.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/state/SubscriberState.md create mode 100644 faststream/nats/broker/state.py create mode 100644 faststream/nats/helpers/state.py create mode 100644 faststream/nats/subscriber/state.py diff --git a/docs/docs/SUMMARY.md b/docs/docs/SUMMARY.md index 8f8c5f0cba..bf061a321a 100644 --- a/docs/docs/SUMMARY.md +++ b/docs/docs/SUMMARY.md @@ -513,6 +513,11 @@ search: - [NatsParamsStorage](api/faststream/nats/broker/logging/NatsParamsStorage.md) - registrator - [NatsRegistrator](api/faststream/nats/broker/registrator/NatsRegistrator.md) + - state + - [BrokerState](api/faststream/nats/broker/state/BrokerState.md) + - [ConnectedState](api/faststream/nats/broker/state/ConnectedState.md) + - [ConnectionBrokenState](api/faststream/nats/broker/state/ConnectionBrokenState.md) + - [EmptyBrokerState](api/faststream/nats/broker/state/EmptyBrokerState.md) - fastapi - [Context](api/faststream/nats/fastapi/Context.md) - [NatsRouter](api/faststream/nats/fastapi/NatsRouter.md) @@ -528,6 +533,10 @@ search: - [OSBucketDeclarer](api/faststream/nats/helpers/obj_storage_declarer/OSBucketDeclarer.md) - object_builder - [StreamBuilder](api/faststream/nats/helpers/object_builder/StreamBuilder.md) + - state + - [ConnectedState](api/faststream/nats/helpers/state/ConnectedState.md) + - [ConnectionState](api/faststream/nats/helpers/state/ConnectionState.md) + - [EmptyConnectionState](api/faststream/nats/helpers/state/EmptyConnectionState.md) - message - [NatsBatchMessage](api/faststream/nats/message/NatsBatchMessage.md) - [NatsKvMessage](api/faststream/nats/message/NatsKvMessage.md) @@ -612,6 +621,10 @@ search: - [SpecificationPullStreamSubscriber](api/faststream/nats/subscriber/specified/SpecificationPullStreamSubscriber.md) - [SpecificationStreamSubscriber](api/faststream/nats/subscriber/specified/SpecificationStreamSubscriber.md) - [SpecificationSubscriber](api/faststream/nats/subscriber/specified/SpecificationSubscriber.md) + - state + - [ConnectedSubscriberState](api/faststream/nats/subscriber/state/ConnectedSubscriberState.md) + - [EmptySubscriberState](api/faststream/nats/subscriber/state/EmptySubscriberState.md) + - [SubscriberState](api/faststream/nats/subscriber/state/SubscriberState.md) - usecase - [BatchPullStreamSubscriber](api/faststream/nats/subscriber/usecase/BatchPullStreamSubscriber.md) - [ConcurrentCoreSubscriber](api/faststream/nats/subscriber/usecase/ConcurrentCoreSubscriber.md) diff --git a/docs/docs/en/api/faststream/broker/subscriber/mixins/TasksMixin.md b/docs/docs/en/api/faststream/nats/broker/state/BrokerState.md similarity index 68% rename from docs/docs/en/api/faststream/broker/subscriber/mixins/TasksMixin.md rename to docs/docs/en/api/faststream/nats/broker/state/BrokerState.md index 6d483bef85..ed5dc00c35 100644 --- a/docs/docs/en/api/faststream/broker/subscriber/mixins/TasksMixin.md +++ b/docs/docs/en/api/faststream/nats/broker/state/BrokerState.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.broker.subscriber.mixins.TasksMixin +::: faststream.nats.broker.state.BrokerState diff --git a/docs/docs/en/api/faststream/broker/subscriber/mixins/ConcurrentMixin.md b/docs/docs/en/api/faststream/nats/broker/state/ConnectedState.md similarity index 66% rename from docs/docs/en/api/faststream/broker/subscriber/mixins/ConcurrentMixin.md rename to docs/docs/en/api/faststream/nats/broker/state/ConnectedState.md index 994f224aea..b7bb106798 100644 --- a/docs/docs/en/api/faststream/broker/subscriber/mixins/ConcurrentMixin.md +++ b/docs/docs/en/api/faststream/nats/broker/state/ConnectedState.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.broker.subscriber.mixins.ConcurrentMixin +::: faststream.nats.broker.state.ConnectedState diff --git a/docs/docs/en/api/faststream/nats/broker/state/ConnectionBrokenState.md b/docs/docs/en/api/faststream/nats/broker/state/ConnectionBrokenState.md new file mode 100644 index 0000000000..66df604330 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/broker/state/ConnectionBrokenState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.broker.state.ConnectionBrokenState diff --git a/docs/docs/en/api/faststream/nats/broker/state/EmptyBrokerState.md b/docs/docs/en/api/faststream/nats/broker/state/EmptyBrokerState.md new file mode 100644 index 0000000000..88bf83710d --- /dev/null +++ b/docs/docs/en/api/faststream/nats/broker/state/EmptyBrokerState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.broker.state.EmptyBrokerState diff --git a/docs/docs/en/api/faststream/nats/helpers/state/ConnectedState.md b/docs/docs/en/api/faststream/nats/helpers/state/ConnectedState.md new file mode 100644 index 0000000000..888302338b --- /dev/null +++ b/docs/docs/en/api/faststream/nats/helpers/state/ConnectedState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.helpers.state.ConnectedState diff --git a/docs/docs/en/api/faststream/nats/helpers/state/ConnectionState.md b/docs/docs/en/api/faststream/nats/helpers/state/ConnectionState.md new file mode 100644 index 0000000000..0d99fb56ed --- /dev/null +++ b/docs/docs/en/api/faststream/nats/helpers/state/ConnectionState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.helpers.state.ConnectionState diff --git a/docs/docs/en/api/faststream/nats/helpers/state/EmptyConnectionState.md b/docs/docs/en/api/faststream/nats/helpers/state/EmptyConnectionState.md new file mode 100644 index 0000000000..31a062d4ad --- /dev/null +++ b/docs/docs/en/api/faststream/nats/helpers/state/EmptyConnectionState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.helpers.state.EmptyConnectionState diff --git a/docs/docs/en/api/faststream/nats/subscriber/state/ConnectedSubscriberState.md b/docs/docs/en/api/faststream/nats/subscriber/state/ConnectedSubscriberState.md new file mode 100644 index 0000000000..3398403cb2 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/state/ConnectedSubscriberState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.state.ConnectedSubscriberState diff --git a/docs/docs/en/api/faststream/nats/subscriber/state/EmptySubscriberState.md b/docs/docs/en/api/faststream/nats/subscriber/state/EmptySubscriberState.md new file mode 100644 index 0000000000..de80057014 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/state/EmptySubscriberState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.state.EmptySubscriberState diff --git a/docs/docs/en/api/faststream/nats/subscriber/state/SubscriberState.md b/docs/docs/en/api/faststream/nats/subscriber/state/SubscriberState.md new file mode 100644 index 0000000000..a61839436a --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/state/SubscriberState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.state.SubscriberState diff --git a/docs/docs/en/getting-started/dependencies/index.md b/docs/docs/en/getting-started/dependencies/index.md index 8d88ab81d2..6f2fae0c54 100644 --- a/docs/docs/en/getting-started/dependencies/index.md +++ b/docs/docs/en/getting-started/dependencies/index.md @@ -21,7 +21,7 @@ By default, it applies to all event handlers, unless you disabled the same optio !!! warning Setting the `apply_types=False` flag not only disables type casting but also `Depends` and `Context`. - If you want to disable only type casting, use `validate=False` instead. + If you want to disable only type casting, use `serializer=None` instead. This flag can be useful if you are using **FastStream** within another framework and you need to use its native dependency system. diff --git a/docs/docs/en/getting-started/subscription/index.md b/docs/docs/en/getting-started/subscription/index.md index e1ae7ecef2..2604674830 100644 --- a/docs/docs/en/getting-started/subscription/index.md +++ b/docs/docs/en/getting-started/subscription/index.md @@ -41,7 +41,7 @@ This way **FastStream** still consumes `#!python json.loads` result, but without !!! warning Setting the `apply_types=False` flag not only disables type casting but also `Depends` and `Context`. - If you want to disable only type casting, use `validate=False` instead. + If you want to disable only type casting, use `serializer=None` instead. ## Multiple Subscriptions diff --git a/docs/docs_src/getting_started/asyncapi/asyncapi_customization/basic.py b/docs/docs_src/getting_started/asyncapi/asyncapi_customization/basic.py index 52c427af6c..1dc0c0b9e9 100644 --- a/docs/docs_src/getting_started/asyncapi/asyncapi_customization/basic.py +++ b/docs/docs_src/getting_started/asyncapi/asyncapi_customization/basic.py @@ -1,5 +1,5 @@ from faststream import FastStream -from faststream.kafka import KafkaBroker, KafkaMessage +from faststream.kafka import KafkaBroker broker = KafkaBroker("localhost:9092") app = FastStream(broker) diff --git a/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_info.py b/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_info.py index 8645296a34..4121bebe29 100644 --- a/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_info.py +++ b/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_info.py @@ -7,9 +7,7 @@ broker = KafkaBroker("localhost:9092") description="""# Title of the description This description supports **Markdown** syntax""" -app = FastStream( - broker, -) +app = FastStream(broker) docs_obj = AsyncAPI( broker, title="My App", diff --git a/docs/docs_src/getting_started/context/confluent/cast.py b/docs/docs_src/getting_started/context/confluent/cast.py index 3d0b14c343..77000f7b5b 100644 --- a/docs/docs_src/getting_started/context/confluent/cast.py +++ b/docs/docs_src/getting_started/context/confluent/cast.py @@ -1,9 +1,9 @@ -from faststream import Context, FastStream, context +from faststream import Context, FastStream from faststream.confluent import KafkaBroker broker = KafkaBroker("localhost:9092") app = FastStream(broker) -context.set_global("secret", "1") +app.context.set_global("secret", "1") @broker.subscriber("test-topic") async def handle( diff --git a/docs/docs_src/getting_started/context/confluent/custom_local_context.py b/docs/docs_src/getting_started/context/confluent/custom_local_context.py index e10da7f3fa..5c23081e2d 100644 --- a/docs/docs_src/getting_started/context/confluent/custom_local_context.py +++ b/docs/docs_src/getting_started/context/confluent/custom_local_context.py @@ -16,7 +16,7 @@ async def handle( call() -@apply_types +@apply_types(context__=app.context) def call( message: KafkaMessage, correlation_id=Context(), diff --git a/docs/docs_src/getting_started/context/confluent/manual_local_context.py b/docs/docs_src/getting_started/context/confluent/manual_local_context.py index c4264548d0..d419bda9a2 100644 --- a/docs/docs_src/getting_started/context/confluent/manual_local_context.py +++ b/docs/docs_src/getting_started/context/confluent/manual_local_context.py @@ -1,4 +1,4 @@ -from faststream import Context, FastStream, apply_types, context +from faststream import Context, FastStream, apply_types, ContextRepo from faststream.confluent import KafkaBroker from faststream.confluent.annotations import KafkaMessage @@ -10,16 +10,17 @@ async def handle( msg: str, message: KafkaMessage, + context: ContextRepo, ): tag = context.set_local("correlation_id", message.correlation_id) call(tag) -@apply_types +@apply_types(context__=app.context) def call( tag, message: KafkaMessage, correlation_id=Context(), ): assert correlation_id == message.correlation_id - context.reset_local("correlation_id", tag) + app.context.reset_local("correlation_id", tag) diff --git a/docs/docs_src/getting_started/context/kafka/cast.py b/docs/docs_src/getting_started/context/kafka/cast.py index 1ef06d3595..00db482531 100644 --- a/docs/docs_src/getting_started/context/kafka/cast.py +++ b/docs/docs_src/getting_started/context/kafka/cast.py @@ -1,9 +1,9 @@ -from faststream import Context, FastStream, context +from faststream import Context, FastStream from faststream.kafka import KafkaBroker broker = KafkaBroker("localhost:9092") app = FastStream(broker) -context.set_global("secret", "1") +app.context.set_global("secret", "1") @broker.subscriber("test-topic") async def handle( diff --git a/docs/docs_src/getting_started/context/kafka/custom_local_context.py b/docs/docs_src/getting_started/context/kafka/custom_local_context.py index e20a5a6567..e137319775 100644 --- a/docs/docs_src/getting_started/context/kafka/custom_local_context.py +++ b/docs/docs_src/getting_started/context/kafka/custom_local_context.py @@ -16,7 +16,7 @@ async def handle( call() -@apply_types +@apply_types(context__=app.context) def call( message: KafkaMessage, correlation_id=Context(), diff --git a/docs/docs_src/getting_started/context/kafka/manual_local_context.py b/docs/docs_src/getting_started/context/kafka/manual_local_context.py index 3e39cff046..4e69f6600a 100644 --- a/docs/docs_src/getting_started/context/kafka/manual_local_context.py +++ b/docs/docs_src/getting_started/context/kafka/manual_local_context.py @@ -1,4 +1,4 @@ -from faststream import Context, FastStream, apply_types, context +from faststream import Context, FastStream, apply_types, ContextRepo from faststream.kafka import KafkaBroker from faststream.kafka.annotations import KafkaMessage @@ -10,16 +10,17 @@ async def handle( msg: str, message: KafkaMessage, + context: ContextRepo, ): tag = context.set_local("correlation_id", message.correlation_id) call(tag) -@apply_types +@apply_types(context__=app.context) def call( tag, message: KafkaMessage, correlation_id=Context(), ): assert correlation_id == message.correlation_id - context.reset_local("correlation_id", tag) + app.context.reset_local("correlation_id", tag) diff --git a/docs/docs_src/getting_started/context/nats/cast.py b/docs/docs_src/getting_started/context/nats/cast.py index 0733561043..128cb19dd8 100644 --- a/docs/docs_src/getting_started/context/nats/cast.py +++ b/docs/docs_src/getting_started/context/nats/cast.py @@ -1,9 +1,9 @@ -from faststream import Context, FastStream, context +from faststream import Context, FastStream from faststream.nats import NatsBroker broker = NatsBroker("nats://localhost:4222") app = FastStream(broker) -context.set_global("secret", "1") +app.context.set_global("secret", "1") @broker.subscriber("test-subject") async def handle( diff --git a/docs/docs_src/getting_started/context/nats/custom_local_context.py b/docs/docs_src/getting_started/context/nats/custom_local_context.py index 510ec251e4..484bb9f5f8 100644 --- a/docs/docs_src/getting_started/context/nats/custom_local_context.py +++ b/docs/docs_src/getting_started/context/nats/custom_local_context.py @@ -16,7 +16,7 @@ async def handle( call() -@apply_types +@apply_types(context__=app.context) def call( message: NatsMessage, correlation_id=Context(), diff --git a/docs/docs_src/getting_started/context/nats/manual_local_context.py b/docs/docs_src/getting_started/context/nats/manual_local_context.py index 72a3519daf..fac68e4394 100644 --- a/docs/docs_src/getting_started/context/nats/manual_local_context.py +++ b/docs/docs_src/getting_started/context/nats/manual_local_context.py @@ -1,4 +1,4 @@ -from faststream import Context, FastStream, apply_types, context +from faststream import Context, FastStream, apply_types from faststream.nats import NatsBroker from faststream.nats.annotations import NatsMessage @@ -11,15 +11,15 @@ async def handle( msg: str, message: NatsMessage, ): - tag = context.set_local("correlation_id", message.correlation_id) + tag = app.context.set_local("correlation_id", message.correlation_id) call(tag) -@apply_types +@apply_types(context__=app.context) def call( tag, message: NatsMessage, correlation_id=Context(), ): assert correlation_id == message.correlation_id - context.reset_local("correlation_id", tag) + app.context.reset_local("correlation_id", tag) diff --git a/docs/docs_src/getting_started/context/nested.py b/docs/docs_src/getting_started/context/nested.py index 6eac7ca816..362112850d 100644 --- a/docs/docs_src/getting_started/context/nested.py +++ b/docs/docs_src/getting_started/context/nested.py @@ -11,6 +11,6 @@ async def handler(body): nested_func(body) -@apply_types +@apply_types(context__=broker.context) def nested_func(body, logger=Context()): logger.info(body) diff --git a/docs/docs_src/getting_started/context/rabbit/cast.py b/docs/docs_src/getting_started/context/rabbit/cast.py index 24cf1bf72e..47ce2b4525 100644 --- a/docs/docs_src/getting_started/context/rabbit/cast.py +++ b/docs/docs_src/getting_started/context/rabbit/cast.py @@ -1,9 +1,9 @@ -from faststream import Context, FastStream, context +from faststream import Context, FastStream from faststream.rabbit import RabbitBroker broker = RabbitBroker("amqp://guest:guest@localhost:5672/") app = FastStream(broker) -context.set_global("secret", "1") +app.context.set_global("secret", "1") @broker.subscriber("test-queue") async def handle( diff --git a/docs/docs_src/getting_started/context/rabbit/custom_local_context.py b/docs/docs_src/getting_started/context/rabbit/custom_local_context.py index 6ee9866967..9a3f922073 100644 --- a/docs/docs_src/getting_started/context/rabbit/custom_local_context.py +++ b/docs/docs_src/getting_started/context/rabbit/custom_local_context.py @@ -16,7 +16,7 @@ async def handle( call() -@apply_types +@apply_types(context__=app.context) def call( message: RabbitMessage, correlation_id=Context(), diff --git a/docs/docs_src/getting_started/context/rabbit/manual_local_context.py b/docs/docs_src/getting_started/context/rabbit/manual_local_context.py index 426abe88bb..c6859ff184 100644 --- a/docs/docs_src/getting_started/context/rabbit/manual_local_context.py +++ b/docs/docs_src/getting_started/context/rabbit/manual_local_context.py @@ -1,4 +1,4 @@ -from faststream import Context, FastStream, apply_types, context +from faststream import Context, FastStream, apply_types from faststream.rabbit import RabbitBroker from faststream.rabbit.annotations import RabbitMessage @@ -11,15 +11,15 @@ async def handle( msg: str, message: RabbitMessage, ): - tag = context.set_local("correlation_id", message.correlation_id) + tag = app.context.set_local("correlation_id", message.correlation_id) call(tag) -@apply_types +@apply_types(context__=app.context) def call( tag, message: RabbitMessage, correlation_id=Context(), ): assert correlation_id == message.correlation_id - context.reset_local("correlation_id", tag) + app.context.reset_local("correlation_id", tag) diff --git a/docs/docs_src/getting_started/context/redis/cast.py b/docs/docs_src/getting_started/context/redis/cast.py index fbd5eaeb3b..203daafb30 100644 --- a/docs/docs_src/getting_started/context/redis/cast.py +++ b/docs/docs_src/getting_started/context/redis/cast.py @@ -1,9 +1,9 @@ -from faststream import Context, FastStream, context +from faststream import Context, FastStream from faststream.redis import RedisBroker broker = RedisBroker("redis://localhost:6379") app = FastStream(broker) -context.set_global("secret", "1") +app.context.set_global("secret", "1") @broker.subscriber("test-channel") async def handle( diff --git a/docs/docs_src/getting_started/context/redis/custom_local_context.py b/docs/docs_src/getting_started/context/redis/custom_local_context.py index 4feb1eb438..9e06b3ea93 100644 --- a/docs/docs_src/getting_started/context/redis/custom_local_context.py +++ b/docs/docs_src/getting_started/context/redis/custom_local_context.py @@ -16,7 +16,7 @@ async def handle( call() -@apply_types +@apply_types(context__=app.context) def call( message: RedisMessage, correlation_id=Context(), diff --git a/docs/docs_src/getting_started/context/redis/manual_local_context.py b/docs/docs_src/getting_started/context/redis/manual_local_context.py index f52af02782..74a5ced413 100644 --- a/docs/docs_src/getting_started/context/redis/manual_local_context.py +++ b/docs/docs_src/getting_started/context/redis/manual_local_context.py @@ -1,4 +1,4 @@ -from faststream import Context, FastStream, apply_types, context +from faststream import Context, FastStream, apply_types from faststream.redis import RedisBroker from faststream.redis.annotations import RedisMessage @@ -11,15 +11,15 @@ async def handle( msg: str, message: RedisMessage, ): - tag = context.set_local("correlation_id", message.correlation_id) + tag = app.context.set_local("correlation_id", message.correlation_id) call(tag) -@apply_types +@apply_types(context__=app.context) def call( tag, message: RedisMessage, correlation_id=Context(), ): assert correlation_id == message.correlation_id - context.reset_local("correlation_id", tag) + app.context.reset_local("correlation_id", tag) diff --git a/docs/docs_src/getting_started/lifespan/multiple.py b/docs/docs_src/getting_started/lifespan/multiple.py index f0280d4da4..d1d6fd75f6 100644 --- a/docs/docs_src/getting_started/lifespan/multiple.py +++ b/docs/docs_src/getting_started/lifespan/multiple.py @@ -1,6 +1,8 @@ +from unittest.mock import AsyncMock + from faststream import Context, ContextRepo, FastStream -app = FastStream() +app = FastStream(AsyncMock()) @app.on_startup diff --git a/docs/docs_src/getting_started/subscription/confluent/real_testing.py b/docs/docs_src/getting_started/subscription/confluent/real_testing.py index 43973935b9..fcbd09f7e4 100644 --- a/docs/docs_src/getting_started/subscription/confluent/real_testing.py +++ b/docs/docs_src/getting_started/subscription/confluent/real_testing.py @@ -1,5 +1,5 @@ import pytest -from pydantic import ValidationError +from fast_depends.exceptions import ValidationError from faststream.confluent import TestKafkaBroker diff --git a/docs/docs_src/getting_started/subscription/confluent/testing.py b/docs/docs_src/getting_started/subscription/confluent/testing.py index 57ed6acaaa..dfb2bf964d 100644 --- a/docs/docs_src/getting_started/subscription/confluent/testing.py +++ b/docs/docs_src/getting_started/subscription/confluent/testing.py @@ -1,5 +1,5 @@ import pytest -from pydantic import ValidationError +from fast_depends.exceptions import ValidationError from faststream.confluent import TestKafkaBroker diff --git a/docs/docs_src/getting_started/subscription/kafka/real_testing.py b/docs/docs_src/getting_started/subscription/kafka/real_testing.py index 0cf374b233..5eb6fd7817 100644 --- a/docs/docs_src/getting_started/subscription/kafka/real_testing.py +++ b/docs/docs_src/getting_started/subscription/kafka/real_testing.py @@ -1,5 +1,5 @@ import pytest -from pydantic import ValidationError +from fast_depends.exceptions import ValidationError from faststream.kafka import TestKafkaBroker diff --git a/docs/docs_src/getting_started/subscription/kafka/testing.py b/docs/docs_src/getting_started/subscription/kafka/testing.py index e1f6241276..cf834ff802 100644 --- a/docs/docs_src/getting_started/subscription/kafka/testing.py +++ b/docs/docs_src/getting_started/subscription/kafka/testing.py @@ -1,5 +1,5 @@ import pytest -from pydantic import ValidationError +from fast_depends.exceptions import ValidationError from faststream.kafka import TestKafkaBroker diff --git a/docs/docs_src/getting_started/subscription/nats/real_testing.py b/docs/docs_src/getting_started/subscription/nats/real_testing.py index 5e9d6e4567..c14123218c 100644 --- a/docs/docs_src/getting_started/subscription/nats/real_testing.py +++ b/docs/docs_src/getting_started/subscription/nats/real_testing.py @@ -1,5 +1,5 @@ import pytest -from pydantic import ValidationError +from fast_depends.exceptions import ValidationError from faststream.nats import TestNatsBroker diff --git a/docs/docs_src/getting_started/subscription/nats/testing.py b/docs/docs_src/getting_started/subscription/nats/testing.py index 0f7560e043..4d66a744c0 100644 --- a/docs/docs_src/getting_started/subscription/nats/testing.py +++ b/docs/docs_src/getting_started/subscription/nats/testing.py @@ -1,5 +1,5 @@ import pytest -from pydantic import ValidationError +from fast_depends.exceptions import ValidationError from faststream.nats import TestNatsBroker diff --git a/docs/docs_src/getting_started/subscription/rabbit/real_testing.py b/docs/docs_src/getting_started/subscription/rabbit/real_testing.py index 900b6046e7..7cf61a2df5 100644 --- a/docs/docs_src/getting_started/subscription/rabbit/real_testing.py +++ b/docs/docs_src/getting_started/subscription/rabbit/real_testing.py @@ -1,5 +1,5 @@ import pytest -from pydantic import ValidationError +from fast_depends.exceptions import ValidationError from faststream.rabbit import TestRabbitBroker diff --git a/docs/docs_src/getting_started/subscription/rabbit/testing.py b/docs/docs_src/getting_started/subscription/rabbit/testing.py index 78425924da..f49be05c7a 100644 --- a/docs/docs_src/getting_started/subscription/rabbit/testing.py +++ b/docs/docs_src/getting_started/subscription/rabbit/testing.py @@ -1,5 +1,5 @@ import pytest -from pydantic import ValidationError +from fast_depends.exceptions import ValidationError from faststream.rabbit import TestRabbitBroker diff --git a/docs/docs_src/getting_started/subscription/redis/real_testing.py b/docs/docs_src/getting_started/subscription/redis/real_testing.py index b2c05c203e..6514d66902 100644 --- a/docs/docs_src/getting_started/subscription/redis/real_testing.py +++ b/docs/docs_src/getting_started/subscription/redis/real_testing.py @@ -1,5 +1,5 @@ import pytest -from pydantic import ValidationError +from fast_depends.exceptions import ValidationError from faststream.redis import TestRedisBroker diff --git a/docs/docs_src/getting_started/subscription/redis/testing.py b/docs/docs_src/getting_started/subscription/redis/testing.py index 4934366f75..bb38ffd5fe 100644 --- a/docs/docs_src/getting_started/subscription/redis/testing.py +++ b/docs/docs_src/getting_started/subscription/redis/testing.py @@ -1,5 +1,5 @@ import pytest -from pydantic import ValidationError +from fast_depends.exceptions import ValidationError from faststream.redis import TestRedisBroker diff --git a/docs/docs_src/index/confluent/test.py b/docs/docs_src/index/confluent/test.py index 1cc613d157..b569184a81 100644 --- a/docs/docs_src/index/confluent/test.py +++ b/docs/docs_src/index/confluent/test.py @@ -1,7 +1,7 @@ from .pydantic import broker import pytest -import pydantic +from fast_depends.exceptions import ValidationError from faststream.confluent import TestKafkaBroker @@ -16,5 +16,5 @@ async def test_correct(): @pytest.mark.asyncio async def test_invalid(): async with TestKafkaBroker(broker) as br: - with pytest.raises(pydantic.ValidationError): + with pytest.raises(ValidationError): await br.publish("wrong message", "in-topic") diff --git a/docs/docs_src/index/kafka/test.py b/docs/docs_src/index/kafka/test.py index bfd740312c..67b57e6f12 100644 --- a/docs/docs_src/index/kafka/test.py +++ b/docs/docs_src/index/kafka/test.py @@ -1,7 +1,7 @@ from .pydantic import broker import pytest -import pydantic +from fast_depends.exceptions import ValidationError from faststream.kafka import TestKafkaBroker @@ -16,5 +16,5 @@ async def test_correct(): @pytest.mark.asyncio async def test_invalid(): async with TestKafkaBroker(broker) as br: - with pytest.raises(pydantic.ValidationError): + with pytest.raises(ValidationError): await br.publish("wrong message", "in-topic") diff --git a/docs/docs_src/index/nats/test.py b/docs/docs_src/index/nats/test.py index 85b2e6de76..ca2e71e7b9 100644 --- a/docs/docs_src/index/nats/test.py +++ b/docs/docs_src/index/nats/test.py @@ -1,7 +1,7 @@ from .pydantic import broker import pytest -import pydantic +from fast_depends.exceptions import ValidationError from faststream.nats import TestNatsBroker @@ -16,5 +16,5 @@ async def test_correct(): @pytest.mark.asyncio async def test_invalid(): async with TestNatsBroker(broker) as br: - with pytest.raises(pydantic.ValidationError): + with pytest.raises(ValidationError): await br.publish("wrong message", "in-subject") diff --git a/docs/docs_src/index/rabbit/test.py b/docs/docs_src/index/rabbit/test.py index a193db35b2..7b67df49dc 100644 --- a/docs/docs_src/index/rabbit/test.py +++ b/docs/docs_src/index/rabbit/test.py @@ -1,7 +1,7 @@ from .pydantic import broker import pytest -import pydantic +from fast_depends.exceptions import ValidationError from faststream.rabbit import TestRabbitBroker @@ -16,5 +16,5 @@ async def test_correct(): @pytest.mark.asyncio async def test_invalid(): async with TestRabbitBroker(broker) as br: - with pytest.raises(pydantic.ValidationError): + with pytest.raises(ValidationError): await br.publish("wrong message", "in-queue") diff --git a/docs/docs_src/index/redis/test.py b/docs/docs_src/index/redis/test.py index 9a14ba4190..411e032edb 100644 --- a/docs/docs_src/index/redis/test.py +++ b/docs/docs_src/index/redis/test.py @@ -1,7 +1,7 @@ from .pydantic import broker import pytest -import pydantic +from fast_depends.exceptions import ValidationError from faststream.redis import TestRedisBroker @@ -16,5 +16,5 @@ async def test_correct(): @pytest.mark.asyncio async def test_invalid(): async with TestRedisBroker(broker) as br: - with pytest.raises(pydantic.ValidationError): + with pytest.raises(ValidationError): await br.publish("wrong message", "in-channel") diff --git a/faststream/__init__.py b/faststream/__init__.py index b4241ff458..09514567a8 100644 --- a/faststream/__init__.py +++ b/faststream/__init__.py @@ -1,6 +1,5 @@ """A Python framework for building services interacting with Apache Kafka, RabbitMQ, NATS and Redis.""" -from faststream._internal.context import context from faststream._internal.testing.app import TestApp from faststream._internal.utils import apply_types from faststream.annotations import ContextRepo, Logger @@ -35,6 +34,4 @@ "TestApp", # utils "apply_types", - # context - "context", ) diff --git a/faststream/_internal/_compat.py b/faststream/_internal/_compat.py index c63389ed39..90a63aafab 100644 --- a/faststream/_internal/_compat.py +++ b/faststream/_internal/_compat.py @@ -13,14 +13,13 @@ Union, ) -from fast_depends._compat import ( # type: ignore[attr-defined] - PYDANTIC_V2, - PYDANTIC_VERSION, -) from pydantic import BaseModel +from pydantic.version import VERSION as PYDANTIC_VERSION from faststream._internal.basic_types import AnyDict +PYDANTIC_V2 = PYDANTIC_VERSION.startswith("2.") + IS_WINDOWS = ( sys.platform == "win32" or sys.platform == "cygwin" or sys.platform == "msys" ) diff --git a/faststream/_internal/application.py b/faststream/_internal/application.py index 15c389b6e8..056b11930c 100644 --- a/faststream/_internal/application.py +++ b/faststream/_internal/application.py @@ -10,11 +10,13 @@ TypeVar, ) +from fast_depends import Provider from typing_extensions import ParamSpec -from faststream._internal.context import context +from faststream._internal.constants import EMPTY +from faststream._internal.context import ContextRepo from faststream._internal.log import logger -from faststream._internal.setup.state import EmptyState +from faststream._internal.setup.state import FastDependsData from faststream._internal.utils import apply_types from faststream._internal.utils.functions import ( drop_response_type, @@ -23,6 +25,8 @@ ) if TYPE_CHECKING: + from fast_depends.library.serializer import SerializerProto + from faststream._internal.basic_types import ( AnyCallable, AsyncFunc, @@ -68,59 +72,94 @@ async def catch_startup_validation_error() -> AsyncIterator[None]: class StartAbleApplication: def __init__( self, - broker: Optional["BrokerUsecase[Any, Any]"] = None, + broker: "BrokerUsecase[Any, Any]", + /, + provider: Optional["Provider"] = None, + serializer: Optional["SerializerProto"] = EMPTY, + ) -> None: + self._init_setupable_( + broker, + provider=provider, + serializer=serializer, + ) + + def _init_setupable_( # noqa: PLW3201 + self, + broker: "BrokerUsecase[Any, Any]", + /, + provider: Optional["Provider"] = None, + serializer: Optional["SerializerProto"] = EMPTY, ) -> None: - self._state = EmptyState() + self.context = ContextRepo() + self.provider = provider or Provider() + + if serializer is EMPTY: + from fast_depends.pydantic.serializer import PydanticSerializer + + serializer = PydanticSerializer() + + self._state = FastDependsData( + use_fastdepends=True, + get_dependent=None, + call_decorators=(), + serializer=serializer, + provider=self.provider, + context=self.context, + ) self.broker = broker + self._setup() + def _setup(self) -> None: - if self.broker is not None: - self.broker._setup(self._state) + self.broker._setup(di_state=self._state) async def _start_broker(self) -> None: - if self.broker is not None: - await self.broker.connect() - self._setup() - await self.broker.start() + await self.broker.start() class Application(StartAbleApplication): def __init__( self, - *, - broker: Optional["BrokerUsecase[Any, Any]"] = None, + broker: "BrokerUsecase[Any, Any]", + /, logger: Optional["LoggerProto"] = logger, + provider: Optional["Provider"] = None, + serializer: Optional["SerializerProto"] = EMPTY, lifespan: Optional["Lifespan"] = None, on_startup: Sequence["AnyCallable"] = (), after_startup: Sequence["AnyCallable"] = (), on_shutdown: Sequence["AnyCallable"] = (), after_shutdown: Sequence["AnyCallable"] = (), ) -> None: - super().__init__(broker) + super().__init__( + broker, + provider=provider, + serializer=serializer, + ) - context.set_global("app", self) + self.context.set_global("app", self) self.logger = logger - self.context = context self._on_startup_calling: list[AsyncFunc] = [ - apply_types(to_async(x)) for x in on_startup + apply_types(to_async(x), context__=self.context) for x in on_startup ] self._after_startup_calling: list[AsyncFunc] = [ - apply_types(to_async(x)) for x in after_startup + apply_types(to_async(x), context__=self.context) for x in after_startup ] self._on_shutdown_calling: list[AsyncFunc] = [ - apply_types(to_async(x)) for x in on_shutdown + apply_types(to_async(x), context__=self.context) for x in on_shutdown ] self._after_shutdown_calling: list[AsyncFunc] = [ - apply_types(to_async(x)) for x in after_shutdown + apply_types(to_async(x), context__=self.context) for x in after_shutdown ] if lifespan is not None: self.lifespan_context = apply_types( func=lifespan, wrap_model=drop_response_type, + context__=self.context, ) else: self.lifespan_context = fake_context @@ -198,8 +237,7 @@ async def _shutdown(self, log_level: int = logging.INFO) -> None: async def stop(self) -> None: """Executes shutdown hooks and stop broker.""" async with self._shutdown_hooks_context(): - if self.broker is not None: - await self.broker.close() + await self.broker.close() @asynccontextmanager async def _shutdown_hooks_context(self) -> AsyncIterator[None]: @@ -235,13 +273,6 @@ def _log(self, level: int, message: str) -> None: if self.logger is not None: self.logger.log(level, message) - def set_broker(self, broker: "BrokerUsecase[Any, Any]") -> None: - """Set already existed App object broker. - - Useful then you create/init broker in `on_startup` hook. - """ - self.broker = broker - # Hooks def on_startup( @@ -252,7 +283,9 @@ def on_startup( This hook also takes an extra CLI options as a kwargs. """ - self._on_startup_calling.append(apply_types(to_async(func))) + self._on_startup_calling.append( + apply_types(to_async(func), context__=self.context) + ) return func def on_shutdown( @@ -260,7 +293,9 @@ def on_shutdown( func: Callable[P_HookParams, T_HookReturn], ) -> Callable[P_HookParams, T_HookReturn]: """Add hook running BEFORE broker disconnected.""" - self._on_shutdown_calling.append(apply_types(to_async(func))) + self._on_shutdown_calling.append( + apply_types(to_async(func), context__=self.context) + ) return func def after_startup( @@ -268,7 +303,9 @@ def after_startup( func: Callable[P_HookParams, T_HookReturn], ) -> Callable[P_HookParams, T_HookReturn]: """Add hook running AFTER broker connected.""" - self._after_startup_calling.append(apply_types(to_async(func))) + self._after_startup_calling.append( + apply_types(to_async(func), context__=self.context) + ) return func def after_shutdown( @@ -276,5 +313,7 @@ def after_shutdown( func: Callable[P_HookParams, T_HookReturn], ) -> Callable[P_HookParams, T_HookReturn]: """Add hook running AFTER broker disconnected.""" - self._after_shutdown_calling.append(apply_types(to_async(func))) + self._after_shutdown_calling.append( + apply_types(to_async(func), context__=self.context) + ) return func diff --git a/faststream/_internal/broker/abc_broker.py b/faststream/_internal/broker/abc_broker.py index 20aae90d1a..09be9f317f 100644 --- a/faststream/_internal/broker/abc_broker.py +++ b/faststream/_internal/broker/abc_broker.py @@ -10,7 +10,7 @@ from faststream._internal.types import BrokerMiddleware, CustomCallable, MsgType if TYPE_CHECKING: - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant from faststream._internal.publisher.proto import PublisherProto from faststream._internal.subscriber.proto import SubscriberProto @@ -24,7 +24,7 @@ def __init__( self, *, prefix: str, - dependencies: Iterable["Depends"], + dependencies: Iterable["Dependant"], middlewares: Iterable["BrokerMiddleware[MsgType]"], parser: Optional["CustomCallable"], decoder: Optional["CustomCallable"], @@ -77,7 +77,7 @@ def include_router( router: "ABCBroker[Any]", *, prefix: str = "", - dependencies: Iterable["Depends"] = (), + dependencies: Iterable["Dependant"] = (), middlewares: Iterable["BrokerMiddleware[MsgType]"] = (), include_in_schema: Optional[bool] = None, ) -> None: diff --git a/faststream/_internal/broker/broker.py b/faststream/_internal/broker/broker.py index 03d7887cba..162ea5fbc6 100644 --- a/faststream/_internal/broker/broker.py +++ b/faststream/_internal/broker/broker.py @@ -12,10 +12,13 @@ cast, ) +from fast_depends import Provider +from fast_depends.pydantic import PydanticSerializer from typing_extensions import Doc, Self from faststream._internal._compat import is_test_env -from faststream._internal.context.repository import context +from faststream._internal.constants import EMPTY +from faststream._internal.context.repository import ContextRepo from faststream._internal.setup import ( EmptyState, FastDependsData, @@ -43,7 +46,8 @@ if TYPE_CHECKING: from types import TracebackType - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant + from fast_depends.library.serializer import SerializerProto from faststream._internal.basic_types import AnyDict, Decorator from faststream._internal.publisher.proto import ( @@ -79,7 +83,7 @@ def __init__( Doc("Custom parser object."), ], dependencies: Annotated[ - Iterable["Depends"], + Iterable["Dependant"], Doc("Dependencies to apply to all broker subscribers."), ], middlewares: Annotated[ @@ -99,10 +103,7 @@ def __init__( bool, Doc("Whether to use FastDepends or not."), ], - validate: Annotated[ - bool, - Doc("Whether to cast types using Pydantic validation."), - ], + serializer: Optional["SerializerProto"] = EMPTY, _get_dependant: Annotated[ Optional[Callable[..., Any]], Doc("Custom library dependant generator callback."), @@ -172,10 +173,12 @@ def __init__( self._state = EmptyState( depends_params=FastDependsData( - apply_types=apply_types, - is_validate=validate, + use_fastdepends=apply_types, get_dependent=_get_dependant, call_decorators=_call_decorators, + serializer=PydanticSerializer() if serializer is EMPTY else serializer, + provider=Provider(), + context=ContextRepo(), ), logger_state=logger_state, ) @@ -188,6 +191,14 @@ def __init__( self.tags = tags self.security = security + @property + def context(self) -> ContextRepo: + return self._state.depends_params.context + + @property + def provider(self) -> Provider: + return self._state.depends_params.provider + async def __aenter__(self) -> "Self": await self.connect() return self @@ -225,20 +236,29 @@ async def _connect(self) -> ConnectionType: """Connect to a resource.""" raise NotImplementedError - def _setup(self, state: Optional[BaseState] = None) -> None: + def _setup(self, di_state: Optional[FastDependsData] = None) -> None: """Prepare all Broker entities to startup.""" if not self._state: - # Fallback to default state if there no - # parent container like FastStream object - default_state = self._state.copy_to_state(SetupState) - - if state: - self._state = state.copy_with_params( - depends_params=default_state.depends_params, - logger_state=default_state.logger_state, + if di_state is not None: + new_state = SetupState( + logger_state=self._state.logger_state, + depends_params=FastDependsData( + use_fastdepends=self._state.depends_params.use_fastdepends, + call_decorators=self._state.depends_params.call_decorators, + get_dependent=self._state.depends_params.get_dependent, + # from parent + serializer=di_state.serializer, + provider=di_state.provider, + context=di_state.context, + ), ) + else: - self._state = default_state + # Fallback to default state if there no + # parent container like FastStream object + new_state = self._state.copy_to_state(SetupState) + + self._state = new_state if not self.running: self.running = True @@ -266,7 +286,7 @@ def setup_subscriber( """Setup the Subscriber to prepare it to starting.""" data = self._subscriber_setup_extra.copy() data.update(kwargs) - subscriber._setup(**data) + subscriber._setup(**data, state=self._state) def setup_publisher( self, @@ -276,7 +296,7 @@ def setup_publisher( """Setup the Publisher to prepare it to starting.""" data = self._publisher_setup_extra.copy() data.update(kwargs) - publisher._setup(**data) + publisher._setup(**data, state=self._state) @property def _subscriber_setup_extra(self) -> "AnyDict": @@ -291,8 +311,6 @@ def _subscriber_setup_extra(self) -> "AnyDict": # broker options "broker_parser": self._parser, "broker_decoder": self._decoder, - # dependant args - "state": self._state, } @property @@ -331,7 +349,7 @@ async def _basic_publish( publish = producer.publish for m in self._middlewares: - publish = partial(m(None, context=context).publish_scope, publish) + publish = partial(m(None, context=self.context).publish_scope, publish) return await publish(cmd) @@ -347,7 +365,7 @@ async def _basic_publish_batch( publish = producer.publish_batch for m in self._middlewares: - publish = partial(m(None, context=context).publish_scope, publish) + publish = partial(m(None, context=self.context).publish_scope, publish) await publish(cmd) @@ -362,13 +380,15 @@ async def _basic_request( request = producer.request for m in self._middlewares: - request = partial(m(None, context=context).publish_scope, request) + request = partial(m(None, context=self.context).publish_scope, request) published_msg = await request(cmd) response_msg: Any = await process_msg( msg=published_msg, - middlewares=self._middlewares, + middlewares=( + m(published_msg, context=self.context) for m in self._middlewares + ), parser=producer._parser, decoder=producer._decoder, source_type=SourceType.Response, diff --git a/faststream/_internal/broker/router.py b/faststream/_internal/broker/router.py index 35d2b2779a..a6a49fae3a 100644 --- a/faststream/_internal/broker/router.py +++ b/faststream/_internal/broker/router.py @@ -15,7 +15,7 @@ from .abc_broker import ABCBroker if TYPE_CHECKING: - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant from faststream._internal.basic_types import AnyDict @@ -64,7 +64,7 @@ def __init__( handlers: Iterable[SubscriberRoute], # base options prefix: str, - dependencies: Iterable["Depends"], + dependencies: Iterable["Dependant"], middlewares: Iterable["BrokerMiddleware[MsgType]"], parser: Optional["CustomCallable"], decoder: Optional["CustomCallable"], diff --git a/faststream/_internal/context/__init__.py b/faststream/_internal/context/__init__.py index 89152e682f..f0a0b1d1cb 100644 --- a/faststream/_internal/context/__init__.py +++ b/faststream/_internal/context/__init__.py @@ -1,8 +1,7 @@ from .context_type import Context -from .repository import ContextRepo, context +from .repository import ContextRepo __all__ = ( "Context", "ContextRepo", - "context", ) diff --git a/faststream/_internal/context/context_type.py b/faststream/_internal/context/context_type.py index c2eb815b6e..b50e859066 100644 --- a/faststream/_internal/context/context_type.py +++ b/faststream/_internal/context/context_type.py @@ -67,6 +67,7 @@ def use(self, /, **kwargs: Any) -> AnyDict: name=name, default=self.default, initial=self.initial, + context=kwargs["context__"], ) ): kwargs[self.param_name] = v diff --git a/faststream/_internal/context/repository.py b/faststream/_internal/context/repository.py index 9990ad9bd0..eab1763088 100644 --- a/faststream/_internal/context/repository.py +++ b/faststream/_internal/context/repository.py @@ -7,8 +7,6 @@ from faststream._internal.constants import EMPTY from faststream.exceptions import ContextError -__all__ = ("ContextRepo", "context") - class ContextRepo: """A class to represent a context repository.""" @@ -171,6 +169,3 @@ def resolve(self, argument: str) -> Any: def clear(self) -> None: self._global_context = {"context": self} self._scope_context.clear() - - -context = ContextRepo() diff --git a/faststream/_internal/context/resolve.py b/faststream/_internal/context/resolve.py index bca91de33a..854229175e 100644 --- a/faststream/_internal/context/resolve.py +++ b/faststream/_internal/context/resolve.py @@ -1,14 +1,16 @@ -from typing import Any, Callable, Optional +from typing import TYPE_CHECKING, Any, Callable, Optional from faststream._internal.constants import EMPTY -from .repository import context +if TYPE_CHECKING: + from .repository import ContextRepo def resolve_context_by_name( name: str, default: Any, initial: Optional[Callable[..., Any]], + context: "ContextRepo", ) -> Any: value: Any = EMPTY diff --git a/faststream/_internal/fastapi/context.py b/faststream/_internal/fastapi/context.py index 0a76e31a19..78d8dd26a7 100644 --- a/faststream/_internal/fastapi/context.py +++ b/faststream/_internal/fastapi/context.py @@ -15,14 +15,18 @@ def Context( # noqa: N802 initial: Optional[Callable[..., Any]] = None, ) -> Any: """Get access to objects of the Context.""" - return params.Depends( - lambda: resolve_context_by_name( + + def solve_context( + context: Annotated[Any, params.Header(alias="context__")], + ) -> Any: + return resolve_context_by_name( name=name, default=default, initial=initial, - ), - use_cache=True, - ) + context=context, + ) + + return params.Depends(solve_context, use_cache=True) Logger = Annotated[logging.Logger, Context("logger")] diff --git a/faststream/_internal/fastapi/get_dependant.py b/faststream/_internal/fastapi/get_dependant.py index e21a62954a..2db1b140d9 100644 --- a/faststream/_internal/fastapi/get_dependant.py +++ b/faststream/_internal/fastapi/get_dependant.py @@ -1,6 +1,7 @@ from collections.abc import Iterable from typing import TYPE_CHECKING, Any, Callable, cast +from fast_depends.library.serializer import OptionItem from fastapi.dependencies.utils import get_dependant, get_parameterless_sub_dependant from faststream._internal._compat import PYDANTIC_V2 @@ -120,6 +121,9 @@ def _patch_fastapi_dependent(dependant: "Dependant") -> "Dependant": ) dependant.custom_fields = {} # type: ignore[attr-defined] - dependant.flat_params = params_unique # type: ignore[attr-defined] + dependant.flat_params = [ + OptionItem(field_name=name, field_type=type_, default_value=default) + for name, (type_, default) in params_unique.items() + ] # type: ignore[attr-defined] return dependant diff --git a/faststream/_internal/fastapi/route.py b/faststream/_internal/fastapi/route.py index dffe9517aa..f45b64194e 100644 --- a/faststream/_internal/fastapi/route.py +++ b/faststream/_internal/fastapi/route.py @@ -35,6 +35,7 @@ from fastapi.types import IncEx from faststream._internal.basic_types import AnyDict + from faststream._internal.setup import FastDependsData from faststream.message import StreamMessage as NativeMessage @@ -75,6 +76,7 @@ def wrap_callable_to_fastapi_compatible( response_model_exclude_unset: bool, response_model_exclude_defaults: bool, response_model_exclude_none: bool, + state: "FastDependsData", ) -> Callable[["NativeMessage[Any]"], Awaitable[Any]]: __magic_attr = "__faststream_consumer__" @@ -100,6 +102,7 @@ def wrap_callable_to_fastapi_compatible( response_model_exclude_unset=response_model_exclude_unset, response_model_exclude_defaults=response_model_exclude_defaults, response_model_exclude_none=response_model_exclude_none, + state=state, ) setattr(parsed_callable, __magic_attr, True) @@ -117,6 +120,7 @@ def build_faststream_to_fastapi_parser( response_model_exclude_unset: bool, response_model_exclude_defaults: bool, response_model_exclude_none: bool, + state: "FastDependsData", ) -> Callable[["NativeMessage[Any]"], Awaitable[Any]]: """Creates a session for handling requests.""" assert dependent.call # nosec B101 @@ -158,14 +162,14 @@ async def parsed_consumer(message: "NativeMessage[Any]") -> Any: stream_message = StreamMessage( body=fastapi_body, - headers=message.headers, + headers={"context__": state.context, **message.headers}, path={**path, **message.path}, ) else: stream_message = StreamMessage( body={}, - headers={}, + headers={"context__": state.context}, path={}, ) diff --git a/faststream/_internal/fastapi/router.py b/faststream/_internal/fastapi/router.py index 68c32f7aec..910c8a0387 100644 --- a/faststream/_internal/fastapi/router.py +++ b/faststream/_internal/fastapi/router.py @@ -26,12 +26,10 @@ from faststream._internal.application import StartAbleApplication from faststream._internal.broker.router import BrokerRouter -from faststream._internal.context.repository import context from faststream._internal.fastapi.get_dependant import get_fastapi_dependant from faststream._internal.fastapi.route import ( wrap_callable_to_fastapi_compatible, ) -from faststream._internal.setup import EmptyState from faststream._internal.types import ( MsgType, P_HandlerParams, @@ -70,7 +68,7 @@ async def __aexit__( if not exc_type and ( background := cast( Optional[BackgroundTasks], - getattr(context.get_local("message"), "background", None), + getattr(self.context.get_local("message"), "background", None), ) ): await background() @@ -131,7 +129,7 @@ def __init__( self.broker_class ), "You should specify `broker_class` at your implementation" - self.broker = self.broker_class( + broker = self.broker_class( *connection_args, middlewares=( *middlewares, @@ -144,6 +142,11 @@ def __init__( **connection_kwars, ) + self._init_setupable_( + broker, + provider=None, + ) + self.setup_state = setup_state # Specification information @@ -160,10 +163,6 @@ def __init__( self.contact = None self.schema = None - # Flag to prevent double lifespan start - self._lifespan_started = False - - self._state = EmptyState() super().__init__( prefix=prefix, @@ -197,6 +196,8 @@ def __init__( self._after_startup_hooks = [] self._on_shutdown_hooks = [] + self._lifespan_started = False + def _get_dependencies_overides_provider(self) -> Optional[Any]: """Dependency provider WeakRef resolver.""" if self.dependency_overrides_provider is not None: @@ -234,6 +235,7 @@ def wrapper( response_model_exclude_defaults=response_model_exclude_defaults, response_model_exclude_none=response_model_exclude_none, provider_factory=self._get_dependencies_overides_provider, + state=self._state, ) return wrapper @@ -317,12 +319,7 @@ async def start_broker_lifespan( self.weak_dependencies_provider.add(app) async with lifespan_context(app) as maybe_context: - if maybe_context is None: - context: AnyDict = {} - else: - context = dict(maybe_context) - - context.update({"broker": self.broker}) + lifespan_extra = {"broker": self.broker, **(maybe_context or {})} if not self._lifespan_started: await self._start_broker() @@ -334,13 +331,11 @@ async def start_broker_lifespan( ) for h in self._after_startup_hooks: - h_context = await h(app) - if h_context: # pragma: no branch - context.update(h_context) + lifespan_extra.update(await h(app) or {}) try: if self.setup_state: - yield context + yield lifespan_extra else: # NOTE: old asgi compatibility yield None diff --git a/faststream/_internal/log/logging.py b/faststream/_internal/log/logging.py index 4156b24270..7ffc83ded3 100644 --- a/faststream/_internal/log/logging.py +++ b/faststream/_internal/log/logging.py @@ -2,10 +2,14 @@ import sys from collections.abc import Mapping from logging import LogRecord +from typing import TYPE_CHECKING -from faststream._internal.context.repository import context from faststream._internal.log.formatter import ColourizedFormatter +if TYPE_CHECKING: + from faststream._internal.context.repository import ContextRepo + + logger = logging.getLogger("faststream") logger.setLevel(logging.INFO) logger.propagate = False @@ -24,15 +28,17 @@ def __init__( self, default_context: Mapping[str, str], message_id_ln: int, + context: "ContextRepo", name: str = "", ) -> None: self.default_context = default_context self.message_id_ln = message_id_ln + self.context = context super().__init__(name) def filter(self, record: LogRecord) -> bool: if is_suitable := super().filter(record): - log_context: Mapping[str, str] = context.get_local( + log_context: Mapping[str, str] = self.context.get_local( "log_context", self.default_context, ) @@ -51,11 +57,12 @@ def get_broker_logger( default_context: Mapping[str, str], message_id_ln: int, fmt: str, + context: "ContextRepo", ) -> logging.Logger: logger = logging.getLogger(f"faststream.access.{name}") logger.setLevel(logging.INFO) logger.propagate = False - logger.addFilter(ExtendedFilter(default_context, message_id_ln)) + logger.addFilter(ExtendedFilter(default_context, message_id_ln, context=context)) handler = logging.StreamHandler(stream=sys.stdout) handler.setFormatter( ColourizedFormatter( diff --git a/faststream/_internal/publisher/proto.py b/faststream/_internal/publisher/proto.py index 4037e1d285..fef4cb1b68 100644 --- a/faststream/_internal/publisher/proto.py +++ b/faststream/_internal/publisher/proto.py @@ -11,6 +11,7 @@ if TYPE_CHECKING: from faststream._internal.basic_types import SendableMessage + from faststream._internal.setup import SetupState from faststream._internal.types import ( AsyncCallable, BrokerMiddleware, @@ -102,6 +103,7 @@ def _setup( # type: ignore[override] self, *, producer: Optional["ProducerProto"], + state: "SetupState", ) -> None: ... @abstractmethod diff --git a/faststream/_internal/publisher/usecase.py b/faststream/_internal/publisher/usecase.py index fbd735a783..049ed1e5a5 100644 --- a/faststream/_internal/publisher/usecase.py +++ b/faststream/_internal/publisher/usecase.py @@ -1,6 +1,6 @@ from collections.abc import Awaitable, Iterable from functools import partial -from inspect import unwrap +from inspect import Parameter, unwrap from itertools import chain from typing import ( TYPE_CHECKING, @@ -11,11 +11,10 @@ ) from unittest.mock import MagicMock -from fast_depends._compat import create_model, get_config_base -from fast_depends.core import CallModel, build_call_model +from fast_depends.core import build_call_model +from fast_depends.pydantic._compat import create_model, get_config_base from typing_extensions import Doc, override -from faststream._internal.context.repository import context from faststream._internal.publisher.proto import PublisherProto from faststream._internal.subscriber.call_wrapper.call import HandlerCallWrapper from faststream._internal.subscriber.utils import process_msg @@ -26,12 +25,15 @@ ) from faststream.exceptions import NOT_CONNECTED_YET from faststream.message.source_type import SourceType -from faststream.specification.asyncapi.message import get_response_schema +from faststream.specification.asyncapi.message import ( + get_model_schema, +) from faststream.specification.asyncapi.utils import to_camelcase if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict from faststream._internal.publisher.proto import ProducerProto + from faststream._internal.setup import SetupState from faststream._internal.types import ( BrokerMiddleware, PublisherMiddleware, @@ -96,11 +98,10 @@ def add_middleware(self, middleware: "BrokerMiddleware[MsgType]") -> None: @override def _setup( # type: ignore[override] - self, - *, - producer: Optional["ProducerProto"], + self, *, producer: Optional["ProducerProto"], state: Optional["SetupState"] ) -> None: self._producer = producer + self._state = state def set_test( self, @@ -151,7 +152,7 @@ async def _basic_publish( ( _extra_middlewares or ( - m(None, context=context).publish_scope + m(None, context=self._state.depends_params.context).publish_scope for m in self._broker_middlewares ) ), @@ -167,6 +168,8 @@ async def _basic_request( ) -> Optional[Any]: assert self._producer, NOT_CONNECTED_YET # nosec B101 + context = self._state.depends_params.context + request = self._producer.request for pub_m in chain( @@ -179,7 +182,9 @@ async def _basic_request( response_msg: Any = await process_msg( msg=published_msg, - middlewares=self._broker_middlewares, + middlewares=( + m(published_msg, context=context) for m in self._broker_middlewares + ), parser=self._producer._parser, decoder=self._producer._decoder, source_type=SourceType.Response, @@ -197,7 +202,13 @@ async def _basic_publish_batch( pub = self._producer.publish_batch for pub_m in chain( - (m(None, context=context).publish_scope for m in self._broker_middlewares), + ( + _extra_middlewares + or ( + m(None, context=self._state.depends_params.context).publish_scope + for m in self._broker_middlewares + ) + ), self._middlewares, ): pub = partial(pub_m, pub) @@ -208,34 +219,39 @@ def get_payloads(self) -> list[tuple["AnyDict", str]]: payloads: list[tuple[AnyDict, str]] = [] if self.schema_: - params = {"response__": (self.schema_, ...)} - - call_model: CallModel[Any, Any] = CallModel( - call=lambda: None, - model=create_model("Fake"), - response_model=create_model( # type: ignore[call-overload] + body = get_model_schema( + call=create_model( "", __config__=get_config_base(), - **params, + response__=(self.schema_, ...), ), - params=params, - ) - - body = get_response_schema( - call_model, prefix=f"{self.name}:Message", ) + if body: # pragma: no branch payloads.append((body, "")) else: for call in self.calls: - call_model = build_call_model(call) - body = get_response_schema( - call_model, - prefix=f"{self.name}:Message", + call_model = build_call_model( + call, + dependency_provider=self._state.depends_params.provider, + serializer_cls=self._state.depends_params.serializer, ) - if body: - payloads.append((body, to_camelcase(unwrap(call).__name__))) + + response_type = next( + iter(call_model.serializer.response_option.values()) + ).field_type + if response_type is not None and response_type is not Parameter.empty: + body = get_model_schema( + create_model( + "", + __config__=get_config_base(), + response__=(response_type, ...), + ), + prefix=f"{self.name}:Message", + ) + if body: + payloads.append((body, to_camelcase(unwrap(call).__name__))) return payloads diff --git a/faststream/_internal/setup/fast_depends.py b/faststream/_internal/setup/fast_depends.py index aa3a664540..ad5be38da2 100644 --- a/faststream/_internal/setup/fast_depends.py +++ b/faststream/_internal/setup/fast_depends.py @@ -3,12 +3,18 @@ from typing import TYPE_CHECKING, Any, Callable, Optional if TYPE_CHECKING: + from fast_depends import Provider + from fast_depends.library.serializer import SerializerProto + from faststream._internal.basic_types import Decorator + from faststream._internal.context import ContextRepo @dataclass class FastDependsData: - apply_types: bool - is_validate: bool + use_fastdepends: bool get_dependent: Optional[Callable[..., Any]] call_decorators: Sequence["Decorator"] + provider: "Provider" + serializer: Optional["SerializerProto"] + context: "ContextRepo" diff --git a/faststream/_internal/setup/logger.py b/faststream/_internal/setup/logger.py index 45d660c687..fb7da8f493 100644 --- a/faststream/_internal/setup/logger.py +++ b/faststream/_internal/setup/logger.py @@ -1,6 +1,6 @@ import warnings from dataclasses import dataclass, field -from typing import Optional, Protocol +from typing import TYPE_CHECKING, Optional, Protocol from faststream._internal.basic_types import AnyDict, LoggerProto from faststream._internal.constants import EMPTY @@ -8,6 +8,9 @@ from .proto import SetupAble +if TYPE_CHECKING: + from faststream._internal.context import ContextRepo + __all__ = ( "DefaultLoggerStorage", "LoggerParamsStorage", @@ -105,14 +108,14 @@ def log( class LoggerParamsStorage(Protocol): def setup_log_contest(self, params: "AnyDict") -> None: ... - def get_logger(self) -> Optional["LoggerProto"]: ... + def get_logger(self, *, context: "ContextRepo") -> Optional["LoggerProto"]: ... class _EmptyLoggerStorage(LoggerParamsStorage): def setup_log_contest(self, params: AnyDict) -> None: pass - def get_logger(self) -> None: + def get_logger(self, *, context: "ContextRepo") -> None: return None @@ -123,7 +126,7 @@ def __init__(self, logger: "LoggerProto") -> None: def setup_log_contest(self, params: AnyDict) -> None: pass - def get_logger(self) -> LoggerProto: + def get_logger(self, *, context: "ContextRepo") -> LoggerProto: return self.__logger @@ -153,8 +156,8 @@ def log( exc_info=exc_info, ) - def _setup(self) -> None: - if logger := self.params_storage.get_logger(): + def _setup(self, *, context: "ContextRepo") -> None: + if logger := self.params_storage.get_logger(context=context): self.logger = _RealLoggerObject(logger) else: self.logger = _EmptyLoggerObject() diff --git a/faststream/_internal/setup/state.py b/faststream/_internal/setup/state.py index 907d8a3b56..da34c29c9e 100644 --- a/faststream/_internal/setup/state.py +++ b/faststream/_internal/setup/state.py @@ -25,7 +25,7 @@ def __bool__(self) -> bool: raise NotImplementedError def _setup(self) -> None: - self.logger_state._setup() + self.logger_state._setup(context=self.depends_params.context) def copy_with_params( self, diff --git a/faststream/_internal/subscriber/call_item.py b/faststream/_internal/subscriber/call_item.py index 6a20e3ac7c..e0d9d94255 100644 --- a/faststream/_internal/subscriber/call_item.py +++ b/faststream/_internal/subscriber/call_item.py @@ -5,7 +5,6 @@ from typing import ( TYPE_CHECKING, Any, - Callable, Generic, Optional, cast, @@ -18,9 +17,10 @@ from faststream.exceptions import IgnoredException, SetupError if TYPE_CHECKING: - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant from faststream._internal.basic_types import AsyncFuncAny, Decorator + from faststream._internal.setup import FastDependsData from faststream._internal.subscriber.call_wrapper.call import HandlerCallWrapper from faststream._internal.types import ( AsyncCallable, @@ -54,7 +54,7 @@ def __init__( item_parser: Optional["CustomCallable"], item_decoder: Optional["CustomCallable"], item_middlewares: Iterable["SubscriberMiddleware[StreamMessage[MsgType]]"], - dependencies: Iterable["Depends"], + dependencies: Iterable["Dependant"], ) -> None: self.handler = handler self.filter = filter @@ -75,10 +75,8 @@ def _setup( # type: ignore[override] *, parser: "AsyncCallable", decoder: "AsyncCallable", - broker_dependencies: Iterable["Depends"], - apply_types: bool, - is_validate: bool, - _get_dependant: Optional[Callable[..., Any]], + broker_dependencies: Iterable["Dependant"], + fast_depends_state: "FastDependsData", _call_decorators: Iterable["Decorator"], ) -> None: if self.dependant is None: @@ -88,17 +86,15 @@ def _setup( # type: ignore[override] dependencies = (*broker_dependencies, *self.dependencies) dependant = self.handler.set_wrapped( - apply_types=apply_types, - is_validate=is_validate, dependencies=dependencies, - _get_dependant=_get_dependant, _call_decorators=_call_decorators, + state=fast_depends_state, ) - if _get_dependant is None: + if fast_depends_state.get_dependent is None: self.dependant = dependant else: - self.dependant = _get_dependant( + self.dependant = fast_depends_state.get_dependent( self.handler._original_call, dependencies, ) diff --git a/faststream/_internal/subscriber/call_wrapper/call.py b/faststream/_internal/subscriber/call_wrapper/call.py index 208821ad38..ed2c3b839b 100644 --- a/faststream/_internal/subscriber/call_wrapper/call.py +++ b/faststream/_internal/subscriber/call_wrapper/call.py @@ -11,8 +11,8 @@ from unittest.mock import MagicMock import anyio +from fast_depends import inject from fast_depends.core import CallModel, build_call_model -from fast_depends.use import _InjectWrapper, inject from faststream._internal.types import ( MsgType, @@ -23,10 +23,12 @@ from faststream.exceptions import SetupError if TYPE_CHECKING: - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant + from fast_depends.use import InjectWrapper from faststream._internal.basic_types import Decorator from faststream._internal.publisher.proto import PublisherProto + from faststream._internal.setup.fast_depends import FastDependsData from faststream.message import StreamMessage @@ -144,12 +146,10 @@ def refresh(self, with_mock: bool = False) -> None: def set_wrapped( self, *, - apply_types: bool, - is_validate: bool, - dependencies: Iterable["Depends"], - _get_dependant: Optional[Callable[..., Any]], + dependencies: Iterable["Dependant"], _call_decorators: Iterable["Decorator"], - ) -> Optional["CallModel[..., Any]"]: + state: "FastDependsData", + ) -> Optional["CallModel"]: call = self._original_call for decor in _call_decorators: call = decor(call) @@ -157,16 +157,20 @@ def set_wrapped( f: Callable[..., Awaitable[Any]] = to_async(call) - dependent: Optional[CallModel[..., Any]] = None - if _get_dependant is None: + dependent: Optional[CallModel] = None + if state.get_dependent is None: dependent = build_call_model( f, - cast=is_validate, - extra_dependencies=dependencies, # type: ignore[arg-type] + extra_dependencies=dependencies, + dependency_provider=state.provider, + serializer_cls=state.serializer, ) - if apply_types: - wrapper: _InjectWrapper[Any, Any] = inject(func=None) + if state.use_fastdepends: + wrapper: InjectWrapper[Any, Any] = inject( + func=None, + context__=state.context, + ) f = wrapper(func=f, model=dependent) f = _wrap_decode_message( diff --git a/faststream/_internal/subscriber/call_wrapper/proto.py b/faststream/_internal/subscriber/call_wrapper/proto.py index 161905351a..160b054e6b 100644 --- a/faststream/_internal/subscriber/call_wrapper/proto.py +++ b/faststream/_internal/subscriber/call_wrapper/proto.py @@ -19,7 +19,7 @@ ) if TYPE_CHECKING: - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant from .call import HandlerCallWrapper @@ -36,7 +36,7 @@ def __call__( parser: Optional["CustomCallable"] = None, decoder: Optional["CustomCallable"] = None, middlewares: Iterable["SubscriberMiddleware[Any]"] = (), - dependencies: Iterable["Depends"] = (), + dependencies: Iterable["Dependant"] = (), ) -> Callable[ [Callable[P_HandlerParams, T_HandlerReturn]], "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]", @@ -54,7 +54,7 @@ def __call__( parser: Optional["CustomCallable"] = None, decoder: Optional["CustomCallable"] = None, middlewares: Iterable["SubscriberMiddleware[Any]"] = (), - dependencies: Iterable["Depends"] = (), + dependencies: Iterable["Dependant"] = (), ) -> "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]": ... def __call__( @@ -69,7 +69,7 @@ def __call__( parser: Optional["CustomCallable"] = None, decoder: Optional["CustomCallable"] = None, middlewares: Iterable["SubscriberMiddleware[Any]"] = (), - dependencies: Iterable["Depends"] = (), + dependencies: Iterable["Dependant"] = (), ) -> Union[ "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]", Callable[ diff --git a/faststream/_internal/subscriber/proto.py b/faststream/_internal/subscriber/proto.py index e376a497f9..1b42548e7a 100644 --- a/faststream/_internal/subscriber/proto.py +++ b/faststream/_internal/subscriber/proto.py @@ -1,6 +1,6 @@ from abc import abstractmethod from collections.abc import Iterable -from typing import TYPE_CHECKING, Any, Callable, Optional +from typing import TYPE_CHECKING, Any, Optional from typing_extensions import Self, override @@ -10,13 +10,14 @@ from faststream.specification.base.proto import EndpointProto if TYPE_CHECKING: - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant - from faststream._internal.basic_types import AnyDict, Decorator, LoggerProto + from faststream._internal.basic_types import AnyDict, LoggerProto from faststream._internal.publisher.proto import ( BasePublisherProto, ProducerProto, ) + from faststream._internal.setup import SetupState from faststream._internal.subscriber.call_item import HandlerItem from faststream._internal.types import ( BrokerMiddleware, @@ -36,7 +37,7 @@ class SubscriberProto( calls: list["HandlerItem[MsgType]"] running: bool - _broker_dependencies: Iterable["Depends"] + _broker_dependencies: Iterable["Dependant"] _broker_middlewares: Iterable["BrokerMiddleware[MsgType]"] _producer: Optional["ProducerProto"] @@ -56,16 +57,14 @@ def _setup( # type: ignore[override] self, *, logger: Optional["LoggerProto"], + producer: Optional["ProducerProto"], graceful_timeout: Optional[float], + extra_context: "AnyDict", + # broker options broker_parser: Optional["CustomCallable"], broker_decoder: Optional["CustomCallable"], - producer: Optional["ProducerProto"], - extra_context: "AnyDict", - # FastDepends options - apply_types: bool, - is_validate: bool, - _get_dependant: Optional[Callable[..., Any]], - _call_decorators: Iterable["Decorator"], + # dependant args + state: "SetupState", ) -> None: ... @abstractmethod @@ -105,5 +104,5 @@ def add_call( parser_: "CustomCallable", decoder_: "CustomCallable", middlewares_: Iterable["SubscriberMiddleware[Any]"], - dependencies_: Iterable["Depends"], + dependencies_: Iterable["Dependant"], ) -> Self: ... diff --git a/faststream/_internal/subscriber/usecase.py b/faststream/_internal/subscriber/usecase.py index 6eda9add2e..0133be3493 100644 --- a/faststream/_internal/subscriber/usecase.py +++ b/faststream/_internal/subscriber/usecase.py @@ -13,7 +13,6 @@ from typing_extensions import Self, override -from faststream._internal.context.repository import context from faststream._internal.subscriber.call_item import HandlerItem from faststream._internal.subscriber.call_wrapper.call import HandlerCallWrapper from faststream._internal.subscriber.proto import SubscriberProto @@ -35,9 +34,10 @@ from faststream.specification.asyncapi.utils import to_camelcase if TYPE_CHECKING: - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant from faststream._internal.basic_types import AnyDict, Decorator, LoggerProto + from faststream._internal.context.repository import ContextRepo from faststream._internal.publisher.proto import ( BasePublisherProto, ProducerProto, @@ -69,7 +69,7 @@ def __init__( parser: Optional["CustomCallable"], decoder: Optional["CustomCallable"], middlewares: Iterable["SubscriberMiddleware[Any]"], - dependencies: Iterable["Depends"], + dependencies: Iterable["Dependant"], ) -> None: self.parser = parser self.decoder = decoder @@ -85,7 +85,7 @@ class SubscriberUsecase(SubscriberProto[MsgType]): extra_context: "AnyDict" graceful_timeout: Optional[float] - _broker_dependencies: Iterable["Depends"] + _broker_dependencies: Iterable["Dependant"] _call_options: Optional["_CallOptions"] _call_decorators: Iterable["Decorator"] @@ -95,7 +95,7 @@ def __init__( no_ack: bool, no_reply: bool, retry: Union[bool, int], - broker_dependencies: Iterable["Depends"], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[MsgType]"], default_parser: "AsyncCallable", default_decoder: "AsyncCallable", @@ -151,6 +151,8 @@ def _setup( # type: ignore[override] # dependant args state: "SetupState", ) -> None: + self._state = state + self._producer = producer self.graceful_timeout = graceful_timeout self.extra_context = extra_context @@ -174,9 +176,7 @@ def _setup( # type: ignore[override] call._setup( parser=async_parser, decoder=async_decoder, - apply_types=state.depends_params.apply_types, - is_validate=state.depends_params.is_validate, - _get_dependant=state.depends_params.get_dependent, + fast_depends_state=state.depends_params, _call_decorators=( *self._call_decorators, *state.depends_params.call_decorators, @@ -209,7 +209,7 @@ def add_call( parser_: Optional["CustomCallable"], decoder_: Optional["CustomCallable"], middlewares_: Iterable["SubscriberMiddleware[Any]"], - dependencies_: Iterable["Depends"], + dependencies_: Iterable["Dependant"], ) -> Self: self._call_options = _CallOptions( parser=parser_, @@ -228,7 +228,7 @@ def __call__( parser: Optional["CustomCallable"] = None, decoder: Optional["CustomCallable"] = None, middlewares: Iterable["SubscriberMiddleware[Any]"] = (), - dependencies: Iterable["Depends"] = (), + dependencies: Iterable["Dependant"] = (), ) -> Callable[ [Callable[P_HandlerParams, T_HandlerReturn]], "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]", @@ -243,7 +243,7 @@ def __call__( parser: Optional["CustomCallable"] = None, decoder: Optional["CustomCallable"] = None, middlewares: Iterable["SubscriberMiddleware[Any]"] = (), - dependencies: Iterable["Depends"] = (), + dependencies: Iterable["Dependant"] = (), ) -> "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]": ... def __call__( @@ -254,7 +254,7 @@ def __call__( parser: Optional["CustomCallable"] = None, decoder: Optional["CustomCallable"] = None, middlewares: Iterable["SubscriberMiddleware[Any]"] = (), - dependencies: Iterable["Depends"] = (), + dependencies: Iterable["Dependant"] = (), ) -> Any: if (options := self._call_options) is None: msg = ( @@ -308,7 +308,7 @@ async def consume(self, msg: MsgType) -> Any: # Stop handler at `exit()` call await self.close() - if app := context.get("app"): + if app := self._state.depends_params.context.get("app"): app.exit() except Exception: # nosec B110 @@ -317,6 +317,8 @@ async def consume(self, msg: MsgType) -> Any: async def process_message(self, msg: MsgType) -> "Response": """Execute all message processing stages.""" + context: ContextRepo = self._state.depends_params.context + async with AsyncExitStack() as stack: stack.enter_context(self.lock) @@ -394,7 +396,6 @@ async def process_message(self, msg: MsgType) -> "Response": msg = f"There is no suitable handler for {msg=}" raise SubscriberNotFound(msg) - # An error was raised and processed by some middleware return ensure_response(None) diff --git a/faststream/_internal/subscriber/utils.py b/faststream/_internal/subscriber/utils.py index 5b6d0c990e..4dc615a9c0 100644 --- a/faststream/_internal/subscriber/utils.py +++ b/faststream/_internal/subscriber/utils.py @@ -15,7 +15,6 @@ import anyio from typing_extensions import Literal, Self, overload -from faststream._internal.context.repository import context from faststream._internal.subscriber.acknowledgement_watcher import ( WatcherContext, get_watcher, @@ -30,17 +29,17 @@ from faststream._internal.basic_types import LoggerProto from faststream._internal.types import ( AsyncCallable, - BrokerMiddleware, CustomCallable, SyncCallable, ) from faststream.message import StreamMessage + from faststream.middlewares import BaseMiddleware @overload async def process_msg( msg: Literal[None], - middlewares: Iterable["BrokerMiddleware[MsgType]"], + middlewares: Iterable["BaseMiddleware"], parser: Callable[[MsgType], Awaitable["StreamMessage[MsgType]"]], decoder: Callable[["StreamMessage[MsgType]"], "Any"], source_type: SourceType = SourceType.Consume, @@ -50,7 +49,7 @@ async def process_msg( @overload async def process_msg( msg: MsgType, - middlewares: Iterable["BrokerMiddleware[MsgType]"], + middlewares: Iterable["BaseMiddleware"], parser: Callable[[MsgType], Awaitable["StreamMessage[MsgType]"]], decoder: Callable[["StreamMessage[MsgType]"], "Any"], source_type: SourceType = SourceType.Consume, @@ -59,7 +58,7 @@ async def process_msg( async def process_msg( msg: Optional[MsgType], - middlewares: Iterable["BrokerMiddleware[MsgType]"], + middlewares: Iterable["BaseMiddleware"], parser: Callable[[MsgType], Awaitable["StreamMessage[MsgType]"]], decoder: Callable[["StreamMessage[MsgType]"], "Any"], source_type: SourceType = SourceType.Consume, @@ -74,9 +73,8 @@ async def process_msg( ] = return_input for m in middlewares: - mid = m(msg, context=context) - await stack.enter_async_context(mid) - return_msg = partial(mid.consume_scope, return_msg) + await stack.enter_async_context(m) + return_msg = partial(m.consume_scope, return_msg) parsed_msg = await parser(msg) parsed_msg._source_type = source_type diff --git a/faststream/_internal/utils/functions.py b/faststream/_internal/utils/functions.py index 3fd2eea179..be90e6f0a2 100644 --- a/faststream/_internal/utils/functions.py +++ b/faststream/_internal/utils/functions.py @@ -5,13 +5,19 @@ Any, Callable, Optional, + TypeVar, Union, overload, ) import anyio from fast_depends.core import CallModel -from fast_depends.utils import run_async as call_or_await +from fast_depends.utils import ( + is_coroutine_callable, + run_async as call_or_await, + run_in_threadpool, +) +from typing_extensions import ParamSpec from faststream._internal.basic_types import F_Return, F_Spec @@ -23,6 +29,9 @@ "to_async", ) +P = ParamSpec("P") +T = TypeVar("T") + @overload def to_async( @@ -43,11 +52,13 @@ def to_async( ], ) -> Callable[F_Spec, Awaitable[F_Return]]: """Converts a synchronous function to an asynchronous function.""" + if is_coroutine_callable(func): + return func @wraps(func) async def to_async_wrapper(*args: F_Spec.args, **kwargs: F_Spec.kwargs) -> F_Return: """Wraps a function to make it asynchronous.""" - return await call_or_await(func, *args, **kwargs) + return await run_in_threadpool(func, *args, **kwargs) return to_async_wrapper @@ -72,10 +83,8 @@ def sync_fake_context(*args: Any, **kwargs: Any) -> Iterator[None]: yield None -def drop_response_type( - model: CallModel[F_Spec, F_Return], -) -> CallModel[F_Spec, F_Return]: - model.response_model = None +def drop_response_type(model: CallModel) -> CallModel: + model.serializer.response_callback = None return model diff --git a/faststream/app.py b/faststream/app.py index c43638c839..6e31e12b62 100644 --- a/faststream/app.py +++ b/faststream/app.py @@ -15,14 +15,14 @@ from faststream._internal.basic_types import Lifespan, LoggerProto from faststream._internal.broker.broker import BrokerUsecase from faststream._internal.cli.supervisors.utils import set_exit +from faststream._internal.constants import EMPTY from faststream._internal.log import logger from faststream.asgi.app import AsgiFastStream -P_HookParams = ParamSpec("P_HookParams") -T_HookReturn = TypeVar("T_HookReturn") - - if TYPE_CHECKING: + from fast_depends import Provider + from fast_depends.library.serializer import SerializerProto + from faststream._internal.basic_types import ( AnyCallable, Lifespan, @@ -32,16 +32,21 @@ from faststream._internal.broker.broker import BrokerUsecase from faststream.asgi.types import ASGIApp +P_HookParams = ParamSpec("P_HookParams") +T_HookReturn = TypeVar("T_HookReturn") + class FastStream(Application): """A class representing a FastStream application.""" def __init__( self, - broker: Optional["BrokerUsecase[Any, Any]"] = None, + broker: "BrokerUsecase[Any, Any]", /, # regular broker args logger: Optional["LoggerProto"] = logger, + provider: Optional["Provider"] = None, + serializer: Optional["SerializerProto"] = EMPTY, lifespan: Optional["Lifespan"] = None, on_startup: Sequence["AnyCallable"] = (), after_startup: Sequence["AnyCallable"] = (), @@ -49,8 +54,10 @@ def __init__( after_shutdown: Sequence["AnyCallable"] = (), ) -> None: super().__init__( - broker=broker, + broker, logger=logger, + provider=provider, + serializer=serializer, lifespan=lifespan, on_startup=on_startup, after_startup=after_startup, @@ -66,8 +73,6 @@ async def run( sleep_time: float = 0.1, ) -> None: """Run FastStream Application.""" - assert self.broker, "You should setup a broker" # nosec B101 - set_exit(lambda *_: self.exit(), sync=False) async with self.lifespan_context(**(run_extra_options or {})): diff --git a/faststream/asgi/app.py b/faststream/asgi/app.py index 7258bccef2..b5293ea508 100644 --- a/faststream/asgi/app.py +++ b/faststream/asgi/app.py @@ -15,6 +15,7 @@ from faststream._internal._compat import HAS_TYPER, ExceptionGroup from faststream._internal.application import Application +from faststream._internal.constants import EMPTY from faststream._internal.log import logger from faststream.asgi.response import AsgiResponse from faststream.asgi.websocket import WebSocketClose @@ -24,6 +25,8 @@ from types import FrameType from anyio.abc import TaskStatus + from fast_depends import Provider + from fast_depends.library.serializer import SerializerProto from faststream._internal.basic_types import ( AnyCallable, @@ -75,11 +78,13 @@ class AsgiFastStream(Application): def __init__( self, - broker: Optional["BrokerUsecase[Any, Any]"] = None, + broker: "BrokerUsecase[Any, Any]", /, asgi_routes: Sequence[tuple[str, "ASGIApp"]] = (), # regular broker args logger: Optional["LoggerProto"] = logger, + provider: Optional["Provider"] = None, + serializer: Optional["SerializerProto"] = EMPTY, lifespan: Optional["Lifespan"] = None, # hooks on_startup: Sequence["AnyCallable"] = (), @@ -88,8 +93,10 @@ def __init__( after_shutdown: Sequence["AnyCallable"] = (), ) -> None: super().__init__( - broker=broker, + broker, logger=logger, + provider=provider, + serializer=serializer, lifespan=lifespan, on_startup=on_startup, after_startup=after_startup, diff --git a/faststream/confluent/broker/broker.py b/faststream/confluent/broker/broker.py index 4451d0e8c0..8eb7aefd87 100644 --- a/faststream/confluent/broker/broker.py +++ b/faststream/confluent/broker/broker.py @@ -36,7 +36,8 @@ from types import TracebackType from confluent_kafka import Message - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant + from fast_depends.library.serializer import SerializerProto from faststream._internal.basic_types import ( AnyDict, @@ -266,7 +267,7 @@ def __init__( Doc("Custom parser object."), ] = None, dependencies: Annotated[ - Iterable["Depends"], + Iterable["Dependant"], Doc("Dependencies to apply to all broker subscribers."), ] = (), middlewares: Annotated[ @@ -323,10 +324,7 @@ def __init__( bool, Doc("Whether to use FastDepends or not."), ] = True, - validate: Annotated[ - bool, - Doc("Whether to cast types using Pydantic validation."), - ] = True, + serializer: Optional["SerializerProto"] = EMPTY, _get_dependant: Annotated[ Optional[Callable[..., Any]], Doc("Custom library dependant generator callback."), @@ -397,7 +395,7 @@ def __init__( _get_dependant=_get_dependant, _call_decorators=_call_decorators, apply_types=apply_types, - validate=validate, + serializer=serializer, ) self.client_id = client_id self._producer = None diff --git a/faststream/confluent/broker/logging.py b/faststream/confluent/broker/logging.py index 276c571373..9e64efca0e 100644 --- a/faststream/confluent/broker/logging.py +++ b/faststream/confluent/broker/logging.py @@ -9,6 +9,7 @@ if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict, LoggerProto + from faststream._internal.context import ContextRepo class KafkaParamsStorage(DefaultLoggerStorage): @@ -35,7 +36,7 @@ def setup_log_contest(self, params: "AnyDict") -> None: ), ) - def get_logger(self) -> Optional["LoggerProto"]: + def get_logger(self, *, context: "ContextRepo") -> Optional["LoggerProto"]: message_id_ln = 10 # TODO: generate unique logger names to not share between brokers @@ -58,6 +59,7 @@ def get_logger(self) -> Optional["LoggerProto"]: f"%(message_id)-{message_id_ln}s ", "- %(message)s", )), + context=context, ) diff --git a/faststream/confluent/broker/registrator.py b/faststream/confluent/broker/registrator.py index 289ee413ac..8eb5c58326 100644 --- a/faststream/confluent/broker/registrator.py +++ b/faststream/confluent/broker/registrator.py @@ -19,7 +19,7 @@ if TYPE_CHECKING: from confluent_kafka import Message - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant from faststream._internal.types import ( CustomCallable, @@ -279,8 +279,8 @@ def subscriber( ] = None, # broker args dependencies: Annotated[ - Iterable["Depends"], - Doc("Dependencies list (`[Depends(),]`) to apply to the subscriber."), + Iterable["Dependant"], + Doc("Dependencies list (`[Dependant(),]`) to apply to the subscriber."), ] = (), parser: Annotated[ Optional["CustomCallable"], @@ -550,8 +550,8 @@ def subscriber( ] = None, # broker args dependencies: Annotated[ - Iterable["Depends"], - Doc("Dependencies list (`[Depends(),]`) to apply to the subscriber."), + Iterable["Dependant"], + Doc("Dependencies list (`[Dependant(),]`) to apply to the subscriber."), ] = (), parser: Annotated[ Optional["CustomCallable"], @@ -821,8 +821,8 @@ def subscriber( ] = None, # broker args dependencies: Annotated[ - Iterable["Depends"], - Doc("Dependencies list (`[Depends(),]`) to apply to the subscriber."), + Iterable["Dependant"], + Doc("Dependencies list (`[Dependant(),]`) to apply to the subscriber."), ] = (), parser: Annotated[ Optional["CustomCallable"], @@ -1095,8 +1095,8 @@ def subscriber( ] = None, # broker args dependencies: Annotated[ - Iterable["Depends"], - Doc("Dependencies list (`[Depends(),]`) to apply to the subscriber."), + Iterable["Dependant"], + Doc("Dependencies list (`[Dependant(),]`) to apply to the subscriber."), ] = (), parser: Annotated[ Optional["CustomCallable"], diff --git a/faststream/confluent/parser.py b/faststream/confluent/parser.py index 85063b53b2..5a04cc2248 100644 --- a/faststream/confluent/parser.py +++ b/faststream/confluent/parser.py @@ -1,23 +1,30 @@ from collections.abc import Sequence -from typing import TYPE_CHECKING, Any, Optional, Union +from typing import TYPE_CHECKING, Any, Union -from faststream._internal.context.repository import context -from faststream.confluent.message import FAKE_CONSUMER, KafkaMessage from faststream.message import decode_message +from .message import FAKE_CONSUMER, KafkaMessage + if TYPE_CHECKING: from confluent_kafka import Message from faststream._internal.basic_types import DecodedMessage - from faststream.confluent.subscriber.usecase import LogicSubscriber - from faststream.message import StreamMessage + + from .message import ConsumerProtocol, StreamMessage class AsyncConfluentParser: """A class to parse Kafka messages.""" - @staticmethod + def __init__(self, is_manual: bool = False) -> None: + self.is_manual = is_manual + self._consumer: ConsumerProtocol = FAKE_CONSUMER + + def _setup(self, consumer: "ConsumerProtocol") -> None: + self._consumer = consumer + async def parse_message( + self, message: "Message", ) -> KafkaMessage: """Parses a Kafka message.""" @@ -27,8 +34,6 @@ async def parse_message( offset = message.offset() _, timestamp = message.timestamp() - handler: Optional[LogicSubscriber[Any]] = context.get_local("handler_") - return KafkaMessage( body=body, headers=headers, @@ -37,12 +42,12 @@ async def parse_message( message_id=f"{offset}-{timestamp}", correlation_id=headers.get("correlation_id"), raw_message=message, - consumer=getattr(handler, "consumer", None) or FAKE_CONSUMER, - is_manual=getattr(handler, "is_manual", True), + consumer=self._consumer, + is_manual=self.is_manual, ) - @staticmethod async def parse_message_batch( + self, message: tuple["Message", ...], ) -> KafkaMessage: """Parses a batch of messages from a Kafka consumer.""" @@ -60,8 +65,6 @@ async def parse_message_batch( _, first_timestamp = first.timestamp() - handler: Optional[LogicSubscriber[Any]] = context.get_local("handler_") - return KafkaMessage( body=body, headers=headers, @@ -71,24 +74,23 @@ async def parse_message_batch( message_id=f"{first.offset()}-{last.offset()}-{first_timestamp}", correlation_id=headers.get("correlation_id"), raw_message=message, - consumer=getattr(handler, "consumer", None) or FAKE_CONSUMER, - is_manual=getattr(handler, "is_manual", True), + consumer=self._consumer, + is_manual=self.is_manual, ) - @staticmethod async def decode_message( + self, msg: "StreamMessage[Message]", ) -> "DecodedMessage": """Decodes a message.""" return decode_message(msg) - @classmethod async def decode_message_batch( - cls, + self, msg: "StreamMessage[tuple[Message, ...]]", ) -> "DecodedMessage": """Decode a batch of messages.""" - return [decode_message(await cls.parse_message(m)) for m in msg.raw_message] + return [decode_message(await self.parse_message(m)) for m in msg.raw_message] def _parse_msg_headers( diff --git a/faststream/confluent/publisher/producer.py b/faststream/confluent/publisher/producer.py index 0ca1a00217..fcb4328638 100644 --- a/faststream/confluent/publisher/producer.py +++ b/faststream/confluent/publisher/producer.py @@ -26,7 +26,7 @@ def __init__( self._producer = producer # NOTE: register default parser to be compatible with request - default = AsyncConfluentParser + default = AsyncConfluentParser() self._parser = resolve_custom_func(parser, default.parse_message) self._decoder = resolve_custom_func(decoder, default.decode_message) diff --git a/faststream/confluent/router.py b/faststream/confluent/router.py index 2d7f599d18..cd1fc9509c 100644 --- a/faststream/confluent/router.py +++ b/faststream/confluent/router.py @@ -20,7 +20,7 @@ if TYPE_CHECKING: from confluent_kafka import Message - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant from faststream._internal.basic_types import SendableMessage from faststream._internal.types import ( @@ -365,8 +365,8 @@ def __init__( ] = None, # broker args dependencies: Annotated[ - Iterable["Depends"], - Doc("Dependencies list (`[Depends(),]`) to apply to the subscriber."), + Iterable["Dependant"], + Doc("Dependencies list (`[Dependant(),]`) to apply to the subscriber."), ] = (), parser: Annotated[ Optional["CustomCallable"], @@ -473,9 +473,9 @@ def __init__( ] = (), *, dependencies: Annotated[ - Iterable["Depends"], + Iterable["Dependant"], Doc( - "Dependencies list (`[Depends(),]`) to apply to all routers' publishers/subscribers.", + "Dependencies list (`[Dependant(),]`) to apply to all routers' publishers/subscribers.", ), ] = (), middlewares: Annotated[ diff --git a/faststream/confluent/subscriber/factory.py b/faststream/confluent/subscriber/factory.py index c1d4a2d444..24107e56be 100644 --- a/faststream/confluent/subscriber/factory.py +++ b/faststream/confluent/subscriber/factory.py @@ -14,7 +14,7 @@ if TYPE_CHECKING: from confluent_kafka import Message as ConfluentMsg - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant from faststream._internal.basic_types import AnyDict from faststream._internal.types import BrokerMiddleware @@ -36,7 +36,7 @@ def create_subscriber( no_ack: bool, no_reply: bool, retry: bool, - broker_dependencies: Iterable["Depends"], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[tuple[ConfluentMsg, ...]]"], # Specification args title_: Optional[str], @@ -60,7 +60,7 @@ def create_subscriber( no_ack: bool, no_reply: bool, retry: bool, - broker_dependencies: Iterable["Depends"], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[ConfluentMsg]"], # Specification args title_: Optional[str], @@ -84,7 +84,7 @@ def create_subscriber( no_ack: bool, no_reply: bool, retry: bool, - broker_dependencies: Iterable["Depends"], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable[ "BrokerMiddleware[Union[ConfluentMsg, tuple[ConfluentMsg, ...]]]" ], @@ -112,7 +112,7 @@ def create_subscriber( no_ack: bool, no_reply: bool, retry: bool, - broker_dependencies: Iterable["Depends"], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable[ "BrokerMiddleware[Union[ConfluentMsg, tuple[ConfluentMsg, ...]]]" ], diff --git a/faststream/confluent/subscriber/usecase.py b/faststream/confluent/subscriber/usecase.py index be1ce66dfa..470fb57840 100644 --- a/faststream/confluent/subscriber/usecase.py +++ b/faststream/confluent/subscriber/usecase.py @@ -20,7 +20,7 @@ from faststream.confluent.schemas import TopicPartition if TYPE_CHECKING: - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant from faststream._internal.basic_types import AnyDict, LoggerProto from faststream._internal.publisher.proto import BasePublisherProto, ProducerProto @@ -42,6 +42,7 @@ class LogicSubscriber(ABC, SubscriberUsecase[MsgType]): builder: Optional[Callable[..., "AsyncConfluentConsumer"]] consumer: Optional["AsyncConfluentConsumer"] + parser: AsyncConfluentParser task: Optional["asyncio.Task[None]"] client_id: Optional[str] @@ -54,14 +55,13 @@ def __init__( # Kafka information group_id: Optional[str], connection_data: "AnyDict", - is_manual: bool, # Subscriber args default_parser: "AsyncCallable", default_decoder: "AsyncCallable", no_ack: bool, no_reply: bool, retry: bool, - broker_dependencies: Iterable["Depends"], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[MsgType]"], # AsyncAPI args title_: Optional[str], @@ -88,7 +88,6 @@ def __init__( self.group_id = group_id self.topics = topics self.partitions = partitions - self.is_manual = is_manual self.consumer = None self.task = None @@ -140,6 +139,7 @@ async def start(self) -> None: client_id=self.client_id, **self.__connection_data, ) + self.parser._setup(consumer) await consumer.start() await super().start() @@ -174,7 +174,10 @@ async def get_one( return await process_msg( msg=raw_message, - middlewares=self._broker_middlewares, + middlewares=( + m(raw_message, context=self._state.depends_params.context) + for m in self._broker_middlewares + ), parser=self._parser, decoder=self._decoder, ) @@ -263,23 +266,24 @@ def __init__( no_ack: bool, no_reply: bool, retry: bool, - broker_dependencies: Iterable["Depends"], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[Message]"], # AsyncAPI args title_: Optional[str], description_: Optional[str], include_in_schema: bool, ) -> None: + self.parser = AsyncConfluentParser(is_manual=is_manual) + super().__init__( *topics, partitions=partitions, polling_interval=polling_interval, group_id=group_id, connection_data=connection_data, - is_manual=is_manual, # subscriber args - default_parser=AsyncConfluentParser.parse_message, - default_decoder=AsyncConfluentParser.decode_message, + default_parser=self.parser.parse_message, + default_decoder=self.parser.decode_message, # Propagated args no_ack=no_ack, no_reply=no_reply, @@ -327,7 +331,7 @@ def __init__( no_ack: bool, no_reply: bool, retry: bool, - broker_dependencies: Iterable["Depends"], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[tuple[Message, ...]]"], # AsyncAPI args title_: Optional[str], @@ -336,16 +340,17 @@ def __init__( ) -> None: self.max_records = max_records + self.parser = AsyncConfluentParser(is_manual=is_manual) + super().__init__( *topics, partitions=partitions, polling_interval=polling_interval, group_id=group_id, connection_data=connection_data, - is_manual=is_manual, # subscriber args - default_parser=AsyncConfluentParser.parse_message_batch, - default_decoder=AsyncConfluentParser.decode_message_batch, + default_parser=self.parser.parse_message_batch, + default_decoder=self.parser.decode_message_batch, # Propagated args no_ack=no_ack, no_reply=no_reply, diff --git a/faststream/confluent/testing.py b/faststream/confluent/testing.py index 973a7fb58d..27a81703e3 100644 --- a/faststream/confluent/testing.py +++ b/faststream/confluent/testing.py @@ -94,7 +94,7 @@ class FakeProducer(AsyncConfluentFastProducer): def __init__(self, broker: KafkaBroker) -> None: self.broker = broker - default = AsyncConfluentParser + default = AsyncConfluentParser() self._parser = resolve_custom_func(broker._parser, default.parse_message) self._decoder = resolve_custom_func(broker._decoder, default.decode_message) diff --git a/faststream/kafka/broker/broker.py b/faststream/kafka/broker/broker.py index ce2969b12b..3564d52c9c 100644 --- a/faststream/kafka/broker/broker.py +++ b/faststream/kafka/broker/broker.py @@ -41,7 +41,8 @@ from aiokafka import ConsumerRecord from aiokafka.abc import AbstractTokenProvider - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant + from fast_depends.library.serializer import SerializerProto from typing_extensions import TypedDict, Unpack from faststream._internal.basic_types import ( @@ -440,7 +441,7 @@ def __init__( Doc("Custom parser object."), ] = None, dependencies: Annotated[ - Iterable["Depends"], + Iterable["Dependant"], Doc("Dependencies to apply to all broker subscribers."), ] = (), middlewares: Annotated[ @@ -497,10 +498,7 @@ def __init__( bool, Doc("Whether to use FastDepends or not."), ] = True, - validate: Annotated[ - bool, - Doc("Whether to cast types using Pydantic validation."), - ] = True, + serializer: Optional["SerializerProto"] = EMPTY, _get_dependant: Annotated[ Optional[Callable[..., Any]], Doc("Custom library dependant generator callback."), @@ -578,7 +576,7 @@ def __init__( _get_dependant=_get_dependant, _call_decorators=_call_decorators, apply_types=apply_types, - validate=validate, + serializer=serializer, ) self.client_id = client_id diff --git a/faststream/kafka/broker/logging.py b/faststream/kafka/broker/logging.py index c39b71a604..9518a4f7ec 100644 --- a/faststream/kafka/broker/logging.py +++ b/faststream/kafka/broker/logging.py @@ -9,6 +9,7 @@ if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict, LoggerProto + from faststream._internal.context import ContextRepo class KafkaParamsStorage(DefaultLoggerStorage): @@ -35,7 +36,7 @@ def setup_log_contest(self, params: "AnyDict") -> None: ), ) - def get_logger(self) -> Optional["LoggerProto"]: + def get_logger(self, *, context: "ContextRepo") -> Optional["LoggerProto"]: message_id_ln = 10 # TODO: generate unique logger names to not share between brokers @@ -58,6 +59,7 @@ def get_logger(self) -> Optional["LoggerProto"]: f"%(message_id)-{message_id_ln}s ", "- %(message)s", )), + context=context, ) diff --git a/faststream/kafka/broker/registrator.py b/faststream/kafka/broker/registrator.py index 8a7efeff2f..b5b7c4b0d9 100644 --- a/faststream/kafka/broker/registrator.py +++ b/faststream/kafka/broker/registrator.py @@ -23,7 +23,7 @@ from aiokafka import TopicPartition from aiokafka.abc import ConsumerRebalanceListener from aiokafka.coordinator.assignors.abstract import AbstractPartitionAssignor - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant from faststream._internal.types import ( CustomCallable, @@ -381,8 +381,8 @@ def subscriber( ] = (), # broker args dependencies: Annotated[ - Iterable["Depends"], - Doc("Dependencies list (`[Depends(),]`) to apply to the subscriber."), + Iterable["Dependant"], + Doc("Dependencies list (`[Dependant(),]`) to apply to the subscriber."), ] = (), parser: Annotated[ Optional["CustomCallable"], @@ -751,8 +751,8 @@ def subscriber( ] = (), # broker args dependencies: Annotated[ - Iterable["Depends"], - Doc("Dependencies list (`[Depends(),]`) to apply to the subscriber."), + Iterable["Dependant"], + Doc("Dependencies list (`[Dependant(),]`) to apply to the subscriber."), ] = (), parser: Annotated[ Optional["CustomCallable"], @@ -1121,8 +1121,8 @@ def subscriber( ] = (), # broker args dependencies: Annotated[ - Iterable["Depends"], - Doc("Dependencies list (`[Depends(),]`) to apply to the subscriber."), + Iterable["Dependant"], + Doc("Dependencies list (`[Dependant(),]`) to apply to the subscriber."), ] = (), parser: Annotated[ Optional["CustomCallable"], @@ -1494,8 +1494,8 @@ def subscriber( ] = (), # broker args dependencies: Annotated[ - Iterable["Depends"], - Doc("Dependencies list (`[Depends(),]`) to apply to the subscriber."), + Iterable["Dependant"], + Doc("Dependencies list (`[Dependant(),]`) to apply to the subscriber."), ] = (), parser: Annotated[ Optional["CustomCallable"], diff --git a/faststream/kafka/parser.py b/faststream/kafka/parser.py index c4ce947a34..94275cc041 100644 --- a/faststream/kafka/parser.py +++ b/faststream/kafka/parser.py @@ -1,7 +1,6 @@ from typing import TYPE_CHECKING, Any, Optional, cast -from faststream._internal.context.repository import context -from faststream.kafka.message import FAKE_CONSUMER, KafkaMessage +from faststream.kafka.message import FAKE_CONSUMER, ConsumerProtocol, KafkaMessage from faststream.message import decode_message if TYPE_CHECKING: @@ -10,7 +9,6 @@ from aiokafka import ConsumerRecord from faststream._internal.basic_types import DecodedMessage - from faststream.kafka.subscriber.usecase import LogicSubscriber from faststream.message import StreamMessage @@ -25,13 +23,17 @@ def __init__( self.msg_class = msg_class self.regex = regex + self._consumer: ConsumerProtocol = FAKE_CONSUMER + + def _setup(self, consumer: ConsumerProtocol) -> None: + self._consumer = consumer + async def parse_message( self, message: "ConsumerRecord", ) -> "StreamMessage[ConsumerRecord]": """Parses a Kafka message.""" headers = {i: j.decode() for i, j in message.headers} - handler: Optional[LogicSubscriber[Any]] = context.get_local("handler_") return self.msg_class( body=message.value, @@ -42,7 +44,7 @@ async def parse_message( correlation_id=headers.get("correlation_id"), raw_message=message, path=self.get_path(message.topic), - consumer=getattr(handler, "consumer", None) or FAKE_CONSUMER, + consumer=self._consumer, ) async def decode_message( @@ -76,8 +78,6 @@ async def parse_message( headers = next(iter(batch_headers), {}) - handler: Optional[LogicSubscriber[Any]] = context.get_local("handler_") - return self.msg_class( body=body, headers=headers, @@ -88,7 +88,7 @@ async def parse_message( correlation_id=headers.get("correlation_id"), raw_message=message, path=self.get_path(first.topic), - consumer=getattr(handler, "consumer", None) or FAKE_CONSUMER, + consumer=self._consumer, ) async def decode_message( diff --git a/faststream/kafka/router.py b/faststream/kafka/router.py index e79e422e8b..1652e52901 100644 --- a/faststream/kafka/router.py +++ b/faststream/kafka/router.py @@ -23,7 +23,7 @@ from aiokafka import ConsumerRecord, TopicPartition from aiokafka.abc import ConsumerRebalanceListener from aiokafka.coordinator.assignors.abstract import AbstractPartitionAssignor - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant from faststream._internal.basic_types import SendableMessage from faststream._internal.types import ( @@ -468,8 +468,8 @@ def __init__( ] = (), # broker args dependencies: Annotated[ - Iterable["Depends"], - Doc("Dependencies list (`[Depends(),]`) to apply to the subscriber."), + Iterable["Dependant"], + Doc("Dependencies list (`[Dependant(),]`) to apply to the subscriber."), ] = (), parser: Annotated[ Optional["CustomCallable"], @@ -583,9 +583,9 @@ def __init__( ] = (), *, dependencies: Annotated[ - Iterable["Depends"], + Iterable["Dependant"], Doc( - "Dependencies list (`[Depends(),]`) to apply to all routers' publishers/subscribers.", + "Dependencies list (`[Dependant(),]`) to apply to all routers' publishers/subscribers.", ), ] = (), middlewares: Annotated[ diff --git a/faststream/kafka/subscriber/factory.py b/faststream/kafka/subscriber/factory.py index b4ae8638f1..e53654283e 100644 --- a/faststream/kafka/subscriber/factory.py +++ b/faststream/kafka/subscriber/factory.py @@ -16,7 +16,7 @@ if TYPE_CHECKING: from aiokafka import ConsumerRecord, TopicPartition from aiokafka.abc import ConsumerRebalanceListener - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant from faststream._internal.basic_types import AnyDict from faststream._internal.types import BrokerMiddleware @@ -39,7 +39,7 @@ def create_subscriber( no_ack: bool, no_reply: bool, retry: bool, - broker_dependencies: Iterable["Depends"], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[tuple[ConsumerRecord, ...]]"], # Specification args title_: Optional[str], @@ -65,7 +65,7 @@ def create_subscriber( no_ack: bool, no_reply: bool, retry: bool, - broker_dependencies: Iterable["Depends"], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[ConsumerRecord]"], # Specification args title_: Optional[str], @@ -91,7 +91,7 @@ def create_subscriber( no_ack: bool, no_reply: bool, retry: bool, - broker_dependencies: Iterable["Depends"], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable[ "BrokerMiddleware[Union[ConsumerRecord, tuple[ConsumerRecord, ...]]]" ], @@ -121,7 +121,7 @@ def create_subscriber( no_ack: bool, no_reply: bool, retry: bool, - broker_dependencies: Iterable["Depends"], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable[ "BrokerMiddleware[Union[ConsumerRecord, tuple[ConsumerRecord, ...]]]" ], diff --git a/faststream/kafka/subscriber/usecase.py b/faststream/kafka/subscriber/usecase.py index 4d12aa9abd..03dae21687 100644 --- a/faststream/kafka/subscriber/usecase.py +++ b/faststream/kafka/subscriber/usecase.py @@ -30,7 +30,7 @@ if TYPE_CHECKING: from aiokafka import AIOKafkaConsumer, ConsumerRecord from aiokafka.abc import ConsumerRebalanceListener - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant from faststream._internal.basic_types import AnyDict, LoggerProto from faststream._internal.publisher.proto import BasePublisherProto, ProducerProto @@ -50,6 +50,7 @@ class LogicSubscriber(SubscriberUsecase[MsgType]): task: Optional["asyncio.Task[None]"] client_id: Optional[str] batch: bool + parser: AioKafkaParser def __init__( self, @@ -66,7 +67,7 @@ def __init__( no_ack: bool, no_reply: bool, retry: bool, - broker_dependencies: Iterable["Depends"], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[MsgType]"], # AsyncAPI args title_: Optional[str], @@ -143,6 +144,8 @@ async def start(self) -> None: **self.__connection_args, ) + self.parser._setup(consumer) + if self.topics or self._pattern: consumer.subscribe( topics=self.topics, @@ -194,7 +197,10 @@ async def get_one( msg: StreamMessage[MsgType] = await process_msg( msg=raw_message, - middlewares=self._broker_middlewares, + middlewares=( + m(raw_message, context=self._state.depends_params.context) + for m in self._broker_middlewares + ), parser=self._parser, decoder=self._decoder, ) @@ -289,7 +295,7 @@ def __init__( no_ack: bool, no_reply: bool, retry: bool, - broker_dependencies: Iterable["Depends"], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[ConsumerRecord]"], # AsyncAPI args title_: Optional[str], @@ -306,7 +312,7 @@ def __init__( else: reg = None - parser = AioKafkaParser( + self.parser = AioKafkaParser( msg_class=KafkaAckableMessage if is_manual else KafkaMessage, regex=reg, ) @@ -319,8 +325,8 @@ def __init__( connection_args=connection_args, partitions=partitions, # subscriber args - default_parser=parser.parse_message, - default_decoder=parser.decode_message, + default_parser=self.parser.parse_message, + default_decoder=self.parser.decode_message, # Propagated args no_ack=no_ack, no_reply=no_reply, @@ -370,7 +376,7 @@ def __init__( no_ack: bool, no_reply: bool, retry: bool, - broker_dependencies: Iterable["Depends"], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable[ "BrokerMiddleware[Sequence[tuple[ConsumerRecord, ...]]]" ], @@ -392,7 +398,7 @@ def __init__( else: reg = None - parser = AioKafkaBatchParser( + self.parser = AioKafkaBatchParser( msg_class=KafkaAckableMessage if is_manual else KafkaMessage, regex=reg, ) @@ -405,8 +411,8 @@ def __init__( connection_args=connection_args, partitions=partitions, # subscriber args - default_parser=parser.parse_message, - default_decoder=parser.decode_message, + default_parser=self.parser.parse_message, + default_decoder=self.parser.decode_message, # Propagated args no_ack=no_ack, no_reply=no_reply, diff --git a/faststream/middlewares/exception.py b/faststream/middlewares/exception.py index 8530bb8a77..eb18aa4f24 100644 --- a/faststream/middlewares/exception.py +++ b/faststream/middlewares/exception.py @@ -12,7 +12,6 @@ from typing_extensions import Literal, TypeAlias -from faststream._internal.context import context from faststream._internal.utils import apply_types from faststream._internal.utils.functions import sync_fake_context, to_async from faststream.exceptions import IgnoredException @@ -183,7 +182,7 @@ async def consume_scope( for handler_type, handler in self._publish_handlers: if issubclass(exc_type, handler_type): - return await handler(exc) + return await handler(exc, context__=self.context) raise @@ -199,13 +198,13 @@ async def after_processed( # TODO: remove it after context will be moved to middleware # In case parser/decoder error occurred scope: AbstractContextManager[Any] - if not context.get_local("message"): - scope = context.scope("message", self.msg) + if not self.context.get_local("message"): + scope = self.context.scope("message", self.msg) else: scope = sync_fake_context() with scope: - await handler(exc_val) + await handler(exc_val, context__=self.context) return True @@ -214,5 +213,8 @@ async def after_processed( return None -async def ignore_handler(exception: IgnoredException) -> NoReturn: +async def ignore_handler( + exception: IgnoredException, + **kwargs: Any, # suppress context +) -> NoReturn: raise exception diff --git a/faststream/middlewares/logging.py b/faststream/middlewares/logging.py index f24d507266..2c82299532 100644 --- a/faststream/middlewares/logging.py +++ b/faststream/middlewares/logging.py @@ -1,7 +1,6 @@ import logging from typing import TYPE_CHECKING, Any, Optional -from faststream._internal.context.repository import context from faststream.exceptions import IgnoredException from faststream.message.source_type import SourceType @@ -59,7 +58,7 @@ async def consume_scope( if source_type is not SourceType.Response: self.logger.log( "Received", - extra=context.get_local("log_context", {}), + extra=self.context.get_local("log_context", {}), ) return await call_next(msg) @@ -72,7 +71,7 @@ async def __aexit__( ) -> bool: """Asynchronously called after processing.""" if self._source_type is not SourceType.Response: - c = context.get_local("log_context", {}) + c = self.context.get_local("log_context", {}) if exc_type: if issubclass(exc_type, IgnoredException): diff --git a/faststream/nats/broker/broker.py b/faststream/nats/broker/broker.py index 09aed61b54..4aa6812c6a 100644 --- a/faststream/nats/broker/broker.py +++ b/faststream/nats/broker/broker.py @@ -42,12 +42,14 @@ from .logging import make_nats_logger_state from .registrator import NatsRegistrator +from .state import BrokerState, ConnectedState, EmptyBrokerState if TYPE_CHECKING: import ssl from types import TracebackType - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant + from fast_depends.library.serializer import SerializerProto from nats.aio.client import ( Callback, Credentials, @@ -56,7 +58,6 @@ SignatureCallback, ) from nats.js.api import Placement, RePublish, StorageType - from nats.js.client import JetStreamContext from nats.js.kv import KeyValue from nats.js.object_store import ObjectStore from typing_extensions import TypedDict, Unpack @@ -223,12 +224,11 @@ class NatsBroker( """A class to represent a NATS broker.""" url: list[str] - stream: Optional["JetStreamContext"] - _producer: Optional["NatsFastProducer"] - _js_producer: Optional["NatsJSFastProducer"] - _kv_declarer: Optional["KVBucketDeclarer"] - _os_declarer: Optional["OSBucketDeclarer"] + _producer: "NatsFastProducer" + _js_producer: "NatsJSFastProducer" + _kv_declarer: "KVBucketDeclarer" + _os_declarer: "OSBucketDeclarer" def __init__( self, @@ -387,7 +387,7 @@ def __init__( Doc("Custom parser object."), ] = None, dependencies: Annotated[ - Iterable["Depends"], + Iterable["Dependant"], Doc("Dependencies to apply to all broker subscribers."), ] = (), middlewares: Annotated[ @@ -439,10 +439,7 @@ def __init__( bool, Doc("Whether to use FastDepends or not."), ] = True, - validate: Annotated[ - bool, - Doc("Whether to cast types using Pydantic validation."), - ] = True, + serializer: Optional["SerializerProto"] = EMPTY, _get_dependant: Annotated[ Optional[Callable[..., Any]], Doc("Custom library dependant generator callback."), @@ -545,19 +542,25 @@ def __init__( ), # FastDepends args apply_types=apply_types, - validate=validate, + serializer=serializer, _get_dependant=_get_dependant, _call_decorators=_call_decorators, ) - self.__is_connected = False - self._producer = None + self._producer = NatsFastProducer( + decoder=self._decoder, + parser=self._parser, + ) - # JS options - self.stream = None - self._js_producer = None - self._kv_declarer = None - self._os_declarer = None + self._js_producer = NatsJSFastProducer( + decoder=self._decoder, + parser=self._parser, + ) + + self._kv_declarer = KVBucketDeclarer() + self._os_declarer = OSBucketDeclarer() + + self._connection_state: BrokerState = EmptyBrokerState() @override async def connect( # type: ignore[override] @@ -583,25 +586,17 @@ async def connect( # type: ignore[override] return await super().connect(**connect_kwargs) async def _connect(self, **kwargs: Any) -> "Client": - self.__is_connected = True connection = await nats.connect(**kwargs) - self._producer = NatsFastProducer( - connection=connection, - decoder=self._decoder, - parser=self._parser, - ) + stream = connection.jetstream() - stream = self.stream = connection.jetstream() + self._producer.connect(connection) + self._js_producer.connect(stream) - self._js_producer = NatsJSFastProducer( - connection=stream, - decoder=self._decoder, - parser=self._parser, - ) + self._kv_declarer.connect(stream) + self._os_declarer.connect(stream) - self._kv_declarer = KVBucketDeclarer(stream) - self._os_declarer = OSBucketDeclarer(stream) + self._connection_state = ConnectedState(connection, stream) return connection @@ -617,24 +612,26 @@ async def close( await self._connection.drain() self._connection = None - self.stream = None - self._producer = None - self._js_producer = None - self.__is_connected = False + self._producer.disconnect() + self._js_producer.disconnect() + self._kv_declarer.disconnect() + self._os_declarer.disconnect() + + self._connection_state = EmptyBrokerState() async def start(self) -> None: """Connect broker to NATS cluster and startup all subscribers.""" await self.connect() self._setup() - assert self.stream, "Broker should be started already" # nosec B101 + stream_context = self._connection_state.stream for stream in filter( lambda x: x.declare, self._stream_builder.objects.values(), ): try: - await self.stream.add_stream( + await stream_context.add_stream( config=stream.config, subjects=stream.subjects, ) @@ -651,15 +648,14 @@ async def start(self) -> None: e.description == "stream name already in use with a different configuration" ): - old_config = (await self.stream.stream_info(stream.name)).config + old_config = (await stream_context.stream_info(stream.name)).config self._state.logger_state.log(str(e), logging.WARNING, log_context) - await self.stream.update_stream( - config=stream.config, - subjects=tuple( - set(old_config.subjects or ()).union(stream.subjects), - ), - ) + + for subject in old_config.subjects or (): + stream.add_subject(subject) + + await stream_context.update_stream(config=stream.config) else: # pragma: no cover self._state.logger_state.log( @@ -803,29 +799,11 @@ def setup_subscriber( # type: ignore[override] self, subscriber: "SpecificationSubscriber", ) -> None: - connection: Union[ - Client, - JetStreamContext, - KVBucketDeclarer, - OSBucketDeclarer, - None, - ] = None - - if getattr(subscriber, "kv_watch", None): - connection = self._kv_declarer - - elif getattr(subscriber, "obj_watch", None): - connection = self._os_declarer - - elif getattr(subscriber, "stream", None): - connection = self.stream - - else: - connection = self._connection - return super().setup_subscriber( subscriber, - connection=connection, + connection_state=self._connection_state, + kv_declarer=self._kv_declarer, + os_declarer=self._os_declarer, ) @override @@ -833,14 +811,7 @@ def setup_publisher( # type: ignore[override] self, publisher: "SpecificationPublisher", ) -> None: - producer: Optional[ProducerProto] = None - - if publisher.stream is not None: - if self._js_producer is not None: - producer = self._js_producer - - elif self._producer is not None: - producer = self._producer + producer = self._producer if publisher.stream is None else self._js_producer super().setup_publisher(publisher, producer=producer) @@ -861,8 +832,6 @@ async def key_value( # custom declare: bool = True, ) -> "KeyValue": - assert self._kv_declarer, "Broker should be connected already." # nosec B101 - return await self._kv_declarer.create_key_value( bucket=bucket, description=description, @@ -891,8 +860,6 @@ async def object_storage( # custom declare: bool = True, ) -> "ObjectStore": - assert self._os_declarer, "Broker should be connected already." # nosec B101 - return await self._os_declarer.create_object_store( bucket=bucket, description=description, @@ -914,14 +881,14 @@ async def wrapper(err: Exception) -> None: if error_cb is not None: await error_cb(err) - if isinstance(err, Error) and self.__is_connected: + if isinstance(err, Error) and self._connection_state: self._state.logger_state.log( f"Connection broken with {err!r}", logging.WARNING, c, exc_info=err, ) - self.__is_connected = False + self._connection_state = self._connection_state.brake() return wrapper @@ -935,9 +902,9 @@ async def wrapper() -> None: if cb is not None: await cb() - if not self.__is_connected: + if not self._connection_state: self._state.logger_state.log("Connection established", logging.INFO, c) - self.__is_connected = True + self._connection_state = self._connection_state.reconnect() return wrapper diff --git a/faststream/nats/broker/logging.py b/faststream/nats/broker/logging.py index f4e2500cdb..0238e2208d 100644 --- a/faststream/nats/broker/logging.py +++ b/faststream/nats/broker/logging.py @@ -9,6 +9,7 @@ if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict, LoggerProto + from faststream._internal.context import ContextRepo class NatsParamsStorage(DefaultLoggerStorage): @@ -42,7 +43,7 @@ def setup_log_contest(self, params: "AnyDict") -> None: ), ) - def get_logger(self) -> Optional["LoggerProto"]: + def get_logger(self, *, context: "ContextRepo") -> Optional["LoggerProto"]: message_id_ln = 10 # TODO: generate unique logger names to not share between brokers @@ -67,6 +68,7 @@ def get_logger(self) -> Optional["LoggerProto"]: f"%(message_id)-{message_id_ln}s - ", "%(message)s", )), + context=context, ) diff --git a/faststream/nats/broker/registrator.py b/faststream/nats/broker/registrator.py index 811f1ab847..4ff8f0fbda 100644 --- a/faststream/nats/broker/registrator.py +++ b/faststream/nats/broker/registrator.py @@ -13,7 +13,7 @@ from faststream.nats.subscriber.specified import SpecificationSubscriber if TYPE_CHECKING: - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant from nats.aio.msg import Msg from faststream._internal.types import ( @@ -141,8 +141,8 @@ def subscriber( # type: ignore[override] ] = None, # broker arguments dependencies: Annotated[ - Iterable["Depends"], - Doc("Dependencies list (`[Depends(),]`) to apply to the subscriber."), + Iterable["Dependant"], + Doc("Dependencies list (`[Dependant(),]`) to apply to the subscriber."), ] = (), parser: Annotated[ Optional["CustomCallable"], @@ -346,7 +346,7 @@ def include_router( # type: ignore[override] router: "NatsRegistrator", *, prefix: str = "", - dependencies: Iterable["Depends"] = (), + dependencies: Iterable["Dependant"] = (), middlewares: Iterable["BrokerMiddleware[Msg]"] = (), include_in_schema: Optional[bool] = None, ) -> None: diff --git a/faststream/nats/broker/state.py b/faststream/nats/broker/state.py new file mode 100644 index 0000000000..08b5821597 --- /dev/null +++ b/faststream/nats/broker/state.py @@ -0,0 +1,78 @@ +from typing import TYPE_CHECKING, Protocol + +from faststream.exceptions import IncorrectState + +if TYPE_CHECKING: + from nats.aio.client import Client + from nats.js import JetStreamContext + + +class BrokerState(Protocol): + stream: "JetStreamContext" + connection: "Client" + + def __bool__(self) -> bool: ... + + def brake(self) -> "BrokerState": ... + + def reconnect(self) -> "BrokerState": ... + + +class EmptyBrokerState(BrokerState): + @property + def connection(self) -> "Client": + msg = "Connection is not available yet. Please, connect the broker first." + raise IncorrectState(msg) + + @property + def stream(self) -> "JetStreamContext": + msg = "Stream is not available yet. Please, connect the broker first." + raise IncorrectState(msg) + + def brake(self) -> "BrokerState": + return self + + def reconnect(self) -> "BrokerState": + msg = "You can't reconnect an empty state. Please, connect the broker first." + raise IncorrectState(msg) + + def __bool__(self) -> bool: + return False + + +class ConnectedState(BrokerState): + def __init__( + self, + connection: "Client", + stream: "JetStreamContext", + ) -> None: + self.connection = connection + self.stream = stream + + def __bool__(self) -> bool: + return True + + def brake(self) -> "ConnectionBrokenState": + return ConnectionBrokenState( + connection=self.connection, + stream=self.stream, + ) + + +class ConnectionBrokenState(BrokerState): + def __init__( + self, + connection: "Client", + stream: "JetStreamContext", + ) -> None: + self.connection = connection + self.stream = stream + + def __bool__(self) -> bool: + return False + + def reconnect(self) -> "ConnectedState": + return ConnectedState( + connection=self.connection, + stream=self.stream, + ) diff --git a/faststream/nats/fastapi/__init__.py b/faststream/nats/fastapi/__init__.py index 18a28e4e8d..b7aa38c664 100644 --- a/faststream/nats/fastapi/__init__.py +++ b/faststream/nats/fastapi/__init__.py @@ -6,7 +6,6 @@ from faststream._internal.fastapi.context import Context, ContextRepo, Logger from faststream.nats.broker import NatsBroker as NB from faststream.nats.message import NatsMessage as NM -from faststream.nats.publisher.producer import NatsFastProducer, NatsJSFastProducer from .fastapi import NatsRouter @@ -14,8 +13,6 @@ NatsBroker = Annotated[NB, Context("broker")] Client = Annotated[NatsClient, Context("broker._connection")] JsClient = Annotated[JetStreamContext, Context("broker._stream")] -NatsProducer = Annotated[NatsFastProducer, Context("broker._producer")] -NatsJsProducer = Annotated[NatsJSFastProducer, Context("broker._js_producer")] __all__ = ( "Client", @@ -24,8 +21,6 @@ "JsClient", "Logger", "NatsBroker", - "NatsJsProducer", "NatsMessage", - "NatsProducer", "NatsRouter", ) diff --git a/faststream/nats/helpers/bucket_declarer.py b/faststream/nats/helpers/bucket_declarer.py index 2a0c3f68e4..617eb4edad 100644 --- a/faststream/nats/helpers/bucket_declarer.py +++ b/faststream/nats/helpers/bucket_declarer.py @@ -2,6 +2,8 @@ from nats.js.api import KeyValueConfig +from .state import ConnectedState, ConnectionState, EmptyConnectionState + if TYPE_CHECKING: from nats.js import JetStreamContext from nats.js.api import Placement, RePublish, StorageType @@ -11,10 +13,17 @@ class KVBucketDeclarer: buckets: dict[str, "KeyValue"] - def __init__(self, connection: "JetStreamContext") -> None: - self._connection = connection + def __init__(self) -> None: self.buckets = {} + self.__state: ConnectionState[JetStreamContext] = EmptyConnectionState() + + def connect(self, connection: "JetStreamContext") -> None: + self.__state = ConnectedState(connection) + + def disconnect(self) -> None: + self.__state = EmptyConnectionState() + async def create_key_value( self, bucket: str, @@ -34,7 +43,7 @@ async def create_key_value( ) -> "KeyValue": if (key_value := self.buckets.get(bucket)) is None: if declare: - key_value = await self._connection.create_key_value( + key_value = await self.__state.connection.create_key_value( config=KeyValueConfig( bucket=bucket, description=description, @@ -50,7 +59,7 @@ async def create_key_value( ), ) else: - key_value = await self._connection.key_value(bucket) + key_value = await self.__state.connection.key_value(bucket) self.buckets[bucket] = key_value diff --git a/faststream/nats/helpers/obj_storage_declarer.py b/faststream/nats/helpers/obj_storage_declarer.py index f137fa1586..f0f31918d7 100644 --- a/faststream/nats/helpers/obj_storage_declarer.py +++ b/faststream/nats/helpers/obj_storage_declarer.py @@ -2,6 +2,8 @@ from nats.js.api import ObjectStoreConfig +from .state import ConnectedState, ConnectionState, EmptyConnectionState + if TYPE_CHECKING: from nats.js import JetStreamContext from nats.js.api import Placement, StorageType @@ -11,10 +13,17 @@ class OSBucketDeclarer: buckets: dict[str, "ObjectStore"] - def __init__(self, connection: "JetStreamContext") -> None: - self._connection = connection + def __init__(self) -> None: self.buckets = {} + self.__state: ConnectionState[JetStreamContext] = EmptyConnectionState() + + def connect(self, connection: "JetStreamContext") -> None: + self.__state = ConnectedState(connection) + + def disconnect(self) -> None: + self.__state = EmptyConnectionState() + async def create_object_store( self, bucket: str, @@ -30,7 +39,7 @@ async def create_object_store( ) -> "ObjectStore": if (object_store := self.buckets.get(bucket)) is None: if declare: - object_store = await self._connection.create_object_store( + object_store = await self.__state.connection.create_object_store( bucket=bucket, config=ObjectStoreConfig( bucket=bucket, @@ -43,7 +52,7 @@ async def create_object_store( ), ) else: - object_store = await self._connection.object_store(bucket) + object_store = await self.__state.connection.object_store(bucket) self.buckets[bucket] = object_store diff --git a/faststream/nats/helpers/state.py b/faststream/nats/helpers/state.py new file mode 100644 index 0000000000..91c9f84ff7 --- /dev/null +++ b/faststream/nats/helpers/state.py @@ -0,0 +1,27 @@ +from typing import Protocol, TypeVar + +from nats.aio.client import Client +from nats.js import JetStreamContext + +from faststream.exceptions import IncorrectState + +ClientT = TypeVar("ClientT", Client, JetStreamContext) + + +class ConnectionState(Protocol[ClientT]): + connection: ClientT + + +class EmptyConnectionState(ConnectionState[ClientT]): + __slots__ = () + + @property + def connection(self) -> ClientT: + raise IncorrectState + + +class ConnectedState(ConnectionState[ClientT]): + __slots__ = ("connection",) + + def __init__(self, connection: ClientT) -> None: + self.connection = connection diff --git a/faststream/nats/publisher/producer.py b/faststream/nats/publisher/producer.py index 2af4fdfc48..f2ed4715e0 100644 --- a/faststream/nats/publisher/producer.py +++ b/faststream/nats/publisher/producer.py @@ -9,6 +9,11 @@ from faststream._internal.subscriber.utils import resolve_custom_func from faststream.exceptions import FeatureNotSupportedException from faststream.message import encode_message +from faststream.nats.helpers.state import ( + ConnectedState, + ConnectionState, + EmptyConnectionState, +) from faststream.nats.parser import NatsParser if TYPE_CHECKING: @@ -32,16 +37,21 @@ class NatsFastProducer(ProducerProto): def __init__( self, *, - connection: "Client", parser: Optional["CustomCallable"], decoder: Optional["CustomCallable"], ) -> None: - self._connection = connection - default = NatsParser(pattern="", no_ack=False) self._parser = resolve_custom_func(parser, default.parse_message) self._decoder = resolve_custom_func(decoder, default.decode_message) + self.__state: ConnectionState[Client] = EmptyConnectionState() + + def connect(self, connection: "Client") -> None: + self.__state = ConnectedState(connection) + + def disconnect(self) -> None: + self.__state = EmptyConnectionState() + @override async def publish( # type: ignore[override] self, @@ -54,7 +64,7 @@ async def publish( # type: ignore[override] **cmd.headers_to_publish(), } - await self._connection.publish( + await self.__state.connection.publish( subject=cmd.destination, payload=payload, reply=cmd.reply_to, @@ -73,7 +83,7 @@ async def request( # type: ignore[override] **cmd.headers_to_publish(), } - return await self._connection.request( + return await self.__state.connection.request( subject=cmd.destination, payload=payload, headers=headers_to_send, @@ -98,16 +108,21 @@ class NatsJSFastProducer(ProducerProto): def __init__( self, *, - connection: "JetStreamContext", parser: Optional["CustomCallable"], decoder: Optional["CustomCallable"], ) -> None: - self._connection = connection - default = NatsParser(pattern="", no_ack=False) self._parser = resolve_custom_func(parser, default.parse_message) self._decoder = resolve_custom_func(decoder, default.decode_message) + self.__state: ConnectionState[JetStreamContext] = EmptyConnectionState() + + def connect(self, connection: "Client") -> None: + self.__state = ConnectedState(connection) + + def disconnect(self) -> None: + self.__state = EmptyConnectionState() + @override async def publish( # type: ignore[override] self, @@ -120,7 +135,7 @@ async def publish( # type: ignore[override] **cmd.headers_to_publish(js=True), } - await self._connection.publish( + await self.__state.connection.publish( subject=cmd.destination, payload=payload, headers=headers_to_send, @@ -137,9 +152,11 @@ async def request( # type: ignore[override] ) -> "Msg": payload, content_type = encode_message(cmd.body) - reply_to = self._connection._nc.new_inbox() + reply_to = self.__state.connection._nc.new_inbox() future: asyncio.Future[Msg] = asyncio.Future() - sub = await self._connection._nc.subscribe(reply_to, future=future, max_msgs=1) + sub = await self.__state.connection._nc.subscribe( + reply_to, future=future, max_msgs=1 + ) await sub.unsubscribe(limit=1) headers_to_send = { @@ -149,7 +166,7 @@ async def request( # type: ignore[override] } with anyio.fail_after(cmd.timeout): - await self._connection.publish( + await self.__state.connection.publish( subject=cmd.destination, payload=payload, headers=headers_to_send, diff --git a/faststream/nats/router.py b/faststream/nats/router.py index 982f274b50..3b98073050 100644 --- a/faststream/nats/router.py +++ b/faststream/nats/router.py @@ -19,7 +19,7 @@ from faststream.nats.broker.registrator import NatsRegistrator if TYPE_CHECKING: - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant from nats.aio.msg import Msg from faststream._internal.basic_types import SendableMessage @@ -231,8 +231,8 @@ def __init__( ] = None, # broker arguments dependencies: Annotated[ - Iterable["Depends"], - Doc("Dependencies list (`[Depends(),]`) to apply to the subscriber."), + Iterable["Dependant"], + Doc("Dependencies list (`[Dependant(),]`) to apply to the subscriber."), ] = (), parser: Annotated[ Optional["CustomCallable"], @@ -334,9 +334,9 @@ def __init__( ] = (), *, dependencies: Annotated[ - Iterable["Depends"], + Iterable["Dependant"], Doc( - "Dependencies list (`[Depends(),]`) to apply to all routers' publishers/subscribers.", + "Dependencies list (`[Dependant(),]`) to apply to all routers' publishers/subscribers.", ), ] = (), middlewares: Annotated[ diff --git a/faststream/nats/schemas/js_stream.py b/faststream/nats/schemas/js_stream.py index da6e41f3bf..0d9b23ac4f 100644 --- a/faststream/nats/schemas/js_stream.py +++ b/faststream/nats/schemas/js_stream.py @@ -194,6 +194,7 @@ def __init__( self.subjects = subjects self.declare = declare + self.config = StreamConfig( name=name, description=description, diff --git a/faststream/nats/subscriber/factory.py b/faststream/nats/subscriber/factory.py index f2853f06b9..613a76a535 100644 --- a/faststream/nats/subscriber/factory.py +++ b/faststream/nats/subscriber/factory.py @@ -25,7 +25,7 @@ ) if TYPE_CHECKING: - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant from nats.js import api from faststream._internal.basic_types import AnyDict @@ -62,7 +62,7 @@ def create_subscriber( no_ack: bool, no_reply: bool, retry: Union[bool, int], - broker_dependencies: Iterable["Depends"], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[Any]"], # Specification information title_: Optional[str], diff --git a/faststream/nats/subscriber/specified.py b/faststream/nats/subscriber/specified.py index 09320906a4..ee3bf32bdb 100644 --- a/faststream/nats/subscriber/specified.py +++ b/faststream/nats/subscriber/specified.py @@ -21,7 +21,7 @@ from faststream.specification.schema.operation import Operation -class SpecificationSubscriber(LogicSubscriber[Any, Any]): +class SpecificationSubscriber(LogicSubscriber[Any]): """A class to represent a NATS handler.""" def get_name(self) -> str: diff --git a/faststream/nats/subscriber/state.py b/faststream/nats/subscriber/state.py new file mode 100644 index 0000000000..d8e2825d83 --- /dev/null +++ b/faststream/nats/subscriber/state.py @@ -0,0 +1,60 @@ +from typing import TYPE_CHECKING, Protocol + +from faststream.exceptions import IncorrectState + +if TYPE_CHECKING: + from nats.aio.client import Client + from nats.js import JetStreamContext + + from faststream.nats.broker.state import BrokerState + from faststream.nats.helpers import KVBucketDeclarer, OSBucketDeclarer + + +class SubscriberState(Protocol): + client: "Client" + js: "JetStreamContext" + kv_declarer: "KVBucketDeclarer" + os_declarer: "OSBucketDeclarer" + + +class EmptySubscriberState(SubscriberState): + @property + def client(self) -> "Client": + msg = "Connection is not available yet. Please, setup the subscriber first." + raise IncorrectState(msg) + + @property + def js(self) -> "JetStreamContext": + msg = "Stream is not available yet. Please, setup the subscriber first." + raise IncorrectState(msg) + + @property + def kv_declarer(self) -> "KVBucketDeclarer": + msg = "KeyValue is not available yet. Please, setup the subscriber first." + raise IncorrectState(msg) + + @property + def os_declarer(self) -> "OSBucketDeclarer": + msg = "ObjectStorage is not available yet. Please, setup the subscriber first." + raise IncorrectState(msg) + + +class ConnectedSubscriberState(SubscriberState): + def __init__( + self, + *, + parent_state: "BrokerState", + kv_declarer: "KVBucketDeclarer", + os_declarer: "OSBucketDeclarer", + ) -> None: + self._parent_state = parent_state + self.kv_declarer = kv_declarer + self.os_declarer = os_declarer + + @property + def client(self) -> "Client": + return self._parent_state.connection + + @property + def js(self) -> "JetStreamContext": + return self._parent_state.stream diff --git a/faststream/nats/subscriber/usecase.py b/faststream/nats/subscriber/usecase.py index b3493d69e2..9f15f00456 100644 --- a/faststream/nats/subscriber/usecase.py +++ b/faststream/nats/subscriber/usecase.py @@ -8,23 +8,21 @@ Callable, Generic, Optional, - TypeVar, Union, cast, ) import anyio -from fast_depends.dependencies import Depends +from fast_depends.dependencies import Dependant from nats.errors import ConnectionClosedError, TimeoutError from nats.js.api import ConsumerConfig, ObjectInfo from typing_extensions import Doc, override -from faststream._internal.context.repository import context from faststream._internal.subscriber.mixins import ConcurrentMixin, TasksMixin from faststream._internal.subscriber.usecase import SubscriberUsecase from faststream._internal.subscriber.utils import process_msg from faststream._internal.types import MsgType -from faststream.exceptions import NOT_CONNECTED_YET +from faststream.nats.helpers import KVBucketDeclarer, OSBucketDeclarer from faststream.nats.message import NatsMessage from faststream.nats.parser import ( BatchParser, @@ -40,8 +38,9 @@ Unsubscriptable, ) +from .state import ConnectedSubscriberState, EmptySubscriberState, SubscriberState + if TYPE_CHECKING: - from nats.aio.client import Client from nats.aio.msg import Msg from nats.aio.subscription import Subscription from nats.js import JetStreamContext @@ -61,21 +60,18 @@ CustomCallable, ) from faststream.message import StreamMessage + from faststream.nats.broker.state import BrokerState from faststream.nats.helpers import KVBucketDeclarer, OSBucketDeclarer from faststream.nats.message import NatsKvMessage, NatsObjMessage from faststream.nats.schemas import JStream, KvWatch, ObjWatch, PullSub -ConnectionType = TypeVar("ConnectionType") - - -class LogicSubscriber(SubscriberUsecase[MsgType], Generic[ConnectionType, MsgType]): +class LogicSubscriber(SubscriberUsecase[MsgType], Generic[MsgType]): """A class to represent a NATS handler.""" subscription: Optional[Unsubscriptable] _fetch_sub: Optional[Unsubscriptable] producer: Optional["ProducerProto"] - _connection: Optional[ConnectionType] def __init__( self, @@ -89,7 +85,7 @@ def __init__( no_ack: bool, no_reply: bool, retry: Union[bool, int], - broker_dependencies: Iterable[Depends], + broker_dependencies: Iterable[Dependant], broker_middlewares: Iterable["BrokerMiddleware[MsgType]"], # AsyncAPI args title_: Optional[str], @@ -116,16 +112,19 @@ def __init__( include_in_schema=include_in_schema, ) - self._connection = None self._fetch_sub = None self.subscription = None self.producer = None + self._connection_state: SubscriberState = EmptySubscriberState() + @override def _setup( # type: ignore[override] self, *, - connection: ConnectionType, + connection_state: "BrokerState", + os_declarer: "OSBucketDeclarer", + kv_declarer: "KVBucketDeclarer", # basic args logger: Optional["LoggerProto"], producer: Optional["ProducerProto"], @@ -137,7 +136,11 @@ def _setup( # type: ignore[override] # dependant args state: "SetupState", ) -> None: - self._connection = connection + self._connection_state = ConnectedSubscriberState( + parent_state=connection_state, + os_declarer=os_declarer, + kv_declarer=kv_declarer, + ) super()._setup( logger=logger, @@ -157,12 +160,10 @@ def clear_subject(self) -> str: async def start(self) -> None: """Create NATS subscription and start consume tasks.""" - assert self._connection, NOT_CONNECTED_YET # nosec B101 - await super().start() if self.calls: - await self._create_subscription(connection=self._connection) + await self._create_subscription() async def close(self) -> None: """Clean up handler subscription, cancel consume task in graceful mode.""" @@ -177,11 +178,7 @@ async def close(self) -> None: self.subscription = None @abstractmethod - async def _create_subscription( - self, - *, - connection: ConnectionType, - ) -> None: + async def _create_subscription(self) -> None: """Create NATS subscription object to consume messages.""" raise NotImplementedError @@ -227,7 +224,7 @@ def _resolved_subject_string(self) -> str: return self.subject or ", ".join(self.config.filter_subjects or ()) -class _DefaultSubscriber(LogicSubscriber[ConnectionType, MsgType]): +class _DefaultSubscriber(LogicSubscriber[MsgType]): def __init__( self, *, @@ -241,7 +238,7 @@ def __init__( no_ack: bool, no_reply: bool, retry: Union[bool, int], - broker_dependencies: Iterable[Depends], + broker_dependencies: Iterable[Dependant], broker_middlewares: Iterable["BrokerMiddleware[MsgType]"], # AsyncAPI args title_: Optional[str], @@ -296,7 +293,7 @@ def get_log_context( ) -class CoreSubscriber(_DefaultSubscriber["Client", "Msg"]): +class CoreSubscriber(_DefaultSubscriber["Msg"]): subscription: Optional["Subscription"] _fetch_sub: Optional["Subscription"] @@ -312,7 +309,7 @@ def __init__( no_ack: bool, no_reply: bool, retry: Union[bool, int], - broker_dependencies: Iterable[Depends], + broker_dependencies: Iterable[Dependant], broker_middlewares: Iterable["BrokerMiddleware[Msg]"], # AsyncAPI args title_: Optional[str], @@ -348,13 +345,12 @@ async def get_one( *, timeout: float = 5.0, ) -> "Optional[NatsMessage]": - assert self._connection, "Please, start() subscriber first" # nosec B101 assert ( # nosec B101 not self.calls ), "You can't use `get_one` method if subscriber has registered handlers." if self._fetch_sub is None: - fetch_sub = self._fetch_sub = await self._connection.subscribe( + fetch_sub = self._fetch_sub = await self._connection_state.client.subscribe( subject=self.clear_subject, queue=self.queue, **self.extra_options, @@ -369,23 +365,22 @@ async def get_one( msg: NatsMessage = await process_msg( # type: ignore[assignment] msg=raw_message, - middlewares=self._broker_middlewares, + middlewares=( + m(raw_message, context=self._state.depends_params.context) + for m in self._broker_middlewares + ), parser=self._parser, decoder=self._decoder, ) return msg @override - async def _create_subscription( - self, - *, - connection: "Client", - ) -> None: + async def _create_subscription(self) -> None: """Create NATS subscription and start consume task.""" if self.subscription: return - self.subscription = await connection.subscribe( + self.subscription = await self._connection_state.client.subscribe( subject=self.clear_subject, queue=self.queue, cb=self.consume, @@ -424,7 +419,7 @@ def __init__( no_ack: bool, no_reply: bool, retry: Union[bool, int], - broker_dependencies: Iterable[Depends], + broker_dependencies: Iterable[Dependant], broker_middlewares: Iterable["BrokerMiddleware[Msg]"], # AsyncAPI args title_: Optional[str], @@ -451,18 +446,14 @@ def __init__( ) @override - async def _create_subscription( - self, - *, - connection: "Client", - ) -> None: + async def _create_subscription(self) -> None: """Create NATS subscription and start consume task.""" if self.subscription: return self.start_consume_task() - self.subscription = await connection.subscribe( + self.subscription = await self._connection_state.client.subscribe( subject=self.clear_subject, queue=self.queue, cb=self._put_msg, @@ -470,7 +461,7 @@ async def _create_subscription( ) -class _StreamSubscriber(_DefaultSubscriber["JetStreamContext", "Msg"]): +class _StreamSubscriber(_DefaultSubscriber["Msg"]): _fetch_sub: Optional["JetStreamContext.PullSubscription"] def __init__( @@ -486,7 +477,7 @@ def __init__( no_ack: bool, no_reply: bool, retry: Union[bool, int], - broker_dependencies: Iterable[Depends], + broker_dependencies: Iterable[Dependant], broker_middlewares: Iterable["BrokerMiddleware[Msg]"], # AsyncAPI args title_: Optional[str], @@ -538,7 +529,6 @@ async def get_one( *, timeout: float = 5, ) -> Optional["NatsMessage"]: - assert self._connection, "Please, start() subscriber first" # nosec B101 assert ( # nosec B101 not self.calls ), "You can't use `get_one` method if subscriber has registered handlers." @@ -553,7 +543,7 @@ async def get_one( if inbox_prefix := self.extra_options.get("inbox_prefix"): extra_options["inbox_prefix"] = inbox_prefix - self._fetch_sub = await self._connection.pull_subscribe( + self._fetch_sub = await self._connection_state.js.pull_subscribe( subject=self.clear_subject, config=self.config, **extra_options, @@ -571,7 +561,10 @@ async def get_one( msg: NatsMessage = await process_msg( # type: ignore[assignment] msg=raw_message, - middlewares=self._broker_middlewares, + middlewares=( + m(raw_message, context=self._state.depends_params.context) + for m in self._broker_middlewares + ), parser=self._parser, decoder=self._decoder, ) @@ -582,16 +575,12 @@ class PushStreamSubscription(_StreamSubscriber): subscription: Optional["JetStreamContext.PushSubscription"] @override - async def _create_subscription( - self, - *, - connection: "JetStreamContext", - ) -> None: + async def _create_subscription(self) -> None: """Create NATS subscription and start consume task.""" if self.subscription: return - self.subscription = await connection.subscribe( + self.subscription = await self._connection_state.js.subscribe( subject=self.clear_subject, queue=self.queue, cb=self.consume, @@ -620,7 +609,7 @@ def __init__( no_ack: bool, no_reply: bool, retry: Union[bool, int], - broker_dependencies: Iterable[Depends], + broker_dependencies: Iterable[Dependant], broker_middlewares: Iterable["BrokerMiddleware[Msg]"], # AsyncAPI args title_: Optional[str], @@ -648,18 +637,14 @@ def __init__( ) @override - async def _create_subscription( - self, - *, - connection: "JetStreamContext", - ) -> None: + async def _create_subscription(self) -> None: """Create NATS subscription and start consume task.""" if self.subscription: return self.start_consume_task() - self.subscription = await connection.subscribe( + self.subscription = await self._connection_state.js.subscribe( subject=self.clear_subject, queue=self.queue, cb=self._put_msg, @@ -687,7 +672,7 @@ def __init__( no_ack: bool, no_reply: bool, retry: Union[bool, int], - broker_dependencies: Iterable[Depends], + broker_dependencies: Iterable[Dependant], broker_middlewares: Iterable["BrokerMiddleware[Msg]"], # AsyncAPI args title_: Optional[str], @@ -716,16 +701,12 @@ def __init__( ) @override - async def _create_subscription( - self, - *, - connection: "JetStreamContext", - ) -> None: + async def _create_subscription(self) -> None: """Create NATS subscription and start consume task.""" if self.subscription: return - self.subscription = await connection.pull_subscribe( + self.subscription = await self._connection_state.js.pull_subscribe( subject=self.clear_subject, config=self.config, **self.extra_options, @@ -771,7 +752,7 @@ def __init__( no_ack: bool, no_reply: bool, retry: Union[bool, int], - broker_dependencies: Iterable[Depends], + broker_dependencies: Iterable[Dependant], broker_middlewares: Iterable["BrokerMiddleware[Msg]"], # AsyncAPI args title_: Optional[str], @@ -799,18 +780,14 @@ def __init__( ) @override - async def _create_subscription( - self, - *, - connection: "JetStreamContext", - ) -> None: + async def _create_subscription(self) -> None: """Create NATS subscription and start consume task.""" if self.subscription: return self.start_consume_task() - self.subscription = await connection.pull_subscribe( + self.subscription = await self._connection_state.js.pull_subscribe( subject=self.clear_subject, config=self.config, **self.extra_options, @@ -820,7 +797,7 @@ async def _create_subscription( class BatchPullStreamSubscriber( TasksMixin, - _DefaultSubscriber["JetStreamContext", list["Msg"]], + _DefaultSubscriber[list["Msg"]], ): """Batch-message consumer class.""" @@ -840,7 +817,7 @@ def __init__( no_ack: bool, no_reply: bool, retry: Union[bool, int], - broker_dependencies: Iterable[Depends], + broker_dependencies: Iterable[Dependant], broker_middlewares: Iterable["BrokerMiddleware[list[Msg]]"], # AsyncAPI args title_: Optional[str], @@ -877,13 +854,14 @@ async def get_one( *, timeout: float = 5, ) -> Optional["NatsMessage"]: - assert self._connection, "Please, start() subscriber first" # nosec B101 assert ( # nosec B101 not self.calls ), "You can't use `get_one` method if subscriber has registered handlers." if not self._fetch_sub: - fetch_sub = self._fetch_sub = await self._connection.pull_subscribe( + fetch_sub = ( + self._fetch_sub + ) = await self._connection_state.js.pull_subscribe( subject=self.clear_subject, config=self.config, **self.extra_options, @@ -903,23 +881,22 @@ async def get_one( NatsMessage, await process_msg( msg=raw_message, - middlewares=self._broker_middlewares, + middlewares=( + m(raw_message, context=self._state.depends_params.context) + for m in self._broker_middlewares + ), parser=self._parser, decoder=self._decoder, ), ) @override - async def _create_subscription( - self, - *, - connection: "JetStreamContext", - ) -> None: + async def _create_subscription(self) -> None: """Create NATS subscription and start consume task.""" if self.subscription: return - self.subscription = await connection.pull_subscribe( + self.subscription = await self._connection_state.js.pull_subscribe( subject=self.clear_subject, config=self.config, **self.extra_options, @@ -943,7 +920,7 @@ async def _consume_pull(self) -> None: class KeyValueWatchSubscriber( TasksMixin, - LogicSubscriber["KVBucketDeclarer", "KeyValue.Entry"], + LogicSubscriber["KeyValue.Entry"], ): subscription: Optional["UnsubscribeAdapter[KeyValue.KeyWatcher]"] _fetch_sub: Optional[UnsubscribeAdapter["KeyValue.KeyWatcher"]] @@ -954,7 +931,7 @@ def __init__( subject: str, config: "ConsumerConfig", kv_watch: "KvWatch", - broker_dependencies: Iterable[Depends], + broker_dependencies: Iterable[Dependant], broker_middlewares: Iterable["BrokerMiddleware[KeyValue.Entry]"], # AsyncAPI args title_: Optional[str], @@ -987,13 +964,12 @@ async def get_one( *, timeout: float = 5, ) -> Optional["NatsKvMessage"]: - assert self._connection, "Please, start() subscriber first" # nosec B101 assert ( # nosec B101 not self.calls ), "You can't use `get_one` method if subscriber has registered handlers." if not self._fetch_sub: - bucket = await self._connection.create_key_value( + bucket = await self._connection_state.kv_declarer.create_key_value( bucket=self.kv_watch.name, declare=self.kv_watch.declare, ) @@ -1014,28 +990,28 @@ async def get_one( sleep_interval = timeout / 10 with anyio.move_on_after(timeout): while ( # noqa: ASYNC110 - raw_message := await fetch_sub.obj.updates(timeout) # type: ignore[no-untyped-call] + # type: ignore[no-untyped-call] + raw_message := await fetch_sub.obj.updates(timeout) ) is None: await anyio.sleep(sleep_interval) msg: NatsKvMessage = await process_msg( msg=raw_message, - middlewares=self._broker_middlewares, + middlewares=( + m(raw_message, context=self._state.depends_params.context) + for m in self._broker_middlewares + ), parser=self._parser, decoder=self._decoder, ) return msg @override - async def _create_subscription( - self, - *, - connection: "KVBucketDeclarer", - ) -> None: + async def _create_subscription(self) -> None: if self.subscription: return - bucket = await connection.create_key_value( + bucket = await self._connection_state.kv_declarer.create_key_value( bucket=self.kv_watch.name, declare=self.kv_watch.declare, ) @@ -1050,9 +1026,9 @@ async def _create_subscription( ), ) - self.add_task(self._consume_watch()) + self.add_task(self.__consume_watch()) - async def _consume_watch(self) -> None: + async def __consume_watch(self) -> None: assert self.subscription, "You should call `create_subscription` at first." # nosec B101 key_watcher = self.subscription.obj @@ -1061,7 +1037,8 @@ async def _consume_watch(self) -> None: with suppress(ConnectionClosedError, TimeoutError): message = cast( Optional["KeyValue.Entry"], - await key_watcher.updates(self.kv_watch.timeout), # type: ignore[no-untyped-call] + # type: ignore[no-untyped-call] + await key_watcher.updates(self.kv_watch.timeout), ) if message: @@ -1097,7 +1074,7 @@ def get_log_context( class ObjStoreWatchSubscriber( TasksMixin, - LogicSubscriber["OSBucketDeclarer", ObjectInfo], + LogicSubscriber[ObjectInfo], ): subscription: Optional["UnsubscribeAdapter[ObjectStore.ObjectWatcher]"] _fetch_sub: Optional[UnsubscribeAdapter["ObjectStore.ObjectWatcher"]] @@ -1108,7 +1085,7 @@ def __init__( subject: str, config: "ConsumerConfig", obj_watch: "ObjWatch", - broker_dependencies: Iterable[Depends], + broker_dependencies: Iterable[Dependant], broker_middlewares: Iterable["BrokerMiddleware[list[Msg]]"], # AsyncAPI args title_: Optional[str], @@ -1143,13 +1120,12 @@ async def get_one( *, timeout: float = 5, ) -> Optional["NatsObjMessage"]: - assert self._connection, "Please, start() subscriber first" # nosec B101 assert ( # nosec B101 not self.calls ), "You can't use `get_one` method if subscriber has registered handlers." if not self._fetch_sub: - self.bucket = await self._connection.create_object_store( + self.bucket = await self._connection_state.os_declarer.create_object_store( bucket=self.subject, declare=self.obj_watch.declare, ) @@ -1169,35 +1145,35 @@ async def get_one( sleep_interval = timeout / 10 with anyio.move_on_after(timeout): while ( # noqa: ASYNC110 - raw_message := await fetch_sub.obj.updates(timeout) # type: ignore[no-untyped-call] + # type: ignore[no-untyped-call] + raw_message := await fetch_sub.obj.updates(timeout) ) is None: await anyio.sleep(sleep_interval) msg: NatsObjMessage = await process_msg( msg=raw_message, - middlewares=self._broker_middlewares, + middlewares=( + m(raw_message, context=self._state.depends_params.context) + for m in self._broker_middlewares + ), parser=self._parser, decoder=self._decoder, ) return msg @override - async def _create_subscription( - self, - *, - connection: "OSBucketDeclarer", - ) -> None: + async def _create_subscription(self) -> None: if self.subscription: return - self.bucket = await connection.create_object_store( + self.bucket = await self._connection_state.os_declarer.create_object_store( bucket=self.subject, declare=self.obj_watch.declare, ) - self.add_task(self._consume_watch()) + self.add_task(self.__consume_watch()) - async def _consume_watch(self) -> None: + async def __consume_watch(self) -> None: assert self.bucket, "You should call `create_subscription` at first." # nosec B101 # Should be created inside task to avoid nats-py lock @@ -1213,11 +1189,14 @@ async def _consume_watch(self) -> None: with suppress(TimeoutError): message = cast( Optional["ObjectInfo"], - await obj_watch.updates(self.obj_watch.timeout), # type: ignore[no-untyped-call] + # type: ignore[no-untyped-call] + await obj_watch.updates(self.obj_watch.timeout), ) if message: - with context.scope(OBJECT_STORAGE_CONTEXT_KEY, self.bucket): + with self._state.depends_params.context.scope( + OBJECT_STORAGE_CONTEXT_KEY, self.bucket + ): await self.consume(message) def _make_response_publisher( diff --git a/faststream/nats/testing.py b/faststream/nats/testing.py index 80e2b91f7e..4ee0d1602c 100644 --- a/faststream/nats/testing.py +++ b/faststream/nats/testing.py @@ -16,6 +16,7 @@ from faststream.exceptions import SubscriberNotFound from faststream.message import encode_message, gen_cor_id from faststream.nats.broker import NatsBroker +from faststream.nats.broker.state import ConnectedState from faststream.nats.parser import NatsParser from faststream.nats.publisher.producer import NatsFastProducer from faststream.nats.schemas.js_stream import is_subject_match_wildcard @@ -58,7 +59,7 @@ async def _fake_connect( # type: ignore[override] *args: Any, **kwargs: Any, ) -> AsyncMock: - broker.stream = AsyncMock() + broker._connection_state = ConnectedState(AsyncMock(), AsyncMock()) broker._js_producer = broker._producer = FakeProducer( # type: ignore[assignment] broker, ) diff --git a/faststream/prometheus/middleware.py b/faststream/prometheus/middleware.py index 3d7f256f05..54270ae6c9 100644 --- a/faststream/prometheus/middleware.py +++ b/faststream/prometheus/middleware.py @@ -16,10 +16,10 @@ if TYPE_CHECKING: from prometheus_client import CollectorRegistry + from faststream._internal.basic_types import AsyncFunc, AsyncFuncAny from faststream._internal.context.repository import ContextRepo from faststream.message.message import StreamMessage from faststream.response.response import PublishCommand - from faststream.types import AsyncFunc, AsyncFuncAny class PrometheusMiddleware: diff --git a/faststream/rabbit/broker/broker.py b/faststream/rabbit/broker/broker.py index 80b30305e6..49286ea81b 100644 --- a/faststream/rabbit/broker/broker.py +++ b/faststream/rabbit/broker/broker.py @@ -46,7 +46,8 @@ RobustQueue, ) from aio_pika.abc import DateType, HeadersType, SSLOptions, TimeoutType - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant + from fast_depends.library.serializer import SerializerProto from pamqp.common import FieldTable from yarl import URL @@ -163,7 +164,7 @@ def __init__( Doc("Custom parser object."), ] = None, dependencies: Annotated[ - Iterable["Depends"], + Iterable["Dependant"], Doc("Dependencies to apply to all broker subscribers."), ] = (), middlewares: Annotated[ @@ -215,10 +216,7 @@ def __init__( bool, Doc("Whether to use FastDepends or not."), ] = True, - validate: Annotated[ - bool, - Doc("Whether to cast types using Pydantic validation."), - ] = True, + serializer: Optional["SerializerProto"] = EMPTY, _get_dependant: Annotated[ Optional[Callable[..., Any]], Doc("Custom library dependant generator callback."), @@ -282,7 +280,7 @@ def __init__( ), # FastDepends args apply_types=apply_types, - validate=validate, + serializer=serializer, _get_dependant=_get_dependant, _call_decorators=_call_decorators, ) diff --git a/faststream/rabbit/broker/logging.py b/faststream/rabbit/broker/logging.py index 4074d3e6df..1d1451cca2 100644 --- a/faststream/rabbit/broker/logging.py +++ b/faststream/rabbit/broker/logging.py @@ -9,6 +9,7 @@ if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict, LoggerProto + from faststream._internal.context import ContextRepo class RabbitParamsStorage(DefaultLoggerStorage): @@ -31,7 +32,7 @@ def setup_log_contest(self, params: "AnyDict") -> None: len(params.get("queue", "")), ) - def get_logger(self) -> "LoggerProto": + def get_logger(self, *, context: "ContextRepo") -> "LoggerProto": message_id_ln = 10 # TODO: generate unique logger names to not share between brokers @@ -50,6 +51,7 @@ def get_logger(self) -> "LoggerProto": f"%(message_id)-{message_id_ln}s " "- %(message)s" ), + context=context, ) diff --git a/faststream/rabbit/broker/registrator.py b/faststream/rabbit/broker/registrator.py index 5b6ffbb606..20893edbd0 100644 --- a/faststream/rabbit/broker/registrator.py +++ b/faststream/rabbit/broker/registrator.py @@ -17,7 +17,7 @@ if TYPE_CHECKING: from aio_pika import IncomingMessage # noqa: F401 from aio_pika.abc import DateType, HeadersType, TimeoutType - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant from faststream._internal.basic_types import AnyDict from faststream._internal.types import ( @@ -59,8 +59,8 @@ def subscriber( # type: ignore[override] ] = None, # broker arguments dependencies: Annotated[ - Iterable["Depends"], - Doc("Dependencies list (`[Depends(),]`) to apply to the subscriber."), + Iterable["Dependant"], + Doc("Dependencies list (`[Dependant(),]`) to apply to the subscriber."), ] = (), parser: Annotated[ Optional["CustomCallable"], diff --git a/faststream/rabbit/publisher/usecase.py b/faststream/rabbit/publisher/usecase.py index d8aafe7df8..71a357576f 100644 --- a/faststream/rabbit/publisher/usecase.py +++ b/faststream/rabbit/publisher/usecase.py @@ -23,6 +23,7 @@ if TYPE_CHECKING: import aiormq + from faststream._internal.setup import SetupState from faststream._internal.types import BrokerMiddleware, PublisherMiddleware from faststream.rabbit.message import RabbitMessage from faststream.rabbit.publisher.producer import AioPikaFastProducer @@ -107,6 +108,7 @@ def _setup( # type: ignore[override] producer: Optional["AioPikaFastProducer"], app_id: Optional[str], virtual_host: str, + state: "SetupState", ) -> None: if app_id: self.message_options["app_id"] = app_id @@ -114,7 +116,7 @@ def _setup( # type: ignore[override] self.virtual_host = virtual_host - super()._setup(producer=producer) + super()._setup(producer=producer, state=state) @property def routing(self) -> str: diff --git a/faststream/rabbit/router.py b/faststream/rabbit/router.py index 8106d48078..a11b5ddbb6 100644 --- a/faststream/rabbit/router.py +++ b/faststream/rabbit/router.py @@ -13,13 +13,13 @@ if TYPE_CHECKING: from aio_pika.abc import DateType, HeadersType, TimeoutType from aio_pika.message import IncomingMessage - from broker.types import PublisherMiddleware - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant from faststream._internal.basic_types import AnyDict from faststream._internal.types import ( BrokerMiddleware, CustomCallable, + PublisherMiddleware, SubscriberMiddleware, ) from faststream.rabbit.message import RabbitMessage @@ -214,8 +214,8 @@ def __init__( ] = None, # broker arguments dependencies: Annotated[ - Iterable["Depends"], - Doc("Dependencies list (`[Depends(),]`) to apply to the subscriber."), + Iterable["Dependant"], + Doc("Dependencies list (`[Dependant(),]`) to apply to the subscriber."), ] = (), parser: Annotated[ Optional["CustomCallable"], @@ -297,9 +297,9 @@ def __init__( ] = (), *, dependencies: Annotated[ - Iterable["Depends"], + Iterable["Dependant"], Doc( - "Dependencies list (`[Depends(),]`) to apply to all routers' publishers/subscribers.", + "Dependencies list (`[Dependant(),]`) to apply to all routers' publishers/subscribers.", ), ] = (), middlewares: Annotated[ diff --git a/faststream/rabbit/subscriber/factory.py b/faststream/rabbit/subscriber/factory.py index 23b190b13e..b82210bd3d 100644 --- a/faststream/rabbit/subscriber/factory.py +++ b/faststream/rabbit/subscriber/factory.py @@ -5,7 +5,7 @@ if TYPE_CHECKING: from aio_pika import IncomingMessage - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant from faststream._internal.basic_types import AnyDict from faststream._internal.types import BrokerMiddleware @@ -21,7 +21,7 @@ def create_subscriber( no_ack: bool, no_reply: bool, retry: Union[bool, int], - broker_dependencies: Iterable["Depends"], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[IncomingMessage]"], # AsyncAPI args title_: Optional[str], diff --git a/faststream/rabbit/subscriber/usecase.py b/faststream/rabbit/subscriber/usecase.py index 67566d0fb1..aeae29d970 100644 --- a/faststream/rabbit/subscriber/usecase.py +++ b/faststream/rabbit/subscriber/usecase.py @@ -18,7 +18,7 @@ if TYPE_CHECKING: from aio_pika import IncomingMessage, RobustQueue - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant from faststream._internal.basic_types import AnyDict, LoggerProto from faststream._internal.publisher.proto import BasePublisherProto @@ -57,7 +57,7 @@ def __init__( no_ack: bool, no_reply: bool, retry: Union[bool, int], - broker_dependencies: Iterable["Depends"], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[IncomingMessage]"], # AsyncAPI args title_: Optional[str], @@ -197,7 +197,10 @@ async def get_one( msg: Optional[RabbitMessage] = await process_msg( # type: ignore[assignment] msg=raw_message, - middlewares=self._broker_middlewares, + middlewares=( + m(raw_message, context=self._state.depends_params.context) + for m in self._broker_middlewares + ), parser=self._parser, decoder=self._decoder, ) diff --git a/faststream/redis/broker/broker.py b/faststream/redis/broker/broker.py index 4ddcdeac05..edfc5774c6 100644 --- a/faststream/redis/broker/broker.py +++ b/faststream/redis/broker/broker.py @@ -1,6 +1,5 @@ import logging from collections.abc import Iterable, Mapping -from functools import partial from typing import ( TYPE_CHECKING, Annotated, @@ -27,7 +26,6 @@ from faststream.__about__ import __version__ from faststream._internal.broker.broker import BrokerUsecase from faststream._internal.constants import EMPTY -from faststream._internal.context.repository import context from faststream.message import gen_cor_id from faststream.redis.message import UnifyRedisDict from faststream.redis.publisher.producer import RedisFastProducer @@ -41,13 +39,13 @@ if TYPE_CHECKING: from types import TracebackType - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant + from fast_depends.library.serializer import SerializerProto from redis.asyncio.connection import BaseParser from typing_extensions import TypedDict, Unpack from faststream._internal.basic_types import ( AnyDict, - AsyncFunc, Decorator, LoggerProto, SendableMessage, @@ -133,7 +131,7 @@ def __init__( Doc("Custom parser object."), ] = None, dependencies: Annotated[ - Iterable["Depends"], + Iterable["Dependant"], Doc("Dependencies to apply to all broker subscribers."), ] = (), middlewares: Annotated[ @@ -185,10 +183,7 @@ def __init__( bool, Doc("Whether to use FastDepends or not."), ] = True, - validate: Annotated[ - bool, - Doc("Whether to cast types using Pydantic validation."), - ] = True, + serializer: Optional["SerializerProto"] = EMPTY, _get_dependant: Annotated[ Optional[Callable[..., Any]], Doc("Custom library dependant generator callback."), @@ -250,7 +245,7 @@ def __init__( ), # FastDepends args apply_types=apply_types, - validate=validate, + serializer=serializer, _get_dependant=_get_dependant, _call_decorators=_call_decorators, ) @@ -490,11 +485,6 @@ async def publish_batch( _publish_type=PublishType.Publish, ) - call: AsyncFunc = self._producer.publish_batch - - for m in self._middlewares: - call = partial(m(None, context=context).publish_scope, call) - await self._basic_publish_batch(cmd, producer=self._producer) @override diff --git a/faststream/redis/broker/logging.py b/faststream/redis/broker/logging.py index fba197c5da..3855efbdf8 100644 --- a/faststream/redis/broker/logging.py +++ b/faststream/redis/broker/logging.py @@ -9,6 +9,7 @@ if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict, LoggerProto + from faststream._internal.context import ContextRepo class RedisParamsStorage(DefaultLoggerStorage): @@ -28,7 +29,7 @@ def setup_log_contest(self, params: "AnyDict") -> None: ), ) - def get_logger(self) -> Optional["LoggerProto"]: + def get_logger(self, *, context: "ContextRepo") -> Optional["LoggerProto"]: message_id_ln = 10 # TODO: generate unique logger names to not share between brokers @@ -45,6 +46,7 @@ def get_logger(self) -> Optional["LoggerProto"]: f"%(message_id)-{message_id_ln}s " "- %(message)s" ), + context=context, ) diff --git a/faststream/redis/broker/registrator.py b/faststream/redis/broker/registrator.py index 9f852284d3..9b10aae10e 100644 --- a/faststream/redis/broker/registrator.py +++ b/faststream/redis/broker/registrator.py @@ -11,7 +11,7 @@ from faststream.redis.subscriber.specified import SpecificationSubscriber if TYPE_CHECKING: - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant from faststream._internal.basic_types import AnyDict from faststream._internal.types import ( @@ -48,8 +48,8 @@ def subscriber( # type: ignore[override] ] = None, # broker arguments dependencies: Annotated[ - Iterable["Depends"], - Doc("Dependencies list (`[Depends(),]`) to apply to the subscriber."), + Iterable["Dependant"], + Doc("Dependencies list (`[Dependant(),]`) to apply to the subscriber."), ] = (), parser: Annotated[ Optional["CustomCallable"], diff --git a/faststream/redis/router.py b/faststream/redis/router.py index 4e651c78eb..f7e60051fe 100644 --- a/faststream/redis/router.py +++ b/faststream/redis/router.py @@ -12,7 +12,7 @@ from faststream.redis.message import BaseMessage if TYPE_CHECKING: - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant from faststream._internal.basic_types import AnyDict, SendableMessage from faststream._internal.types import ( @@ -130,8 +130,8 @@ def __init__( ] = None, # broker arguments dependencies: Annotated[ - Iterable["Depends"], - Doc("Dependencies list (`[Depends(),]`) to apply to the subscriber."), + Iterable["Dependant"], + Doc("Dependencies list (`[Dependant(),]`) to apply to the subscriber."), ] = (), parser: Annotated[ Optional["CustomCallable"], @@ -215,9 +215,9 @@ def __init__( ] = (), *, dependencies: Annotated[ - Iterable["Depends"], + Iterable["Dependant"], Doc( - "Dependencies list (`[Depends(),]`) to apply to all routers' publishers/subscribers.", + "Dependencies list (`[Dependant(),]`) to apply to all routers' publishers/subscribers.", ), ] = (), middlewares: Annotated[ diff --git a/faststream/redis/subscriber/factory.py b/faststream/redis/subscriber/factory.py index 248ce141cf..9238628332 100644 --- a/faststream/redis/subscriber/factory.py +++ b/faststream/redis/subscriber/factory.py @@ -15,7 +15,7 @@ ) if TYPE_CHECKING: - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant from faststream._internal.types import BrokerMiddleware from faststream.redis.message import UnifyRedisDict @@ -38,7 +38,7 @@ def create_subscriber( no_ack: bool = False, no_reply: bool = False, retry: bool = False, - broker_dependencies: Iterable["Depends"] = (), + broker_dependencies: Iterable["Dependant"] = (), broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"] = (), # AsyncAPI args title_: Optional[str] = None, diff --git a/faststream/redis/subscriber/usecase.py b/faststream/redis/subscriber/usecase.py index 769aaf34e5..70ccaf73e9 100644 --- a/faststream/redis/subscriber/usecase.py +++ b/faststream/redis/subscriber/usecase.py @@ -43,7 +43,7 @@ from faststream.redis.schemas import ListSub, PubSub, StreamSub if TYPE_CHECKING: - from fast_depends.dependencies import Depends + from fast_depends.dependencies import Dependant from faststream._internal.basic_types import AnyDict, LoggerProto from faststream._internal.publisher.proto import BasePublisherProto, ProducerProto @@ -74,7 +74,7 @@ def __init__( no_ack: bool, no_reply: bool, retry: bool, - broker_dependencies: Iterable["Depends"], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], # AsyncAPI args title_: Optional[str], @@ -218,7 +218,7 @@ def __init__( no_ack: bool, no_reply: bool, retry: bool, - broker_dependencies: Iterable["Depends"], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], # AsyncAPI args title_: Optional[str], @@ -290,15 +290,18 @@ async def get_one( # type: ignore[override] sleep_interval = timeout / 10 - message: Optional[PubSubMessage] = None + raw_message: Optional[PubSubMessage] = None with anyio.move_on_after(timeout): - while (message := await self._get_message(self.subscription)) is None: # noqa: ASYNC110 + while (raw_message := await self._get_message(self.subscription)) is None: # noqa: ASYNC110 await anyio.sleep(sleep_interval) msg: Optional[RedisMessage] = await process_msg( # type: ignore[assignment] - msg=message, - middlewares=self._broker_middlewares, # type: ignore[arg-type] + msg=raw_message, + middlewares=( + m(raw_message, context=self._state.depends_params.context) + for m in self._broker_middlewares + ), parser=self._parser, decoder=self._decoder, ) @@ -341,7 +344,7 @@ def __init__( no_ack: bool, no_reply: bool, retry: bool, - broker_dependencies: Iterable["Depends"], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], # AsyncAPI args title_: Optional[str], @@ -416,13 +419,18 @@ async def get_one( # type: ignore[override] if not raw_message: return None + redis_incoming_msg = DefaultListMessage( + type="list", + data=raw_message, + channel=self.list_sub.name, + ) + msg: RedisListMessage = await process_msg( # type: ignore[assignment] - msg=DefaultListMessage( - type="list", - data=raw_message, - channel=self.list_sub.name, + msg=redis_incoming_msg, + middlewares=( + m(redis_incoming_msg, context=self._state.depends_params.context) + for m in self._broker_middlewares ), - middlewares=self._broker_middlewares, # type: ignore[arg-type] parser=self._parser, decoder=self._decoder, ) @@ -443,7 +451,7 @@ def __init__( no_ack: bool, no_reply: bool, retry: bool, - broker_dependencies: Iterable["Depends"], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], # AsyncAPI args title_: Optional[str], @@ -492,7 +500,7 @@ def __init__( no_ack: bool, no_reply: bool, retry: bool, - broker_dependencies: Iterable["Depends"], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], # AsyncAPI args title_: Optional[str], @@ -546,7 +554,7 @@ def __init__( no_ack: bool, no_reply: bool, retry: bool, - broker_dependencies: Iterable["Depends"], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], # AsyncAPI args title_: Optional[str], @@ -704,14 +712,19 @@ async def get_one( # type: ignore[override] self.last_id = message_id.decode() + redis_incoming_msg = DefaultStreamMessage( + type="stream", + channel=stream_name.decode(), + message_ids=[message_id], + data=raw_message, + ) + msg: RedisStreamMessage = await process_msg( # type: ignore[assignment] - msg=DefaultStreamMessage( - type="stream", - channel=stream_name.decode(), - message_ids=[message_id], - data=raw_message, + msg=redis_incoming_msg, + middlewares=( + m(redis_incoming_msg, context=self._state.depends_params.context) + for m in self._broker_middlewares ), - middlewares=self._broker_middlewares, # type: ignore[arg-type] parser=self._parser, decoder=self._decoder, ) @@ -732,7 +745,7 @@ def __init__( no_ack: bool, no_reply: bool, retry: bool, - broker_dependencies: Iterable["Depends"], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], # AsyncAPI args title_: Optional[str], @@ -801,7 +814,7 @@ def __init__( no_ack: bool, no_reply: bool, retry: bool, - broker_dependencies: Iterable["Depends"], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], # AsyncAPI args title_: Optional[str], diff --git a/faststream/specification/asyncapi/factory.py b/faststream/specification/asyncapi/factory.py index 720a7ebea4..7b537be3c8 100644 --- a/faststream/specification/asyncapi/factory.py +++ b/faststream/specification/asyncapi/factory.py @@ -3,9 +3,6 @@ from faststream.specification.base.specification import Specification -from .v2_6_0.facade import AsyncAPI2 -from .v3_0_0.facade import AsyncAPI3 - if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict, AnyHttpUrl from faststream._internal.broker.broker import BrokerUsecase @@ -34,6 +31,8 @@ def __new__( # type: ignore[misc] identifier: Optional[str] = None, ) -> Specification: if schema_version.startswith("3.0."): + from .v3_0_0.facade import AsyncAPI3 + return AsyncAPI3( broker, title=title, @@ -48,6 +47,8 @@ def __new__( # type: ignore[misc] external_docs=external_docs, ) if schema_version.startswith("2.6."): + from .v2_6_0.facade import AsyncAPI2 + return AsyncAPI2( broker, title=title, diff --git a/faststream/specification/asyncapi/message.py b/faststream/specification/asyncapi/message.py index d105200f6f..187cc70af0 100644 --- a/faststream/specification/asyncapi/message.py +++ b/faststream/specification/asyncapi/message.py @@ -1,6 +1,6 @@ from collections.abc import Sequence from inspect import isclass -from typing import TYPE_CHECKING, Any, Optional, overload +from typing import TYPE_CHECKING, Optional, overload from pydantic import BaseModel, create_model @@ -16,15 +16,15 @@ from fast_depends.core import CallModel -def parse_handler_params(call: "CallModel[Any, Any]", prefix: str = "") -> AnyDict: +def parse_handler_params(call: "CallModel", prefix: str = "") -> AnyDict: """Parses the handler parameters.""" - model = call.model + model = getattr(call, "serializer", call).model assert model # nosec B101 body = get_model_schema( create_model( # type: ignore[call-overload] model.__name__, - **call.flat_params, + **{p.field_name: (p.field_type, p.default_value) for p in call.flat_params}, ), prefix=prefix, exclude=tuple(call.custom_fields.keys()), @@ -41,11 +41,11 @@ def get_response_schema(call: None, prefix: str = "") -> None: ... @overload -def get_response_schema(call: "CallModel[Any, Any]", prefix: str = "") -> AnyDict: ... +def get_response_schema(call: "CallModel", prefix: str = "") -> AnyDict: ... def get_response_schema( - call: Optional["CallModel[Any, Any]"], + call: Optional["CallModel"], prefix: str = "", ) -> Optional[AnyDict]: """Get the response schema for a given call.""" diff --git a/pyproject.toml b/pyproject.toml index 1a600d1dd9..4cfce9283a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,7 +56,7 @@ dynamic = ["version"] dependencies = [ "anyio>=3.7.1,<5", - "fast-depends>=2.4.0b0,<3.0.0", + "fast-depends[pydantic]>=3.0.0a2,<4.0.0", "typing-extensions>=4.8.0", ] diff --git a/tests/a_docs/getting_started/cli/confluent/test_confluent_context.py b/tests/a_docs/getting_started/cli/confluent/test_confluent_context.py index cb6aa4d83e..3615e32d80 100644 --- a/tests/a_docs/getting_started/cli/confluent/test_confluent_context.py +++ b/tests/a_docs/getting_started/cli/confluent/test_confluent_context.py @@ -1,6 +1,6 @@ import pytest -from faststream import TestApp, context +from faststream import TestApp from faststream.confluent import TestKafkaBroker from tests.marks import pydantic_v2 from tests.mocks import mock_pydantic_settings_env @@ -13,4 +13,4 @@ async def test() -> None: from docs.docs_src.getting_started.cli.confluent_context import app, broker async with TestKafkaBroker(broker), TestApp(app, {"env": ""}): - assert context.get("settings").host == "localhost" + assert app.context.get("settings").host == "localhost" diff --git a/tests/a_docs/getting_started/cli/kafka/test_kafka_context.py b/tests/a_docs/getting_started/cli/kafka/test_kafka_context.py index a3d1d24557..9b26e90f34 100644 --- a/tests/a_docs/getting_started/cli/kafka/test_kafka_context.py +++ b/tests/a_docs/getting_started/cli/kafka/test_kafka_context.py @@ -1,6 +1,6 @@ import pytest -from faststream import TestApp, context +from faststream import TestApp from faststream.kafka import TestKafkaBroker from tests.marks import pydantic_v2 from tests.mocks import mock_pydantic_settings_env @@ -13,4 +13,4 @@ async def test() -> None: from docs.docs_src.getting_started.cli.kafka_context import app, broker async with TestKafkaBroker(broker), TestApp(app, {"env": ""}): - assert context.get("settings").host == "localhost" + assert app.context.get("settings").host == "localhost" diff --git a/tests/a_docs/getting_started/cli/nats/test_nats_context.py b/tests/a_docs/getting_started/cli/nats/test_nats_context.py index f562be059b..fcb8ed5bb9 100644 --- a/tests/a_docs/getting_started/cli/nats/test_nats_context.py +++ b/tests/a_docs/getting_started/cli/nats/test_nats_context.py @@ -1,6 +1,6 @@ import pytest -from faststream import TestApp, context +from faststream import TestApp from faststream.nats import TestNatsBroker from tests.marks import pydantic_v2 from tests.mocks import mock_pydantic_settings_env @@ -13,4 +13,4 @@ async def test() -> None: from docs.docs_src.getting_started.cli.nats_context import app, broker async with TestNatsBroker(broker), TestApp(app, {"env": ""}): - assert context.get("settings").host == "localhost" + assert app.context.get("settings").host == "localhost" diff --git a/tests/a_docs/getting_started/cli/rabbit/test_rabbit_context.py b/tests/a_docs/getting_started/cli/rabbit/test_rabbit_context.py index 99d8cb9951..2fef4df0cd 100644 --- a/tests/a_docs/getting_started/cli/rabbit/test_rabbit_context.py +++ b/tests/a_docs/getting_started/cli/rabbit/test_rabbit_context.py @@ -1,6 +1,6 @@ import pytest -from faststream import TestApp, context +from faststream import TestApp from faststream.rabbit import TestRabbitBroker from tests.marks import pydantic_v2 from tests.mocks import mock_pydantic_settings_env @@ -16,6 +16,6 @@ async def test() -> None: async with TestRabbitBroker(broker), TestApp(app, {"env": ".env"}): assert ( - context.get("settings").host + app.context.get("settings").host == "amqp://guest:guest@localhost:5673/" # pragma: allowlist secret ) diff --git a/tests/a_docs/getting_started/cli/redis/test_redis_context.py b/tests/a_docs/getting_started/cli/redis/test_redis_context.py index 283934f6f3..07536cbfdc 100644 --- a/tests/a_docs/getting_started/cli/redis/test_redis_context.py +++ b/tests/a_docs/getting_started/cli/redis/test_redis_context.py @@ -1,6 +1,6 @@ import pytest -from faststream import TestApp, context +from faststream import TestApp from faststream.redis import TestRedisBroker from tests.marks import pydantic_v2 from tests.mocks import mock_pydantic_settings_env @@ -13,4 +13,4 @@ async def test() -> None: from docs.docs_src.getting_started.cli.redis_context import app, broker async with TestRedisBroker(broker), TestApp(app, {"env": ".env"}): - assert context.get("settings").host == "redis://localhost:6380" + assert app.context.get("settings").host == "redis://localhost:6380" diff --git a/tests/a_docs/getting_started/context/test_initial.py b/tests/a_docs/getting_started/context/test_initial.py index 8291ffca80..7b973b8dfc 100644 --- a/tests/a_docs/getting_started/context/test_initial.py +++ b/tests/a_docs/getting_started/context/test_initial.py @@ -1,6 +1,5 @@ import pytest -from faststream import context from tests.marks import ( python39, require_aiokafka, @@ -22,8 +21,8 @@ async def test_kafka() -> None: await br.publish("", "test-topic") await br.publish("", "test-topic") - assert context.get("collector") == ["", ""] - context.clear() + assert broker.context.get("collector") == ["", ""] + broker.context.clear() @pytest.mark.asyncio() @@ -37,8 +36,8 @@ async def test_confluent() -> None: await br.publish("", "test-topic") await br.publish("", "test-topic") - assert context.get("collector") == ["", ""] - context.clear() + assert broker.context.get("collector") == ["", ""] + broker.context.clear() @pytest.mark.asyncio() @@ -52,8 +51,8 @@ async def test_rabbit() -> None: await br.publish("", "test-queue") await br.publish("", "test-queue") - assert context.get("collector") == ["", ""] - context.clear() + assert broker.context.get("collector") == ["", ""] + broker.context.clear() @pytest.mark.asyncio() @@ -67,8 +66,8 @@ async def test_nats() -> None: await br.publish("", "test-subject") await br.publish("", "test-subject") - assert context.get("collector") == ["", ""] - context.clear() + assert broker.context.get("collector") == ["", ""] + broker.context.clear() @pytest.mark.asyncio() @@ -82,5 +81,5 @@ async def test_redis() -> None: await br.publish("", "test-channel") await br.publish("", "test-channel") - assert context.get("collector") == ["", ""] - context.clear() + assert broker.context.get("collector") == ["", ""] + broker.context.clear() diff --git a/tests/a_docs/getting_started/lifespan/test_basic.py b/tests/a_docs/getting_started/lifespan/test_basic.py index 6b4e98cbc9..97706e94ab 100644 --- a/tests/a_docs/getting_started/lifespan/test_basic.py +++ b/tests/a_docs/getting_started/lifespan/test_basic.py @@ -1,6 +1,6 @@ import pytest -from faststream import TestApp, context +from faststream import TestApp from tests.marks import ( pydantic_v2, require_aiokafka, @@ -22,7 +22,7 @@ async def test_rabbit_basic_lifespan() -> None: from docs.docs_src.getting_started.lifespan.rabbit.basic import app, broker async with TestRabbitBroker(broker), TestApp(app): - assert context.get("settings").host == "localhost" + assert app.context.get("settings").host == "localhost" @pydantic_v2 @@ -35,7 +35,7 @@ async def test_kafka_basic_lifespan() -> None: from docs.docs_src.getting_started.lifespan.kafka.basic import app, broker async with TestKafkaBroker(broker), TestApp(app): - assert context.get("settings").host == "localhost" + assert app.context.get("settings").host == "localhost" @pydantic_v2 @@ -48,7 +48,7 @@ async def test_confluent_basic_lifespan() -> None: from docs.docs_src.getting_started.lifespan.confluent.basic import app, broker async with TestConfluentKafkaBroker(broker), TestApp(app): - assert context.get("settings").host == "localhost" + assert app.context.get("settings").host == "localhost" @pydantic_v2 @@ -61,7 +61,7 @@ async def test_nats_basic_lifespan() -> None: from docs.docs_src.getting_started.lifespan.nats.basic import app, broker async with TestNatsBroker(broker), TestApp(app): - assert context.get("settings").host == "localhost" + assert app.context.get("settings").host == "localhost" @pydantic_v2 @@ -74,4 +74,4 @@ async def test_redis_basic_lifespan() -> None: from docs.docs_src.getting_started.lifespan.redis.basic import app, broker async with TestRedisBroker(broker), TestApp(app): - assert context.get("settings").host == "localhost" + assert app.context.get("settings").host == "localhost" diff --git a/tests/a_docs/getting_started/lifespan/test_multi.py b/tests/a_docs/getting_started/lifespan/test_multi.py index 02bbfedfae..8d4b0e2a98 100644 --- a/tests/a_docs/getting_started/lifespan/test_multi.py +++ b/tests/a_docs/getting_started/lifespan/test_multi.py @@ -1,6 +1,6 @@ import pytest -from faststream import TestApp, context +from faststream import TestApp @pytest.mark.asyncio() @@ -8,4 +8,4 @@ async def test_multi_lifespan() -> None: from docs.docs_src.getting_started.lifespan.multiple import app async with TestApp(app): - assert context.get("field") == 1 + assert app.context.get("field") == 1 diff --git a/tests/a_docs/getting_started/subscription/test_annotated.py b/tests/a_docs/getting_started/subscription/test_annotated.py index 07c2e841a2..0c9d24a927 100644 --- a/tests/a_docs/getting_started/subscription/test_annotated.py +++ b/tests/a_docs/getting_started/subscription/test_annotated.py @@ -1,7 +1,7 @@ from typing import Any import pytest -from pydantic import ValidationError +from fast_depends.exceptions import ValidationError from typing_extensions import TypeAlias from faststream._internal.broker.broker import BrokerUsecase diff --git a/tests/asgi/testcase.py b/tests/asgi/testcase.py index 47fdafe0e4..20f4ed6fc7 100644 --- a/tests/asgi/testcase.py +++ b/tests/asgi/testcase.py @@ -1,4 +1,5 @@ from typing import Any +from unittest.mock import AsyncMock import pytest from starlette.testclient import TestClient @@ -22,14 +23,14 @@ def get_test_broker(self, broker) -> Any: raise NotImplementedError def test_not_found(self) -> None: - app = AsgiFastStream() + app = AsgiFastStream(AsyncMock()) with TestClient(app) as client: response = client.get("/") assert response.status_code == 404 def test_ws_not_found(self) -> None: - app = AsgiFastStream() + app = AsgiFastStream(AsyncMock()) with TestClient(app) as client: # noqa: SIM117 with pytest.raises(WebSocketDisconnect): @@ -40,6 +41,7 @@ def test_asgi_ping_unhealthy(self) -> None: broker = self.get_broker() app = AsgiFastStream( + AsyncMock(), asgi_routes=[ ("/health", make_ping_asgi(broker, timeout=5.0)), ], @@ -68,7 +70,8 @@ async def test_asyncapi_asgi(self) -> None: broker = self.get_broker() app = AsgiFastStream( - broker, asgi_routes=[("/docs", make_asyncapi_asgi(AsyncAPI(broker)))] + broker, + asgi_routes=[("/docs", make_asyncapi_asgi(AsyncAPI(broker)))], ) async with self.get_test_broker(broker): @@ -82,7 +85,7 @@ def test_get_decorator(self) -> None: async def some_handler(scope) -> AsgiResponse: return AsgiResponse(body=b"test", status_code=200) - app = AsgiFastStream(asgi_routes=[("/test", some_handler)]) + app = AsgiFastStream(AsyncMock(), asgi_routes=[("/test", some_handler)]) with TestClient(app) as client: response = client.get("/test") diff --git a/tests/brokers/base/consume.py b/tests/brokers/base/consume.py index 9f0acf2806..62d68072ca 100644 --- a/tests/brokers/base/consume.py +++ b/tests/brokers/base/consume.py @@ -205,7 +205,7 @@ async def test_consume_validate_false( ) -> None: consume_broker = self.get_broker( apply_types=True, - validate=False, + serializer=None, ) class Foo(BaseModel): diff --git a/tests/brokers/base/fastapi.py b/tests/brokers/base/fastapi.py index 0523511cf1..53725c23cb 100644 --- a/tests/brokers/base/fastapi.py +++ b/tests/brokers/base/fastapi.py @@ -8,7 +8,7 @@ from fastapi.exceptions import RequestValidationError from fastapi.testclient import TestClient -from faststream import Response, context +from faststream import Response from faststream._internal.broker.broker import BrokerUsecase from faststream._internal.broker.router import BrokerRouter from faststream._internal.fastapi.context import Context @@ -79,6 +79,10 @@ async def hello(msg, tasks: BackgroundTasks) -> None: async def test_context(self, mock: Mock, queue: str, event: asyncio.Event) -> None: router = self.router_class() + context = router.context + from loguru import logger + + logger.debug(context) context_key = "message.headers" @@ -86,14 +90,19 @@ async def test_context(self, mock: Mock, queue: str, event: asyncio.Event) -> No @router.subscriber(*args, **kwargs) async def hello(msg=Context(context_key)): - event.set() - return mock(msg == context.resolve(context_key)) + try: + mock(msg == context.resolve(context_key) and msg["1"] == "1") + finally: + event.set() + router._setup() async with router.broker: await router.broker.start() await asyncio.wait( ( - asyncio.create_task(router.broker.publish("", queue)), + asyncio.create_task( + router.broker.publish("", queue, headers={"1": "1"}) + ), asyncio.create_task(event.wait()), ), timeout=self.timeout, @@ -104,6 +113,7 @@ async def hello(msg=Context(context_key)): async def test_initial_context(self, queue: str, event: asyncio.Event) -> None: router = self.router_class() + context = router.context args, kwargs = self.get_subscriber_params(queue) @@ -113,6 +123,7 @@ async def hello(msg: int, data=Context(queue, initial=set)) -> None: if len(data) == 2: event.set() + router._setup() async with router.broker: await router.broker.start() await asyncio.wait( diff --git a/tests/cli/conftest.py b/tests/cli/conftest.py index 8398f4a286..21900fdd09 100644 --- a/tests/cli/conftest.py +++ b/tests/cli/conftest.py @@ -13,12 +13,7 @@ def broker(): @pytest.fixture() def app_without_logger(broker): - return FastStream(broker, None) - - -@pytest.fixture() -def app_without_broker(): - return FastStream() + return FastStream(broker, logger=None) @pytest.fixture() diff --git a/tests/cli/rabbit/test_app.py b/tests/cli/rabbit/test_app.py index 2dcfbc29ea..c21e26d996 100644 --- a/tests/cli/rabbit/test_app.py +++ b/tests/cli/rabbit/test_app.py @@ -17,20 +17,6 @@ def test_init(app: FastStream, broker) -> None: assert app.logger is logger -def test_init_without_broker(app_without_broker: FastStream) -> None: - assert app_without_broker.broker is None - - -def test_init_without_logger(app_without_logger: FastStream) -> None: - assert app_without_logger.logger is None - - -def test_set_broker(broker, app_without_broker: FastStream) -> None: - assert app_without_broker.broker is None - app_without_broker.set_broker(broker) - assert app_without_broker.broker is broker - - def test_log(app: FastStream, app_without_logger: FastStream) -> None: app._log(logging.INFO, "test") app_without_logger._log(logging.INFO, "test") @@ -46,7 +32,7 @@ async def call2() -> None: await async_mock.call_start2() assert mock.call_start1.call_count == 1 - test_app = FastStream(on_startup=[call1, call2]) + test_app = FastStream(AsyncMock(), on_startup=[call1, call2]) await test_app.start() @@ -56,7 +42,9 @@ async def call2() -> None: @pytest.mark.asyncio() async def test_startup_calls_lifespans( - mock: Mock, app_without_broker: FastStream + mock: Mock, + app: FastStream, + async_mock: AsyncMock, ) -> None: def call1() -> None: mock.call_start1() @@ -66,10 +54,11 @@ def call2() -> None: mock.call_start2() assert mock.call_start1.call_count == 1 - app_without_broker.on_startup(call1) - app_without_broker.on_startup(call2) + app.on_startup(call1) + app.on_startup(call2) - await app_without_broker.start() + with patch.object(app.broker, "start", async_mock): + await app.start() mock.call_start1.assert_called_once() mock.call_start2.assert_called_once() @@ -85,7 +74,7 @@ async def call2() -> None: await async_mock.call_stop2() assert mock.call_stop1.call_count == 1 - test_app = FastStream(on_shutdown=[call1, call2]) + test_app = FastStream(AsyncMock(), on_shutdown=[call1, call2]) await test_app.stop() @@ -94,9 +83,9 @@ async def call2() -> None: @pytest.mark.asyncio() -async def test_shutdown_calls_lifespans( - mock: Mock, app_without_broker: FastStream -) -> None: +async def test_shutdown_calls_lifespans(mock: Mock) -> None: + app = FastStream(AsyncMock()) + def call1() -> None: mock.call_stop1() assert not mock.call_stop2.called @@ -105,10 +94,10 @@ def call2() -> None: mock.call_stop2() assert mock.call_stop1.call_count == 1 - app_without_broker.on_shutdown(call1) - app_without_broker.on_shutdown(call2) + app.on_shutdown(call1) + app.on_shutdown(call2) - await app_without_broker.stop() + await app.stop() mock.call_stop1.assert_called_once() mock.call_stop2.assert_called_once() @@ -126,14 +115,7 @@ async def call2() -> None: test_app = FastStream(broker, after_startup=[call1, call2]) - with ( - patch.object(test_app.broker, "start", async_mock.broker_start), - patch.object( - test_app.broker, - "connect", - async_mock.broker_connect, - ), - ): + with patch.object(test_app.broker, "start", async_mock.broker_start): await test_app.start() mock.after_startup1.assert_called_once() @@ -227,16 +209,10 @@ async def test_running(async_mock: AsyncMock, app: FastStream) -> None: with ( patch.object(app.broker, "start", async_mock.broker_run), - patch.object( - app.broker, - "connect", - async_mock.broker_connect, - ), patch.object(app.broker, "close", async_mock.broker_stopped), ): await app.run() - async_mock.broker_connect.assert_called_once() async_mock.broker_run.assert_called_once() async_mock.broker_stopped.assert_called_once() @@ -265,23 +241,13 @@ async def lifespan(env: str): yield mock.off() - app = FastStream(app.broker, lifespan=lifespan) + app = FastStream(async_mock, lifespan=lifespan) app.exit() - with ( - patch.object(app.broker, "start", async_mock.broker_run), - patch.object( - app.broker, - "connect", - async_mock.broker_connect, - ), - patch.object(app.broker, "close", async_mock.broker_stopped), - ): - await app.run(run_extra_options={"env": "test"}) + await app.run(run_extra_options={"env": "test"}) - async_mock.broker_connect.assert_called_once() - async_mock.broker_run.assert_called_once() - async_mock.broker_stopped.assert_called_once() + async_mock.start.assert_called_once() + async_mock.close.assert_called_once() mock.on.assert_called_once_with("test") mock.off.assert_called_once() @@ -289,7 +255,7 @@ async def lifespan(env: str): @pytest.mark.asyncio() async def test_test_app(mock: Mock) -> None: - app = FastStream() + app = FastStream(AsyncMock()) app.on_startup(mock.on) app.on_shutdown(mock.off) @@ -303,7 +269,7 @@ async def test_test_app(mock: Mock) -> None: @pytest.mark.asyncio() async def test_test_app_with_excp(mock: Mock) -> None: - app = FastStream() + app = FastStream(AsyncMock()) app.on_startup(mock.on) app.on_shutdown(mock.off) @@ -317,7 +283,7 @@ async def test_test_app_with_excp(mock: Mock) -> None: def test_sync_test_app(mock: Mock) -> None: - app = FastStream() + app = FastStream(AsyncMock()) app.on_startup(mock.on) app.on_shutdown(mock.off) @@ -330,7 +296,7 @@ def test_sync_test_app(mock: Mock) -> None: def test_sync_test_app_with_excp(mock: Mock) -> None: - app = FastStream() + app = FastStream(AsyncMock()) app.on_startup(mock.on) app.on_shutdown(mock.off) @@ -354,11 +320,6 @@ async def lifespan(env: str): with ( patch.object(app.broker, "start", async_mock.broker_run), - patch.object( - app.broker, - "connect", - async_mock.broker_connect, - ), patch.object(app.broker, "close", async_mock.broker_stopped), ): async with TestApp(app, {"env": "test"}): @@ -367,7 +328,6 @@ async def lifespan(env: str): async_mock.on.assert_awaited_once_with("test") async_mock.off.assert_awaited_once() async_mock.broker_run.assert_called_once() - async_mock.broker_connect.assert_called_once() async_mock.broker_stopped.assert_called_once() @@ -387,7 +347,6 @@ async def lifespan(env: str): "close", async_mock.broker_stopped, ), - patch.object(app.broker, "connect", async_mock.broker_connect), TestApp( app, {"env": "test"}, @@ -398,7 +357,6 @@ async def lifespan(env: str): async_mock.on.assert_awaited_once_with("test") async_mock.off.assert_awaited_once() async_mock.broker_run.assert_called_once() - async_mock.broker_connect.assert_called_once() async_mock.broker_stopped.assert_called_once() @@ -407,11 +365,6 @@ async def lifespan(env: str): async def test_stop_with_sigint(async_mock, app: FastStream) -> None: with ( patch.object(app.broker, "start", async_mock.broker_run_sigint), - patch.object( - app.broker, - "connect", - async_mock.broker_connect, - ), patch.object(app.broker, "close", async_mock.broker_stopped_sigint), ): async with anyio.create_task_group() as tg: @@ -419,7 +372,6 @@ async def test_stop_with_sigint(async_mock, app: FastStream) -> None: tg.start_soon(_kill, signal.SIGINT) async_mock.broker_run_sigint.assert_called_once() - async_mock.broker_connect.assert_called_once() async_mock.broker_stopped_sigint.assert_called_once() @@ -428,11 +380,6 @@ async def test_stop_with_sigint(async_mock, app: FastStream) -> None: async def test_stop_with_sigterm(async_mock, app: FastStream) -> None: with ( patch.object(app.broker, "start", async_mock.broker_run_sigterm), - patch.object( - app.broker, - "connect", - async_mock.broker_connect, - ), patch.object(app.broker, "close", async_mock.broker_stopped_sigterm), ): async with anyio.create_task_group() as tg: @@ -440,7 +387,6 @@ async def test_stop_with_sigterm(async_mock, app: FastStream) -> None: tg.start_soon(_kill, signal.SIGTERM) async_mock.broker_run_sigterm.assert_called_once() - async_mock.broker_connect.assert_called_once() async_mock.broker_stopped_sigterm.assert_called_once() @@ -460,11 +406,6 @@ async def test_run_asgi(async_mock: AsyncMock, app: FastStream) -> None: with ( patch.object(app.broker, "start", async_mock.broker_run), - patch.object( - app.broker, - "connect", - async_mock.broker_connect, - ), patch.object(app.broker, "close", async_mock.broker_stopped), ): async with anyio.create_task_group() as tg: @@ -472,7 +413,6 @@ async def test_run_asgi(async_mock: AsyncMock, app: FastStream) -> None: tg.start_soon(_kill, signal.SIGINT) async_mock.broker_run.assert_called_once() - async_mock.broker_connect.assert_called_once() async_mock.broker_stopped.assert_called_once() diff --git a/tests/cli/rabbit/test_logs.py b/tests/cli/rabbit/test_logs.py index 50a6187911..d9abbcd0cc 100644 --- a/tests/cli/rabbit/test_logs.py +++ b/tests/cli/rabbit/test_logs.py @@ -29,11 +29,6 @@ def test_set_level(level, app: FastStream) -> None: @pytest.mark.parametrize( ("level", "app"), ( - pytest.param( - logging.CRITICAL, - FastStream(), - id="empty app", - ), pytest.param( logging.CRITICAL, FastStream(RabbitBroker(), logger=None), @@ -56,8 +51,8 @@ def test_set_level_to_none(level, app: FastStream) -> None: set_log_level(get_log_level(level), app) -def test_set_default() -> None: - app = FastStream() +def test_set_default(broker) -> None: + app = FastStream(broker) level = "wrong_level" set_log_level(get_log_level(level), app) assert app.logger.level is logging.INFO diff --git a/tests/cli/test_asyncapi_docs.py b/tests/cli/test_asyncapi_docs.py index 42d321ceaa..9deb1877b9 100644 --- a/tests/cli/test_asyncapi_docs.py +++ b/tests/cli/test_asyncapi_docs.py @@ -75,7 +75,7 @@ def test_serve_asyncapi_docs( m.setattr(HTTPServer, "serve_forever", mock) r = runner.invoke(cli, SERVE_CMD + [kafka_ascynapi_project]) # noqa: RUF005 - assert r.exit_code == 0 + assert r.exit_code == 0, r.exc_info mock.assert_called_once() @@ -94,7 +94,7 @@ def test_serve_asyncapi_json_schema( m.setattr(HTTPServer, "serve_forever", mock) r = runner.invoke(cli, SERVE_CMD + [str(schema_path)]) # noqa: RUF005 - assert r.exit_code == 0 + assert r.exit_code == 0, r.exc_info mock.assert_called_once() schema_path.unlink() @@ -115,7 +115,7 @@ def test_serve_asyncapi_yaml_schema( m.setattr(HTTPServer, "serve_forever", mock) r = runner.invoke(cli, SERVE_CMD + [str(schema_path)]) # noqa: RUF005 - assert r.exit_code == 0 + assert r.exit_code == 0, r.exc_info mock.assert_called_once() schema_path.unlink() diff --git a/tests/cli/test_run_asgi.py b/tests/cli/test_run_asgi.py index fac7662c04..c644c04bb2 100644 --- a/tests/cli/test_run_asgi.py +++ b/tests/cli/test_run_asgi.py @@ -9,7 +9,7 @@ def test_run_as_asgi(runner: CliRunner) -> None: - app = AsgiFastStream() + app = AsgiFastStream(AsyncMock()) app.run = AsyncMock() with patch( @@ -43,7 +43,7 @@ def test_run_as_asgi(runner: CliRunner) -> None: ), ) def test_run_as_asgi_with_workers(runner: CliRunner, workers: int) -> None: - app = AsgiFastStream() + app = AsgiFastStream(AsyncMock()) app.run = AsyncMock() with patch( @@ -73,7 +73,7 @@ def test_run_as_asgi_with_workers(runner: CliRunner, workers: int) -> None: def test_run_as_asgi_callable(runner: CliRunner) -> None: - app = AsgiFastStream() + app = AsgiFastStream(AsyncMock()) app.run = AsyncMock() app_factory = Mock(return_value=app) diff --git a/tests/cli/test_run_regular.py b/tests/cli/test_run_regular.py index e696389070..7edf3152ce 100644 --- a/tests/cli/test_run_regular.py +++ b/tests/cli/test_run_regular.py @@ -9,7 +9,7 @@ def test_run(runner: CliRunner) -> None: - app = FastStream() + app = FastStream(MagicMock()) app.run = AsyncMock() with patch( @@ -35,7 +35,7 @@ def test_run(runner: CliRunner) -> None: def test_run_factory(runner: CliRunner) -> None: - app = FastStream() + app = FastStream(MagicMock()) app.run = AsyncMock() app_factory = MagicMock(return_value=app) @@ -58,7 +58,7 @@ def test_run_factory(runner: CliRunner) -> None: def test_run_workers(runner: CliRunner) -> None: - app = FastStream() + app = FastStream(MagicMock()) app.run = AsyncMock() with ( @@ -85,7 +85,7 @@ def test_run_workers(runner: CliRunner) -> None: def test_run_factory_with_workers(runner: CliRunner) -> None: - app = FastStream() + app = FastStream(MagicMock()) app.run = AsyncMock() app_factory = MagicMock(return_value=app) @@ -113,7 +113,7 @@ def test_run_factory_with_workers(runner: CliRunner) -> None: def test_run_reloader(runner: CliRunner) -> None: - app = FastStream() + app = FastStream(MagicMock()) app.run = AsyncMock() with ( @@ -150,7 +150,7 @@ def test_run_reloader(runner: CliRunner) -> None: def test_run_reloader_with_factory(runner: CliRunner) -> None: - app = FastStream() + app = FastStream(MagicMock()) app.run = AsyncMock() app_factory = MagicMock(return_value=app) diff --git a/tests/conftest.py b/tests/conftest.py index ce7cfbd8f0..02f1c26724 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -6,10 +6,7 @@ from typer.testing import CliRunner from faststream.__about__ import __version__ -from faststream._internal.context import ( - ContextRepo, - context as global_context, -) +from faststream._internal.context import ContextRepo @pytest.hookimpl(tryfirst=True) @@ -58,8 +55,7 @@ def version() -> str: @pytest.fixture() def context() -> ContextRepo: - yield global_context - global_context.clear() + return ContextRepo() @pytest.fixture() diff --git a/tests/utils/context/test_alias.py b/tests/utils/context/test_alias.py index e01fbde325..a84e475a03 100644 --- a/tests/utils/context/test_alias.py +++ b/tests/utils/context/test_alias.py @@ -11,7 +11,7 @@ async def test_base_context_alias(context: ContextRepo) -> None: key = 1000 context.set_global("key", key) - @apply_types + @apply_types(context__=context) async def func(k=Context("key")): return k is key @@ -23,7 +23,7 @@ async def test_context_cast(context: ContextRepo) -> None: key = 1000 context.set_global("key", key) - @apply_types + @apply_types(context__=context) async def func(k: float = Context("key", cast=True)): return isinstance(k, float) @@ -35,7 +35,7 @@ async def test_nested_context_alias(context: ContextRepo) -> None: model = SomeModel(field=SomeModel(field=1000)) context.set_global("model", model) - @apply_types + @apply_types(context__=context) async def func( m=Context("model.field.field"), m2=Context("model.not_existed", default=None), @@ -59,7 +59,7 @@ async def test_annotated_alias(context: ContextRepo) -> None: model = SomeModel(field=SomeModel(field=1000)) context.set_global("model", model) - @apply_types + @apply_types(context__=context) async def func(m: Annotated[int, Context("model.field.field")]): return m is model.field.field diff --git a/tests/utils/context/test_main.py b/tests/utils/context/test_main.py index 006a478061..c34317a879 100644 --- a/tests/utils/context/test_main.py +++ b/tests/utils/context/test_main.py @@ -1,5 +1,5 @@ import pytest -from pydantic import ValidationError +from fast_depends.exceptions import ValidationError from faststream import Context, ContextRepo from faststream._internal.utils import apply_types @@ -18,7 +18,7 @@ async def test_context_apply(context: ContextRepo) -> None: a = 1000 context.set_global("key", a) - @apply_types + @apply_types(context__=context) async def use(key=Context()): return key is a @@ -30,7 +30,7 @@ async def test_context_ignore(context: ContextRepo) -> None: a = 3 context.set_global("key", a) - @apply_types + @apply_types(context__=context) async def use() -> None: return None @@ -45,19 +45,19 @@ async def test_context_apply_multi(context: ContextRepo) -> None: b = 1000 context.set_global("key_b", b) - @apply_types + @apply_types(context__=context) async def use1(key_a=Context()): return key_a is a assert await use1() - @apply_types + @apply_types(context__=context) async def use2(key_b=Context()): return key_b is b assert await use2() - @apply_types + @apply_types(context__=context) async def use3(key_a=Context(), key_b=Context()): return key_a is a and key_b is b @@ -72,7 +72,7 @@ async def test_context_overrides(context: ContextRepo) -> None: b = 1000 context.set_global("test", b) - @apply_types + @apply_types(context__=context) async def use(test=Context()): return test is b @@ -84,11 +84,11 @@ async def test_context_nested_apply(context: ContextRepo) -> None: a = 1000 context.set_global("key", a) - @apply_types + @apply_types(context__=context) def use_nested(key=Context()): return key - @apply_types + @apply_types(context__=context) async def use(key=Context()): return key is use_nested() is a @@ -101,7 +101,7 @@ async def test_reset_global(context: ContextRepo) -> None: context.set_global("key", a) context.reset_global("key") - @apply_types + @apply_types(context__=context) async def use(key=Context()) -> None: ... with pytest.raises(ValidationError): @@ -114,7 +114,7 @@ async def test_clear_context(context: ContextRepo) -> None: context.set_global("key", a) context.clear() - @apply_types + @apply_types(context__=context) async def use(key=Context(default=None)): return key is None @@ -122,7 +122,7 @@ async def use(key=Context(default=None)): def test_scope(context: ContextRepo) -> None: - @apply_types + @apply_types(context__=context) def use(key=Context(), key2=Context()) -> None: assert key == 1 assert key2 == 1 @@ -135,7 +135,7 @@ def use(key=Context(), key2=Context()) -> None: def test_default(context: ContextRepo) -> None: - @apply_types + @apply_types(context__=context) def use( key=Context(), key2=Context(), @@ -169,8 +169,8 @@ def test_local_default(context: ContextRepo) -> None: assert context.get_local(key, 1) == 1 -def test_initial() -> None: - @apply_types +def test_initial(context: ContextRepo) -> None: + @apply_types(context__=context) def use( a, key=Context(initial=list), @@ -201,7 +201,7 @@ def __ne__(self, other): user2 = User(user_id=2) user3 = User(user_id=3) - @apply_types + @apply_types(context__=context) async def use( key1=Context("user1"), key2=Context("user2", default=user2), From 40d007b318dbca8c47bce17b9a2352b69c81755a Mon Sep 17 00:00:00 2001 From: Roma Frolov <98967567+roma-frolov@users.noreply.github.com> Date: Fri, 1 Nov 2024 07:46:41 +0300 Subject: [PATCH 181/245] Fixed RPC for Prometheus metrics (#1887) * fixing metrics for rpc * == -> is --- faststream/prometheus/middleware.py | 6 +++-- tests/prometheus/basic.py | 31 ++++++++++++++++++++++++++ tests/prometheus/nats/test_nats.py | 4 ++-- tests/prometheus/rabbit/test_rabbit.py | 4 ++-- tests/prometheus/redis/test_redis.py | 4 ++-- 5 files changed, 41 insertions(+), 8 deletions(-) diff --git a/faststream/prometheus/middleware.py b/faststream/prometheus/middleware.py index 54270ae6c9..5d35708cfe 100644 --- a/faststream/prometheus/middleware.py +++ b/faststream/prometheus/middleware.py @@ -4,6 +4,7 @@ from faststream import BaseMiddleware from faststream._internal.constants import EMPTY +from faststream.message import SourceType from faststream.prometheus.consts import ( PROCESSING_STATUS_BY_ACK_STATUS, PROCESSING_STATUS_BY_HANDLER_EXCEPTION_MAP, @@ -12,6 +13,7 @@ from faststream.prometheus.manager import MetricsManager from faststream.prometheus.provider import MetricsSettingsProvider from faststream.prometheus.types import ProcessingStatus, PublishingStatus +from faststream.response import PublishType if TYPE_CHECKING: from prometheus_client import CollectorRegistry @@ -86,7 +88,7 @@ async def consume_scope( call_next: "AsyncFuncAny", msg: "StreamMessage[Any]", ) -> Any: - if self._settings_provider is None: + if self._settings_provider is None or msg._source_type is SourceType.Response: return await call_next(msg) messaging_system = self._settings_provider.messaging_system @@ -163,7 +165,7 @@ async def publish_scope( call_next: "AsyncFunc", cmd: "PublishCommand", ) -> Any: - if self._settings_provider is None: + if self._settings_provider is None or cmd.publish_type is PublishType.Reply: return await call_next(cmd) destination_name = ( diff --git a/tests/prometheus/basic.py b/tests/prometheus/basic.py index 74c55dc4c0..004afa8457 100644 --- a/tests/prometheus/basic.py +++ b/tests/prometheus/basic.py @@ -202,3 +202,34 @@ def assert_publish_metrics(self, metrics_manager: Any): status="success", ), ] + + +class LocalRPCPrometheusTestcase: + @pytest.mark.asyncio() + async def test_rpc_request( + self, + queue: str, + event: asyncio.Event, + ) -> None: + middleware = self.get_middleware(registry=CollectorRegistry()) + metrics_manager_mock = Mock() + middleware._metrics_manager = metrics_manager_mock + + broker = self.get_broker(apply_types=True, middlewares=(middleware,)) + + @broker.subscriber(queue) + async def handle(): + event.set() + return "" + + async with self.patch_broker(broker) as br: + await br.start() + + await asyncio.wait_for( + br.request("", queue), + timeout=3, + ) + + assert event.is_set() + metrics_manager_mock.add_received_message.assert_called_once() + metrics_manager_mock.add_published_message.assert_called_once() diff --git a/tests/prometheus/nats/test_nats.py b/tests/prometheus/nats/test_nats.py index 81e34bd5cb..4af2685a7d 100644 --- a/tests/prometheus/nats/test_nats.py +++ b/tests/prometheus/nats/test_nats.py @@ -9,7 +9,7 @@ from faststream.nats.prometheus.middleware import NatsPrometheusMiddleware from tests.brokers.nats.test_consume import TestConsume from tests.brokers.nats.test_publish import TestPublish -from tests.prometheus.basic import LocalPrometheusTestcase +from tests.prometheus.basic import LocalPrometheusTestcase, LocalRPCPrometheusTestcase @pytest.fixture() @@ -18,7 +18,7 @@ def stream(queue): @pytest.mark.nats() -class TestPrometheus(LocalPrometheusTestcase): +class TestPrometheus(LocalPrometheusTestcase, LocalRPCPrometheusTestcase): def get_broker(self, apply_types=False, **kwargs): return NatsBroker(apply_types=apply_types, **kwargs) diff --git a/tests/prometheus/rabbit/test_rabbit.py b/tests/prometheus/rabbit/test_rabbit.py index a5a7a67cbe..f64786fc4f 100644 --- a/tests/prometheus/rabbit/test_rabbit.py +++ b/tests/prometheus/rabbit/test_rabbit.py @@ -5,7 +5,7 @@ from faststream.rabbit.prometheus.middleware import RabbitPrometheusMiddleware from tests.brokers.rabbit.test_consume import TestConsume from tests.brokers.rabbit.test_publish import TestPublish -from tests.prometheus.basic import LocalPrometheusTestcase +from tests.prometheus.basic import LocalPrometheusTestcase, LocalRPCPrometheusTestcase @pytest.fixture() @@ -14,7 +14,7 @@ def exchange(queue): @pytest.mark.rabbit() -class TestPrometheus(LocalPrometheusTestcase): +class TestPrometheus(LocalPrometheusTestcase, LocalRPCPrometheusTestcase): def get_broker(self, apply_types=False, **kwargs): return RabbitBroker(apply_types=apply_types, **kwargs) diff --git a/tests/prometheus/redis/test_redis.py b/tests/prometheus/redis/test_redis.py index 3a4aa9cc98..ce7f81f49f 100644 --- a/tests/prometheus/redis/test_redis.py +++ b/tests/prometheus/redis/test_redis.py @@ -9,11 +9,11 @@ from faststream.redis.prometheus.middleware import RedisPrometheusMiddleware from tests.brokers.redis.test_consume import TestConsume from tests.brokers.redis.test_publish import TestPublish -from tests.prometheus.basic import LocalPrometheusTestcase +from tests.prometheus.basic import LocalPrometheusTestcase, LocalRPCPrometheusTestcase @pytest.mark.redis() -class TestPrometheus(LocalPrometheusTestcase): +class TestPrometheus(LocalPrometheusTestcase, LocalRPCPrometheusTestcase): def get_broker(self, apply_types=False, **kwargs): return RedisBroker(apply_types=apply_types, **kwargs) From 0fa5fc1fe2ab873902df55ab6354a6e1a9990760 Mon Sep 17 00:00:00 2001 From: Roma Frolov <98967567+roma-frolov@users.noreply.github.com> Date: Tue, 5 Nov 2024 15:56:12 +0300 Subject: [PATCH 182/245] tests on MetricsSettingsProvider for all brokers (#1890) * tests on MetricsSettingsProvider for all brokers * chore: fix tests * chore: remove loguru usage --------- Co-authored-by: Nikita Pastukhov --- pyproject.toml | 4 +- tests/brokers/base/fastapi.py | 3 - tests/prometheus/basic.py | 19 +++ tests/prometheus/confluent/test_provider.py | 106 +++++++++++++++++ tests/prometheus/kafka/test_provider.py | 101 ++++++++++++++++ tests/prometheus/nats/test_provider.py | 107 +++++++++++++++++ tests/prometheus/rabbit/test_provider.py | 65 ++++++++++ tests/prometheus/redis/test_provider.py | 125 ++++++++++++++++++++ 8 files changed, 524 insertions(+), 6 deletions(-) create mode 100644 tests/prometheus/confluent/test_provider.py create mode 100644 tests/prometheus/kafka/test_provider.py create mode 100644 tests/prometheus/nats/test_provider.py create mode 100644 tests/prometheus/rabbit/test_provider.py create mode 100644 tests/prometheus/redis/test_provider.py diff --git a/pyproject.toml b/pyproject.toml index 4cfce9283a..f875f7a652 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,7 +56,7 @@ dynamic = ["version"] dependencies = [ "anyio>=3.7.1,<5", - "fast-depends[pydantic]>=3.0.0a2,<4.0.0", + "fast-depends[pydantic]>=3.0.0a3,<4.0.0", "typing-extensions>=4.8.0", ] @@ -171,8 +171,6 @@ files = ["faststream", "tests/mypy"] strict = true python_version = "3.9" ignore_missing_imports = true -install_types = true -non_interactive = true plugins = ["pydantic.mypy"] # from https://blog.wolt.com/engineering/2021/09/30/professional-grade-mypy-configuration/ diff --git a/tests/brokers/base/fastapi.py b/tests/brokers/base/fastapi.py index 53725c23cb..38c9475ae2 100644 --- a/tests/brokers/base/fastapi.py +++ b/tests/brokers/base/fastapi.py @@ -80,9 +80,6 @@ async def hello(msg, tasks: BackgroundTasks) -> None: async def test_context(self, mock: Mock, queue: str, event: asyncio.Event) -> None: router = self.router_class() context = router.context - from loguru import logger - - logger.debug(context) context_key = "message.headers" diff --git a/tests/prometheus/basic.py b/tests/prometheus/basic.py index 004afa8457..22c13b1540 100644 --- a/tests/prometheus/basic.py +++ b/tests/prometheus/basic.py @@ -8,6 +8,7 @@ from faststream import Context from faststream.exceptions import RejectMessage from faststream.message import AckStatus +from faststream.prometheus import MetricsSettingsProvider from faststream.prometheus.middleware import ( PROCESSING_STATUS_BY_ACK_STATUS, PROCESSING_STATUS_BY_HANDLER_EXCEPTION_MAP, @@ -233,3 +234,21 @@ async def handle(): assert event.is_set() metrics_manager_mock.add_received_message.assert_called_once() metrics_manager_mock.add_published_message.assert_called_once() + + +class LocalMetricsSettingsProviderTestcase: + messaging_system: str + + @staticmethod + def get_provider() -> MetricsSettingsProvider: + raise NotImplementedError + + def test_messaging_system(self) -> None: + provider = self.get_provider() + assert provider.messaging_system == self.messaging_system + + def test_get_consume_attrs_from_message(self, *args, **kwargs) -> None: + raise NotImplementedError + + def test_get_publish_destination_name_from_cmd(self, *args, **kwargs) -> None: + raise NotImplementedError diff --git a/tests/prometheus/confluent/test_provider.py b/tests/prometheus/confluent/test_provider.py new file mode 100644 index 0000000000..87d9f5659b --- /dev/null +++ b/tests/prometheus/confluent/test_provider.py @@ -0,0 +1,106 @@ +import random +from types import SimpleNamespace + +import pytest + +from faststream.confluent.prometheus.provider import ( + BatchConfluentMetricsSettingsProvider, + ConfluentMetricsSettingsProvider, + settings_provider_factory, +) +from faststream.prometheus import MetricsSettingsProvider +from tests.prometheus.basic import LocalMetricsSettingsProviderTestcase + + +class LocalBaseConfluentMetricsSettingsProviderTestcase( + LocalMetricsSettingsProviderTestcase +): + messaging_system = "kafka" + + def test_get_publish_destination_name_from_cmd(self, queue: str) -> None: + expected_destination_name = queue + provider = self.get_provider() + command = SimpleNamespace(destination=queue) + + destination_name = provider.get_publish_destination_name_from_cmd(command) + + assert destination_name == expected_destination_name + + +class TestKafkaMetricsSettingsProvider( + LocalBaseConfluentMetricsSettingsProviderTestcase +): + @staticmethod + def get_provider() -> MetricsSettingsProvider: + return ConfluentMetricsSettingsProvider() + + def test_get_consume_attrs_from_message(self, queue: str) -> None: + body = b"Hello" + expected_attrs = { + "destination_name": queue, + "message_size": len(body), + "messages_count": 1, + } + + message = SimpleNamespace( + body=body, raw_message=SimpleNamespace(topic=lambda: queue) + ) + + provider = self.get_provider() + attrs = provider.get_consume_attrs_from_message(message) + + assert attrs == expected_attrs + + +class TestBatchConfluentMetricsSettingsProvider( + LocalBaseConfluentMetricsSettingsProviderTestcase +): + @staticmethod + def get_provider() -> MetricsSettingsProvider: + return BatchConfluentMetricsSettingsProvider() + + def test_get_consume_attrs_from_message(self, queue: str) -> None: + body = [b"Hi ", b"again, ", b"FastStream!"] + message = SimpleNamespace( + body=body, + raw_message=[ + SimpleNamespace(topic=lambda: queue) + for _ in range(random.randint(a=2, b=10)) + ], + ) + expected_attrs = { + "destination_name": message.raw_message[0].topic(), + "message_size": len(bytearray().join(body)), + "messages_count": len(message.raw_message), + } + + provider = self.get_provider() + attrs = provider.get_consume_attrs_from_message(message) + + assert attrs == expected_attrs + + +@pytest.mark.parametrize( + ("msg", "expected_provider"), + ( + pytest.param( + (SimpleNamespace(), SimpleNamespace()), + BatchConfluentMetricsSettingsProvider(), + id="message is batch", + ), + pytest.param( + SimpleNamespace(), + ConfluentMetricsSettingsProvider(), + id="single message", + ), + pytest.param( + None, + ConfluentMetricsSettingsProvider(), + id="message is None", + ), + ), +) +def test_settings_provider_factory(msg, expected_provider) -> None: + provider = settings_provider_factory(msg) + + assert isinstance(provider, type(expected_provider)) diff --git a/tests/prometheus/kafka/test_provider.py b/tests/prometheus/kafka/test_provider.py new file mode 100644 index 0000000000..4127eed58e --- /dev/null +++ b/tests/prometheus/kafka/test_provider.py @@ -0,0 +1,101 @@ +import random +from types import SimpleNamespace + +import pytest + +from faststream.kafka.prometheus.provider import ( + BatchKafkaMetricsSettingsProvider, + KafkaMetricsSettingsProvider, + settings_provider_factory, +) +from faststream.prometheus import MetricsSettingsProvider +from tests.prometheus.basic import LocalMetricsSettingsProviderTestcase + + +class LocalBaseKafkaMetricsSettingsProviderTestcase( + LocalMetricsSettingsProviderTestcase +): + messaging_system = "kafka" + + def test_get_publish_destination_name_from_cmd(self, queue: str) -> None: + expected_destination_name = queue + provider = self.get_provider() + command = SimpleNamespace(destination=queue) + + destination_name = provider.get_publish_destination_name_from_cmd(command) + + assert destination_name == expected_destination_name + + +class TestKafkaMetricsSettingsProvider(LocalBaseKafkaMetricsSettingsProviderTestcase): + @staticmethod + def get_provider() -> MetricsSettingsProvider: + return KafkaMetricsSettingsProvider() + + def test_get_consume_attrs_from_message(self, queue: str) -> None: + body = b"Hello" + expected_attrs = { + "destination_name": queue, + "message_size": len(body), + "messages_count": 1, + } + + message = SimpleNamespace(body=body, raw_message=SimpleNamespace(topic=queue)) + + provider = self.get_provider() + attrs = provider.get_consume_attrs_from_message(message) + + assert attrs == expected_attrs + + +class TestBatchKafkaMetricsSettingsProvider( + LocalBaseKafkaMetricsSettingsProviderTestcase +): + @staticmethod + def get_provider() -> MetricsSettingsProvider: + return BatchKafkaMetricsSettingsProvider() + + def test_get_consume_attrs_from_message(self, queue: str) -> None: + body = [b"Hi ", b"again, ", b"FastStream!"] + message = SimpleNamespace( + body=body, + raw_message=[ + SimpleNamespace(topic=queue) for _ in range(random.randint(a=2, b=10)) + ], + ) + expected_attrs = { + "destination_name": message.raw_message[0].topic, + "message_size": len(bytearray().join(body)), + "messages_count": len(message.raw_message), + } + + provider = self.get_provider() + attrs = provider.get_consume_attrs_from_message(message) + + assert attrs == expected_attrs + + +@pytest.mark.parametrize( + ("msg", "expected_provider"), + ( + pytest.param( + (SimpleNamespace(), SimpleNamespace()), + BatchKafkaMetricsSettingsProvider(), + id="message is batch", + ), + pytest.param( + SimpleNamespace(), + KafkaMetricsSettingsProvider(), + id="single message", + ), + pytest.param( + None, + KafkaMetricsSettingsProvider(), + id="message is None", + ), + ), +) +def test_settings_provider_factory(msg, expected_provider) -> None: + provider = settings_provider_factory(msg) + + assert isinstance(provider, type(expected_provider)) diff --git a/tests/prometheus/nats/test_provider.py b/tests/prometheus/nats/test_provider.py new file mode 100644 index 0000000000..817a37142d --- /dev/null +++ b/tests/prometheus/nats/test_provider.py @@ -0,0 +1,107 @@ +import random +from types import SimpleNamespace + +import pytest +from nats.aio.msg import Msg + +from faststream.nats.prometheus.provider import ( + BatchNatsMetricsSettingsProvider, + NatsMetricsSettingsProvider, + settings_provider_factory, +) +from faststream.prometheus import MetricsSettingsProvider +from tests.prometheus.basic import LocalMetricsSettingsProviderTestcase + + +class LocalBaseNatsMetricsSettingsProviderTestcase( + LocalMetricsSettingsProviderTestcase +): + messaging_system = "nats" + + def test_get_publish_destination_name_from_cmd(self, queue: str) -> None: + expected_destination_name = queue + command = SimpleNamespace(destination=queue) + + provider = self.get_provider() + destination_name = provider.get_publish_destination_name_from_cmd(command) + + assert destination_name == expected_destination_name + + +class TestNatsMetricsSettingsProvider(LocalBaseNatsMetricsSettingsProviderTestcase): + @staticmethod + def get_provider() -> MetricsSettingsProvider: + return NatsMetricsSettingsProvider() + + def test_get_consume_attrs_from_message(self, queue: str) -> None: + body = b"Hello" + expected_attrs = { + "destination_name": queue, + "message_size": len(body), + "messages_count": 1, + } + message = SimpleNamespace(body=body, raw_message=SimpleNamespace(subject=queue)) + + provider = self.get_provider() + attrs = provider.get_consume_attrs_from_message(message) + + assert attrs == expected_attrs + + +class TestBatchNatsMetricsSettingsProvider( + LocalBaseNatsMetricsSettingsProviderTestcase +): + @staticmethod + def get_provider() -> MetricsSettingsProvider: + return BatchNatsMetricsSettingsProvider() + + def test_get_consume_attrs_from_message(self, queue: str) -> None: + body = b"Hello" + raw_messages = [ + SimpleNamespace(subject=queue) for _ in range(random.randint(a=2, b=10)) + ] + + expected_attrs = { + "destination_name": raw_messages[0].subject, + "message_size": len(body), + "messages_count": len(raw_messages), + } + message = SimpleNamespace(body=body, raw_message=raw_messages) + + provider = self.get_provider() + attrs = provider.get_consume_attrs_from_message(message) + + assert attrs == expected_attrs + + +@pytest.mark.parametrize( + ("msg", "expected_provider"), + ( + pytest.param( + (Msg(SimpleNamespace()), Msg(SimpleNamespace())), + BatchNatsMetricsSettingsProvider(), + id="message is sequence", + ), + pytest.param( + Msg( + SimpleNamespace(), + ), + NatsMetricsSettingsProvider(), + id="single message", + ), + pytest.param( + None, + NatsMetricsSettingsProvider(), + id="message is None", + ), + pytest.param( + SimpleNamespace(), + None, + id="message is not Msg instance", + ), + ), +) +def test_settings_provider_factory(msg, expected_provider) -> None: + provider = settings_provider_factory(msg) + + assert isinstance(provider, type(expected_provider)) diff --git a/tests/prometheus/rabbit/test_provider.py b/tests/prometheus/rabbit/test_provider.py new file mode 100644 index 0000000000..71d47a781b --- /dev/null +++ b/tests/prometheus/rabbit/test_provider.py @@ -0,0 +1,65 @@ +from types import SimpleNamespace +from typing import Union + +import pytest + +from faststream.prometheus import MetricsSettingsProvider +from faststream.rabbit.prometheus.provider import RabbitMetricsSettingsProvider +from tests.prometheus.basic import LocalMetricsSettingsProviderTestcase + + +class TestRabbitMetricsSettingsProvider(LocalMetricsSettingsProviderTestcase): + messaging_system = "rabbitmq" + + @staticmethod + def get_provider() -> MetricsSettingsProvider: + return RabbitMetricsSettingsProvider() + + @pytest.mark.parametrize( + "exchange", + ( + pytest.param("my_exchange", id="with exchange"), + pytest.param(None, id="without exchange"), + ), + ) + def test_get_consume_attrs_from_message( + self, + exchange: Union[str, None], + queue: str, + ) -> None: + body = b"Hello" + expected_attrs = { + "destination_name": f"{exchange or 'default'}.{queue}", + "message_size": len(body), + "messages_count": 1, + } + message = SimpleNamespace( + body=body, raw_message=SimpleNamespace(exchange=exchange, routing_key=queue) + ) + + provider = self.get_provider() + attrs = provider.get_consume_attrs_from_message(message) + + assert attrs == expected_attrs + + @pytest.mark.parametrize( + "exchange", + ( + pytest.param("my_exchange", id="with exchange"), + pytest.param(None, id="without exchange"), + ), + ) + def test_get_publish_destination_name_from_cmd( + self, + exchange: Union[str, None], + queue: str, + ) -> None: + expected_destination_name = f"{exchange or 'default'}.{queue}" + command = SimpleNamespace( + exchange=SimpleNamespace(name=exchange), destination=queue + ) + + provider = self.get_provider() + destination_name = provider.get_publish_destination_name_from_cmd(command) + + assert destination_name == expected_destination_name diff --git a/tests/prometheus/redis/test_provider.py b/tests/prometheus/redis/test_provider.py new file mode 100644 index 0000000000..9bafd26402 --- /dev/null +++ b/tests/prometheus/redis/test_provider.py @@ -0,0 +1,125 @@ +from types import SimpleNamespace + +import pytest + +from faststream.prometheus import MetricsSettingsProvider +from faststream.redis.prometheus.provider import ( + BatchRedisMetricsSettingsProvider, + RedisMetricsSettingsProvider, + settings_provider_factory, +) +from tests.prometheus.basic import LocalMetricsSettingsProviderTestcase + + +class LocalBaseRedisMetricsSettingsProviderTestcase( + LocalMetricsSettingsProviderTestcase +): + messaging_system = "redis" + + def test_get_publish_destination_name_from_cmd(self, queue: str) -> None: + expected_destination_name = queue + provider = self.get_provider() + command = SimpleNamespace(destination=queue) + + destination_name = provider.get_publish_destination_name_from_cmd(command) + + assert destination_name == expected_destination_name + + +class TestRedisMetricsSettingsProvider(LocalBaseRedisMetricsSettingsProviderTestcase): + @staticmethod + def get_provider() -> MetricsSettingsProvider: + return RedisMetricsSettingsProvider() + + @pytest.mark.parametrize( + "destination", + ( + pytest.param("channel", id="destination is channel"), + pytest.param("list", id="destination is list"), + pytest.param("stream", id="destination is stream"), + pytest.param("", id="destination is blank"), + ), + ) + def test_get_consume_attrs_from_message(self, queue: str, destination: str) -> None: + body = b"Hello" + expected_attrs = { + "destination_name": queue if destination else "", + "message_size": len(body), + "messages_count": 1, + } + raw_message = {} + + if destination: + raw_message[destination] = queue + + message = SimpleNamespace(body=body, raw_message=raw_message) + + provider = self.get_provider() + attrs = provider.get_consume_attrs_from_message(message) + + assert attrs == expected_attrs + + +class TestBatchRedisMetricsSettingsProvider( + LocalBaseRedisMetricsSettingsProviderTestcase +): + @staticmethod + def get_provider() -> MetricsSettingsProvider: + return BatchRedisMetricsSettingsProvider() + + @pytest.mark.parametrize( + "destination", + ( + pytest.param("channel", id="destination is channel"), + pytest.param("list", id="destination is list"), + pytest.param("stream", id="destination is stream"), + pytest.param("", id="destination is blank"), + ), + ) + def test_get_consume_attrs_from_message(self, queue: str, destination: str) -> None: + decoded_body = ["Hi ", "again, ", "FastStream!"] + body = str(decoded_body).encode() + expected_attrs = { + "destination_name": queue if destination else "", + "message_size": len(body), + "messages_count": len(decoded_body), + } + raw_message = {} + + if destination: + raw_message[destination] = queue + + message = SimpleNamespace( + body=body, _decoded_body=decoded_body, raw_message=raw_message + ) + + provider = self.get_provider() + attrs = provider.get_consume_attrs_from_message(message) + + assert attrs == expected_attrs + + +@pytest.mark.parametrize( + ("msg", "expected_provider"), + ( + pytest.param( + {"type": "blist"}, + BatchRedisMetricsSettingsProvider(), + id="message is batch", + ), + pytest.param( + {"type": "not_blist"}, + RedisMetricsSettingsProvider(), + id="single message", + ), + pytest.param( + None, + RedisMetricsSettingsProvider(), + id="message is None", + ), + ), +) +def test_settings_provider_factory(msg, expected_provider) -> None: + provider = settings_provider_factory(msg) + + assert isinstance(provider, type(expected_provider)) From 0578c1bf1178142ec92284f9cb13b2978af494c2 Mon Sep 17 00:00:00 2001 From: Ruslan Alimov Date: Tue, 5 Nov 2024 16:48:57 +0300 Subject: [PATCH 183/245] feat/ack_middleware added middleware (#1869) * feat/ack_middleware added ack middleware * tests: fix FastAPI tests * feat/ack_middleware added ack middleware * ack_middleware fixed redis stream * tests: fix FastAPI tests * ack_middleware fixed redis stream * chore: remove conflicts * chore: refactor AckMiddleware * docs: generate API References --------- Co-authored-by: Nikita Pastukhov Co-authored-by: Pastukhov Nikita Co-authored-by: Lancetnik --- docs/docs/SUMMARY.md | 9 + docs/docs/en/api/faststream/AckPolicy.md | 11 + .../api/faststream/middlewares/AckPolicy.md | 11 + .../middlewares/AcknowledgementMiddleware.md | 11 + .../acknowledgement/conf/AckPolicy.md | 11 + .../middleware/AcknowledgementMiddleware.md | 11 + faststream/__init__.py | 3 +- faststream/_internal/broker/broker.py | 11 +- .../subscriber/acknowledgement_watcher.py | 220 ------------------ faststream/_internal/subscriber/usecase.py | 30 +-- faststream/_internal/subscriber/utils.py | 27 +-- faststream/confluent/broker/registrator.py | 52 ++--- faststream/confluent/fastapi/fastapi.py | 40 ++-- faststream/confluent/router.py | 16 +- faststream/confluent/subscriber/factory.py | 19 +- faststream/confluent/subscriber/usecase.py | 19 +- faststream/kafka/broker/registrator.py | 52 ++--- faststream/kafka/fastapi/fastapi.py | 52 ++--- faststream/kafka/router.py | 16 +- faststream/kafka/subscriber/factory.py | 19 +- faststream/kafka/subscriber/usecase.py | 19 +- faststream/middlewares/__init__.py | 9 +- .../middlewares/acknowledgement/__init__.py | 0 .../middlewares/acknowledgement/conf.py | 8 + .../middlewares/acknowledgement/middleware.py | 111 +++++++++ faststream/nats/broker/registrator.py | 16 +- faststream/nats/fastapi/fastapi.py | 16 +- faststream/nats/parser.py | 7 +- faststream/nats/publisher/producer.py | 5 +- faststream/nats/router.py | 16 +- faststream/nats/schemas/js_stream.py | 13 +- faststream/nats/subscriber/factory.py | 25 +- faststream/nats/subscriber/usecase.py | 88 +++---- faststream/nats/testing.py | 3 +- faststream/rabbit/broker/registrator.py | 16 +- faststream/rabbit/fastapi/fastapi.py | 16 +- faststream/rabbit/router.py | 16 +- faststream/rabbit/subscriber/factory.py | 9 +- faststream/rabbit/subscriber/usecase.py | 11 +- faststream/redis/broker/registrator.py | 16 +- faststream/redis/fastapi/fastapi.py | 16 +- faststream/redis/router.py | 16 +- faststream/redis/schemas/stream_sub.py | 5 +- faststream/redis/subscriber/factory.py | 19 +- faststream/redis/subscriber/usecase.py | 49 ++-- tests/brokers/base/fastapi.py | 32 ++- tests/brokers/base/router.py | 9 +- tests/brokers/confluent/test_consume.py | 5 +- tests/brokers/kafka/test_consume.py | 5 +- tests/brokers/nats/test_consume.py | 5 +- tests/brokers/rabbit/test_consume.py | 22 +- tests/brokers/rabbit/test_test_client.py | 6 +- tests/brokers/test_pushback.py | 124 ---------- 53 files changed, 528 insertions(+), 845 deletions(-) create mode 100644 docs/docs/en/api/faststream/AckPolicy.md create mode 100644 docs/docs/en/api/faststream/middlewares/AckPolicy.md create mode 100644 docs/docs/en/api/faststream/middlewares/AcknowledgementMiddleware.md create mode 100644 docs/docs/en/api/faststream/middlewares/acknowledgement/conf/AckPolicy.md create mode 100644 docs/docs/en/api/faststream/middlewares/acknowledgement/middleware/AcknowledgementMiddleware.md delete mode 100644 faststream/_internal/subscriber/acknowledgement_watcher.py create mode 100644 faststream/middlewares/acknowledgement/__init__.py create mode 100644 faststream/middlewares/acknowledgement/conf.py create mode 100644 faststream/middlewares/acknowledgement/middleware.py delete mode 100644 tests/brokers/test_pushback.py diff --git a/docs/docs/SUMMARY.md b/docs/docs/SUMMARY.md index bf061a321a..5c5b4db5b4 100644 --- a/docs/docs/SUMMARY.md +++ b/docs/docs/SUMMARY.md @@ -119,6 +119,7 @@ search: - [Reference - Code API](api/index.md) - Public API - faststream + - [AckPolicy](public_api/faststream/AckPolicy.md) - [BaseMiddleware](public_api/faststream/BaseMiddleware.md) - [Context](public_api/faststream/Context.md) - [Depends](public_api/faststream/Depends.md) @@ -205,6 +206,7 @@ search: - [TestRedisBroker](public_api/faststream/redis/TestRedisBroker.md) - All API - faststream + - [AckPolicy](api/faststream/AckPolicy.md) - [BaseMiddleware](api/faststream/BaseMiddleware.md) - [Context](api/faststream/Context.md) - [Depends](api/faststream/Depends.md) @@ -472,8 +474,15 @@ search: - [encode_message](api/faststream/message/utils/encode_message.md) - [gen_cor_id](api/faststream/message/utils/gen_cor_id.md) - middlewares + - [AckPolicy](api/faststream/middlewares/AckPolicy.md) + - [AcknowledgementMiddleware](api/faststream/middlewares/AcknowledgementMiddleware.md) - [BaseMiddleware](api/faststream/middlewares/BaseMiddleware.md) - [ExceptionMiddleware](api/faststream/middlewares/ExceptionMiddleware.md) + - acknowledgement + - conf + - [AckPolicy](api/faststream/middlewares/acknowledgement/conf/AckPolicy.md) + - middleware + - [AcknowledgementMiddleware](api/faststream/middlewares/acknowledgement/middleware/AcknowledgementMiddleware.md) - base - [BaseMiddleware](api/faststream/middlewares/base/BaseMiddleware.md) - exception diff --git a/docs/docs/en/api/faststream/AckPolicy.md b/docs/docs/en/api/faststream/AckPolicy.md new file mode 100644 index 0000000000..4d7218c81b --- /dev/null +++ b/docs/docs/en/api/faststream/AckPolicy.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.AckPolicy diff --git a/docs/docs/en/api/faststream/middlewares/AckPolicy.md b/docs/docs/en/api/faststream/middlewares/AckPolicy.md new file mode 100644 index 0000000000..82d0033dfb --- /dev/null +++ b/docs/docs/en/api/faststream/middlewares/AckPolicy.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.middlewares.AckPolicy diff --git a/docs/docs/en/api/faststream/middlewares/AcknowledgementMiddleware.md b/docs/docs/en/api/faststream/middlewares/AcknowledgementMiddleware.md new file mode 100644 index 0000000000..d3e7d6a763 --- /dev/null +++ b/docs/docs/en/api/faststream/middlewares/AcknowledgementMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.middlewares.AcknowledgementMiddleware diff --git a/docs/docs/en/api/faststream/middlewares/acknowledgement/conf/AckPolicy.md b/docs/docs/en/api/faststream/middlewares/acknowledgement/conf/AckPolicy.md new file mode 100644 index 0000000000..8a92ec0a54 --- /dev/null +++ b/docs/docs/en/api/faststream/middlewares/acknowledgement/conf/AckPolicy.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.middlewares.acknowledgement.conf.AckPolicy diff --git a/docs/docs/en/api/faststream/middlewares/acknowledgement/middleware/AcknowledgementMiddleware.md b/docs/docs/en/api/faststream/middlewares/acknowledgement/middleware/AcknowledgementMiddleware.md new file mode 100644 index 0000000000..79b2956eb4 --- /dev/null +++ b/docs/docs/en/api/faststream/middlewares/acknowledgement/middleware/AcknowledgementMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.middlewares.acknowledgement.middleware.AcknowledgementMiddleware diff --git a/faststream/__init__.py b/faststream/__init__.py index 09514567a8..cad7e628bf 100644 --- a/faststream/__init__.py +++ b/faststream/__init__.py @@ -4,7 +4,7 @@ from faststream._internal.utils import apply_types from faststream.annotations import ContextRepo, Logger from faststream.app import FastStream -from faststream.middlewares import BaseMiddleware, ExceptionMiddleware +from faststream.middlewares import AckPolicy, BaseMiddleware, ExceptionMiddleware from faststream.params import ( Context, Depends, @@ -16,6 +16,7 @@ __all__ = ( # middlewares + "AckPolicy", "BaseMiddleware", # params "Context", diff --git a/faststream/_internal/broker/broker.py b/faststream/_internal/broker/broker.py index 162ea5fbc6..f4229be5c6 100644 --- a/faststream/_internal/broker/broker.py +++ b/faststream/_internal/broker/broker.py @@ -16,7 +16,6 @@ from fast_depends.pydantic import PydanticSerializer from typing_extensions import Doc, Self -from faststream._internal._compat import is_test_env from faststream._internal.constants import EMPTY from faststream._internal.context.repository import ContextRepo from faststream._internal.setup import ( @@ -164,12 +163,10 @@ def __init__( self._connection = None self._producer = None - # TODO: remove useless middleware filter - if not is_test_env(): - self._middlewares = ( - CriticalLogMiddleware(logger_state), - *self._middlewares, - ) + self._middlewares = ( + CriticalLogMiddleware(logger_state), + *self._middlewares, + ) self._state = EmptyState( depends_params=FastDependsData( diff --git a/faststream/_internal/subscriber/acknowledgement_watcher.py b/faststream/_internal/subscriber/acknowledgement_watcher.py deleted file mode 100644 index c86e59baf6..0000000000 --- a/faststream/_internal/subscriber/acknowledgement_watcher.py +++ /dev/null @@ -1,220 +0,0 @@ -import logging -from abc import ABC, abstractmethod -from collections import ( - Counter, - Counter as CounterType, -) -from typing import TYPE_CHECKING, Any, Optional, Union - -from faststream.exceptions import ( - AckMessage, - HandlerException, - NackMessage, - RejectMessage, - SkipMessage, -) - -if TYPE_CHECKING: - from types import TracebackType - - from faststream._internal.basic_types import LoggerProto - from faststream._internal.types import MsgType - from faststream.message import StreamMessage - - -class BaseWatcher(ABC): - """A base class for a watcher.""" - - max_tries: int - - def __init__( - self, - max_tries: int = 0, - logger: Optional["LoggerProto"] = None, - ) -> None: - self.logger = logger - self.max_tries = max_tries - - @abstractmethod - def add(self, message_id: str) -> None: - """Add a message.""" - raise NotImplementedError - - @abstractmethod - def is_max(self, message_id: str) -> bool: - """Check if the given message ID is the maximum attempt.""" - raise NotImplementedError - - @abstractmethod - def remove(self, message_id: str) -> None: - """Remove a message.""" - raise NotImplementedError - - -class EndlessWatcher(BaseWatcher): - """A class to watch and track messages.""" - - def add(self, message_id: str) -> None: - """Add a message to the list.""" - - def is_max(self, message_id: str) -> bool: - """Check if the given message ID is the maximum attempt.""" - return False - - def remove(self, message_id: str) -> None: - """Remove a message.""" - - -class OneTryWatcher(BaseWatcher): - """A class to watch and track messages.""" - - def add(self, message_id: str) -> None: - """Add a message.""" - - def is_max(self, message_id: str) -> bool: - """Check if the given message ID is the maximum attempt.""" - return True - - def remove(self, message_id: str) -> None: - """Remove a message.""" - - -class CounterWatcher(BaseWatcher): - """A class to watch and track the count of messages.""" - - memory: CounterType[str] - - def __init__( - self, - max_tries: int = 3, - logger: Optional["LoggerProto"] = None, - ) -> None: - super().__init__(logger=logger, max_tries=max_tries) - self.memory = Counter() - - def add(self, message_id: str) -> None: - """Check if the given message ID is the maximum attempt.""" - self.memory[message_id] += 1 - - def is_max(self, message_id: str) -> bool: - """Check if the number of tries for a message has exceeded the maximum allowed tries.""" - is_max = self.memory[message_id] > self.max_tries - if self.logger is not None: - if is_max: - self.logger.log( - logging.ERROR, - f"Already retried {self.max_tries} times. Skipped.", - ) - else: - self.logger.log( - logging.ERROR, - "Error is occurred. Pushing back to queue.", - ) - return is_max - - def remove(self, message_id: str) -> None: - """Remove a message from memory.""" - self.memory[message_id] = 0 - self.memory += Counter() - - -class WatcherContext: - """A class representing a context for a watcher.""" - - def __init__( - self, - message: "StreamMessage[MsgType]", - watcher: BaseWatcher, - logger: Optional["LoggerProto"] = None, - **extra_options: Any, - ) -> None: - self.watcher = watcher - self.message = message - self.extra_options = extra_options - self.logger = logger - - async def __aenter__(self) -> None: - self.watcher.add(self.message.message_id) - - async def __aexit__( - self, - exc_type: Optional[type[BaseException]], - exc_val: Optional[BaseException], - exc_tb: Optional["TracebackType"], - ) -> bool: - """Exit the asynchronous context manager.""" - if not exc_type: - await self.__ack() - - elif isinstance(exc_val, HandlerException): - if isinstance(exc_val, SkipMessage): - self.watcher.remove(self.message.message_id) - - elif isinstance(exc_val, AckMessage): - await self.__ack(**exc_val.extra_options) - - elif isinstance(exc_val, NackMessage): - await self.__nack(**exc_val.extra_options) - - elif isinstance(exc_val, RejectMessage): # pragma: no branch - await self.__reject(**exc_val.extra_options) - - # Exception was processed and suppressed - return True - - elif self.watcher.is_max(self.message.message_id): - await self.__reject() - - else: - await self.__nack() - - # Exception was not processed - return False - - async def __ack(self, **exc_extra_options: Any) -> None: - try: - await self.message.ack(**self.extra_options, **exc_extra_options) - except Exception as er: - if self.logger is not None: - self.logger.log(logging.ERROR, er, exc_info=er) - else: - self.watcher.remove(self.message.message_id) - - async def __nack(self, **exc_extra_options: Any) -> None: - try: - await self.message.nack(**self.extra_options, **exc_extra_options) - except Exception as er: - if self.logger is not None: - self.logger.log(logging.ERROR, er, exc_info=er) - - async def __reject(self, **exc_extra_options: Any) -> None: - try: - await self.message.reject(**self.extra_options, **exc_extra_options) - except Exception as er: - if self.logger is not None: - self.logger.log(logging.ERROR, er, exc_info=er) - else: - self.watcher.remove(self.message.message_id) - - -def get_watcher( - logger: Optional["LoggerProto"], - try_number: Union[bool, int], -) -> BaseWatcher: - """Get a watcher object based on the provided parameters. - - Args: - logger: Optional logger object for logging messages. - try_number: Optional parameter to specify the type of watcher. - - If set to True, an EndlessWatcher object will be returned. - - If set to False, a OneTryWatcher object will be returned. - - If set to an integer, a CounterWatcher object with the specified maximum number of tries will be returned. - """ - watcher: Optional[BaseWatcher] - if try_number is True: - watcher = EndlessWatcher() - elif try_number is False: - watcher = OneTryWatcher() - else: - watcher = CounterWatcher(logger=logger, max_tries=try_number) - return watcher diff --git a/faststream/_internal/subscriber/usecase.py b/faststream/_internal/subscriber/usecase.py index 0133be3493..58ed1a8e2a 100644 --- a/faststream/_internal/subscriber/usecase.py +++ b/faststream/_internal/subscriber/usecase.py @@ -7,7 +7,6 @@ Any, Callable, Optional, - Union, overload, ) @@ -19,7 +18,6 @@ from faststream._internal.subscriber.utils import ( MultiLock, default_filter, - get_watcher_context, resolve_custom_func, ) from faststream._internal.types import ( @@ -29,6 +27,7 @@ ) from faststream._internal.utils.functions import sync_fake_context, to_async from faststream.exceptions import SetupError, StopConsume, SubscriberNotFound +from faststream.middlewares import AckPolicy, AcknowledgementMiddleware from faststream.response import ensure_response from faststream.specification.asyncapi.message import parse_handler_params from faststream.specification.asyncapi.utils import to_camelcase @@ -92,13 +91,12 @@ class SubscriberUsecase(SubscriberProto[MsgType]): def __init__( self, *, - no_ack: bool, no_reply: bool, - retry: Union[bool, int], broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[MsgType]"], default_parser: "AsyncCallable", default_decoder: "AsyncCallable", + ack_policy: AckPolicy, # AsyncAPI information title_: Optional[str], description_: Optional[str], @@ -110,9 +108,7 @@ def __init__( self._parser = default_parser self._decoder = default_decoder self._no_reply = no_reply - # Watcher args - self._no_ack = no_ack - self._retry = retry + self.ack_policy = ack_policy self._call_options = None self._call_decorators = () @@ -134,6 +130,15 @@ def __init__( self.description_ = description_ self.include_in_schema = include_in_schema + if self.ack_policy is not AckPolicy.DO_NOTHING: + self._broker_middlewares = ( + AcknowledgementMiddleware( + self.ack_policy, + self.extra_watcher_options, + ), + *self._broker_middlewares, + ) + def add_middleware(self, middleware: "BrokerMiddleware[MsgType]") -> None: self._broker_middlewares = (*self._broker_middlewares, middleware) @@ -157,8 +162,6 @@ def _setup( # type: ignore[override] self.graceful_timeout = graceful_timeout self.extra_context = extra_context - self.watcher = get_watcher_context(logger, self._no_ack, self._retry) - for call in self.calls: if parser := call.item_parser or broker_parser: async_parser = resolve_custom_func(to_async(parser), self._parser) @@ -345,15 +348,6 @@ async def process_message(self, msg: MsgType) -> "Response": break if message is not None: - # Acknowledgement scope - # TODO: move it to scope enter at `retry` option deprecation - await stack.enter_async_context( - self.watcher( - message, - **self.extra_watcher_options, - ), - ) - stack.enter_context( context.scope("log_context", self.get_log_context(message)), ) diff --git a/faststream/_internal/subscriber/utils.py b/faststream/_internal/subscriber/utils.py index 4dc615a9c0..fb9002c3a3 100644 --- a/faststream/_internal/subscriber/utils.py +++ b/faststream/_internal/subscriber/utils.py @@ -1,7 +1,7 @@ import asyncio import inspect from collections.abc import Awaitable, Iterable -from contextlib import AbstractAsyncContextManager, AsyncExitStack, suppress +from contextlib import AsyncExitStack, suppress from functools import partial from typing import ( TYPE_CHECKING, @@ -15,18 +15,13 @@ import anyio from typing_extensions import Literal, Self, overload -from faststream._internal.subscriber.acknowledgement_watcher import ( - WatcherContext, - get_watcher, -) from faststream._internal.types import MsgType -from faststream._internal.utils.functions import fake_context, return_input, to_async +from faststream._internal.utils.functions import return_input, to_async from faststream.message.source_type import SourceType if TYPE_CHECKING: from types import TracebackType - from faststream._internal.basic_types import LoggerProto from faststream._internal.types import ( AsyncCallable, CustomCallable, @@ -90,24 +85,6 @@ async def default_filter(msg: "StreamMessage[Any]") -> bool: return not msg.processed -def get_watcher_context( - logger: Optional["LoggerProto"], - no_ack: bool, - retry: Union[bool, int], - **extra_options: Any, -) -> Callable[..., "AbstractAsyncContextManager[None]"]: - """Create Acknowledgement scope.""" - if no_ack: - return fake_context - - return partial( - WatcherContext, - watcher=get_watcher(logger, retry), - logger=logger, - **extra_options, - ) - - class MultiLock: """A class representing a multi lock.""" diff --git a/faststream/confluent/broker/registrator.py b/faststream/confluent/broker/registrator.py index 8eb5c58326..7187c56a03 100644 --- a/faststream/confluent/broker/registrator.py +++ b/faststream/confluent/broker/registrator.py @@ -16,6 +16,7 @@ from faststream.confluent.publisher.factory import create_publisher from faststream.confluent.subscriber.factory import create_subscriber from faststream.exceptions import SetupError +from faststream.middlewares import AckPolicy if TYPE_CHECKING: from confluent_kafka import Message @@ -294,14 +295,10 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - retry: Annotated[ - bool, - Doc("Whether to `nack` message at processing exception."), - ] = False, - no_ack: Annotated[ - bool, - Doc("Whether to disable **FastStream** autoacknowledgement logic or not."), - ] = False, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, no_reply: Annotated[ bool, Doc( @@ -565,14 +562,10 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - retry: Annotated[ - bool, - Doc("Whether to `nack` message at processing exception."), - ] = False, - no_ack: Annotated[ - bool, - Doc("Whether to disable **FastStream** autoacknowledgement logic or not."), - ] = False, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, no_reply: Annotated[ bool, Doc( @@ -836,14 +829,10 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - retry: Annotated[ - bool, - Doc("Whether to `nack` message at processing exception."), - ] = False, - no_ack: Annotated[ - bool, - Doc("Whether to disable **FastStream** autoacknowledgement logic or not."), - ] = False, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, no_reply: Annotated[ bool, Doc( @@ -1110,14 +1099,10 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - retry: Annotated[ - bool, - Doc("Whether to `nack` message at processing exception."), - ] = False, - no_ack: Annotated[ - bool, - Doc("Whether to disable **FastStream** autoacknowledgement logic or not."), - ] = False, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, no_reply: Annotated[ bool, Doc( @@ -1174,9 +1159,8 @@ def subscriber( }, is_manual=not auto_commit, # subscriber args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=self._middlewares, broker_dependencies=self._dependencies, # Specification diff --git a/faststream/confluent/fastapi/fastapi.py b/faststream/confluent/fastapi/fastapi.py index 73f6972a40..ac24669769 100644 --- a/faststream/confluent/fastapi/fastapi.py +++ b/faststream/confluent/fastapi/fastapi.py @@ -25,6 +25,7 @@ from faststream._internal.constants import EMPTY from faststream._internal.fastapi.router import StreamRouter from faststream.confluent.broker.broker import KafkaBroker as KB +from faststream.middlewares import AckPolicy if TYPE_CHECKING: from enum import Enum @@ -833,14 +834,10 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - retry: Annotated[ - bool, - Doc("Whether to `nack` message at processing exception."), - ] = False, - no_ack: Annotated[ - bool, - Doc("Whether to disable **FastStream** autoacknowledgement logic or not."), - ] = False, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, no_reply: Annotated[ bool, Doc( @@ -1607,14 +1604,10 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - retry: Annotated[ - bool, - Doc("Whether to `nack` message at processing exception."), - ] = False, - no_ack: Annotated[ - bool, - Doc("Whether to disable **FastStream** autoacknowledgement logic or not."), - ] = False, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, no_reply: Annotated[ bool, Doc( @@ -2004,14 +1997,10 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - retry: Annotated[ - bool, - Doc("Whether to `nack` message at processing exception."), - ] = False, - no_ack: Annotated[ - bool, - Doc("Whether to disable **FastStream** autoacknowledgement logic or not."), - ] = False, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, no_reply: Annotated[ bool, Doc( @@ -2187,8 +2176,7 @@ def subscriber( parser=parser, decoder=decoder, middlewares=middlewares, - retry=retry, - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, title=title, description=description, diff --git a/faststream/confluent/router.py b/faststream/confluent/router.py index cd1fc9509c..c4d36fd7e0 100644 --- a/faststream/confluent/router.py +++ b/faststream/confluent/router.py @@ -17,6 +17,7 @@ SubscriberRoute, ) from faststream.confluent.broker.registrator import KafkaRegistrator +from faststream.middlewares import AckPolicy if TYPE_CHECKING: from confluent_kafka import Message @@ -380,14 +381,10 @@ def __init__( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - retry: Annotated[ - bool, - Doc("Whether to `nack` message at processing exception."), - ] = False, - no_ack: Annotated[ - bool, - Doc("Whether to disable **FastStream** autoacknowledgement logic or not."), - ] = False, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, no_reply: Annotated[ bool, Doc( @@ -445,8 +442,7 @@ def __init__( description=description, include_in_schema=include_in_schema, # FastDepends args - retry=retry, - no_ack=no_ack, + ack_policy=ack_policy, ) diff --git a/faststream/confluent/subscriber/factory.py b/faststream/confluent/subscriber/factory.py index 24107e56be..744a47f744 100644 --- a/faststream/confluent/subscriber/factory.py +++ b/faststream/confluent/subscriber/factory.py @@ -19,6 +19,7 @@ from faststream._internal.basic_types import AnyDict from faststream._internal.types import BrokerMiddleware from faststream.confluent.schemas import TopicPartition + from faststream.middlewares import AckPolicy @overload @@ -33,9 +34,8 @@ def create_subscriber( connection_data: "AnyDict", is_manual: bool, # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[tuple[ConfluentMsg, ...]]"], # Specification args @@ -57,9 +57,8 @@ def create_subscriber( connection_data: "AnyDict", is_manual: bool, # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[ConfluentMsg]"], # Specification args @@ -81,9 +80,8 @@ def create_subscriber( connection_data: "AnyDict", is_manual: bool, # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable[ "BrokerMiddleware[Union[ConfluentMsg, tuple[ConfluentMsg, ...]]]" @@ -109,9 +107,8 @@ def create_subscriber( connection_data: "AnyDict", is_manual: bool, # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable[ "BrokerMiddleware[Union[ConfluentMsg, tuple[ConfluentMsg, ...]]]" @@ -133,9 +130,8 @@ def create_subscriber( group_id=group_id, connection_data=connection_data, is_manual=is_manual, - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, title_=title_, @@ -149,9 +145,8 @@ def create_subscriber( group_id=group_id, connection_data=connection_data, is_manual=is_manual, - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, title_=title_, diff --git a/faststream/confluent/subscriber/usecase.py b/faststream/confluent/subscriber/usecase.py index 470fb57840..e14e2903d2 100644 --- a/faststream/confluent/subscriber/usecase.py +++ b/faststream/confluent/subscriber/usecase.py @@ -32,6 +32,7 @@ ) from faststream.confluent.client import AsyncConfluentConsumer from faststream.message import StreamMessage + from faststream.middlewares import AckPolicy class LogicSubscriber(ABC, SubscriberUsecase[MsgType]): @@ -58,9 +59,8 @@ def __init__( # Subscriber args default_parser: "AsyncCallable", default_decoder: "AsyncCallable", - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[MsgType]"], # AsyncAPI args @@ -72,9 +72,8 @@ def __init__( default_parser=default_parser, default_decoder=default_decoder, # Propagated args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, # AsyncAPI args @@ -263,9 +262,8 @@ def __init__( connection_data: "AnyDict", is_manual: bool, # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[Message]"], # AsyncAPI args @@ -285,9 +283,8 @@ def __init__( default_parser=self.parser.parse_message, default_decoder=self.parser.decode_message, # Propagated args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, # AsyncAPI args @@ -328,9 +325,8 @@ def __init__( connection_data: "AnyDict", is_manual: bool, # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[tuple[Message, ...]]"], # AsyncAPI args @@ -352,9 +348,8 @@ def __init__( default_parser=self.parser.parse_message_batch, default_decoder=self.parser.decode_message_batch, # Propagated args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, # AsyncAPI args diff --git a/faststream/kafka/broker/registrator.py b/faststream/kafka/broker/registrator.py index b5b7c4b0d9..76cb4ec77b 100644 --- a/faststream/kafka/broker/registrator.py +++ b/faststream/kafka/broker/registrator.py @@ -18,6 +18,7 @@ from faststream._internal.broker.abc_broker import ABCBroker from faststream.kafka.publisher.factory import create_publisher from faststream.kafka.subscriber.factory import create_subscriber +from faststream.middlewares import AckPolicy if TYPE_CHECKING: from aiokafka import TopicPartition @@ -396,14 +397,10 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - retry: Annotated[ - bool, - Doc("Whether to `nack` message at processing exception."), - ] = False, - no_ack: Annotated[ - bool, - Doc("Whether to disable **FastStream** autoacknowledgement logic or not."), - ] = False, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, no_reply: Annotated[ bool, Doc( @@ -766,14 +763,10 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - retry: Annotated[ - bool, - Doc("Whether to `nack` message at processing exception."), - ] = False, - no_ack: Annotated[ - bool, - Doc("Whether to disable **FastStream** autoacknowledgement logic or not."), - ] = False, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, no_reply: Annotated[ bool, Doc( @@ -1136,14 +1129,10 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - retry: Annotated[ - bool, - Doc("Whether to `nack` message at processing exception."), - ] = False, - no_ack: Annotated[ - bool, - Doc("Whether to disable **FastStream** autoacknowledgement logic or not."), - ] = False, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, no_reply: Annotated[ bool, Doc( @@ -1509,14 +1498,10 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - retry: Annotated[ - bool, - Doc("Whether to `nack` message at processing exception."), - ] = False, - no_ack: Annotated[ - bool, - Doc("Whether to disable **FastStream** autoacknowledgement logic or not."), - ] = False, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, no_reply: Annotated[ bool, Doc( @@ -1576,9 +1561,8 @@ def subscriber( partitions=partitions, is_manual=not auto_commit, # subscriber args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=self._middlewares, broker_dependencies=self._dependencies, # Specification diff --git a/faststream/kafka/fastapi/fastapi.py b/faststream/kafka/fastapi/fastapi.py index 1b92a1029c..3cd73426db 100644 --- a/faststream/kafka/fastapi/fastapi.py +++ b/faststream/kafka/fastapi/fastapi.py @@ -28,6 +28,7 @@ from faststream._internal.constants import EMPTY from faststream._internal.fastapi.router import StreamRouter from faststream.kafka.broker.broker import KafkaBroker as KB +from faststream.middlewares import AckPolicy if TYPE_CHECKING: from asyncio import AbstractEventLoop @@ -944,14 +945,10 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - retry: Annotated[ - bool, - Doc("Whether to `nack` message at processing exception."), - ] = False, - no_ack: Annotated[ - bool, - Doc("Whether to disable **FastStream** autoacknowledgement logic or not."), - ] = False, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, no_reply: Annotated[ bool, Doc( @@ -1434,14 +1431,10 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - retry: Annotated[ - bool, - Doc("Whether to `nack` message at processing exception."), - ] = False, - no_ack: Annotated[ - bool, - Doc("Whether to disable **FastStream** autoacknowledgement logic or not."), - ] = False, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, no_reply: Annotated[ bool, Doc( @@ -1924,14 +1917,10 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - retry: Annotated[ - bool, - Doc("Whether to `nack` message at processing exception."), - ] = False, - no_ack: Annotated[ - bool, - Doc("Whether to disable **FastStream** autoacknowledgement logic or not."), - ] = False, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, no_reply: Annotated[ bool, Doc( @@ -2417,14 +2406,10 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - retry: Annotated[ - bool, - Doc("Whether to `nack` message at processing exception."), - ] = False, - no_ack: Annotated[ - bool, - Doc("Whether to disable **FastStream** autoacknowledgement logic or not."), - ] = False, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, no_reply: Annotated[ bool, Doc( @@ -2607,8 +2592,7 @@ def subscriber( parser=parser, decoder=decoder, middlewares=middlewares, - retry=retry, - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, title=title, description=description, diff --git a/faststream/kafka/router.py b/faststream/kafka/router.py index 1652e52901..416d23df20 100644 --- a/faststream/kafka/router.py +++ b/faststream/kafka/router.py @@ -18,6 +18,7 @@ SubscriberRoute, ) from faststream.kafka.broker.registrator import KafkaRegistrator +from faststream.middlewares import AckPolicy if TYPE_CHECKING: from aiokafka import ConsumerRecord, TopicPartition @@ -483,14 +484,10 @@ def __init__( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - retry: Annotated[ - bool, - Doc("Whether to `nack` message at processing exception."), - ] = False, - no_ack: Annotated[ - bool, - Doc("Whether to disable **FastStream** autoacknowledgement logic or not."), - ] = False, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, no_reply: Annotated[ bool, Doc( @@ -555,8 +552,7 @@ def __init__( description=description, include_in_schema=include_in_schema, # FastDepends args - retry=retry, - no_ack=no_ack, + ack_policy=ack_policy, ) diff --git a/faststream/kafka/subscriber/factory.py b/faststream/kafka/subscriber/factory.py index e53654283e..7542a11cd6 100644 --- a/faststream/kafka/subscriber/factory.py +++ b/faststream/kafka/subscriber/factory.py @@ -20,6 +20,7 @@ from faststream._internal.basic_types import AnyDict from faststream._internal.types import BrokerMiddleware + from faststream.middlewares import AckPolicy @overload @@ -36,9 +37,8 @@ def create_subscriber( partitions: Iterable["TopicPartition"], is_manual: bool, # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[tuple[ConsumerRecord, ...]]"], # Specification args @@ -62,9 +62,8 @@ def create_subscriber( partitions: Iterable["TopicPartition"], is_manual: bool, # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[ConsumerRecord]"], # Specification args @@ -88,9 +87,8 @@ def create_subscriber( partitions: Iterable["TopicPartition"], is_manual: bool, # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable[ "BrokerMiddleware[Union[ConsumerRecord, tuple[ConsumerRecord, ...]]]" @@ -118,9 +116,8 @@ def create_subscriber( partitions: Iterable["TopicPartition"], is_manual: bool, # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable[ "BrokerMiddleware[Union[ConsumerRecord, tuple[ConsumerRecord, ...]]]" @@ -163,9 +160,8 @@ def create_subscriber( connection_args=connection_args, partitions=partitions, is_manual=is_manual, - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, title_=title_, @@ -181,9 +177,8 @@ def create_subscriber( connection_args=connection_args, partitions=partitions, is_manual=is_manual, - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, title_=title_, diff --git a/faststream/kafka/subscriber/usecase.py b/faststream/kafka/subscriber/usecase.py index 03dae21687..f3cf9c2122 100644 --- a/faststream/kafka/subscriber/usecase.py +++ b/faststream/kafka/subscriber/usecase.py @@ -36,6 +36,7 @@ from faststream._internal.publisher.proto import BasePublisherProto, ProducerProto from faststream._internal.setup import SetupState from faststream.message import StreamMessage + from faststream.middlewares import AckPolicy class LogicSubscriber(SubscriberUsecase[MsgType]): @@ -64,9 +65,8 @@ def __init__( # Subscriber args default_parser: "AsyncCallable", default_decoder: "AsyncCallable", - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[MsgType]"], # AsyncAPI args @@ -78,9 +78,8 @@ def __init__( default_parser=default_parser, default_decoder=default_decoder, # Propagated args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, # AsyncAPI args @@ -292,9 +291,8 @@ def __init__( partitions: Iterable["TopicPartition"], is_manual: bool, # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[ConsumerRecord]"], # AsyncAPI args @@ -328,9 +326,8 @@ def __init__( default_parser=self.parser.parse_message, default_decoder=self.parser.decode_message, # Propagated args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, # AsyncAPI args @@ -373,9 +370,8 @@ def __init__( partitions: Iterable["TopicPartition"], is_manual: bool, # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable[ "BrokerMiddleware[Sequence[tuple[ConsumerRecord, ...]]]" @@ -414,9 +410,8 @@ def __init__( default_parser=self.parser.parse_message, default_decoder=self.parser.decode_message, # Propagated args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, # AsyncAPI args diff --git a/faststream/middlewares/__init__.py b/faststream/middlewares/__init__.py index 0615c88194..f8d57bdf50 100644 --- a/faststream/middlewares/__init__.py +++ b/faststream/middlewares/__init__.py @@ -1,4 +1,11 @@ +from faststream.middlewares.acknowledgement.conf import AckPolicy +from faststream.middlewares.acknowledgement.middleware import AcknowledgementMiddleware from faststream.middlewares.base import BaseMiddleware from faststream.middlewares.exception import ExceptionMiddleware -__all__ = ("BaseMiddleware", "ExceptionMiddleware") +__all__ = ( + "AckPolicy", + "AcknowledgementMiddleware", + "BaseMiddleware", + "ExceptionMiddleware", +) diff --git a/faststream/middlewares/acknowledgement/__init__.py b/faststream/middlewares/acknowledgement/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/faststream/middlewares/acknowledgement/conf.py b/faststream/middlewares/acknowledgement/conf.py new file mode 100644 index 0000000000..60b910264d --- /dev/null +++ b/faststream/middlewares/acknowledgement/conf.py @@ -0,0 +1,8 @@ +from enum import Enum + + +class AckPolicy(str, Enum): + ACK = "ack" + REJECT_ON_ERROR = "reject_on_error" + NACK_ON_ERROR = "nack_on_error" + DO_NOTHING = "do_nothing" diff --git a/faststream/middlewares/acknowledgement/middleware.py b/faststream/middlewares/acknowledgement/middleware.py new file mode 100644 index 0000000000..2513768649 --- /dev/null +++ b/faststream/middlewares/acknowledgement/middleware.py @@ -0,0 +1,111 @@ +import logging +from typing import TYPE_CHECKING, Any, Optional + +from faststream.exceptions import ( + AckMessage, + HandlerException, + NackMessage, + RejectMessage, +) +from faststream.middlewares.acknowledgement.conf import AckPolicy +from faststream.middlewares.base import BaseMiddleware + +if TYPE_CHECKING: + from types import TracebackType + + from faststream._internal.basic_types import AnyDict, AsyncFuncAny + from faststream._internal.context.repository import ContextRepo + from faststream.message import StreamMessage + + +class AcknowledgementMiddleware: + def __init__(self, ack_policy: AckPolicy, extra_options: "AnyDict") -> None: + self.ack_policy = ack_policy + self.extra_options = extra_options + + def __call__(self, msg: Optional[Any], context: "ContextRepo") -> "_AcknowledgementMiddleware": + return _AcknowledgementMiddleware( + msg, + ack_policy=self.ack_policy, + extra_options=self.extra_options, + context=context, + ) + + +class _AcknowledgementMiddleware(BaseMiddleware): + def __init__( + self, + msg: Optional[Any], + /, + *, + context: "ContextRepo", + ack_policy: AckPolicy, + extra_options: "AnyDict", + ) -> None: + super().__init__(msg, context=context) + self.ack_policy = ack_policy + self.extra_options = extra_options + self.logger = context.get_local("logger") + + async def consume_scope( + self, + call_next: "AsyncFuncAny", + msg: "StreamMessage[Any]", + ) -> Any: + self.message = msg + return await call_next(msg) + + async def __aexit__( + self, + exc_type: Optional[type[BaseException]] = None, + exc_val: Optional[BaseException] = None, + exc_tb: Optional["TracebackType"] = None, + ) -> Optional[bool]: + if self.ack_policy is AckPolicy.DO_NOTHING: + return False + + if not exc_type: + await self.__ack() + + elif isinstance(exc_val, HandlerException): + if isinstance(exc_val, AckMessage): + await self.__ack(**exc_val.extra_options) + + elif isinstance(exc_val, NackMessage): + await self.__nack(**exc_val.extra_options) + + elif isinstance(exc_val, RejectMessage): # pragma: no branch + await self.__reject(**exc_val.extra_options) + + # Exception was processed and suppressed + return True + + elif self.ack_policy is AckPolicy.REJECT_ON_ERROR: + await self.__reject() + + elif self.ack_policy is AckPolicy.NACK_ON_ERROR: + await self.__nack() + + # Exception was not processed + return False + + async def __ack(self, **exc_extra_options: Any) -> None: + try: + await self.message.ack(**exc_extra_options, **self.extra_options) + except Exception as er: + if self.logger is not None: + self.logger.log(logging.ERROR, er, exc_info=er) + + async def __nack(self, **exc_extra_options: Any) -> None: + try: + await self.message.nack(**exc_extra_options, **self.extra_options) + except Exception as er: + if self.logger is not None: + self.logger.log(logging.ERROR, er, exc_info=er) + + async def __reject(self, **exc_extra_options: Any) -> None: + try: + await self.message.reject(**exc_extra_options, **self.extra_options) + except Exception as er: + if self.logger is not None: + self.logger.log(logging.ERROR, er, exc_info=er) diff --git a/faststream/nats/broker/registrator.py b/faststream/nats/broker/registrator.py index 4ff8f0fbda..f8feacb294 100644 --- a/faststream/nats/broker/registrator.py +++ b/faststream/nats/broker/registrator.py @@ -5,6 +5,7 @@ from typing_extensions import Doc, override from faststream._internal.broker.abc_broker import ABCBroker +from faststream.middlewares import AckPolicy from faststream.nats.helpers import StreamBuilder from faststream.nats.publisher.factory import create_publisher from faststream.nats.publisher.specified import SpecificationPublisher @@ -160,14 +161,10 @@ def subscriber( # type: ignore[override] int, Doc("Number of workers to process messages concurrently."), ] = 1, - retry: Annotated[ - bool, - Doc("Whether to `nack` message at processing exception."), - ] = False, - no_ack: Annotated[ - bool, - Doc("Whether to disable **FastStream** autoacknowledgement logic or not."), - ] = False, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, no_reply: Annotated[ bool, Doc( @@ -222,9 +219,8 @@ def subscriber( # type: ignore[override] inbox_prefix=inbox_prefix, ack_first=ack_first, # subscriber args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=self._middlewares, broker_dependencies=self._dependencies, # AsyncAPI diff --git a/faststream/nats/fastapi/fastapi.py b/faststream/nats/fastapi/fastapi.py index e2c5ae3d98..aa449acde7 100644 --- a/faststream/nats/fastapi/fastapi.py +++ b/faststream/nats/fastapi/fastapi.py @@ -32,6 +32,7 @@ from faststream.__about__ import SERVICE_NAME from faststream._internal.constants import EMPTY from faststream._internal.fastapi.router import StreamRouter +from faststream.middlewares import AckPolicy from faststream.nats.broker import NatsBroker from faststream.nats.subscriber.specified import SpecificationSubscriber @@ -692,14 +693,10 @@ def subscriber( # type: ignore[override] int, Doc("Number of workers to process messages concurrently."), ] = 1, - retry: Annotated[ - bool, - Doc("Whether to `nack` message at processing exception."), - ] = False, - no_ack: Annotated[ - bool, - Doc("Whether to disable **FastStream** autoacknowledgement logic or not."), - ] = False, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, no_reply: Annotated[ bool, Doc( @@ -871,8 +868,7 @@ def subscriber( # type: ignore[override] decoder=decoder, middlewares=middlewares, max_workers=max_workers, - retry=retry, - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, title=title, description=description, diff --git a/faststream/nats/parser.py b/faststream/nats/parser.py index 0f3b2f4c8c..3cb2c695a8 100644 --- a/faststream/nats/parser.py +++ b/faststream/nats/parser.py @@ -4,6 +4,7 @@ StreamMessage, decode_message, ) +from faststream.middlewares import AckPolicy from faststream.nats.message import ( NatsBatchMessage, NatsKvMessage, @@ -54,9 +55,9 @@ async def decode_message( class NatsParser(NatsBaseParser): """A class to parse NATS core messages.""" - def __init__(self, *, pattern: str, no_ack: bool) -> None: + def __init__(self, *, pattern: str, ack_policy: AckPolicy) -> None: super().__init__(pattern=pattern) - self.no_ack = no_ack + self.ack_policy = ack_policy async def parse_message( self, @@ -69,7 +70,7 @@ async def parse_message( headers = message.header or {} - if not self.no_ack: + if self.ack_policy is not AckPolicy.DO_NOTHING: message._ackd = True # prevent message from acking return NatsMessage( diff --git a/faststream/nats/publisher/producer.py b/faststream/nats/publisher/producer.py index f2ed4715e0..62245c2c7c 100644 --- a/faststream/nats/publisher/producer.py +++ b/faststream/nats/publisher/producer.py @@ -5,6 +5,7 @@ import nats from typing_extensions import override +from faststream import AckPolicy from faststream._internal.publisher.proto import ProducerProto from faststream._internal.subscriber.utils import resolve_custom_func from faststream.exceptions import FeatureNotSupportedException @@ -40,7 +41,7 @@ def __init__( parser: Optional["CustomCallable"], decoder: Optional["CustomCallable"], ) -> None: - default = NatsParser(pattern="", no_ack=False) + default = NatsParser(pattern="", ack_policy=AckPolicy.REJECT_ON_ERROR) self._parser = resolve_custom_func(parser, default.parse_message) self._decoder = resolve_custom_func(decoder, default.decode_message) @@ -111,7 +112,7 @@ def __init__( parser: Optional["CustomCallable"], decoder: Optional["CustomCallable"], ) -> None: - default = NatsParser(pattern="", no_ack=False) + default = NatsParser(pattern="", ack_policy=AckPolicy.REJECT_ON_ERROR) self._parser = resolve_custom_func(parser, default.parse_message) self._decoder = resolve_custom_func(decoder, default.decode_message) diff --git a/faststream/nats/router.py b/faststream/nats/router.py index 3b98073050..5d4f87b03b 100644 --- a/faststream/nats/router.py +++ b/faststream/nats/router.py @@ -16,6 +16,7 @@ BrokerRouter, SubscriberRoute, ) +from faststream.middlewares import AckPolicy from faststream.nats.broker.registrator import NatsRegistrator if TYPE_CHECKING: @@ -250,14 +251,10 @@ def __init__( int, Doc("Number of workers to process messages concurrently."), ] = 1, - retry: Annotated[ - bool, - Doc("Whether to `nack` message at processing exception."), - ] = False, - no_ack: Annotated[ - bool, - Doc("Whether to disable **FastStream** autoacknowledgement logic or not."), - ] = False, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, no_reply: Annotated[ bool, Doc( @@ -307,8 +304,7 @@ def __init__( parser=parser, decoder=decoder, middlewares=middlewares, - retry=retry, - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, title=title, description=description, diff --git a/faststream/nats/schemas/js_stream.py b/faststream/nats/schemas/js_stream.py index 0d9b23ac4f..3ad4fc2e4f 100644 --- a/faststream/nats/schemas/js_stream.py +++ b/faststream/nats/schemas/js_stream.py @@ -6,6 +6,7 @@ from faststream._internal.proto import NameRequired from faststream._internal.utils.path import compile_path +from faststream.middlewares import AckPolicy if TYPE_CHECKING: from re import Pattern @@ -120,13 +121,10 @@ def __init__( "cluster may be available but for reads only.", ), ] = None, - no_ack: Annotated[ - bool, - Doc( - "Should stream acknowledge writes or not. Without acks publisher can't determine, does message " - "received by stream or not.", - ), - ] = False, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, template_owner: Optional[str] = None, duplicate_window: Annotated[ float, @@ -191,6 +189,7 @@ def __init__( super().__init__(name) subjects = subjects or [] + no_ack = ack_policy is AckPolicy.DO_NOTHING self.subjects = subjects self.declare = declare diff --git a/faststream/nats/subscriber/factory.py b/faststream/nats/subscriber/factory.py index 613a76a535..586f0db870 100644 --- a/faststream/nats/subscriber/factory.py +++ b/faststream/nats/subscriber/factory.py @@ -30,6 +30,7 @@ from faststream._internal.basic_types import AnyDict from faststream._internal.types import BrokerMiddleware + from faststream.middlewares import AckPolicy from faststream.nats.schemas import JStream, KvWatch, ObjWatch, PullSub @@ -59,9 +60,8 @@ def create_subscriber( max_workers: int, stream: Optional["JStream"], # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: Union[bool, int], broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[Any]"], # Specification information @@ -159,9 +159,8 @@ def create_subscriber( # basic args extra_options=extra_options, # Subscriber args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, # Specification @@ -177,9 +176,8 @@ def create_subscriber( # basic args extra_options=extra_options, # Subscriber args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, # Specification @@ -199,9 +197,8 @@ def create_subscriber( # basic args extra_options=extra_options, # Subscriber args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, # Specification @@ -219,9 +216,8 @@ def create_subscriber( # basic args extra_options=extra_options, # Subscriber args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, # Specification @@ -240,9 +236,8 @@ def create_subscriber( # basic args extra_options=extra_options, # Subscriber args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, # Specification @@ -259,9 +254,8 @@ def create_subscriber( # basic args extra_options=extra_options, # Subscriber args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, # Specification @@ -278,9 +272,8 @@ def create_subscriber( # basic args extra_options=extra_options, # Subscriber args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, # Specification information diff --git a/faststream/nats/subscriber/usecase.py b/faststream/nats/subscriber/usecase.py index 9f15f00456..2c1e35cd56 100644 --- a/faststream/nats/subscriber/usecase.py +++ b/faststream/nats/subscriber/usecase.py @@ -8,12 +8,10 @@ Callable, Generic, Optional, - Union, cast, ) import anyio -from fast_depends.dependencies import Dependant from nats.errors import ConnectionClosedError, TimeoutError from nats.js.api import ConsumerConfig, ObjectInfo from typing_extensions import Doc, override @@ -22,6 +20,7 @@ from faststream._internal.subscriber.usecase import SubscriberUsecase from faststream._internal.subscriber.utils import process_msg from faststream._internal.types import MsgType +from faststream.middlewares import AckPolicy from faststream.nats.helpers import KVBucketDeclarer, OSBucketDeclarer from faststream.nats.message import NatsMessage from faststream.nats.parser import ( @@ -41,6 +40,7 @@ from .state import ConnectedSubscriberState, EmptySubscriberState, SubscriberState if TYPE_CHECKING: + from fast_depends.dependencies import Dependant from nats.aio.msg import Msg from nats.aio.subscription import Subscription from nats.js import JetStreamContext @@ -82,10 +82,9 @@ def __init__( # Subscriber args default_parser: "AsyncCallable", default_decoder: "AsyncCallable", - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: Union[bool, int], - broker_dependencies: Iterable[Dependant], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[MsgType]"], # AsyncAPI args title_: Optional[str], @@ -101,9 +100,8 @@ def __init__( default_parser=default_parser, default_decoder=default_decoder, # Propagated args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, # AsyncAPI args @@ -235,10 +233,9 @@ def __init__( # Subscriber args default_parser: "AsyncCallable", default_decoder: "AsyncCallable", - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: Union[bool, int], - broker_dependencies: Iterable[Dependant], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[MsgType]"], # AsyncAPI args title_: Optional[str], @@ -253,9 +250,8 @@ def __init__( default_parser=default_parser, default_decoder=default_decoder, # Propagated args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, # AsyncAPI args @@ -306,17 +302,16 @@ def __init__( queue: str, extra_options: Optional["AnyDict"], # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: Union[bool, int], - broker_dependencies: Iterable[Dependant], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[Msg]"], # AsyncAPI args title_: Optional[str], description_: Optional[str], include_in_schema: bool, ) -> None: - parser_ = NatsParser(pattern=subject, no_ack=no_ack) + parser_ = NatsParser(pattern=subject, ack_policy=ack_policy) self.queue = queue @@ -328,9 +323,8 @@ def __init__( default_parser=parser_.parse_message, default_decoder=parser_.decode_message, # Propagated args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, # AsyncAPI args @@ -416,10 +410,9 @@ def __init__( queue: str, extra_options: Optional["AnyDict"], # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: Union[bool, int], - broker_dependencies: Iterable[Dependant], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[Msg]"], # AsyncAPI args title_: Optional[str], @@ -434,9 +427,8 @@ def __init__( queue=queue, extra_options=extra_options, # Propagated args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, # AsyncAPI args @@ -474,10 +466,9 @@ def __init__( queue: str, extra_options: Optional["AnyDict"], # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: Union[bool, int], - broker_dependencies: Iterable[Dependant], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[Msg]"], # AsyncAPI args title_: Optional[str], @@ -497,9 +488,8 @@ def __init__( default_parser=parser_.parse_message, default_decoder=parser_.decode_message, # Propagated args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, # AsyncAPI args @@ -606,10 +596,9 @@ def __init__( queue: str, extra_options: Optional["AnyDict"], # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: Union[bool, int], - broker_dependencies: Iterable[Dependant], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[Msg]"], # AsyncAPI args title_: Optional[str], @@ -625,9 +614,8 @@ def __init__( queue=queue, extra_options=extra_options, # Propagated args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, # AsyncAPI args @@ -669,10 +657,9 @@ def __init__( config: "ConsumerConfig", extra_options: Optional["AnyDict"], # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: Union[bool, int], - broker_dependencies: Iterable[Dependant], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[Msg]"], # AsyncAPI args title_: Optional[str], @@ -689,9 +676,8 @@ def __init__( extra_options=extra_options, queue="", # Propagated args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, # AsyncAPI args @@ -749,10 +735,9 @@ def __init__( config: "ConsumerConfig", extra_options: Optional["AnyDict"], # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: Union[bool, int], - broker_dependencies: Iterable[Dependant], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[Msg]"], # AsyncAPI args title_: Optional[str], @@ -768,9 +753,8 @@ def __init__( config=config, extra_options=extra_options, # Propagated args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, # AsyncAPI args @@ -814,10 +798,9 @@ def __init__( pull_sub: "PullSub", extra_options: Optional["AnyDict"], # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: Union[bool, int], - broker_dependencies: Iterable[Dependant], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[list[Msg]]"], # AsyncAPI args title_: Optional[str], @@ -837,9 +820,8 @@ def __init__( default_parser=parser.parse_batch, default_decoder=parser.decode_batch, # Propagated args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, # AsyncAPI args @@ -931,7 +913,7 @@ def __init__( subject: str, config: "ConsumerConfig", kv_watch: "KvWatch", - broker_dependencies: Iterable[Dependant], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[KeyValue.Entry]"], # AsyncAPI args title_: Optional[str], @@ -945,9 +927,8 @@ def __init__( subject=subject, config=config, extra_options=None, - no_ack=True, + ack_policy=AckPolicy.DO_NOTHING, no_reply=True, - retry=False, default_parser=parser.parse_message, default_decoder=parser.decode_message, broker_middlewares=broker_middlewares, @@ -1085,7 +1066,7 @@ def __init__( subject: str, config: "ConsumerConfig", obj_watch: "ObjWatch", - broker_dependencies: Iterable[Dependant], + broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[list[Msg]]"], # AsyncAPI args title_: Optional[str], @@ -1101,9 +1082,8 @@ def __init__( subject=subject, config=config, extra_options=None, - no_ack=True, + ack_policy=AckPolicy.DO_NOTHING, no_reply=True, - retry=False, default_parser=parser.parse_message, default_decoder=parser.decode_message, broker_middlewares=broker_middlewares, diff --git a/faststream/nats/testing.py b/faststream/nats/testing.py index 4ee0d1602c..d709554993 100644 --- a/faststream/nats/testing.py +++ b/faststream/nats/testing.py @@ -11,6 +11,7 @@ from nats.aio.msg import Msg from typing_extensions import override +from faststream import AckPolicy from faststream._internal.subscriber.utils import resolve_custom_func from faststream._internal.testing.broker import TestBroker from faststream.exceptions import SubscriberNotFound @@ -70,7 +71,7 @@ class FakeProducer(NatsFastProducer): def __init__(self, broker: NatsBroker) -> None: self.broker = broker - default = NatsParser(pattern="", no_ack=False) + default = NatsParser(pattern="", ack_policy=AckPolicy.REJECT_ON_ERROR) self._parser = resolve_custom_func(broker._parser, default.parse_message) self._decoder = resolve_custom_func(broker._decoder, default.decode_message) diff --git a/faststream/rabbit/broker/registrator.py b/faststream/rabbit/broker/registrator.py index 20893edbd0..117aafc1de 100644 --- a/faststream/rabbit/broker/registrator.py +++ b/faststream/rabbit/broker/registrator.py @@ -4,6 +4,7 @@ from typing_extensions import Doc, override from faststream._internal.broker.abc_broker import ABCBroker +from faststream.middlewares import AckPolicy from faststream.rabbit.publisher.factory import create_publisher from faststream.rabbit.publisher.specified import SpecificationPublisher from faststream.rabbit.publisher.usecase import PublishKwargs @@ -57,6 +58,10 @@ def subscriber( # type: ignore[override] Optional["AnyDict"], Doc("Extra consumer arguments to use in `queue.consume(...)` method."), ] = None, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, # broker arguments dependencies: Annotated[ Iterable["Dependant"], @@ -74,14 +79,6 @@ def subscriber( # type: ignore[override] Iterable["SubscriberMiddleware[RabbitMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - retry: Annotated[ - Union[bool, int], - Doc("Whether to `nack` message at processing exception."), - ] = False, - no_ack: Annotated[ - bool, - Doc("Whether to disable **FastStream** autoacknowledgement logic or not."), - ] = False, no_reply: Annotated[ bool, Doc( @@ -113,9 +110,8 @@ def subscriber( # type: ignore[override] exchange=RabbitExchange.validate(exchange), consume_args=consume_args, # subscriber args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=self._middlewares, broker_dependencies=self._dependencies, # AsyncAPI diff --git a/faststream/rabbit/fastapi/fastapi.py b/faststream/rabbit/fastapi/fastapi.py index 9240380079..6411dbc949 100644 --- a/faststream/rabbit/fastapi/fastapi.py +++ b/faststream/rabbit/fastapi/fastapi.py @@ -20,6 +20,7 @@ from faststream.__about__ import SERVICE_NAME from faststream._internal.constants import EMPTY from faststream._internal.fastapi.router import StreamRouter +from faststream.middlewares import AckPolicy from faststream.rabbit.broker.broker import RabbitBroker as RB from faststream.rabbit.schemas import ( RabbitExchange, @@ -511,14 +512,10 @@ def subscriber( # type: ignore[override] Iterable["SubscriberMiddleware[RabbitMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - retry: Annotated[ - Union[bool, int], - Doc("Whether to `nack` message at processing exception."), - ] = False, - no_ack: Annotated[ - bool, - Doc("Whether to disable **FastStream** autoacknowledgement logic or not."), - ] = False, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, no_reply: Annotated[ bool, Doc( @@ -675,8 +672,7 @@ def subscriber( # type: ignore[override] parser=parser, decoder=decoder, middlewares=middlewares, - retry=retry, - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, title=title, description=description, diff --git a/faststream/rabbit/router.py b/faststream/rabbit/router.py index a11b5ddbb6..3edbf447b7 100644 --- a/faststream/rabbit/router.py +++ b/faststream/rabbit/router.py @@ -8,6 +8,7 @@ BrokerRouter, SubscriberRoute, ) +from faststream.middlewares import AckPolicy from faststream.rabbit.broker.registrator import RabbitRegistrator if TYPE_CHECKING: @@ -229,14 +230,10 @@ def __init__( Iterable["SubscriberMiddleware[RabbitMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - retry: Annotated[ - Union[bool, int], - Doc("Whether to `nack` message at processing exception."), - ] = False, - no_ack: Annotated[ - bool, - Doc("Whether to disable **FastStream** autoacknowledgement logic or not."), - ] = False, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, no_reply: Annotated[ bool, Doc( @@ -270,8 +267,7 @@ def __init__( parser=parser, decoder=decoder, middlewares=middlewares, - retry=retry, - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, title=title, description=description, diff --git a/faststream/rabbit/subscriber/factory.py b/faststream/rabbit/subscriber/factory.py index b82210bd3d..4554f9c9c5 100644 --- a/faststream/rabbit/subscriber/factory.py +++ b/faststream/rabbit/subscriber/factory.py @@ -1,5 +1,5 @@ from collections.abc import Iterable -from typing import TYPE_CHECKING, Optional, Union +from typing import TYPE_CHECKING, Optional from faststream.rabbit.subscriber.specified import SpecificationSubscriber @@ -9,6 +9,7 @@ from faststream._internal.basic_types import AnyDict from faststream._internal.types import BrokerMiddleware + from faststream.middlewares import AckPolicy from faststream.rabbit.schemas import RabbitExchange, RabbitQueue @@ -18,11 +19,10 @@ def create_subscriber( exchange: "RabbitExchange", consume_args: Optional["AnyDict"], # Subscriber args - no_ack: bool, no_reply: bool, - retry: Union[bool, int], broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[IncomingMessage]"], + ack_policy: "AckPolicy", # AsyncAPI args title_: Optional[str], description_: Optional[str], @@ -32,9 +32,8 @@ def create_subscriber( queue=queue, exchange=exchange, consume_args=consume_args, - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, title_=title_, diff --git a/faststream/rabbit/subscriber/usecase.py b/faststream/rabbit/subscriber/usecase.py index aeae29d970..119938afb5 100644 --- a/faststream/rabbit/subscriber/usecase.py +++ b/faststream/rabbit/subscriber/usecase.py @@ -3,7 +3,6 @@ TYPE_CHECKING, Any, Optional, - Union, ) import anyio @@ -12,6 +11,7 @@ from faststream._internal.subscriber.usecase import SubscriberUsecase from faststream._internal.subscriber.utils import process_msg from faststream.exceptions import SetupError +from faststream.middlewares import AckPolicy from faststream.rabbit.parser import AioPikaParser from faststream.rabbit.publisher.fake import RabbitFakePublisher from faststream.rabbit.schemas import BaseRMQInformation @@ -54,9 +54,8 @@ def __init__( exchange: "RabbitExchange", consume_args: Optional["AnyDict"], # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: Union[bool, int], broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[IncomingMessage]"], # AsyncAPI args @@ -70,9 +69,8 @@ def __init__( default_parser=parser.parse_message, default_decoder=parser.decode_message, # Propagated options - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, # AsyncAPI @@ -175,7 +173,7 @@ async def get_one( self, *, timeout: float = 5.0, - no_ack: bool = True, + ack_policy: AckPolicy = AckPolicy.REJECT_ON_ERROR, ) -> "Optional[RabbitMessage]": assert self._queue_obj, "You should start subscriber at first." # nosec B101 assert ( # nosec B101 @@ -185,6 +183,7 @@ async def get_one( sleep_interval = timeout / 10 raw_message: Optional[IncomingMessage] = None + no_ack = self.ack_policy is AckPolicy.DO_NOTHING with anyio.move_on_after(timeout): while ( # noqa: ASYNC110 raw_message := await self._queue_obj.get( diff --git a/faststream/redis/broker/registrator.py b/faststream/redis/broker/registrator.py index 9b10aae10e..1599a10d46 100644 --- a/faststream/redis/broker/registrator.py +++ b/faststream/redis/broker/registrator.py @@ -4,6 +4,7 @@ from typing_extensions import Doc, override from faststream._internal.broker.abc_broker import ABCBroker +from faststream.middlewares import AckPolicy from faststream.redis.message import UnifyRedisDict from faststream.redis.publisher.factory import create_publisher from faststream.redis.publisher.specified import SpecificationPublisher @@ -65,14 +66,10 @@ def subscriber( # type: ignore[override] Iterable["SubscriberMiddleware[UnifyRedisMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - retry: Annotated[ - bool, - Doc("Whether to `nack` message at processing exception."), - ] = False, - no_ack: Annotated[ - bool, - Doc("Whether to disable **FastStream** autoacknowledgement logic or not."), - ] = False, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, no_reply: Annotated[ bool, Doc( @@ -104,9 +101,8 @@ def subscriber( # type: ignore[override] list=list, stream=stream, # subscriber args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=self._middlewares, broker_dependencies=self._dependencies, # AsyncAPI diff --git a/faststream/redis/fastapi/fastapi.py b/faststream/redis/fastapi/fastapi.py index ed97300b87..01a5432f5e 100644 --- a/faststream/redis/fastapi/fastapi.py +++ b/faststream/redis/fastapi/fastapi.py @@ -25,6 +25,7 @@ from faststream.__about__ import SERVICE_NAME from faststream._internal.constants import EMPTY from faststream._internal.fastapi.router import StreamRouter +from faststream.middlewares import AckPolicy from faststream.redis.broker.broker import RedisBroker as RB from faststream.redis.message import UnifyRedisDict from faststream.redis.schemas import ListSub, PubSub, StreamSub @@ -461,14 +462,10 @@ def subscriber( # type: ignore[override] Iterable["SubscriberMiddleware[UnifyRedisMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - retry: Annotated[ - bool, - Doc("Whether to `nack` message at processing exception."), - ] = False, - no_ack: Annotated[ - bool, - Doc("Whether to disable **FastStream** autoacknowledgement logic or not."), - ] = False, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, no_reply: Annotated[ bool, Doc( @@ -625,8 +622,7 @@ def subscriber( # type: ignore[override] parser=parser, decoder=decoder, middlewares=middlewares, - retry=retry, - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, title=title, description=description, diff --git a/faststream/redis/router.py b/faststream/redis/router.py index f7e60051fe..32d937dcce 100644 --- a/faststream/redis/router.py +++ b/faststream/redis/router.py @@ -8,6 +8,7 @@ BrokerRouter, SubscriberRoute, ) +from faststream.middlewares import AckPolicy from faststream.redis.broker.registrator import RedisRegistrator from faststream.redis.message import BaseMessage @@ -147,14 +148,10 @@ def __init__( Iterable["SubscriberMiddleware[UnifyRedisMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - retry: Annotated[ - bool, - Doc("Whether to `nack` message at processing exception."), - ] = False, - no_ack: Annotated[ - bool, - Doc("Whether to disable **FastStream** autoacknowledgement logic or not."), - ] = False, + ack_policy: Annotated[ + AckPolicy, + Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + ] = AckPolicy.REJECT_ON_ERROR, no_reply: Annotated[ bool, Doc( @@ -188,8 +185,7 @@ def __init__( parser=parser, decoder=decoder, middlewares=middlewares, - retry=retry, - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, title=title, description=description, diff --git a/faststream/redis/schemas/stream_sub.py b/faststream/redis/schemas/stream_sub.py index 50a0b6d606..07488d5f86 100644 --- a/faststream/redis/schemas/stream_sub.py +++ b/faststream/redis/schemas/stream_sub.py @@ -3,6 +3,7 @@ from faststream._internal.proto import NameRequired from faststream.exceptions import SetupError +from faststream.middlewares import AckPolicy class StreamSub(NameRequired): @@ -27,11 +28,13 @@ def __init__( group: Optional[str] = None, consumer: Optional[str] = None, batch: bool = False, - no_ack: bool = False, + ack_policy: AckPolicy = AckPolicy.REJECT_ON_ERROR, last_id: Optional[str] = None, maxlen: Optional[int] = None, max_records: Optional[int] = None, ) -> None: + no_ack = ack_policy is AckPolicy.DO_NOTHING + if (group and not consumer) or (not group and consumer): msg = "You should specify `group` and `consumer` both" raise SetupError(msg) diff --git a/faststream/redis/subscriber/factory.py b/faststream/redis/subscriber/factory.py index 9238628332..e46d3d6646 100644 --- a/faststream/redis/subscriber/factory.py +++ b/faststream/redis/subscriber/factory.py @@ -18,6 +18,7 @@ from fast_depends.dependencies import Dependant from faststream._internal.types import BrokerMiddleware + from faststream.middlewares import AckPolicy from faststream.redis.message import UnifyRedisDict SubsciberType: TypeAlias = Union[ @@ -35,9 +36,8 @@ def create_subscriber( list: Union["ListSub", str, None], stream: Union["StreamSub", str, None], # Subscriber args - no_ack: bool = False, + ack_policy: "AckPolicy", no_reply: bool = False, - retry: bool = False, broker_dependencies: Iterable["Dependant"] = (), broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"] = (), # AsyncAPI args @@ -51,9 +51,8 @@ def create_subscriber( return AsyncAPIChannelSubscriber( channel=channel_sub, # basic args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, # AsyncAPI args @@ -67,9 +66,8 @@ def create_subscriber( return AsyncAPIStreamBatchSubscriber( stream=stream_sub, # basic args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, # AsyncAPI args @@ -80,9 +78,8 @@ def create_subscriber( return AsyncAPIStreamSubscriber( stream=stream_sub, # basic args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, # AsyncAPI args @@ -96,9 +93,8 @@ def create_subscriber( return AsyncAPIListBatchSubscriber( list=list_sub, # basic args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, # AsyncAPI args @@ -109,9 +105,8 @@ def create_subscriber( return AsyncAPIListSubscriber( list=list_sub, # basic args - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, # AsyncAPI args diff --git a/faststream/redis/subscriber/usecase.py b/faststream/redis/subscriber/usecase.py index 70ccaf73e9..995fc70454 100644 --- a/faststream/redis/subscriber/usecase.py +++ b/faststream/redis/subscriber/usecase.py @@ -54,6 +54,7 @@ CustomCallable, ) from faststream.message import StreamMessage as BrokerStreamMessage + from faststream.middlewares import AckPolicy TopicName: TypeAlias = bytes @@ -71,9 +72,8 @@ def __init__( default_parser: "AsyncCallable", default_decoder: "AsyncCallable", # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], # AsyncAPI args @@ -85,9 +85,8 @@ def __init__( default_parser=default_parser, default_decoder=default_decoder, # Propagated options - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, # AsyncAPI @@ -215,9 +214,8 @@ def __init__( *, channel: "PubSub", # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], # AsyncAPI args @@ -230,9 +228,8 @@ def __init__( default_parser=parser.parse_message, default_decoder=parser.decode_message, # Propagated options - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, # AsyncAPI @@ -341,9 +338,8 @@ def __init__( default_parser: "AsyncCallable", default_decoder: "AsyncCallable", # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], # AsyncAPI args @@ -355,9 +351,8 @@ def __init__( default_parser=default_parser, default_decoder=default_decoder, # Propagated options - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, # AsyncAPI @@ -448,9 +443,8 @@ def __init__( *, list: ListSub, # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], # AsyncAPI args @@ -464,9 +458,8 @@ def __init__( default_parser=parser.parse_message, default_decoder=parser.decode_message, # Propagated options - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, # AsyncAPI @@ -497,9 +490,8 @@ def __init__( *, list: ListSub, # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], # AsyncAPI args @@ -513,9 +505,8 @@ def __init__( default_parser=parser.parse_message, default_decoder=parser.decode_message, # Propagated options - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, # AsyncAPI @@ -551,9 +542,8 @@ def __init__( default_parser: "AsyncCallable", default_decoder: "AsyncCallable", # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], # AsyncAPI args @@ -565,9 +555,8 @@ def __init__( default_parser=default_parser, default_decoder=default_decoder, # Propagated options - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, # AsyncAPI @@ -742,9 +731,8 @@ def __init__( *, stream: StreamSub, # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], # AsyncAPI args @@ -758,9 +746,8 @@ def __init__( default_parser=parser.parse_message, default_decoder=parser.decode_message, # Propagated options - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, # AsyncAPI @@ -811,9 +798,8 @@ def __init__( *, stream: StreamSub, # Subscriber args - no_ack: bool, + ack_policy: "AckPolicy", no_reply: bool, - retry: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], # AsyncAPI args @@ -827,9 +813,8 @@ def __init__( default_parser=parser.parse_message, default_decoder=parser.decode_message, # Propagated options - no_ack=no_ack, + ack_policy=ack_policy, no_reply=no_reply, - retry=retry, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, # AsyncAPI diff --git a/tests/brokers/base/fastapi.py b/tests/brokers/base/fastapi.py index 38c9475ae2..e1e9c15954 100644 --- a/tests/brokers/base/fastapi.py +++ b/tests/brokers/base/fastapi.py @@ -534,7 +534,6 @@ async def hello_router2() -> str: async def test_dependency_overrides(self, mock: Mock, queue: str) -> None: router = self.router_class() - router2 = self.router_class() def dep1() -> None: mock.not_call() @@ -547,10 +546,39 @@ def dep2() -> None: args, kwargs = self.get_subscriber_params(queue) - @router2.subscriber(*args, **kwargs) + @router.subscriber(*args, **kwargs) async def hello_router2(dep: None = Depends(dep1)) -> str: return "hi" + app.include_router(router) + + async with self.patch_broker(router.broker) as br: + with TestClient(app) as client: + assert client.app_state["broker"] is br + + r = await br.request( + "hi", + queue, + timeout=0.5, + ) + assert await r.decode() == "hi", r + + mock.assert_called_once() + assert not mock.not_call.called + + @pytest.mark.xfail(reason="https://github.com/airtai/faststream/issues/1742") + async def test_nested_router(self, mock: Mock, queue: str) -> None: + router = self.router_class() + router2 = self.router_class() + + app = FastAPI() + + args, kwargs = self.get_subscriber_params(queue) + + @router2.subscriber(*args, **kwargs) + async def hello_router2() -> str: + return "hi" + router.include_router(router2) app.include_router(router) diff --git a/tests/brokers/base/router.py b/tests/brokers/base/router.py index 68c8c8552c..1f50340fb9 100644 --- a/tests/brokers/base/router.py +++ b/tests/brokers/base/router.py @@ -447,9 +447,8 @@ def subscriber() -> None: ... sub = next(iter(pub_broker._subscribers)) publisher = next(iter(pub_broker._publishers)) - - assert len((*sub._broker_middlewares, *sub.calls[0].item_middlewares)) == 3 - assert len((*publisher._broker_middlewares, *publisher._middlewares)) == 3 + assert len((*sub._broker_middlewares, *sub.calls[0].item_middlewares)) == 5 + assert len((*publisher._broker_middlewares, *publisher._middlewares)) == 4 async def test_router_include_with_middlewares( self, @@ -473,8 +472,8 @@ def subscriber() -> None: ... publisher = next(iter(pub_broker._publishers)) sub_middlewares = (*sub._broker_middlewares, *sub.calls[0].item_middlewares) - assert len(sub_middlewares) == 3, sub_middlewares - assert len((*publisher._broker_middlewares, *publisher._middlewares)) == 3 + assert len(sub_middlewares) == 5, sub_middlewares + assert len((*publisher._broker_middlewares, *publisher._middlewares)) == 4 async def test_router_parser( self, diff --git a/tests/brokers/confluent/test_consume.py b/tests/brokers/confluent/test_consume.py index 6f61f01d5f..9bb954ee2f 100644 --- a/tests/brokers/confluent/test_consume.py +++ b/tests/brokers/confluent/test_consume.py @@ -4,6 +4,7 @@ import pytest +from faststream import AckPolicy from faststream.confluent import KafkaBroker from faststream.confluent.annotations import KafkaMessage from faststream.confluent.client import AsyncConfluentConsumer @@ -251,7 +252,9 @@ async def test_consume_no_ack( ) -> None: consume_broker = self.get_broker(apply_types=True) - args, kwargs = self.get_subscriber_params(queue, group_id="test", no_ack=True) + args, kwargs = self.get_subscriber_params( + queue, group_id="test", ack_policy=AckPolicy.DO_NOTHING + ) @consume_broker.subscriber(*args, **kwargs) async def handler(msg: KafkaMessage) -> None: diff --git a/tests/brokers/kafka/test_consume.py b/tests/brokers/kafka/test_consume.py index f5e5421fbd..cb0f32db43 100644 --- a/tests/brokers/kafka/test_consume.py +++ b/tests/brokers/kafka/test_consume.py @@ -5,6 +5,7 @@ import pytest from aiokafka import AIOKafkaConsumer +from faststream import AckPolicy from faststream.exceptions import AckMessage from faststream.kafka import KafkaBroker, TopicPartition from faststream.kafka.annotations import KafkaMessage @@ -296,7 +297,9 @@ async def test_consume_no_ack( ) -> None: consume_broker = self.get_broker(apply_types=True) - @consume_broker.subscriber(queue, group_id="test", no_ack=True) + @consume_broker.subscriber( + queue, group_id="test", ack_policy=AckPolicy.DO_NOTHING + ) async def handler(msg: KafkaMessage) -> None: event.set() diff --git a/tests/brokers/nats/test_consume.py b/tests/brokers/nats/test_consume.py index d7200e627f..d253bcb716 100644 --- a/tests/brokers/nats/test_consume.py +++ b/tests/brokers/nats/test_consume.py @@ -5,6 +5,7 @@ import pytest from nats.aio.msg import Msg +from faststream import AckPolicy from faststream.exceptions import AckMessage from faststream.nats import ConsumerConfig, JStream, NatsBroker, PullSub from faststream.nats.annotations import NatsMessage @@ -169,7 +170,7 @@ async def test_core_consume_no_ack( ) -> None: consume_broker = self.get_broker(apply_types=True) - @consume_broker.subscriber(queue, no_ack=True) + @consume_broker.subscriber(queue, ack_policy=AckPolicy.DO_NOTHING) async def handler(msg: NatsMessage) -> None: if not msg.raw_message._ackd: event.set() @@ -278,7 +279,7 @@ async def test_consume_no_ack( ) -> None: consume_broker = self.get_broker(apply_types=True) - @consume_broker.subscriber(queue, no_ack=True) + @consume_broker.subscriber(queue, ack_policy=AckPolicy.DO_NOTHING) async def handler(msg: NatsMessage) -> None: event.set() diff --git a/tests/brokers/rabbit/test_consume.py b/tests/brokers/rabbit/test_consume.py index 742daac225..4f51bb4899 100644 --- a/tests/brokers/rabbit/test_consume.py +++ b/tests/brokers/rabbit/test_consume.py @@ -5,6 +5,7 @@ import pytest from aio_pika import IncomingMessage, Message +from faststream import AckPolicy from faststream.exceptions import AckMessage, NackMessage, RejectMessage, SkipMessage from faststream.rabbit import RabbitBroker, RabbitExchange, RabbitQueue from faststream.rabbit.annotations import RabbitMessage @@ -26,7 +27,7 @@ async def test_consume_from_exchange( ) -> None: consume_broker = self.get_broker() - @consume_broker.subscriber(queue=queue, exchange=exchange, retry=1) + @consume_broker.subscriber(queue=queue, exchange=exchange) def h(m) -> None: event.set() @@ -56,7 +57,6 @@ async def test_consume_with_get_old( @consume_broker.subscriber( queue=RabbitQueue(name=queue, passive=True), exchange=RabbitExchange(name=exchange.name, passive=True), - retry=True, ) def h(m) -> None: event.set() @@ -92,7 +92,7 @@ async def test_consume_ack( ) -> None: consume_broker = self.get_broker(apply_types=True) - @consume_broker.subscriber(queue=queue, exchange=exchange, retry=1) + @consume_broker.subscriber(queue=queue, exchange=exchange) async def handler(msg: RabbitMessage) -> None: event.set() @@ -126,7 +126,7 @@ async def test_consume_manual_ack( ) -> None: consume_broker = self.get_broker(apply_types=True) - @consume_broker.subscriber(queue=queue, exchange=exchange, retry=1) + @consume_broker.subscriber(queue=queue, exchange=exchange) async def handler(msg: RabbitMessage) -> None: await msg.ack() event.set() @@ -160,7 +160,7 @@ async def test_consume_exception_ack( ) -> None: consume_broker = self.get_broker(apply_types=True) - @consume_broker.subscriber(queue=queue, exchange=exchange, retry=1) + @consume_broker.subscriber(queue=queue, exchange=exchange) async def handler(msg: RabbitMessage) -> None: try: raise AckMessage @@ -196,7 +196,7 @@ async def test_consume_manual_nack( ) -> None: consume_broker = self.get_broker(apply_types=True) - @consume_broker.subscriber(queue=queue, exchange=exchange, retry=1) + @consume_broker.subscriber(queue=queue, exchange=exchange) async def handler(msg: RabbitMessage): await msg.nack() event.set() @@ -231,7 +231,7 @@ async def test_consume_exception_nack( ) -> None: consume_broker = self.get_broker(apply_types=True) - @consume_broker.subscriber(queue=queue, exchange=exchange, retry=1) + @consume_broker.subscriber(queue=queue, exchange=exchange) async def handler(msg: RabbitMessage) -> None: try: raise NackMessage @@ -267,7 +267,7 @@ async def test_consume_manual_reject( ) -> None: consume_broker = self.get_broker(apply_types=True) - @consume_broker.subscriber(queue=queue, exchange=exchange, retry=1) + @consume_broker.subscriber(queue=queue, exchange=exchange) async def handler(msg: RabbitMessage): await msg.reject() event.set() @@ -302,7 +302,7 @@ async def test_consume_exception_reject( ) -> None: consume_broker = self.get_broker(apply_types=True) - @consume_broker.subscriber(queue=queue, exchange=exchange, retry=1) + @consume_broker.subscriber(queue=queue, exchange=exchange) async def handler(msg: RabbitMessage) -> None: try: raise RejectMessage @@ -386,7 +386,9 @@ async def test_consume_no_ack( ) -> None: consume_broker = self.get_broker(apply_types=True) - @consume_broker.subscriber(queue, exchange=exchange, retry=1, no_ack=True) + @consume_broker.subscriber( + queue, exchange=exchange, ack_policy=AckPolicy.DO_NOTHING + ) async def handler(msg: RabbitMessage) -> None: event.set() diff --git a/tests/brokers/rabbit/test_test_client.py b/tests/brokers/rabbit/test_test_client.py index 856ed80668..cf76669716 100644 --- a/tests/brokers/rabbit/test_test_client.py +++ b/tests/brokers/rabbit/test_test_client.py @@ -207,18 +207,18 @@ async def test_consume_manual_ack( consume2 = asyncio.Event() consume3 = asyncio.Event() - @broker.subscriber(queue=queue, exchange=exchange, retry=1) + @broker.subscriber(queue=queue, exchange=exchange) async def handler(msg: RabbitMessage) -> None: await msg.raw_message.ack() consume.set() - @broker.subscriber(queue=queue + "1", exchange=exchange, retry=1) + @broker.subscriber(queue=queue + "1", exchange=exchange) async def handler2(msg: RabbitMessage): await msg.raw_message.nack() consume2.set() raise ValueError - @broker.subscriber(queue=queue + "2", exchange=exchange, retry=1) + @broker.subscriber(queue=queue + "2", exchange=exchange) async def handler3(msg: RabbitMessage): await msg.raw_message.reject() consume3.set() diff --git a/tests/brokers/test_pushback.py b/tests/brokers/test_pushback.py deleted file mode 100644 index afb064ff69..0000000000 --- a/tests/brokers/test_pushback.py +++ /dev/null @@ -1,124 +0,0 @@ -from unittest.mock import AsyncMock - -import pytest - -from faststream._internal.subscriber.acknowledgement_watcher import ( - CounterWatcher, - EndlessWatcher, - WatcherContext, -) -from faststream.exceptions import NackMessage, SkipMessage - - -@pytest.fixture() -def message(): - return AsyncMock(message_id=1, committed=None) - - -@pytest.mark.asyncio() -async def test_push_back_correct(async_mock: AsyncMock, message) -> None: - watcher = CounterWatcher(3) - - context = WatcherContext( - message=message, - watcher=watcher, - ) - - async with context: - await async_mock() - - async_mock.assert_awaited_once() - message.ack.assert_awaited_once() - assert not watcher.memory.get(message.message_id) - - -@pytest.mark.asyncio() -async def test_push_back_endless_correct(async_mock: AsyncMock, message) -> None: - watcher = EndlessWatcher() - - context = WatcherContext( - message=message, - watcher=watcher, - ) - - async with context: - await async_mock() - - async_mock.assert_awaited_once() - message.ack.assert_awaited_once() - - -@pytest.mark.asyncio() -async def test_push_back_watcher(async_mock: AsyncMock, message) -> None: - watcher = CounterWatcher(3) - - context = WatcherContext( - message=message, - watcher=watcher, - ) - - async_mock.side_effect = ValueError("Ooops!") - - while not message.reject.called: - with pytest.raises(ValueError): # noqa: PT011 - async with context: - await async_mock() - - assert not message.ack.await_count - assert message.nack.await_count == 3 - message.reject.assert_awaited_once() - - -@pytest.mark.asyncio() -async def test_push_endless_back_watcher(async_mock: AsyncMock, message) -> None: - watcher = EndlessWatcher() - - context = WatcherContext( - message=message, - watcher=watcher, - ) - - async_mock.side_effect = ValueError("Ooops!") - - while message.nack.await_count < 10: - with pytest.raises(ValueError): # noqa: PT011 - async with context: - await async_mock() - - assert not message.ack.called - assert not message.reject.called - assert message.nack.await_count == 10 - - -@pytest.mark.asyncio() -async def test_ignore_skip(async_mock: AsyncMock, message) -> None: - watcher = CounterWatcher(3) - - context = WatcherContext( - message=message, - watcher=watcher, - ) - - async with context: - raise SkipMessage - - assert not message.nack.called - assert not message.reject.called - assert not message.ack.called - - -@pytest.mark.asyncio() -async def test_additional_params_with_handler_exception( - async_mock: AsyncMock, message -) -> None: - watcher = EndlessWatcher() - - context = WatcherContext( - message=message, - watcher=watcher, - ) - - async with context: - raise NackMessage(delay=5) - - message.nack.assert_called_with(delay=5) From f54e5ee9f978545be13d21f9bfadd0950a203ea0 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Tue, 5 Nov 2024 18:21:08 +0300 Subject: [PATCH 184/245] refactor: use caps names for public enums --- faststream/_internal/broker/broker.py | 2 +- faststream/_internal/constants.py | 4 ++-- faststream/_internal/publisher/usecase.py | 2 +- faststream/_internal/subscriber/utils.py | 6 +++--- faststream/message/message.py | 14 +++++++------- faststream/message/source_type.py | 4 ++-- faststream/message/utils.py | 8 ++++---- .../middlewares/acknowledgement/middleware.py | 4 +++- faststream/middlewares/logging.py | 6 +++--- faststream/prometheus/consts.py | 6 +++--- faststream/prometheus/middleware.py | 2 +- faststream/redis/parser.py | 4 ++-- .../specification/asyncapi/v2_6_0/generate.py | 2 +- .../specification/asyncapi/v3_0_0/generate.py | 2 +- tests/prometheus/basic.py | 16 ++++++++-------- 15 files changed, 42 insertions(+), 40 deletions(-) diff --git a/faststream/_internal/broker/broker.py b/faststream/_internal/broker/broker.py index f4229be5c6..cf5959a908 100644 --- a/faststream/_internal/broker/broker.py +++ b/faststream/_internal/broker/broker.py @@ -388,7 +388,7 @@ async def _basic_request( ), parser=producer._parser, decoder=producer._decoder, - source_type=SourceType.Response, + source_type=SourceType.RESPONSE, ) return response_msg diff --git a/faststream/_internal/constants.py b/faststream/_internal/constants.py index 108e318f67..c81916ed95 100644 --- a/faststream/_internal/constants.py +++ b/faststream/_internal/constants.py @@ -7,8 +7,8 @@ class ContentTypes(str, Enum): """A class to represent content types.""" - text = "text/plain" - json = "application/json" + TEXT = "text/plain" + JSON = "application/json" class EmptyPlaceholder: diff --git a/faststream/_internal/publisher/usecase.py b/faststream/_internal/publisher/usecase.py index 049ed1e5a5..39a0da7cb9 100644 --- a/faststream/_internal/publisher/usecase.py +++ b/faststream/_internal/publisher/usecase.py @@ -187,7 +187,7 @@ async def _basic_request( ), parser=self._producer._parser, decoder=self._producer._decoder, - source_type=SourceType.Response, + source_type=SourceType.RESPONSE, ) return response_msg diff --git a/faststream/_internal/subscriber/utils.py b/faststream/_internal/subscriber/utils.py index fb9002c3a3..5f3d6719c2 100644 --- a/faststream/_internal/subscriber/utils.py +++ b/faststream/_internal/subscriber/utils.py @@ -37,7 +37,7 @@ async def process_msg( middlewares: Iterable["BaseMiddleware"], parser: Callable[[MsgType], Awaitable["StreamMessage[MsgType]"]], decoder: Callable[["StreamMessage[MsgType]"], "Any"], - source_type: SourceType = SourceType.Consume, + source_type: SourceType = SourceType.CONSUME, ) -> None: ... @@ -47,7 +47,7 @@ async def process_msg( middlewares: Iterable["BaseMiddleware"], parser: Callable[[MsgType], Awaitable["StreamMessage[MsgType]"]], decoder: Callable[["StreamMessage[MsgType]"], "Any"], - source_type: SourceType = SourceType.Consume, + source_type: SourceType = SourceType.CONSUME, ) -> "StreamMessage[MsgType]": ... @@ -56,7 +56,7 @@ async def process_msg( middlewares: Iterable["BaseMiddleware"], parser: Callable[[MsgType], Awaitable["StreamMessage[MsgType]"]], decoder: Callable[["StreamMessage[MsgType]"], "Any"], - source_type: SourceType = SourceType.Consume, + source_type: SourceType = SourceType.CONSUME, ) -> Optional["StreamMessage[MsgType]"]: if msg is None: return None diff --git a/faststream/message/message.py b/faststream/message/message.py index 7e19bf9c3c..cdba65b5bb 100644 --- a/faststream/message/message.py +++ b/faststream/message/message.py @@ -19,9 +19,9 @@ class AckStatus(str, Enum): - acked = "acked" - nacked = "nacked" - rejected = "rejected" + ACKED = "ACKED" + NACKED = "NACKED" + REJECTED = "REJECTED" class StreamMessage(Generic[MsgType]): @@ -39,7 +39,7 @@ def __init__( content_type: Optional[str] = None, correlation_id: Optional[str] = None, message_id: Optional[str] = None, - source_type: SourceType = SourceType.Consume, + source_type: SourceType = SourceType.CONSUME, ) -> None: self.raw_message = raw_message self.body = body @@ -85,12 +85,12 @@ async def decode(self) -> Optional["DecodedMessage"]: async def ack(self) -> None: if self.committed is None: - self.committed = AckStatus.acked + self.committed = AckStatus.ACKED async def nack(self) -> None: if self.committed is None: - self.committed = AckStatus.nacked + self.committed = AckStatus.NACKED async def reject(self) -> None: if self.committed is None: - self.committed = AckStatus.rejected + self.committed = AckStatus.REJECTED diff --git a/faststream/message/source_type.py b/faststream/message/source_type.py index 1741be23d6..b6e4f95fd9 100644 --- a/faststream/message/source_type.py +++ b/faststream/message/source_type.py @@ -2,8 +2,8 @@ class SourceType(str, Enum): - Consume = "Consume" + CONSUME = "CONSUME" """Message consumed by basic subscriber flow.""" - Response = "Response" + RESPONSE = "RESPONSE" """RPC response consumed.""" diff --git a/faststream/message/utils.py b/faststream/message/utils.py index 5483c27bb5..715c336bd1 100644 --- a/faststream/message/utils.py +++ b/faststream/message/utils.py @@ -32,10 +32,10 @@ def decode_message(message: "StreamMessage[Any]") -> "DecodedMessage": if content_type := getattr(message, "content_type", False): content_type = ContentTypes(cast(str, content_type)) - if content_type is ContentTypes.text: + if content_type is ContentTypes.TEXT: m = body.decode() - elif content_type is ContentTypes.json: + elif content_type is ContentTypes.JSON: m = json_loads(body) else: @@ -65,10 +65,10 @@ def encode_message( if isinstance(msg, str): return ( msg.encode(), - ContentTypes.text.value, + ContentTypes.TEXT.value, ) return ( dump_json(msg), - ContentTypes.json.value, + ContentTypes.JSON.value, ) diff --git a/faststream/middlewares/acknowledgement/middleware.py b/faststream/middlewares/acknowledgement/middleware.py index 2513768649..409bc28262 100644 --- a/faststream/middlewares/acknowledgement/middleware.py +++ b/faststream/middlewares/acknowledgement/middleware.py @@ -23,7 +23,9 @@ def __init__(self, ack_policy: AckPolicy, extra_options: "AnyDict") -> None: self.ack_policy = ack_policy self.extra_options = extra_options - def __call__(self, msg: Optional[Any], context: "ContextRepo") -> "_AcknowledgementMiddleware": + def __call__( + self, msg: Optional[Any], context: "ContextRepo" + ) -> "_AcknowledgementMiddleware": return _AcknowledgementMiddleware( msg, ack_policy=self.ack_policy, diff --git a/faststream/middlewares/logging.py b/faststream/middlewares/logging.py index 2c82299532..f0eeffbe4d 100644 --- a/faststream/middlewares/logging.py +++ b/faststream/middlewares/logging.py @@ -46,7 +46,7 @@ def __init__( ) -> None: super().__init__(msg, context=context) self.logger = logger - self._source_type = SourceType.Consume + self._source_type = SourceType.CONSUME async def consume_scope( self, @@ -55,7 +55,7 @@ async def consume_scope( ) -> "StreamMessage[Any]": source_type = self._source_type = msg._source_type - if source_type is not SourceType.Response: + if source_type is not SourceType.RESPONSE: self.logger.log( "Received", extra=self.context.get_local("log_context", {}), @@ -70,7 +70,7 @@ async def __aexit__( exc_tb: Optional["TracebackType"] = None, ) -> bool: """Asynchronously called after processing.""" - if self._source_type is not SourceType.Response: + if self._source_type is not SourceType.RESPONSE: c = self.context.get_local("log_context", {}) if exc_type: diff --git a/faststream/prometheus/consts.py b/faststream/prometheus/consts.py index 75cb8ba89a..8e592d14ae 100644 --- a/faststream/prometheus/consts.py +++ b/faststream/prometheus/consts.py @@ -11,7 +11,7 @@ PROCESSING_STATUS_BY_ACK_STATUS = { - AckStatus.acked: ProcessingStatus.acked, - AckStatus.nacked: ProcessingStatus.nacked, - AckStatus.rejected: ProcessingStatus.rejected, + AckStatus.ACKED: ProcessingStatus.acked, + AckStatus.NACKED: ProcessingStatus.nacked, + AckStatus.REJECTED: ProcessingStatus.rejected, } diff --git a/faststream/prometheus/middleware.py b/faststream/prometheus/middleware.py index 5d35708cfe..ffdea49d4f 100644 --- a/faststream/prometheus/middleware.py +++ b/faststream/prometheus/middleware.py @@ -88,7 +88,7 @@ async def consume_scope( call_next: "AsyncFuncAny", msg: "StreamMessage[Any]", ) -> Any: - if self._settings_provider is None or msg._source_type is SourceType.Response: + if self._settings_provider is None or msg._source_type is SourceType.RESPONSE: return await call_next(msg) messaging_system = self._settings_provider.messaging_system diff --git a/faststream/redis/parser.py b/faststream/redis/parser.py index 1d33c0e9f3..382d7be15b 100644 --- a/faststream/redis/parser.py +++ b/faststream/redis/parser.py @@ -200,7 +200,7 @@ def _parse_data( dump_json(body), { **first_msg_headers, - "content-type": ContentTypes.json.value, + "content-type": ContentTypes.JSON.value, }, batch_headers, ) @@ -239,7 +239,7 @@ def _parse_data( dump_json(body), { **first_msg_headers, - "content-type": ContentTypes.json.value, + "content-type": ContentTypes.JSON.value, }, batch_headers, ) diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index 7e6f4f5b67..2c6a3b3900 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -72,7 +72,7 @@ def get_app_schema( license=license_from_spec(license) if license else None, ), asyncapi=schema_version, - defaultContentType=ContentTypes.json.value, + defaultContentType=ContentTypes.JSON.value, id=identifier, tags=[tag_from_spec(tag) for tag in tags] if tags else None, externalDocs=docs_from_spec(external_docs) if external_docs else None, diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index 72b5e7966e..b14dca2772 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -98,7 +98,7 @@ def get_app_schema( externalDocs=docs_from_spec(external_docs) if external_docs else None, ), asyncapi=schema_version, - defaultContentType=ContentTypes.json.value, + defaultContentType=ContentTypes.JSON.value, id=identifier, servers=servers, channels=channels, diff --git a/tests/prometheus/basic.py b/tests/prometheus/basic.py index 22c13b1540..2c4d8a2028 100644 --- a/tests/prometheus/basic.py +++ b/tests/prometheus/basic.py @@ -42,17 +42,17 @@ def settings_provider_factory(self): ), ( pytest.param( - AckStatus.acked, + AckStatus.ACKED, RejectMessage, id="acked status with reject message exception", ), pytest.param( - AckStatus.acked, Exception, id="acked status with not handler exception" + AckStatus.ACKED, Exception, id="acked status with not handler exception" ), - pytest.param(AckStatus.acked, None, id="acked status without exception"), - pytest.param(AckStatus.nacked, None, id="nacked status without exception"), + pytest.param(AckStatus.ACKED, None, id="acked status without exception"), + pytest.param(AckStatus.NACKED, None, id="nacked status without exception"), pytest.param( - AckStatus.rejected, None, id="rejected status without exception" + AckStatus.REJECTED, None, id="rejected status without exception" ), ), ) @@ -83,11 +83,11 @@ async def handler(m=Context("message")): if exception_class: raise exception_class - if status == AckStatus.acked: + if status == AckStatus.ACKED: await message.ack() - elif status == AckStatus.nacked: + elif status == AckStatus.NACKED: await message.nack() - elif status == AckStatus.rejected: + elif status == AckStatus.REJECTED: await message.reject() async with broker: From 2a4c51d7219660d39b346016bd2216cdc44ad2fb Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Tue, 5 Nov 2024 23:00:25 +0300 Subject: [PATCH 185/245] refactor: little type changes --- faststream/_internal/fastapi/router.py | 1 + faststream/confluent/broker/broker.py | 2 +- faststream/kafka/broker/broker.py | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/faststream/_internal/fastapi/router.py b/faststream/_internal/fastapi/router.py index 910c8a0387..4828893324 100644 --- a/faststream/_internal/fastapi/router.py +++ b/faststream/_internal/fastapi/router.py @@ -327,6 +327,7 @@ async def start_broker_lifespan( else: warnings.warn( "Specifying 'lifespan_context' manually is no longer necessary with FastAPI >= 0.112.2.", + category=RuntimeWarning, stacklevel=2, ) diff --git a/faststream/confluent/broker/broker.py b/faststream/confluent/broker/broker.py index 8eb7aefd87..b7853ad014 100644 --- a/faststream/confluent/broker/broker.py +++ b/faststream/confluent/broker/broker.py @@ -524,7 +524,7 @@ async def publish( # type: ignore[override] correlation_id=correlation_id or gen_cor_id(), _publish_type=PublishType.Publish, ) - return await super()._basic_publish(cmd, producer=self._producer) + await super()._basic_publish(cmd, producer=self._producer) @override async def request( # type: ignore[override] diff --git a/faststream/kafka/broker/broker.py b/faststream/kafka/broker/broker.py index 3564d52c9c..ad50958ace 100644 --- a/faststream/kafka/broker/broker.py +++ b/faststream/kafka/broker/broker.py @@ -744,7 +744,7 @@ async def publish( # type: ignore[override] correlation_id=correlation_id or gen_cor_id(), _publish_type=PublishType.Publish, ) - return await super()._basic_publish(cmd, producer=self._producer) + await super()._basic_publish(cmd, producer=self._producer) @override async def request( # type: ignore[override] From 65ba4a443ebca89bbf5163f49ff927e90ba86ab9 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Wed, 6 Nov 2024 20:45:15 +0300 Subject: [PATCH 186/245] refactor: new setup logic --- faststream/_internal/application.py | 4 +- faststream/_internal/broker/abc_broker.py | 8 +- faststream/_internal/broker/broker.py | 188 +++++++----------- faststream/_internal/broker/pub_base.py | 97 +++++++++ faststream/_internal/broker/router.py | 4 + faststream/_internal/cli/utils/logs.py | 10 +- faststream/_internal/fastapi/route.py | 6 +- faststream/_internal/log/logging.py | 3 +- faststream/_internal/proto.py | 4 +- faststream/_internal/publisher/proto.py | 10 +- faststream/_internal/publisher/usecase.py | 38 ++-- faststream/_internal/setup/logger.py | 163 --------------- faststream/_internal/setup/state.py | 99 --------- .../_internal/{setup => state}/__init__.py | 14 +- faststream/_internal/state/broker.py | 80 ++++++++ .../{setup => state}/fast_depends.py | 20 +- faststream/_internal/state/logger/__init__.py | 9 + .../_internal/state/logger/logger_proxy.py | 102 ++++++++++ .../_internal/state/logger/params_storage.py | 72 +++++++ faststream/_internal/state/logger/state.py | 72 +++++++ faststream/_internal/state/pointer.py | 19 ++ faststream/_internal/state/producer.py | 29 +++ .../_internal/{setup => state}/proto.py | 0 faststream/_internal/subscriber/call_item.py | 6 +- .../_internal/subscriber/call_wrapper/call.py | 4 +- faststream/_internal/subscriber/proto.py | 9 +- faststream/_internal/subscriber/usecase.py | 28 ++- faststream/_internal/testing/broker.py | 30 ++- faststream/confluent/broker/broker.py | 29 ++- faststream/confluent/broker/logging.py | 11 +- faststream/confluent/broker/registrator.py | 4 +- faststream/confluent/client.py | 2 +- faststream/confluent/publisher/producer.py | 23 ++- faststream/confluent/publisher/state.py | 50 +++++ faststream/confluent/publisher/usecase.py | 6 +- faststream/confluent/response.py | 2 +- faststream/confluent/subscriber/usecase.py | 23 +-- faststream/confluent/testing.py | 20 +- faststream/kafka/broker/broker.py | 28 ++- faststream/kafka/broker/logging.py | 11 +- faststream/kafka/broker/registrator.py | 4 +- faststream/kafka/publisher/producer.py | 26 ++- faststream/kafka/publisher/state.py | 49 +++++ faststream/kafka/publisher/usecase.py | 6 +- faststream/kafka/response.py | 2 +- faststream/kafka/subscriber/usecase.py | 21 +- faststream/kafka/testing.py | 18 +- faststream/middlewares/logging.py | 2 +- faststream/nats/broker/broker.py | 23 +-- faststream/nats/broker/logging.py | 11 +- faststream/nats/broker/registrator.py | 4 +- faststream/nats/publisher/producer.py | 1 - faststream/nats/publisher/usecase.py | 6 +- faststream/nats/response.py | 2 +- faststream/nats/subscriber/usecase.py | 28 +-- faststream/nats/testing.py | 17 +- faststream/prometheus/middleware.py | 2 +- faststream/rabbit/broker/broker.py | 46 ++--- faststream/rabbit/broker/logging.py | 11 +- faststream/rabbit/broker/registrator.py | 4 +- faststream/rabbit/helpers/declarer.py | 28 ++- faststream/rabbit/helpers/state.py | 35 ++++ faststream/rabbit/publisher/producer.py | 37 +++- faststream/rabbit/publisher/usecase.py | 8 +- faststream/rabbit/response.py | 2 +- faststream/rabbit/schemas/exchange.py | 8 + faststream/rabbit/schemas/queue.py | 8 + faststream/rabbit/subscriber/usecase.py | 20 +- faststream/rabbit/testing.py | 11 +- faststream/redis/broker/broker.py | 23 ++- faststream/redis/broker/logging.py | 11 +- faststream/redis/broker/registrator.py | 4 +- faststream/redis/helpers/__init__.py | 0 faststream/redis/helpers/state.py | 27 +++ faststream/redis/publisher/producer.py | 25 ++- faststream/redis/publisher/usecase.py | 14 +- faststream/redis/response.py | 2 +- faststream/redis/subscriber/usecase.py | 25 +-- faststream/redis/testing.py | 11 +- faststream/response/publish_type.py | 6 +- faststream/response/response.py | 2 +- tests/asgi/testcase.py | 2 +- tests/brokers/base/router.py | 4 +- tests/brokers/base/testclient.py | 6 +- tests/brokers/rabbit/specific/test_declare.py | 12 +- tests/cli/rabbit/test_logs.py | 2 +- tests/cli/test_publish.py | 4 +- tests/opentelemetry/basic.py | 4 +- tests/prometheus/confluent/test_provider.py | 4 +- tests/prometheus/kafka/test_provider.py | 4 +- tests/prometheus/redis/test_provider.py | 4 +- 91 files changed, 1225 insertions(+), 748 deletions(-) create mode 100644 faststream/_internal/broker/pub_base.py delete mode 100644 faststream/_internal/setup/logger.py delete mode 100644 faststream/_internal/setup/state.py rename faststream/_internal/{setup => state}/__init__.py (53%) create mode 100644 faststream/_internal/state/broker.py rename faststream/_internal/{setup => state}/fast_depends.py (55%) create mode 100644 faststream/_internal/state/logger/__init__.py create mode 100644 faststream/_internal/state/logger/logger_proxy.py create mode 100644 faststream/_internal/state/logger/params_storage.py create mode 100644 faststream/_internal/state/logger/state.py create mode 100644 faststream/_internal/state/pointer.py create mode 100644 faststream/_internal/state/producer.py rename faststream/_internal/{setup => state}/proto.py (100%) create mode 100644 faststream/confluent/publisher/state.py create mode 100644 faststream/kafka/publisher/state.py create mode 100644 faststream/rabbit/helpers/state.py create mode 100644 faststream/redis/helpers/__init__.py create mode 100644 faststream/redis/helpers/state.py diff --git a/faststream/_internal/application.py b/faststream/_internal/application.py index 056b11930c..d74f1c4a76 100644 --- a/faststream/_internal/application.py +++ b/faststream/_internal/application.py @@ -16,7 +16,7 @@ from faststream._internal.constants import EMPTY from faststream._internal.context import ContextRepo from faststream._internal.log import logger -from faststream._internal.setup.state import FastDependsData +from faststream._internal.state import DIState from faststream._internal.utils import apply_types from faststream._internal.utils.functions import ( drop_response_type, @@ -98,7 +98,7 @@ def _init_setupable_( # noqa: PLW3201 serializer = PydanticSerializer() - self._state = FastDependsData( + self._state = DIState( use_fastdepends=True, get_dependent=None, call_decorators=(), diff --git a/faststream/_internal/broker/abc_broker.py b/faststream/_internal/broker/abc_broker.py index 09be9f317f..b50b0195c5 100644 --- a/faststream/_internal/broker/abc_broker.py +++ b/faststream/_internal/broker/abc_broker.py @@ -37,7 +37,7 @@ def __init__( self._publishers = [] self._dependencies = dependencies - self._middlewares = middlewares + self.middlewares = middlewares self._parser = parser self._decoder = decoder @@ -46,7 +46,7 @@ def add_middleware(self, middleware: "BrokerMiddleware[MsgType]") -> None: Current middleware will be used as a most inner of already existed ones. """ - self._middlewares = (*self._middlewares, middleware) + self.middlewares = (*self.middlewares, middleware) for sub in self._subscribers: sub.add_middleware(middleware) @@ -91,7 +91,7 @@ def include_router( h.include_in_schema = include_in_schema h._broker_middlewares = ( - *self._middlewares, + *self.middlewares, *middlewares, *h._broker_middlewares, ) @@ -111,7 +111,7 @@ def include_router( p.include_in_schema = include_in_schema p._broker_middlewares = ( - *self._middlewares, + *self.middlewares, *middlewares, *p._broker_middlewares, ) diff --git a/faststream/_internal/broker/broker.py b/faststream/_internal/broker/broker.py index cf5959a908..73f7aea2c5 100644 --- a/faststream/_internal/broker/broker.py +++ b/faststream/_internal/broker/broker.py @@ -1,6 +1,5 @@ from abc import abstractmethod from collections.abc import Iterable, Sequence -from functools import partial from typing import ( TYPE_CHECKING, Annotated, @@ -13,21 +12,21 @@ ) from fast_depends import Provider -from fast_depends.pydantic import PydanticSerializer from typing_extensions import Doc, Self from faststream._internal.constants import EMPTY from faststream._internal.context.repository import ContextRepo -from faststream._internal.setup import ( - EmptyState, - FastDependsData, +from faststream._internal.state import ( + DIState, LoggerState, SetupAble, - SetupState, ) -from faststream._internal.setup.state import BaseState +from faststream._internal.state.broker import ( + BrokerState, + InitialBrokerState, +) +from faststream._internal.state.producer import ProducerUnset from faststream._internal.subscriber.proto import SubscriberProto -from faststream._internal.subscriber.utils import process_msg from faststream._internal.types import ( AsyncCustomCallable, BrokerMiddleware, @@ -36,11 +35,10 @@ MsgType, ) from faststream._internal.utils.functions import to_async -from faststream.exceptions import NOT_CONNECTED_YET -from faststream.message.source_type import SourceType from faststream.middlewares.logging import CriticalLogMiddleware from .abc_broker import ABCBroker +from .pub_base import BrokerPublishMixin if TYPE_CHECKING: from types import TracebackType @@ -53,7 +51,6 @@ ProducerProto, PublisherProto, ) - from faststream.response.response import PublishCommand from faststream.security import BaseSecurity from faststream.specification.schema.tag import Tag, TagDict @@ -61,14 +58,14 @@ class BrokerUsecase( ABCBroker[MsgType], SetupAble, + BrokerPublishMixin[MsgType], Generic[MsgType, ConnectionType], ): """A class representing a broker async use case.""" url: Union[str, Sequence[str]] _connection: Optional[ConnectionType] - _producer: Optional["ProducerProto"] - _state: BaseState + _producer: "ProducerProto" def __init__( self, @@ -157,27 +154,27 @@ def __init__( ) self.running = False - self.graceful_timeout = graceful_timeout self._connection_kwargs = connection_kwargs self._connection = None - self._producer = None - self._middlewares = ( + self.middlewares = ( CriticalLogMiddleware(logger_state), - *self._middlewares, + *self.middlewares, ) - self._state = EmptyState( - depends_params=FastDependsData( + self._state: BrokerState = InitialBrokerState( + di_state=DIState( use_fastdepends=apply_types, get_dependent=_get_dependant, call_decorators=_call_decorators, - serializer=PydanticSerializer() if serializer is EMPTY else serializer, + serializer=serializer, provider=Provider(), context=ContextRepo(), ), logger_state=logger_state, + graceful_timeout=graceful_timeout, + producer=ProducerUnset(), ) # AsyncAPI information @@ -189,12 +186,16 @@ def __init__( self.security = security @property - def context(self) -> ContextRepo: - return self._state.depends_params.context + def _producer(self) -> "ProducerProto": + return self._state.producer + + @property + def context(self) -> "ContextRepo": + return self._state.di_state.context @property def provider(self) -> Provider: - return self._state.depends_params.provider + return self._state.di_state.provider async def __aenter__(self) -> "Self": await self.connect() @@ -212,12 +213,19 @@ async def __aexit__( async def start(self) -> None: """Start the broker async use case.""" # TODO: filter by already running handlers after TestClient refactor - for handler in self._subscribers: + for subscriber in self._subscribers: + log_context = subscriber.get_log_context(None) + log_context.pop("message_id", None) + self._state.logger_state.params_storage.setup_log_contest(log_context) + + self._state._setup_logger_state() + + for subscriber in self._subscribers: self._state.logger_state.log( - f"`{handler.call_name}` waiting for messages", - extra=handler.get_log_context(None), + f"`{subscriber.call_name}` waiting for messages", + extra=subscriber.get_log_context(None), ) - await handler.start() + await subscriber.start() async def connect(self, **kwargs: Any) -> ConnectionType: """Connect to a remote server.""" @@ -233,42 +241,42 @@ async def _connect(self) -> ConnectionType: """Connect to a resource.""" raise NotImplementedError - def _setup(self, di_state: Optional[FastDependsData] = None) -> None: - """Prepare all Broker entities to startup.""" - if not self._state: - if di_state is not None: - new_state = SetupState( - logger_state=self._state.logger_state, - depends_params=FastDependsData( - use_fastdepends=self._state.depends_params.use_fastdepends, - call_decorators=self._state.depends_params.call_decorators, - get_dependent=self._state.depends_params.get_dependent, - # from parent - serializer=di_state.serializer, - provider=di_state.provider, - context=di_state.context, - ), - ) - - else: - # Fallback to default state if there no - # parent container like FastStream object - new_state = self._state.copy_to_state(SetupState) - - self._state = new_state + def _setup(self, di_state: Optional[DIState] = None) -> None: + """Prepare all Broker entities to startup. - if not self.running: - self.running = True + Method should be idempotent due could be called twice + """ + broker_serializer = self._state.di_state.serializer + + if di_state is not None: + if broker_serializer is EMPTY: + broker_serializer = di_state.serializer + + self._state.di_state.update( + serializer=broker_serializer, + provider=di_state.provider, + context=di_state.context, + ) - for h in self._subscribers: - log_context = h.get_log_context(None) - log_context.pop("message_id", None) - self._state.logger_state.params_storage.setup_log_contest(log_context) + else: + # Fallback to default state if there no + # parent container like FastStream object + if broker_serializer is EMPTY: + from fast_depends.pydantic import PydanticSerializer - self._state._setup() + broker_serializer = PydanticSerializer() - # TODO: why we can't move it to running? - # TODO: can we setup subscriber in running broker automatically? + self._state.di_state.update( + serializer=broker_serializer, + ) + + self._state._setup() + + # TODO: move to start + if not self.running: + self.running = True + + # TODO: move setup to object creation for h in self._subscribers: self.setup_subscriber(h) @@ -298,12 +306,8 @@ def setup_publisher( @property def _subscriber_setup_extra(self) -> "AnyDict": return { - "logger": self._state.logger_state.logger.logger, - "producer": self._producer, - "graceful_timeout": self.graceful_timeout, "extra_context": { "broker": self, - "logger": self._state.logger_state.logger.logger, }, # broker options "broker_parser": self._parser, @@ -334,64 +338,6 @@ async def close( self.running = False - async def _basic_publish( - self, - cmd: "PublishCommand", - *, - producer: Optional["ProducerProto"], - ) -> Optional[Any]: - """Publish message directly.""" - assert producer, NOT_CONNECTED_YET # nosec B101 - - publish = producer.publish - - for m in self._middlewares: - publish = partial(m(None, context=self.context).publish_scope, publish) - - return await publish(cmd) - - async def _basic_publish_batch( - self, - cmd: "PublishCommand", - *, - producer: Optional["ProducerProto"], - ) -> None: - """Publish a messages batch directly.""" - assert producer, NOT_CONNECTED_YET # nosec B101 - - publish = producer.publish_batch - - for m in self._middlewares: - publish = partial(m(None, context=self.context).publish_scope, publish) - - await publish(cmd) - - async def _basic_request( - self, - cmd: "PublishCommand", - *, - producer: Optional["ProducerProto"], - ) -> Any: - """Publish message directly.""" - assert producer, NOT_CONNECTED_YET # nosec B101 - - request = producer.request - for m in self._middlewares: - request = partial(m(None, context=self.context).publish_scope, request) - - published_msg = await request(cmd) - - response_msg: Any = await process_msg( - msg=published_msg, - middlewares=( - m(published_msg, context=self.context) for m in self._middlewares - ), - parser=producer._parser, - decoder=producer._decoder, - source_type=SourceType.RESPONSE, - ) - return response_msg - @abstractmethod async def ping(self, timeout: Optional[float]) -> bool: """Check connection alive.""" diff --git a/faststream/_internal/broker/pub_base.py b/faststream/_internal/broker/pub_base.py new file mode 100644 index 0000000000..000f007d52 --- /dev/null +++ b/faststream/_internal/broker/pub_base.py @@ -0,0 +1,97 @@ +from abc import abstractmethod +from collections.abc import Iterable +from functools import partial +from typing import TYPE_CHECKING, Any, Generic, Optional + +from faststream._internal.subscriber.utils import process_msg +from faststream._internal.types import MsgType +from faststream.message.source_type import SourceType + +if TYPE_CHECKING: + from faststream._internal.basic_types import SendableMessage + from faststream._internal.context import ContextRepo + from faststream._internal.publisher.proto import ProducerProto + from faststream._internal.types import BrokerMiddleware + from faststream.response import PublishCommand + + +class BrokerPublishMixin(Generic[MsgType]): + middlewares: Iterable["BrokerMiddleware[MsgType]"] + context: "ContextRepo" + + @abstractmethod + async def publish( + self, + message: "SendableMessage", + queue: str, + /, + ) -> None: + raise NotImplementedError + + async def _basic_publish( + self, + cmd: "PublishCommand", + *, + producer: "ProducerProto", + ) -> Optional[Any]: + publish = producer.publish + + for m in self.middlewares: + publish = partial(m(None, context=self.context).publish_scope, publish) + + return await publish(cmd) + + @abstractmethod + async def publish_batch( + self, + *messages: "SendableMessage", + queue: str, + ) -> None: + raise NotImplementedError + + async def _basic_publish_batch( + self, + cmd: "PublishCommand", + *, + producer: "ProducerProto", + ) -> None: + publish = producer.publish_batch + + for m in self.middlewares: + publish = partial(m(None, context=self.context).publish_scope, publish) + + await publish(cmd) + + @abstractmethod + async def request( + self, + message: "SendableMessage", + queue: str, + /, + timeout: float = 0.5, + ) -> Any: + raise NotImplementedError + + async def _basic_request( + self, + cmd: "PublishCommand", + *, + producer: "ProducerProto", + ) -> Any: + request = producer.request + + for m in self.middlewares: + request = partial(m(None, context=self.context).publish_scope, request) + + published_msg = await request(cmd) + + response_msg: Any = await process_msg( + msg=published_msg, + middlewares=( + m(published_msg, context=self.context) for m in self.middlewares + ), + parser=producer._parser, + decoder=producer._decoder, + source_type=SourceType.RESPONSE, + ) + return response_msg diff --git a/faststream/_internal/broker/router.py b/faststream/_internal/broker/router.py index a6a49fae3a..6daa2f245a 100644 --- a/faststream/_internal/broker/router.py +++ b/faststream/_internal/broker/router.py @@ -23,6 +23,8 @@ class ArgsContainer: """Class to store any arguments.""" + __slots__ = ("args", "kwargs") + args: Iterable[Any] kwargs: "AnyDict" @@ -38,6 +40,8 @@ def __init__( class SubscriberRoute(ArgsContainer): """A generic class to represent a broker route.""" + __slots__ = ("args", "call", "kwargs", "publishers") + call: Callable[..., Any] publishers: Iterable[Any] diff --git a/faststream/_internal/cli/utils/logs.py b/faststream/_internal/cli/utils/logs.py index f1656686a4..cd2aa47ea5 100644 --- a/faststream/_internal/cli/utils/logs.py +++ b/faststream/_internal/cli/utils/logs.py @@ -1,10 +1,9 @@ import logging from collections import defaultdict from enum import Enum -from typing import TYPE_CHECKING, Optional, Union +from typing import TYPE_CHECKING, Union if TYPE_CHECKING: - from faststream._internal.basic_types import LoggerProto from faststream.app import FastStream @@ -69,9 +68,4 @@ def set_log_level(level: int, app: "FastStream") -> None: if app.logger and getattr(app.logger, "setLevel", None): app.logger.setLevel(level) # type: ignore[attr-defined] - if app.broker: - broker_logger: Optional[LoggerProto] = ( - app.broker._state.logger_state.logger.logger - ) - if broker_logger is not None and getattr(broker_logger, "setLevel", None): - broker_logger.setLevel(level) # type: ignore[attr-defined] + app.broker._state.logger_state.set_level(level) diff --git a/faststream/_internal/fastapi/route.py b/faststream/_internal/fastapi/route.py index f45b64194e..a132daf3f9 100644 --- a/faststream/_internal/fastapi/route.py +++ b/faststream/_internal/fastapi/route.py @@ -35,7 +35,7 @@ from fastapi.types import IncEx from faststream._internal.basic_types import AnyDict - from faststream._internal.setup import FastDependsData + from faststream._internal.state import DIState from faststream.message import StreamMessage as NativeMessage @@ -76,7 +76,7 @@ def wrap_callable_to_fastapi_compatible( response_model_exclude_unset: bool, response_model_exclude_defaults: bool, response_model_exclude_none: bool, - state: "FastDependsData", + state: "DIState", ) -> Callable[["NativeMessage[Any]"], Awaitable[Any]]: __magic_attr = "__faststream_consumer__" @@ -120,7 +120,7 @@ def build_faststream_to_fastapi_parser( response_model_exclude_unset: bool, response_model_exclude_defaults: bool, response_model_exclude_none: bool, - state: "FastDependsData", + state: "DIState", ) -> Callable[["NativeMessage[Any]"], Awaitable[Any]]: """Creates a session for handling requests.""" assert dependent.call # nosec B101 diff --git a/faststream/_internal/log/logging.py b/faststream/_internal/log/logging.py index 7ffc83ded3..2fa346ca8a 100644 --- a/faststream/_internal/log/logging.py +++ b/faststream/_internal/log/logging.py @@ -58,9 +58,10 @@ def get_broker_logger( message_id_ln: int, fmt: str, context: "ContextRepo", + log_level: int, ) -> logging.Logger: logger = logging.getLogger(f"faststream.access.{name}") - logger.setLevel(logging.INFO) + logger.setLevel(log_level) logger.propagate = False logger.addFilter(ExtendedFilter(default_context, message_id_ln, context=context)) handler = logging.StreamHandler(stream=sys.stdout) diff --git a/faststream/_internal/proto.py b/faststream/_internal/proto.py index b75266d087..615dec872b 100644 --- a/faststream/_internal/proto.py +++ b/faststream/_internal/proto.py @@ -1,10 +1,8 @@ from abc import abstractmethod from typing import Any, Optional, Protocol, TypeVar, Union, overload -from .setup import SetupAble - -class Endpoint(SetupAble, Protocol): +class Endpoint(Protocol): @abstractmethod def add_prefix(self, prefix: str) -> None: ... diff --git a/faststream/_internal/publisher/proto.py b/faststream/_internal/publisher/proto.py index fef4cb1b68..49e7b3151c 100644 --- a/faststream/_internal/publisher/proto.py +++ b/faststream/_internal/publisher/proto.py @@ -11,7 +11,7 @@ if TYPE_CHECKING: from faststream._internal.basic_types import SendableMessage - from faststream._internal.setup import SetupState + from faststream._internal.state import BrokerState from faststream._internal.types import ( AsyncCallable, BrokerMiddleware, @@ -42,6 +42,12 @@ async def publish_batch(self, cmd: "PublishCommand") -> None: ... +class ProducerFactory(Protocol): + def __call__( + self, parser: "AsyncCallable", decoder: "AsyncCallable" + ) -> ProducerProto: ... + + class BasePublisherProto(Protocol): @abstractmethod async def publish( @@ -103,7 +109,7 @@ def _setup( # type: ignore[override] self, *, producer: Optional["ProducerProto"], - state: "SetupState", + state: "BrokerState", ) -> None: ... @abstractmethod diff --git a/faststream/_internal/publisher/usecase.py b/faststream/_internal/publisher/usecase.py index 39a0da7cb9..d487e54859 100644 --- a/faststream/_internal/publisher/usecase.py +++ b/faststream/_internal/publisher/usecase.py @@ -16,6 +16,7 @@ from typing_extensions import Doc, override from faststream._internal.publisher.proto import PublisherProto +from faststream._internal.state.producer import ProducerUnset from faststream._internal.subscriber.call_wrapper.call import HandlerCallWrapper from faststream._internal.subscriber.utils import process_msg from faststream._internal.types import ( @@ -23,7 +24,6 @@ P_HandlerParams, T_HandlerReturn, ) -from faststream.exceptions import NOT_CONNECTED_YET from faststream.message.source_type import SourceType from faststream.specification.asyncapi.message import ( get_model_schema, @@ -33,7 +33,7 @@ if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict from faststream._internal.publisher.proto import ProducerProto - from faststream._internal.setup import SetupState + from faststream._internal.state import BrokerState from faststream._internal.types import ( BrokerMiddleware, PublisherMiddleware, @@ -80,9 +80,10 @@ def __init__( ], ) -> None: self.calls = [] - self._middlewares = middlewares + self.middlewares = middlewares self._broker_middlewares = broker_middlewares - self._producer = None + + self._producer: ProducerProto = ProducerUnset() self._fake_handler = False self.mock = None @@ -98,10 +99,13 @@ def add_middleware(self, middleware: "BrokerMiddleware[MsgType]") -> None: @override def _setup( # type: ignore[override] - self, *, producer: Optional["ProducerProto"], state: Optional["SetupState"] + self, + *, + producer: "ProducerProto", + state: Optional["BrokerState"], ) -> None: - self._producer = producer self._state = state + self._producer = producer def set_test( self, @@ -144,19 +148,17 @@ async def _basic_publish( *, _extra_middlewares: Iterable["PublisherMiddleware"], ) -> Any: - assert self._producer, NOT_CONNECTED_YET # nosec B101 - pub: Callable[..., Awaitable[Any]] = self._producer.publish for pub_m in chain( ( _extra_middlewares or ( - m(None, context=self._state.depends_params.context).publish_scope + m(None, context=self._state.di_state.context).publish_scope for m in self._broker_middlewares ) ), - self._middlewares, + self.middlewares, ): pub = partial(pub_m, pub) @@ -166,15 +168,13 @@ async def _basic_request( self, cmd: "PublishCommand", ) -> Optional[Any]: - assert self._producer, NOT_CONNECTED_YET # nosec B101 - - context = self._state.depends_params.context + context = self._state.di_state.context request = self._producer.request for pub_m in chain( (m(None, context=context).publish_scope for m in self._broker_middlewares), - self._middlewares, + self.middlewares, ): request = partial(pub_m, request) @@ -197,19 +197,17 @@ async def _basic_publish_batch( *, _extra_middlewares: Iterable["PublisherMiddleware"], ) -> Optional[Any]: - assert self._producer, NOT_CONNECTED_YET # nosec B101 - pub = self._producer.publish_batch for pub_m in chain( ( _extra_middlewares or ( - m(None, context=self._state.depends_params.context).publish_scope + m(None, context=self._state.di_state.context).publish_scope for m in self._broker_middlewares ) ), - self._middlewares, + self.middlewares, ): pub = partial(pub_m, pub) @@ -235,8 +233,8 @@ def get_payloads(self) -> list[tuple["AnyDict", str]]: for call in self.calls: call_model = build_call_model( call, - dependency_provider=self._state.depends_params.provider, - serializer_cls=self._state.depends_params.serializer, + dependency_provider=self._state.di_state.provider, + serializer_cls=self._state.di_state.serializer, ) response_type = next( diff --git a/faststream/_internal/setup/logger.py b/faststream/_internal/setup/logger.py deleted file mode 100644 index fb7da8f493..0000000000 --- a/faststream/_internal/setup/logger.py +++ /dev/null @@ -1,163 +0,0 @@ -import warnings -from dataclasses import dataclass, field -from typing import TYPE_CHECKING, Optional, Protocol - -from faststream._internal.basic_types import AnyDict, LoggerProto -from faststream._internal.constants import EMPTY -from faststream.exceptions import IncorrectState - -from .proto import SetupAble - -if TYPE_CHECKING: - from faststream._internal.context import ContextRepo - -__all__ = ( - "DefaultLoggerStorage", - "LoggerParamsStorage", - "LoggerState", - "make_logger_state", -) - - -def make_logger_state( - logger: Optional["LoggerProto"], - log_level: int, - log_fmt: Optional[str], - default_storag_cls: type["DefaultLoggerStorage"], -) -> "LoggerState": - if logger is not EMPTY and log_fmt: - warnings.warn( - message="You can't set custom `logger` with `log_fmt` both.", - category=RuntimeWarning, - stacklevel=1, - ) - - if logger is EMPTY: - storage = default_storag_cls(log_fmt) - elif logger is None: - storage = _EmptyLoggerStorage() - else: - storage = _ManualLoggerStorage(logger) - - return LoggerState( - log_level=log_level, - params_storage=storage, - ) - - -class _LoggerObject(Protocol): - logger: Optional["LoggerProto"] - - def log( - self, - message: str, - log_level: int, - extra: Optional["AnyDict"] = None, - exc_info: Optional[Exception] = None, - ) -> None: ... - - -class _NotSetLoggerObject(_LoggerObject): - def __init__(self) -> None: - self.logger = None - - def log( - self, - message: str, - log_level: int, - extra: Optional["AnyDict"] = None, - exc_info: Optional[Exception] = None, - ) -> None: - msg = "Logger object was not set up." - raise IncorrectState(msg) - - -class _EmptyLoggerObject(_LoggerObject): - def __init__(self) -> None: - self.logger = None - - def log( - self, - message: str, - log_level: int, - extra: Optional["AnyDict"] = None, - exc_info: Optional[Exception] = None, - ) -> None: - pass - - -class _RealLoggerObject(_LoggerObject): - def __init__(self, logger: "LoggerProto") -> None: - self.logger = logger - - def log( - self, - message: str, - log_level: int, - extra: Optional["AnyDict"] = None, - exc_info: Optional[Exception] = None, - ) -> None: - self.logger.log( - log_level, - message, - extra=extra, - exc_info=exc_info, - ) - - -class LoggerParamsStorage(Protocol): - def setup_log_contest(self, params: "AnyDict") -> None: ... - - def get_logger(self, *, context: "ContextRepo") -> Optional["LoggerProto"]: ... - - -class _EmptyLoggerStorage(LoggerParamsStorage): - def setup_log_contest(self, params: AnyDict) -> None: - pass - - def get_logger(self, *, context: "ContextRepo") -> None: - return None - - -class _ManualLoggerStorage(LoggerParamsStorage): - def __init__(self, logger: "LoggerProto") -> None: - self.__logger = logger - - def setup_log_contest(self, params: AnyDict) -> None: - pass - - def get_logger(self, *, context: "ContextRepo") -> LoggerProto: - return self.__logger - - -class DefaultLoggerStorage(LoggerParamsStorage): - def __init__(self, log_fmt: Optional[str]) -> None: - self._log_fmt = log_fmt - - -@dataclass -class LoggerState(SetupAble): - log_level: int - params_storage: LoggerParamsStorage - - logger: _LoggerObject = field(default=_NotSetLoggerObject(), init=False) - - def log( - self, - message: str, - log_level: Optional[int] = None, - extra: Optional["AnyDict"] = None, - exc_info: Optional[Exception] = None, - ) -> None: - self.logger.log( - log_level=(log_level or self.log_level), - message=message, - extra=extra, - exc_info=exc_info, - ) - - def _setup(self, *, context: "ContextRepo") -> None: - if logger := self.params_storage.get_logger(context=context): - self.logger = _RealLoggerObject(logger) - else: - self.logger = _EmptyLoggerObject() diff --git a/faststream/_internal/setup/state.py b/faststream/_internal/setup/state.py deleted file mode 100644 index da34c29c9e..0000000000 --- a/faststream/_internal/setup/state.py +++ /dev/null @@ -1,99 +0,0 @@ -from abc import abstractmethod, abstractproperty -from typing import Optional - -from faststream.exceptions import IncorrectState - -from .fast_depends import FastDependsData -from .logger import LoggerState -from .proto import SetupAble - - -class BaseState(SetupAble): - _depends_params: FastDependsData - _logger_params: LoggerState - - @abstractproperty - def depends_params(self) -> FastDependsData: - raise NotImplementedError - - @abstractproperty - def logger_state(self) -> LoggerState: - raise NotImplementedError - - @abstractmethod - def __bool__(self) -> bool: - raise NotImplementedError - - def _setup(self) -> None: - self.logger_state._setup(context=self.depends_params.context) - - def copy_with_params( - self, - *, - depends_params: Optional[FastDependsData] = None, - logger_state: Optional[LoggerState] = None, - ) -> "SetupState": - return self.__class__( - logger_state=logger_state or self._logger_params, - depends_params=depends_params or self._depends_params, - ) - - def copy_to_state(self, state_cls: type["SetupState"]) -> "SetupState": - return state_cls( - depends_params=self._depends_params, - logger_state=self._logger_params, - ) - - -class SetupState(BaseState): - """State after broker._setup() called.""" - - def __init__( - self, - *, - logger_state: LoggerState, - depends_params: FastDependsData, - ) -> None: - self._depends_params = depends_params - self._logger_params = logger_state - - @property - def depends_params(self) -> FastDependsData: - return self._depends_params - - @property - def logger_state(self) -> LoggerState: - return self._logger_params - - def __bool__(self) -> bool: - return True - - -class EmptyState(BaseState): - """Initial state for App, broker, etc.""" - - def __init__( - self, - *, - logger_state: Optional[LoggerState] = None, - depends_params: Optional[FastDependsData] = None, - ) -> None: - self._depends_params = depends_params - self._logger_params = logger_state - - @property - def depends_params(self) -> FastDependsData: - if not self._depends_params: - raise IncorrectState - - return self._depends_params - - @property - def logger_state(self) -> LoggerState: - if not self._logger_params: - raise IncorrectState - - return self._logger_params - - def __bool__(self) -> bool: - return False diff --git a/faststream/_internal/setup/__init__.py b/faststream/_internal/state/__init__.py similarity index 53% rename from faststream/_internal/setup/__init__.py rename to faststream/_internal/state/__init__.py index bd5d749560..f65fc1cb63 100644 --- a/faststream/_internal/setup/__init__.py +++ b/faststream/_internal/state/__init__.py @@ -1,17 +1,19 @@ -from .fast_depends import FastDependsData +from .broker import BrokerState, EmptyBrokerState +from .fast_depends import DIState from .logger import LoggerParamsStorage, LoggerState +from .pointer import Pointer from .proto import SetupAble -from .state import EmptyState, SetupState __all__ = ( - "EmptyState", + # state + "BrokerState", # FastDepend - "FastDependsData", + "DIState", + "EmptyBrokerState", "LoggerParamsStorage", # logging "LoggerState", + "Pointer", # proto "SetupAble", - # state - "SetupState", ) diff --git a/faststream/_internal/state/broker.py b/faststream/_internal/state/broker.py new file mode 100644 index 0000000000..920daeedec --- /dev/null +++ b/faststream/_internal/state/broker.py @@ -0,0 +1,80 @@ +from typing import TYPE_CHECKING, Optional, Protocol + +from faststream.exceptions import IncorrectState + +from .producer import ProducerUnset + +if TYPE_CHECKING: + from faststream._internal.publisher.proto import ProducerProto + + from .fast_depends import DIState + from .logger import LoggerState + + +class BrokerState(Protocol): + di_state: "DIState" + logger_state: "LoggerState" + producer: "ProducerProto" + + # Persistent variables + graceful_timeout: Optional[float] + + def _setup(self) -> None: ... + + def _setup_logger_state(self) -> None: ... + + def __bool__(self) -> bool: ... + + +class EmptyBrokerState(BrokerState): + def __init__(self, error_msg: str) -> None: + self.error_msg = error_msg + self.producer = ProducerUnset() + + @property + def di_state(self) -> "DIState": + raise IncorrectState(self.error_msg) + + @property + def logger_state(self) -> "DIState": + raise IncorrectState(self.error_msg) + + @property + def graceful_timeout(self) -> Optional[float]: + raise IncorrectState(self.error_msg) + + def _setup(self) -> None: + pass + + def _setup_logger_state(self) -> None: + pass + + def __bool__(self) -> bool: + return False + + +class InitialBrokerState(BrokerState): + def __init__( + self, + *, + di_state: "DIState", + logger_state: "LoggerState", + graceful_timeout: Optional[float], + producer: "ProducerProto", + ) -> None: + self.di_state = di_state + self.logger_state = logger_state + + self.graceful_timeout = graceful_timeout + self.producer = producer + + self.setupped = False + + def _setup(self) -> None: + self.setupped = True + + def _setup_logger_state(self) -> None: + self.logger_state._setup(context=self.di_state.context) + + def __bool__(self) -> bool: + return self.setupped diff --git a/faststream/_internal/setup/fast_depends.py b/faststream/_internal/state/fast_depends.py similarity index 55% rename from faststream/_internal/setup/fast_depends.py rename to faststream/_internal/state/fast_depends.py index ad5be38da2..a5e7a098ad 100644 --- a/faststream/_internal/setup/fast_depends.py +++ b/faststream/_internal/state/fast_depends.py @@ -2,6 +2,8 @@ from dataclasses import dataclass from typing import TYPE_CHECKING, Any, Callable, Optional +from faststream._internal.constants import EMPTY + if TYPE_CHECKING: from fast_depends import Provider from fast_depends.library.serializer import SerializerProto @@ -11,10 +13,26 @@ @dataclass -class FastDependsData: +class DIState: use_fastdepends: bool get_dependent: Optional[Callable[..., Any]] call_decorators: Sequence["Decorator"] provider: "Provider" serializer: Optional["SerializerProto"] context: "ContextRepo" + + def update( + self, + *, + provider: "Provider" = EMPTY, + serializer: Optional["SerializerProto"] = EMPTY, + context: "ContextRepo" = EMPTY, + ) -> None: + if provider is not EMPTY: + self.provider = provider + + if serializer is not EMPTY: + self.serializer = serializer + + if context is not EMPTY: + self.context = context diff --git a/faststream/_internal/state/logger/__init__.py b/faststream/_internal/state/logger/__init__.py new file mode 100644 index 0000000000..466e24c689 --- /dev/null +++ b/faststream/_internal/state/logger/__init__.py @@ -0,0 +1,9 @@ +from .params_storage import DefaultLoggerStorage, LoggerParamsStorage +from .state import LoggerState, make_logger_state + +__all__ = ( + "DefaultLoggerStorage", + "LoggerParamsStorage", + "LoggerState", + "make_logger_state", +) diff --git a/faststream/_internal/state/logger/logger_proxy.py b/faststream/_internal/state/logger/logger_proxy.py new file mode 100644 index 0000000000..a7ca07b920 --- /dev/null +++ b/faststream/_internal/state/logger/logger_proxy.py @@ -0,0 +1,102 @@ +from typing import TYPE_CHECKING, Optional, Protocol + +from faststream.exceptions import IncorrectState + +if TYPE_CHECKING: + from faststream._internal.basic_types import AnyDict, LoggerProto + + +class LoggerObject(Protocol): + logger: Optional["LoggerProto"] + + def __bool__(self) -> bool: ... + + def log( + self, + message: str, + log_level: int, + extra: Optional["AnyDict"] = None, + exc_info: Optional[Exception] = None, + ) -> None: ... + + +class NotSetLoggerObject(LoggerObject): + """Default logger proxy for state. + + Raises an error if user tries to log smth before state setup. + """ + + def __init__(self) -> None: + self.logger = None + + def __bool__(self) -> bool: + return False + + def __repr__(self) -> str: + return f"{self.__class__.__name__}()" + + def log( + self, + message: str, + log_level: int, + extra: Optional["AnyDict"] = None, + exc_info: Optional[Exception] = None, + ) -> None: + msg = "Logger object not set. Please, call `_setup_logger_state` of parent broker state." + raise IncorrectState(msg) + + +class EmptyLoggerObject(LoggerObject): + """Empty logger proxy for state. + + Will be used if user setup `logger=None`. + """ + + def __init__(self) -> None: + self.logger = None + + def __bool__(self) -> bool: + return True + + def __repr__(self) -> str: + return f"{self.__class__.__name__}()" + + def log( + self, + message: str, + log_level: int, + extra: Optional["AnyDict"] = None, + exc_info: Optional[Exception] = None, + ) -> None: + pass + + +class RealLoggerObject(LoggerObject): + """Empty logger proxy for state. + + Will be used if user setup custom `logger` (.params_storage.ManualLoggerStorage) + or in default logger case (.params_storage.DefaultLoggerStorage). + """ + + def __init__(self, logger: "LoggerProto") -> None: + self.logger = logger + + def __bool__(self) -> bool: + return True + + def __repr__(self) -> str: + return f"{self.__class__.__name__}(logger={self.logger})" + + def log( + self, + message: str, + log_level: int, + extra: Optional["AnyDict"] = None, + exc_info: Optional[Exception] = None, + ) -> None: + self.logger.log( + log_level, + message, + extra=extra, + exc_info=exc_info, + ) diff --git a/faststream/_internal/state/logger/params_storage.py b/faststream/_internal/state/logger/params_storage.py new file mode 100644 index 0000000000..6a37ec141e --- /dev/null +++ b/faststream/_internal/state/logger/params_storage.py @@ -0,0 +1,72 @@ +import warnings +from abc import abstractmethod +from typing import TYPE_CHECKING, Optional, Protocol + +from faststream._internal.constants import EMPTY + +if TYPE_CHECKING: + from faststream._internal.basic_types import AnyDict, LoggerProto + from faststream._internal.context import ContextRepo + + +def make_logger_storage( + logger: Optional["LoggerProto"], + log_fmt: Optional[str], + default_storage_cls: type["DefaultLoggerStorage"], +) -> "LoggerParamsStorage": + if logger is EMPTY: + return default_storage_cls(log_fmt) + + if log_fmt: + warnings.warn( + message="You can't set custom `logger` with `log_fmt` both.", + category=RuntimeWarning, + stacklevel=4, + ) + + return EmptyLoggerStorage() if logger is None else ManualLoggerStorage(logger) + + +class LoggerParamsStorage(Protocol): + def setup_log_contest(self, params: "AnyDict") -> None: ... + + def get_logger(self, *, context: "ContextRepo") -> Optional["LoggerProto"]: ... + + def set_level(self, level: int) -> None: ... + + +class EmptyLoggerStorage(LoggerParamsStorage): + def setup_log_contest(self, params: "AnyDict") -> None: + pass + + def get_logger(self, *, context: "ContextRepo") -> None: + return None + + def set_level(self, level: int) -> None: + pass + + +class ManualLoggerStorage(LoggerParamsStorage): + def __init__(self, logger: "LoggerProto") -> None: + self.__logger = logger + + def setup_log_contest(self, params: "AnyDict") -> None: + pass + + def get_logger(self, *, context: "ContextRepo") -> "LoggerProto": + return self.__logger + + def set_level(self, level: int) -> None: + """We shouldn't set custom logger level by CLI.""" + + +class DefaultLoggerStorage(LoggerParamsStorage): + def __init__(self, log_fmt: Optional[str]) -> None: + self._log_fmt = log_fmt + + @abstractmethod + def get_logger(self, *, context: "ContextRepo") -> "LoggerProto": + raise NotImplementedError + + def set_level(self, level: int) -> None: + raise NotImplementedError diff --git a/faststream/_internal/state/logger/state.py b/faststream/_internal/state/logger/state.py new file mode 100644 index 0000000000..132cedf7c5 --- /dev/null +++ b/faststream/_internal/state/logger/state.py @@ -0,0 +1,72 @@ +from typing import TYPE_CHECKING, Optional + +from faststream._internal.state.proto import SetupAble + +from .logger_proxy import ( + EmptyLoggerObject, + LoggerObject, + NotSetLoggerObject, + RealLoggerObject, +) +from .params_storage import LoggerParamsStorage, make_logger_storage + +if TYPE_CHECKING: + from faststream._internal.basic_types import AnyDict, LoggerProto + from faststream._internal.context import ContextRepo + + +def make_logger_state( + logger: Optional["LoggerProto"], + log_level: int, + log_fmt: Optional[str], + default_storage_cls: type["LoggerParamsStorage"], +) -> "LoggerState": + storage = make_logger_storage( + logger=logger, + log_fmt=log_fmt, + default_storage_cls=default_storage_cls, + ) + + return LoggerState( + log_level=log_level, + storage=storage, + ) + + +class LoggerState(SetupAble): + def __init__( + self, + log_level: int, + storage: LoggerParamsStorage, + ) -> None: + self.log_level = log_level + self.params_storage = storage + + self.logger: LoggerObject = NotSetLoggerObject() + + def __repr__(self) -> str: + return f"{self.__class__.__name__}(log_level={self.log_level}, logger={self.logger})" + + def set_level(self, level: int) -> None: + self.params_storage.set_level(level) + + def log( + self, + message: str, + log_level: Optional[int] = None, + extra: Optional["AnyDict"] = None, + exc_info: Optional[Exception] = None, + ) -> None: + self.logger.log( + log_level=(log_level or self.log_level), + message=message, + extra=extra, + exc_info=exc_info, + ) + + def _setup(self, *, context: "ContextRepo") -> None: + if not self.logger: + if logger := self.params_storage.get_logger(context=context): + self.logger = RealLoggerObject(logger) + else: + self.logger = EmptyLoggerObject() diff --git a/faststream/_internal/state/pointer.py b/faststream/_internal/state/pointer.py new file mode 100644 index 0000000000..68a41de65b --- /dev/null +++ b/faststream/_internal/state/pointer.py @@ -0,0 +1,19 @@ +from typing import Generic, TypeVar + +from typing_extensions import Self + +T = TypeVar("T") + + +class Pointer(Generic[T]): + __slots__ = ("__value",) + + def __init__(self, value: T) -> None: + self.__value = value + + def change(self, new_value: T) -> "Self": + self.__value = new_value + return self + + def get(self) -> T: + return self.__value diff --git a/faststream/_internal/state/producer.py b/faststream/_internal/state/producer.py new file mode 100644 index 0000000000..d65cd4f205 --- /dev/null +++ b/faststream/_internal/state/producer.py @@ -0,0 +1,29 @@ +from typing import TYPE_CHECKING, Any, Optional + +from faststream._internal.publisher.proto import ProducerProto +from faststream.exceptions import IncorrectState + +if TYPE_CHECKING: + from faststream._internal.types import AsyncCallable + from faststream.response import PublishCommand + + +class ProducerUnset(ProducerProto): + msg = "Producer is unset yet. You should set producer in broker initial method." + + @property + def _decoder(self) -> "AsyncCallable": + raise IncorrectState(self.msg) + + @property + def _parser(self) -> "AsyncCallable": + raise IncorrectState(self.msg) + + async def publish(self, cmd: "PublishCommand") -> Optional[Any]: + raise IncorrectState(self.msg) + + async def request(self, cmd: "PublishCommand") -> Any: + raise IncorrectState(self.msg) + + async def publish_batch(self, cmd: "PublishCommand") -> None: + raise IncorrectState(self.msg) diff --git a/faststream/_internal/setup/proto.py b/faststream/_internal/state/proto.py similarity index 100% rename from faststream/_internal/setup/proto.py rename to faststream/_internal/state/proto.py diff --git a/faststream/_internal/subscriber/call_item.py b/faststream/_internal/subscriber/call_item.py index e0d9d94255..3a172dd432 100644 --- a/faststream/_internal/subscriber/call_item.py +++ b/faststream/_internal/subscriber/call_item.py @@ -12,7 +12,7 @@ from typing_extensions import override -from faststream._internal.setup import SetupAble +from faststream._internal.state import SetupAble from faststream._internal.types import MsgType from faststream.exceptions import IgnoredException, SetupError @@ -20,7 +20,7 @@ from fast_depends.dependencies import Dependant from faststream._internal.basic_types import AsyncFuncAny, Decorator - from faststream._internal.setup import FastDependsData + from faststream._internal.state import DIState from faststream._internal.subscriber.call_wrapper.call import HandlerCallWrapper from faststream._internal.types import ( AsyncCallable, @@ -76,7 +76,7 @@ def _setup( # type: ignore[override] parser: "AsyncCallable", decoder: "AsyncCallable", broker_dependencies: Iterable["Dependant"], - fast_depends_state: "FastDependsData", + fast_depends_state: "DIState", _call_decorators: Iterable["Decorator"], ) -> None: if self.dependant is None: diff --git a/faststream/_internal/subscriber/call_wrapper/call.py b/faststream/_internal/subscriber/call_wrapper/call.py index ed2c3b839b..dcb93f8a42 100644 --- a/faststream/_internal/subscriber/call_wrapper/call.py +++ b/faststream/_internal/subscriber/call_wrapper/call.py @@ -28,7 +28,7 @@ from faststream._internal.basic_types import Decorator from faststream._internal.publisher.proto import PublisherProto - from faststream._internal.setup.fast_depends import FastDependsData + from faststream._internal.state.fast_depends import DIState from faststream.message import StreamMessage @@ -148,7 +148,7 @@ def set_wrapped( *, dependencies: Iterable["Dependant"], _call_decorators: Iterable["Decorator"], - state: "FastDependsData", + state: "DIState", ) -> Optional["CallModel"]: call = self._original_call for decor in _call_decorators: diff --git a/faststream/_internal/subscriber/proto.py b/faststream/_internal/subscriber/proto.py index 1b42548e7a..14e9e51f4c 100644 --- a/faststream/_internal/subscriber/proto.py +++ b/faststream/_internal/subscriber/proto.py @@ -12,12 +12,12 @@ if TYPE_CHECKING: from fast_depends.dependencies import Dependant - from faststream._internal.basic_types import AnyDict, LoggerProto + from faststream._internal.basic_types import AnyDict from faststream._internal.publisher.proto import ( BasePublisherProto, ProducerProto, ) - from faststream._internal.setup import SetupState + from faststream._internal.state import BrokerState from faststream._internal.subscriber.call_item import HandlerItem from faststream._internal.types import ( BrokerMiddleware, @@ -56,15 +56,12 @@ def get_log_context( def _setup( # type: ignore[override] self, *, - logger: Optional["LoggerProto"], - producer: Optional["ProducerProto"], - graceful_timeout: Optional[float], extra_context: "AnyDict", # broker options broker_parser: Optional["CustomCallable"], broker_decoder: Optional["CustomCallable"], # dependant args - state: "SetupState", + state: "BrokerState", ) -> None: ... @abstractmethod diff --git a/faststream/_internal/subscriber/usecase.py b/faststream/_internal/subscriber/usecase.py index 58ed1a8e2a..60ac9f1b83 100644 --- a/faststream/_internal/subscriber/usecase.py +++ b/faststream/_internal/subscriber/usecase.py @@ -35,13 +35,12 @@ if TYPE_CHECKING: from fast_depends.dependencies import Dependant - from faststream._internal.basic_types import AnyDict, Decorator, LoggerProto + from faststream._internal.basic_types import AnyDict, Decorator from faststream._internal.context.repository import ContextRepo from faststream._internal.publisher.proto import ( BasePublisherProto, - ProducerProto, ) - from faststream._internal.setup import SetupState + from faststream._internal.state import BrokerState from faststream._internal.types import ( AsyncCallable, BrokerMiddleware, @@ -120,8 +119,6 @@ def __init__( self._broker_middlewares = broker_middlewares # register in setup later - self._producer = None - self.graceful_timeout = None self.extra_context = {} self.extra_watcher_options = {} @@ -146,20 +143,15 @@ def add_middleware(self, middleware: "BrokerMiddleware[MsgType]") -> None: def _setup( # type: ignore[override] self, *, - logger: Optional["LoggerProto"], - producer: Optional["ProducerProto"], - graceful_timeout: Optional[float], extra_context: "AnyDict", # broker options broker_parser: Optional["CustomCallable"], broker_decoder: Optional["CustomCallable"], # dependant args - state: "SetupState", + state: "BrokerState", ) -> None: self._state = state - self._producer = producer - self.graceful_timeout = graceful_timeout self.extra_context = extra_context for call in self.calls: @@ -179,10 +171,10 @@ def _setup( # type: ignore[override] call._setup( parser=async_parser, decoder=async_decoder, - fast_depends_state=state.depends_params, + fast_depends_state=state.di_state, _call_decorators=( *self._call_decorators, - *state.depends_params.call_decorators, + *state.di_state.call_decorators, ), broker_dependencies=self._broker_dependencies, ) @@ -204,7 +196,7 @@ async def close(self) -> None: """ self.running = False if isinstance(self.lock, MultiLock): - await self.lock.wait_release(self.graceful_timeout) + await self.lock.wait_release(self._state.graceful_timeout) def add_call( self, @@ -311,7 +303,7 @@ async def consume(self, msg: MsgType) -> Any: # Stop handler at `exit()` call await self.close() - if app := self._state.depends_params.context.get("app"): + if app := self._state.di_state.context.get("app"): app.exit() except Exception: # nosec B110 @@ -320,12 +312,15 @@ async def consume(self, msg: MsgType) -> Any: async def process_message(self, msg: MsgType) -> "Response": """Execute all message processing stages.""" - context: ContextRepo = self._state.depends_params.context + context: ContextRepo = self._state.di_state.context async with AsyncExitStack() as stack: stack.enter_context(self.lock) # Enter context before middlewares + stack.enter_context( + context.scope("logger", self._state.logger_state.logger.logger) + ) for k, v in self.extra_context.items(): stack.enter_context(context.scope(k, v)) @@ -390,6 +385,7 @@ async def process_message(self, msg: MsgType) -> "Response": msg = f"There is no suitable handler for {msg=}" raise SubscriberNotFound(msg) + # An error was raised and processed by some middleware return ensure_response(None) diff --git a/faststream/_internal/testing/broker.py b/faststream/_internal/testing/broker.py index f074b55bbc..00468fa947 100644 --- a/faststream/_internal/testing/broker.py +++ b/faststream/_internal/testing/broker.py @@ -1,6 +1,6 @@ import warnings from abc import abstractmethod -from collections.abc import AsyncGenerator, Generator +from collections.abc import AsyncGenerator, Generator, Iterator from contextlib import asynccontextmanager, contextmanager from functools import partial from typing import ( @@ -14,6 +14,7 @@ from unittest.mock import MagicMock from faststream._internal.broker.broker import BrokerUsecase +from faststream._internal.state.logger.logger_proxy import RealLoggerObject from faststream._internal.subscriber.utils import MultiLock from faststream._internal.testing.app import TestApp from faststream._internal.testing.ast import is_contains_context_name @@ -68,8 +69,13 @@ async def __aenter__(self) -> Broker: self._ctx = self._create_ctx() return await self._ctx.__aenter__() - async def __aexit__(self, *args: object) -> None: - await self._ctx.__aexit__(*args) + async def __aexit__( + self, + exc_type: Optional[type[BaseException]] = None, + exc_val: Optional[BaseException] = None, + exc_tb: Optional["TracebackType"] = None, + ) -> None: + await self._ctx.__aexit__(exc_type, exc_val, exc_tb) @asynccontextmanager async def _create_ctx(self) -> AsyncGenerator[Broker, None]: @@ -88,6 +94,17 @@ async def _create_ctx(self) -> AsyncGenerator[Broker, None]: finally: self._fake_close(self.broker) + @contextmanager + def _patch_producer(self, broker: Broker) -> Iterator[None]: + raise NotImplementedError + + @contextmanager + def _patch_logger(self, broker: Broker) -> Iterator[None]: + old_logger = broker._state.logger_state.logger + broker._state.logger_state.logger = RealLoggerObject(MagicMock()) + yield + broker._state.logger_state.logger = old_logger + @contextmanager def _patch_broker(self, broker: Broker) -> Generator[None, None, None]: with ( @@ -110,11 +127,8 @@ def _patch_broker(self, broker: Broker) -> Generator[None, None, None]: "_connection", new=None, ), - mock.patch.object( - broker, - "_producer", - new=None, - ), + self._patch_producer(broker), + self._patch_logger(broker), mock.patch.object( broker, "ping", diff --git a/faststream/confluent/broker/broker.py b/faststream/confluent/broker/broker.py index b7853ad014..9f57f8217e 100644 --- a/faststream/confluent/broker/broker.py +++ b/faststream/confluent/broker/broker.py @@ -68,7 +68,7 @@ class KafkaBroker( ], ): url: list[str] - _producer: Optional[AsyncConfluentFastProducer] + _producer: AsyncConfluentFastProducer def __init__( self, @@ -398,9 +398,14 @@ def __init__( serializer=serializer, ) self.client_id = client_id - self._producer = None + self.config = ConfluentFastConfig(config) + self._state.producer = AsyncConfluentFastProducer( + parser=self._parser, + decoder=self._decoder, + ) + async def close( self, exc_type: Optional[type[BaseException]] = None, @@ -409,9 +414,7 @@ async def close( ) -> None: await super().close(exc_type, exc_val, exc_tb) - if self._producer is not None: # pragma: no branch - await self._producer.stop() - self._producer = None + await self._producer.disconnect() self._connection = None @@ -444,11 +447,7 @@ async def _connect( # type: ignore[override] config=self.config, ) - self._producer = AsyncConfluentFastProducer( - producer=native_producer, - parser=self._parser, - decoder=self._decoder, - ) + self._producer.connect(native_producer) return partial( AsyncConfluentConsumer, @@ -522,7 +521,7 @@ async def publish( # type: ignore[override] reply_to=reply_to, no_confirm=no_confirm, correlation_id=correlation_id or gen_cor_id(), - _publish_type=PublishType.Publish, + _publish_type=PublishType.PUBLISH, ) await super()._basic_publish(cmd, producer=self._producer) @@ -548,7 +547,7 @@ async def request( # type: ignore[override] headers=headers, timeout=timeout, correlation_id=correlation_id or gen_cor_id(), - _publish_type=PublishType.Request, + _publish_type=PublishType.REQUEST, ) msg: KafkaMessage = await super()._basic_request(cmd, producer=self._producer) @@ -574,7 +573,7 @@ async def publish_batch( reply_to=reply_to, no_confirm=no_confirm, correlation_id=correlation_id or gen_cor_id(), - _publish_type=PublishType.Publish, + _publish_type=PublishType.PUBLISH, ) await self._basic_publish_batch(cmd, producer=self._producer) @@ -584,14 +583,14 @@ async def ping(self, timeout: Optional[float]) -> bool: sleep_time = (timeout or 10) / 10 with anyio.move_on_after(timeout) as cancel_scope: - if self._producer is None: + if not self._producer: return False while True: if cancel_scope.cancel_called: return False - if await self._producer._producer.ping(timeout=timeout): + if await self._producer.ping(timeout=timeout): return True await anyio.sleep(sleep_time) diff --git a/faststream/confluent/broker/logging.py b/faststream/confluent/broker/logging.py index 9e64efca0e..b4523d2b40 100644 --- a/faststream/confluent/broker/logging.py +++ b/faststream/confluent/broker/logging.py @@ -1,8 +1,9 @@ +import logging from functools import partial from typing import TYPE_CHECKING, Optional from faststream._internal.log.logging import get_broker_logger -from faststream._internal.setup.logger import ( +from faststream._internal.state.logger import ( DefaultLoggerStorage, make_logger_state, ) @@ -22,6 +23,11 @@ def __init__( self._max_topic_len = 4 self._max_group_len = 0 + self.logger_log_level = logging.INFO + + def set_level(self, level: int) -> None: + self.logger_log_level = level + def setup_log_contest(self, params: "AnyDict") -> None: self._max_topic_len = max( ( @@ -60,10 +66,11 @@ def get_logger(self, *, context: "ContextRepo") -> Optional["LoggerProto"]: "- %(message)s", )), context=context, + log_level=self.logger_log_level, ) make_kafka_logger_state = partial( make_logger_state, - default_storag_cls=KafkaParamsStorage, + default_storage_cls=KafkaParamsStorage, ) diff --git a/faststream/confluent/broker/registrator.py b/faststream/confluent/broker/registrator.py index 7187c56a03..bf49f8b68a 100644 --- a/faststream/confluent/broker/registrator.py +++ b/faststream/confluent/broker/registrator.py @@ -1161,7 +1161,7 @@ def subscriber( # subscriber args ack_policy=ack_policy, no_reply=no_reply, - broker_middlewares=self._middlewares, + broker_middlewares=self.middlewares, broker_dependencies=self._dependencies, # Specification title_=title, @@ -1503,7 +1503,7 @@ def publisher( headers=headers, reply_to=reply_to, # publisher-specific - broker_middlewares=self._middlewares, + broker_middlewares=self.middlewares, middlewares=middlewares, # Specification title_=title, diff --git a/faststream/confluent/client.py b/faststream/confluent/client.py index 74a3bed571..32afc81c36 100644 --- a/faststream/confluent/client.py +++ b/faststream/confluent/client.py @@ -26,7 +26,7 @@ from typing_extensions import NotRequired, TypedDict from faststream._internal.basic_types import AnyDict, LoggerProto - from faststream._internal.setup.logger import LoggerState + from faststream._internal.state.logger import LoggerState class _SendKwargs(TypedDict): value: Optional[Union[str, bytes]] diff --git a/faststream/confluent/publisher/producer.py b/faststream/confluent/publisher/producer.py index fcb4328638..0aa22e9eba 100644 --- a/faststream/confluent/publisher/producer.py +++ b/faststream/confluent/publisher/producer.py @@ -8,6 +8,8 @@ from faststream.exceptions import FeatureNotSupportedException from faststream.message import encode_message +from .state import EmptyProducerState, ProducerState, RealProducer + if TYPE_CHECKING: from faststream._internal.types import CustomCallable from faststream.confluent.client import AsyncConfluentProducer @@ -19,19 +21,28 @@ class AsyncConfluentFastProducer(ProducerProto): def __init__( self, - producer: "AsyncConfluentProducer", parser: Optional["CustomCallable"], decoder: Optional["CustomCallable"], ) -> None: - self._producer = producer + self._producer: ProducerState = EmptyProducerState() # NOTE: register default parser to be compatible with request default = AsyncConfluentParser() self._parser = resolve_custom_func(parser, default.parse_message) self._decoder = resolve_custom_func(decoder, default.decode_message) - async def stop(self) -> None: + def connect(self, producer: "AsyncConfluentProducer") -> None: + self._producer = RealProducer(producer) + + async def disconnect(self) -> None: await self._producer.stop() + self._producer = EmptyProducerState() + + def __bool__(self) -> bool: + return bool(self._producer) + + async def ping(self, timeout: float) -> None: + return await self._producer.ping(timeout=timeout) @override async def publish( # type: ignore[override] @@ -46,7 +57,7 @@ async def publish( # type: ignore[override] **cmd.headers_to_publish(), } - await self._producer.send( + await self._producer.producer.send( topic=cmd.destination, value=message, key=cmd.key, @@ -61,7 +72,7 @@ async def publish_batch( cmd: "KafkaPublishCommand", ) -> None: """Publish a batch of messages to a topic.""" - batch = self._producer.create_batch() + batch = self._producer.producer.create_batch() headers_to_send = cmd.headers_to_publish() @@ -83,7 +94,7 @@ async def publish_batch( headers=[(i, j.encode()) for i, j in final_headers.items()], ) - await self._producer.send_batch( + await self._producer.producer.send_batch( batch, cmd.destination, partition=cmd.partition, diff --git a/faststream/confluent/publisher/state.py b/faststream/confluent/publisher/state.py new file mode 100644 index 0000000000..13f658903a --- /dev/null +++ b/faststream/confluent/publisher/state.py @@ -0,0 +1,50 @@ +from typing import TYPE_CHECKING, Protocol + +from faststream.exceptions import IncorrectState + +if TYPE_CHECKING: + from faststream.confluent.client import AsyncConfluentProducer + + +class ProducerState(Protocol): + producer: "AsyncConfluentProducer" + + def __bool__(self) -> bool: ... + + async def ping(self, timeout: float) -> bool: ... + + async def stop(self) -> None: ... + + +class EmptyProducerState(ProducerState): + __slots__ = () + + @property + def producer(self) -> "AsyncConfluentProducer": + msg = "You can't use producer here, please connect broker first." + raise IncorrectState(msg) + + async def ping(self, timeout: float) -> bool: + return False + + def __bool__(self) -> bool: + return False + + async def stop(self) -> None: + pass + + +class RealProducer(ProducerState): + __slots__ = ("producer",) + + def __init__(self, producer: "AsyncConfluentProducer") -> None: + self.producer = producer + + def __bool__(self) -> bool: + return True + + async def stop(self) -> None: + await self.producer.stop() + + async def ping(self, timeout: float) -> bool: + return await self.producer.ping(timeout=timeout) diff --git a/faststream/confluent/publisher/usecase.py b/faststream/confluent/publisher/usecase.py index c623bba944..1416632dc6 100644 --- a/faststream/confluent/publisher/usecase.py +++ b/faststream/confluent/publisher/usecase.py @@ -86,7 +86,7 @@ async def request( correlation_id=correlation_id or gen_cor_id(), timestamp_ms=timestamp_ms, timeout=timeout, - _publish_type=PublishType.Request, + _publish_type=PublishType.REQUEST, ) msg: KafkaMessage = await self._basic_request(cmd) @@ -152,7 +152,7 @@ async def publish( correlation_id=correlation_id or gen_cor_id(), timestamp_ms=timestamp_ms, no_confirm=no_confirm, - _publish_type=PublishType.Publish, + _publish_type=PublishType.PUBLISH, ) await self._basic_publish(cmd, _extra_middlewares=()) @@ -223,7 +223,7 @@ async def publish( correlation_id=correlation_id or gen_cor_id(), timestamp_ms=timestamp_ms, no_confirm=no_confirm, - _publish_type=PublishType.Publish, + _publish_type=PublishType.PUBLISH, ) await self._basic_publish_batch(cmd, _extra_middlewares=()) diff --git a/faststream/confluent/response.py b/faststream/confluent/response.py index 2a4f84e21a..2d487484f4 100644 --- a/faststream/confluent/response.py +++ b/faststream/confluent/response.py @@ -43,7 +43,7 @@ def as_publish_command(self) -> "KafkaPublishCommand": self.body, headers=self.headers, correlation_id=self.correlation_id, - _publish_type=PublishType.Reply, + _publish_type=PublishType.REPLY, # Kafka specific topic="", key=self.key, diff --git a/faststream/confluent/subscriber/usecase.py b/faststream/confluent/subscriber/usecase.py index e14e2903d2..c02b016b10 100644 --- a/faststream/confluent/subscriber/usecase.py +++ b/faststream/confluent/subscriber/usecase.py @@ -22,9 +22,9 @@ if TYPE_CHECKING: from fast_depends.dependencies import Dependant - from faststream._internal.basic_types import AnyDict, LoggerProto - from faststream._internal.publisher.proto import BasePublisherProto, ProducerProto - from faststream._internal.setup import SetupState + from faststream._internal.basic_types import AnyDict + from faststream._internal.publisher.proto import BasePublisherProto + from faststream._internal.state import BrokerState from faststream._internal.types import ( AsyncCallable, BrokerMiddleware, @@ -102,24 +102,18 @@ def _setup( # type: ignore[override] *, client_id: Optional[str], builder: Callable[..., "AsyncConfluentConsumer"], - # basic args - logger: Optional["LoggerProto"], - producer: Optional["ProducerProto"], - graceful_timeout: Optional[float], + # basic args, extra_context: "AnyDict", # broker options broker_parser: Optional["CustomCallable"], broker_decoder: Optional["CustomCallable"], # dependant args - state: "SetupState", + state: "BrokerState", ) -> None: self.client_id = client_id self.builder = builder super()._setup( - logger=logger, - producer=producer, - graceful_timeout=graceful_timeout, extra_context=extra_context, broker_parser=broker_parser, broker_decoder=broker_decoder, @@ -174,7 +168,7 @@ async def get_one( return await process_msg( msg=raw_message, middlewares=( - m(raw_message, context=self._state.depends_params.context) + m(raw_message, context=self._state.di_state.context) for m in self._broker_middlewares ), parser=self._parser, @@ -185,12 +179,9 @@ def _make_response_publisher( self, message: "StreamMessage[Any]", ) -> Sequence["BasePublisherProto"]: - if self._producer is None: - return () - return ( KafkaFakePublisher( - self._producer, + self._state.producer, topic=message.reply_to, ), ) diff --git a/faststream/confluent/testing.py b/faststream/confluent/testing.py index 27a81703e3..c254098d25 100644 --- a/faststream/confluent/testing.py +++ b/faststream/confluent/testing.py @@ -1,4 +1,5 @@ -from collections.abc import Generator, Iterable +from collections.abc import Generator, Iterable, Iterator +from contextlib import contextmanager from datetime import datetime, timezone from typing import ( TYPE_CHECKING, @@ -24,24 +25,30 @@ if TYPE_CHECKING: from faststream._internal.basic_types import SendableMessage - from faststream._internal.setup.logger import LoggerState from faststream.confluent.publisher.specified import SpecificationPublisher from faststream.confluent.response import KafkaPublishCommand from faststream.confluent.subscriber.usecase import LogicSubscriber + __all__ = ("TestKafkaBroker",) class TestKafkaBroker(TestBroker[KafkaBroker]): """A class to test Kafka brokers.""" + @contextmanager + def _patch_producer(self, broker: KafkaBroker) -> Iterator[None]: + old_producer = broker._state.producer + broker._state.producer = FakeProducer(broker) + yield + broker._state.producer = old_producer + @staticmethod async def _fake_connect( # type: ignore[override] broker: KafkaBroker, *args: Any, **kwargs: Any, ) -> Callable[..., AsyncMock]: - broker._producer = FakeProducer(broker) return _fake_connection @staticmethod @@ -99,8 +106,11 @@ def __init__(self, broker: KafkaBroker) -> None: self._parser = resolve_custom_func(broker._parser, default.parse_message) self._decoder = resolve_custom_func(broker._decoder, default.decode_message) - def _setup(self, logger_stater: "LoggerState") -> None: - pass + def __bool__(self) -> bool: + return True + + async def ping(self, timeout: float) -> None: + return True @override async def publish( # type: ignore[override] diff --git a/faststream/kafka/broker/broker.py b/faststream/kafka/broker/broker.py index ad50958ace..0c03172e93 100644 --- a/faststream/kafka/broker/broker.py +++ b/faststream/kafka/broker/broker.py @@ -238,7 +238,7 @@ class KafkaBroker( ], ): url: list[str] - _producer: Optional["AioKafkaFastProducer"] + _producer: "AioKafkaFastProducer" def __init__( self, @@ -580,7 +580,10 @@ def __init__( ) self.client_id = client_id - self._producer = None + self._state.producer = AioKafkaFastProducer( + parser=self._parser, + decoder=self._decoder, + ) async def close( self, @@ -590,9 +593,7 @@ async def close( ) -> None: await super().close(exc_type, exc_val, exc_tb) - if self._producer is not None: # pragma: no branch - await self._producer.stop() - self._producer = None + await self._producer.disconnect() self._connection = None @@ -635,12 +636,7 @@ async def _connect( # type: ignore[override] client_id=client_id, ) - await producer.start() - self._producer = AioKafkaFastProducer( - producer=producer, - parser=self._parser, - decoder=self._decoder, - ) + await self._producer.connect(producer) return partial( aiokafka.AIOKafkaConsumer, @@ -742,7 +738,7 @@ async def publish( # type: ignore[override] reply_to=reply_to, no_confirm=no_confirm, correlation_id=correlation_id or gen_cor_id(), - _publish_type=PublishType.Publish, + _publish_type=PublishType.PUBLISH, ) await super()._basic_publish(cmd, producer=self._producer) @@ -815,7 +811,7 @@ async def request( # type: ignore[override] headers=headers, timeout=timeout, correlation_id=correlation_id or gen_cor_id(), - _publish_type=PublishType.Request, + _publish_type=PublishType.REQUEST, ) msg: KafkaMessage = await super()._basic_request(cmd, producer=self._producer) @@ -880,7 +876,7 @@ async def publish_batch( reply_to=reply_to, no_confirm=no_confirm, correlation_id=correlation_id or gen_cor_id(), - _publish_type=PublishType.Publish, + _publish_type=PublishType.PUBLISH, ) await self._basic_publish_batch(cmd, producer=self._producer) @@ -890,14 +886,14 @@ async def ping(self, timeout: Optional[float]) -> bool: sleep_time = (timeout or 10) / 10 with anyio.move_on_after(timeout) as cancel_scope: - if self._producer is None: + if not self._producer: return False while True: if cancel_scope.cancel_called: return False - if not self._producer._producer._closed: + if not self._producer.closed: return True await anyio.sleep(sleep_time) diff --git a/faststream/kafka/broker/logging.py b/faststream/kafka/broker/logging.py index 9518a4f7ec..72a1420325 100644 --- a/faststream/kafka/broker/logging.py +++ b/faststream/kafka/broker/logging.py @@ -1,8 +1,9 @@ +import logging from functools import partial from typing import TYPE_CHECKING, Optional from faststream._internal.log.logging import get_broker_logger -from faststream._internal.setup.logger import ( +from faststream._internal.state.logger import ( DefaultLoggerStorage, make_logger_state, ) @@ -22,6 +23,11 @@ def __init__( self._max_topic_len = 4 self._max_group_len = 0 + self.logger_log_level = logging.INFO + + def set_level(self, level: int) -> None: + self.logger_log_level = level + def setup_log_contest(self, params: "AnyDict") -> None: self._max_topic_len = max( ( @@ -60,10 +66,11 @@ def get_logger(self, *, context: "ContextRepo") -> Optional["LoggerProto"]: "- %(message)s", )), context=context, + log_level=self.logger_log_level, ) make_kafka_logger_state = partial( make_logger_state, - default_storag_cls=KafkaParamsStorage, + default_storage_cls=KafkaParamsStorage, ) diff --git a/faststream/kafka/broker/registrator.py b/faststream/kafka/broker/registrator.py index 76cb4ec77b..bd2c4bd735 100644 --- a/faststream/kafka/broker/registrator.py +++ b/faststream/kafka/broker/registrator.py @@ -1563,7 +1563,7 @@ def subscriber( # subscriber args ack_policy=ack_policy, no_reply=no_reply, - broker_middlewares=self._middlewares, + broker_middlewares=self.middlewares, broker_dependencies=self._dependencies, # Specification title_=title, @@ -1906,7 +1906,7 @@ def publisher( headers=headers, reply_to=reply_to, # publisher-specific - broker_middlewares=self._middlewares, + broker_middlewares=self.middlewares, middlewares=middlewares, # Specification title_=title, diff --git a/faststream/kafka/publisher/producer.py b/faststream/kafka/publisher/producer.py index 661d899118..eba2276e6b 100644 --- a/faststream/kafka/publisher/producer.py +++ b/faststream/kafka/publisher/producer.py @@ -9,6 +9,8 @@ from faststream.kafka.parser import AioKafkaParser from faststream.message import encode_message +from .state import EmptyProducerState, ProducerState, RealProducer + if TYPE_CHECKING: from aiokafka import AIOKafkaProducer @@ -21,22 +23,34 @@ class AioKafkaFastProducer(ProducerProto): def __init__( self, - producer: "AIOKafkaProducer", parser: Optional["CustomCallable"], decoder: Optional["CustomCallable"], ) -> None: - self._producer = producer + self._producer: ProducerState = EmptyProducerState() # NOTE: register default parser to be compatible with request default = AioKafkaParser( msg_class=KafkaMessage, regex=None, ) + self._parser = resolve_custom_func(parser, default.parse_message) self._decoder = resolve_custom_func(decoder, default.decode_message) - async def stop(self) -> None: + async def connect(self, producer: "AIOKafkaProducer") -> None: + await producer.start() + self._producer = RealProducer(producer) + + async def disconnect(self) -> None: await self._producer.stop() + self._producer = EmptyProducerState() + + def __bool__(self) -> None: + return bool(self._producer) + + @property + def closed(self) -> bool: + return self._producer.closed @override async def publish( # type: ignore[override] @@ -51,7 +65,7 @@ async def publish( # type: ignore[override] **cmd.headers_to_publish(), } - send_future = await self._producer.send( + send_future = await self._producer.producer.send( topic=cmd.destination, value=message, key=cmd.key, @@ -68,7 +82,7 @@ async def publish_batch( cmd: "KafkaPublishCommand", ) -> None: """Publish a batch of messages to a topic.""" - batch = self._producer.create_batch() + batch = self._producer.producer.create_batch() headers_to_send = cmd.headers_to_publish() @@ -90,7 +104,7 @@ async def publish_batch( headers=[(i, j.encode()) for i, j in final_headers.items()], ) - send_future = await self._producer.send_batch( + send_future = await self._producer.producer.send_batch( batch, cmd.destination, partition=cmd.partition, diff --git a/faststream/kafka/publisher/state.py b/faststream/kafka/publisher/state.py new file mode 100644 index 0000000000..3094cf02c1 --- /dev/null +++ b/faststream/kafka/publisher/state.py @@ -0,0 +1,49 @@ +from typing import TYPE_CHECKING, Protocol + +from faststream.exceptions import IncorrectState + +if TYPE_CHECKING: + from aiokafka import AIOKafkaProducer + + +class ProducerState(Protocol): + producer: "AIOKafkaProducer" + closed: bool + + def __bool__(self) -> bool: ... + + async def stop(self) -> None: ... + + +class EmptyProducerState(ProducerState): + __slots__ = () + + closed = True + + @property + def producer(self) -> "AIOKafkaProducer": + msg = "You can't use producer here, please connect broker first." + raise IncorrectState(msg) + + def __bool__(self) -> bool: + return False + + async def stop(self) -> None: + pass + + +class RealProducer(ProducerState): + __slots__ = ("producer",) + + def __init__(self, producer: "AIOKafkaProducer") -> None: + self.producer = producer + + def __bool__(self) -> bool: + return True + + async def stop(self) -> None: + await self.producer.stop() + + @property + def closed(self) -> bool: + return self.producer._closed or False diff --git a/faststream/kafka/publisher/usecase.py b/faststream/kafka/publisher/usecase.py index 495d539cea..7174237e49 100644 --- a/faststream/kafka/publisher/usecase.py +++ b/faststream/kafka/publisher/usecase.py @@ -135,7 +135,7 @@ async def request( correlation_id=correlation_id or gen_cor_id(), timestamp_ms=timestamp_ms, timeout=timeout, - _publish_type=PublishType.Request, + _publish_type=PublishType.REQUEST, ) msg: KafkaMessage = await self._basic_request(cmd) @@ -251,7 +251,7 @@ async def publish( correlation_id=correlation_id or gen_cor_id(), timestamp_ms=timestamp_ms, no_confirm=no_confirm, - _publish_type=PublishType.Publish, + _publish_type=PublishType.PUBLISH, ) await self._basic_publish(cmd, _extra_middlewares=()) @@ -406,7 +406,7 @@ async def publish( correlation_id=correlation_id or gen_cor_id(), timestamp_ms=timestamp_ms, no_confirm=no_confirm, - _publish_type=PublishType.Publish, + _publish_type=PublishType.PUBLISH, ) await self._basic_publish_batch(cmd, _extra_middlewares=()) diff --git a/faststream/kafka/response.py b/faststream/kafka/response.py index ac3cd1019d..4f1b46dc3e 100644 --- a/faststream/kafka/response.py +++ b/faststream/kafka/response.py @@ -35,7 +35,7 @@ def as_publish_command(self) -> "KafkaPublishCommand": self.body, headers=self.headers, correlation_id=self.correlation_id, - _publish_type=PublishType.Reply, + _publish_type=PublishType.REPLY, # Kafka specific topic="", key=self.key, diff --git a/faststream/kafka/subscriber/usecase.py b/faststream/kafka/subscriber/usecase.py index f3cf9c2122..f622ad6b9d 100644 --- a/faststream/kafka/subscriber/usecase.py +++ b/faststream/kafka/subscriber/usecase.py @@ -32,9 +32,9 @@ from aiokafka.abc import ConsumerRebalanceListener from fast_depends.dependencies import Dependant - from faststream._internal.basic_types import AnyDict, LoggerProto - from faststream._internal.publisher.proto import BasePublisherProto, ProducerProto - from faststream._internal.setup import SetupState + from faststream._internal.basic_types import AnyDict + from faststream._internal.publisher.proto import BasePublisherProto + from faststream._internal.state import BrokerState from faststream.message import StreamMessage from faststream.middlewares import AckPolicy @@ -110,23 +110,17 @@ def _setup( # type: ignore[override] client_id: Optional[str], builder: Callable[..., "AIOKafkaConsumer"], # basic args - logger: Optional["LoggerProto"], - producer: Optional["ProducerProto"], - graceful_timeout: Optional[float], extra_context: "AnyDict", # broker options broker_parser: Optional["CustomCallable"], broker_decoder: Optional["CustomCallable"], # dependant args - state: "SetupState", + state: "BrokerState", ) -> None: self.client_id = client_id self.builder = builder super()._setup( - logger=logger, - producer=producer, - graceful_timeout=graceful_timeout, extra_context=extra_context, broker_parser=broker_parser, broker_decoder=broker_decoder, @@ -197,7 +191,7 @@ async def get_one( msg: StreamMessage[MsgType] = await process_msg( msg=raw_message, middlewares=( - m(raw_message, context=self._state.depends_params.context) + m(raw_message, context=self._state.di_state.context) for m in self._broker_middlewares ), parser=self._parser, @@ -209,12 +203,9 @@ def _make_response_publisher( self, message: "StreamMessage[Any]", ) -> Sequence["BasePublisherProto"]: - if self._producer is None: - return () - return ( KafkaFakePublisher( - self._producer, + self._state.producer, topic=message.reply_to, ), ) diff --git a/faststream/kafka/testing.py b/faststream/kafka/testing.py index a73e18ade8..90c097eac1 100755 --- a/faststream/kafka/testing.py +++ b/faststream/kafka/testing.py @@ -1,5 +1,6 @@ import re -from collections.abc import Generator, Iterable +from collections.abc import Generator, Iterable, Iterator +from contextlib import contextmanager from datetime import datetime, timezone from typing import ( TYPE_CHECKING, @@ -37,13 +38,19 @@ class TestKafkaBroker(TestBroker[KafkaBroker]): """A class to test Kafka brokers.""" + @contextmanager + def _patch_producer(self, broker: KafkaBroker) -> Iterator[None]: + old_producer = broker._state.producer + broker._state.producer = FakeProducer(broker) + yield + broker._state.producer = old_producer + @staticmethod async def _fake_connect( # type: ignore[override] broker: KafkaBroker, *args: Any, **kwargs: Any, ) -> Callable[..., AsyncMock]: - broker._producer = FakeProducer(broker) return _fake_connection @staticmethod @@ -97,6 +104,13 @@ def __init__(self, broker: KafkaBroker) -> None: self._parser = resolve_custom_func(broker._parser, default.parse_message) self._decoder = resolve_custom_func(broker._decoder, default.decode_message) + def __bool__(self) -> None: + return True + + @property + def closed(self) -> bool: + return False + @override async def publish( # type: ignore[override] self, diff --git a/faststream/middlewares/logging.py b/faststream/middlewares/logging.py index f0eeffbe4d..2fa5987a0e 100644 --- a/faststream/middlewares/logging.py +++ b/faststream/middlewares/logging.py @@ -11,7 +11,7 @@ from faststream._internal.basic_types import AsyncFuncAny from faststream._internal.context.repository import ContextRepo - from faststream._internal.setup.logger import LoggerState + from faststream._internal.state.logger import LoggerState from faststream.message import StreamMessage diff --git a/faststream/nats/broker/broker.py b/faststream/nats/broker/broker.py index 4aa6812c6a..72e9687580 100644 --- a/faststream/nats/broker/broker.py +++ b/faststream/nats/broker/broker.py @@ -68,7 +68,6 @@ LoggerProto, SendableMessage, ) - from faststream._internal.publisher.proto import ProducerProto from faststream._internal.types import ( BrokerMiddleware, CustomCallable, @@ -547,9 +546,9 @@ def __init__( _call_decorators=_call_decorators, ) - self._producer = NatsFastProducer( - decoder=self._decoder, + self._state.producer = NatsFastProducer( parser=self._parser, + decoder=self._decoder, ) self._js_producer = NatsJSFastProducer( @@ -590,7 +589,7 @@ async def _connect(self, **kwargs: Any) -> "Client": stream = connection.jetstream() - self._producer.connect(connection) + self._state.producer.connect(connection) self._js_producer.connect(stream) self._kv_declarer.connect(stream) @@ -612,7 +611,7 @@ async def close( await self._connection.drain() self._connection = None - self._producer.disconnect() + self._state.producer.disconnect() self._js_producer.disconnect() self._kv_declarer.disconnect() self._os_declarer.disconnect() @@ -730,11 +729,10 @@ async def publish( # type: ignore[override] reply_to=reply_to, stream=stream, timeout=timeout, - _publish_type=PublishType.Publish, + _publish_type=PublishType.PUBLISH, ) - producer: Optional[ProducerProto] - producer = self._producer if stream is None else self._js_producer + producer = self._state.producer if stream is None else self._js_producer await super()._basic_publish(cmd, producer=producer) @@ -785,11 +783,10 @@ async def request( # type: ignore[override] headers=headers, timeout=timeout, stream=stream, - _publish_type=PublishType.Request, + _publish_type=PublishType.REQUEST, ) - producer: Optional[ProducerProto] - producer = self._producer if stream is None else self._js_producer + producer = self._state.producer if stream is None else self._js_producer msg: NatsMessage = await super()._basic_request(cmd, producer=producer) return msg @@ -811,7 +808,9 @@ def setup_publisher( # type: ignore[override] self, publisher: "SpecificationPublisher", ) -> None: - producer = self._producer if publisher.stream is None else self._js_producer + producer = ( + self._state.producer if publisher.stream is None else self._js_producer + ) super().setup_publisher(publisher, producer=producer) diff --git a/faststream/nats/broker/logging.py b/faststream/nats/broker/logging.py index 0238e2208d..d67cb8e4bf 100644 --- a/faststream/nats/broker/logging.py +++ b/faststream/nats/broker/logging.py @@ -1,8 +1,9 @@ +import logging from functools import partial from typing import TYPE_CHECKING, Optional from faststream._internal.log.logging import get_broker_logger -from faststream._internal.setup.logger import ( +from faststream._internal.state.logger import ( DefaultLoggerStorage, make_logger_state, ) @@ -23,6 +24,11 @@ def __init__( self._max_stream_len = 0 self._max_subject_len = 4 + self.logger_log_level = logging.INFO + + def set_level(self, level: int) -> None: + self.logger_log_level = level + def setup_log_contest(self, params: "AnyDict") -> None: self._max_subject_len = max( ( @@ -69,10 +75,11 @@ def get_logger(self, *, context: "ContextRepo") -> Optional["LoggerProto"]: "%(message)s", )), context=context, + log_level=self.logger_log_level, ) make_nats_logger_state = partial( make_logger_state, - default_storag_cls=NatsParamsStorage, + default_storage_cls=NatsParamsStorage, ) diff --git a/faststream/nats/broker/registrator.py b/faststream/nats/broker/registrator.py index f8feacb294..1473890702 100644 --- a/faststream/nats/broker/registrator.py +++ b/faststream/nats/broker/registrator.py @@ -221,7 +221,7 @@ def subscriber( # type: ignore[override] # subscriber args ack_policy=ack_policy, no_reply=no_reply, - broker_middlewares=self._middlewares, + broker_middlewares=self.middlewares, broker_dependencies=self._dependencies, # AsyncAPI title_=title, @@ -320,7 +320,7 @@ def publisher( # type: ignore[override] timeout=timeout, stream=stream, # Specific - broker_middlewares=self._middlewares, + broker_middlewares=self.middlewares, middlewares=middlewares, # AsyncAPI title_=title, diff --git a/faststream/nats/publisher/producer.py b/faststream/nats/publisher/producer.py index 62245c2c7c..a90bf89ff0 100644 --- a/faststream/nats/publisher/producer.py +++ b/faststream/nats/publisher/producer.py @@ -37,7 +37,6 @@ class NatsFastProducer(ProducerProto): def __init__( self, - *, parser: Optional["CustomCallable"], decoder: Optional["CustomCallable"], ) -> None: diff --git a/faststream/nats/publisher/usecase.py b/faststream/nats/publisher/usecase.py index 880479546c..b2ca2b3c3e 100644 --- a/faststream/nats/publisher/usecase.py +++ b/faststream/nats/publisher/usecase.py @@ -27,7 +27,7 @@ class LogicPublisher(PublisherUsecase[Msg]): """A class to represent a NATS publisher.""" - _producer: Union["NatsFastProducer", "NatsJSFastProducer", None] + _producer: Union["NatsFastProducer", "NatsJSFastProducer"] def __init__( self, @@ -100,7 +100,7 @@ async def publish( correlation_id=correlation_id or gen_cor_id(), stream=stream or getattr(self.stream, "name", None), timeout=timeout or self.timeout, - _publish_type=PublishType.Publish, + _publish_type=PublishType.PUBLISH, ) return await self._basic_publish(cmd, _extra_middlewares=()) @@ -165,7 +165,7 @@ async def request( timeout=timeout or self.timeout, correlation_id=correlation_id or gen_cor_id(), stream=getattr(self.stream, "name", None), - _publish_type=PublishType.Request, + _publish_type=PublishType.REQUEST, ) msg: NatsMessage = await self._basic_request(cmd) diff --git a/faststream/nats/response.py b/faststream/nats/response.py index a6fcee1961..40289436f5 100644 --- a/faststream/nats/response.py +++ b/faststream/nats/response.py @@ -31,7 +31,7 @@ def as_publish_command(self) -> "NatsPublishCommand": message=self.body, headers=self.headers, correlation_id=self.correlation_id, - _publish_type=PublishType.Reply, + _publish_type=PublishType.REPLY, # Nats specific subject="", stream=self.stream, diff --git a/faststream/nats/subscriber/usecase.py b/faststream/nats/subscriber/usecase.py index 2c1e35cd56..b04c5cc6d0 100644 --- a/faststream/nats/subscriber/usecase.py +++ b/faststream/nats/subscriber/usecase.py @@ -49,11 +49,10 @@ from faststream._internal.basic_types import ( AnyDict, - LoggerProto, SendableMessage, ) from faststream._internal.publisher.proto import BasePublisherProto, ProducerProto - from faststream._internal.setup import SetupState + from faststream._internal.state import BrokerState as BasicState from faststream._internal.types import ( AsyncCallable, BrokerMiddleware, @@ -124,15 +123,12 @@ def _setup( # type: ignore[override] os_declarer: "OSBucketDeclarer", kv_declarer: "KVBucketDeclarer", # basic args - logger: Optional["LoggerProto"], - producer: Optional["ProducerProto"], - graceful_timeout: Optional[float], extra_context: "AnyDict", # broker options broker_parser: Optional["CustomCallable"], broker_decoder: Optional["CustomCallable"], # dependant args - state: "SetupState", + state: "BasicState", ) -> None: self._connection_state = ConnectedSubscriberState( parent_state=connection_state, @@ -141,9 +137,6 @@ def _setup( # type: ignore[override] ) super()._setup( - logger=logger, - producer=producer, - graceful_timeout=graceful_timeout, extra_context=extra_context, broker_parser=broker_parser, broker_decoder=broker_decoder, @@ -265,12 +258,9 @@ def _make_response_publisher( message: "StreamMessage[Any]", ) -> Iterable["BasePublisherProto"]: """Create Publisher objects to use it as one of `publishers` in `self.consume` scope.""" - if self._producer is None: - return () - return ( NatsFakePublisher( - producer=self._producer, + producer=self._state.producer, subject=message.reply_to, ), ) @@ -360,7 +350,7 @@ async def get_one( msg: NatsMessage = await process_msg( # type: ignore[assignment] msg=raw_message, middlewares=( - m(raw_message, context=self._state.depends_params.context) + m(raw_message, context=self._state.di_state.context) for m in self._broker_middlewares ), parser=self._parser, @@ -552,7 +542,7 @@ async def get_one( msg: NatsMessage = await process_msg( # type: ignore[assignment] msg=raw_message, middlewares=( - m(raw_message, context=self._state.depends_params.context) + m(raw_message, context=self._state.di_state.context) for m in self._broker_middlewares ), parser=self._parser, @@ -864,7 +854,7 @@ async def get_one( await process_msg( msg=raw_message, middlewares=( - m(raw_message, context=self._state.depends_params.context) + m(raw_message, context=self._state.di_state.context) for m in self._broker_middlewares ), parser=self._parser, @@ -979,7 +969,7 @@ async def get_one( msg: NatsKvMessage = await process_msg( msg=raw_message, middlewares=( - m(raw_message, context=self._state.depends_params.context) + m(raw_message, context=self._state.di_state.context) for m in self._broker_middlewares ), parser=self._parser, @@ -1133,7 +1123,7 @@ async def get_one( msg: NatsObjMessage = await process_msg( msg=raw_message, middlewares=( - m(raw_message, context=self._state.depends_params.context) + m(raw_message, context=self._state.di_state.context) for m in self._broker_middlewares ), parser=self._parser, @@ -1174,7 +1164,7 @@ async def __consume_watch(self) -> None: ) if message: - with self._state.depends_params.context.scope( + with self._state.di_state.context.scope( OBJECT_STORAGE_CONTEXT_KEY, self.bucket ): await self.consume(message) diff --git a/faststream/nats/testing.py b/faststream/nats/testing.py index d709554993..c91fd5529b 100644 --- a/faststream/nats/testing.py +++ b/faststream/nats/testing.py @@ -1,4 +1,5 @@ -from collections.abc import Generator, Iterable +from collections.abc import Generator, Iterable, Iterator +from contextlib import contextmanager from typing import ( TYPE_CHECKING, Any, @@ -54,16 +55,20 @@ def create_publisher_fake_subscriber( return sub, is_real - @staticmethod - async def _fake_connect( # type: ignore[override] + @contextmanager + def _patch_producer(self, broker: NatsBroker) -> Iterator[None]: + old_js_producer, old_producer = broker._js_producer, broker._state.producer + broker._js_producer = broker._state.producer = FakeProducer(broker) + yield + broker._js_producer, broker._state.producer = old_js_producer, old_producer + + async def _fake_connect( + self, broker: NatsBroker, *args: Any, **kwargs: Any, ) -> AsyncMock: broker._connection_state = ConnectedState(AsyncMock(), AsyncMock()) - broker._js_producer = broker._producer = FakeProducer( # type: ignore[assignment] - broker, - ) return AsyncMock() diff --git a/faststream/prometheus/middleware.py b/faststream/prometheus/middleware.py index ffdea49d4f..d61dc42b0c 100644 --- a/faststream/prometheus/middleware.py +++ b/faststream/prometheus/middleware.py @@ -165,7 +165,7 @@ async def publish_scope( call_next: "AsyncFunc", cmd: "PublishCommand", ) -> Any: - if self._settings_provider is None or cmd.publish_type is PublishType.Reply: + if self._settings_provider is None or cmd.publish_type is PublishType.REPLY: return await call_next(cmd) destination_name = ( diff --git a/faststream/rabbit/broker/broker.py b/faststream/rabbit/broker/broker.py index 49286ea81b..7ba92c36c1 100644 --- a/faststream/rabbit/broker/broker.py +++ b/faststream/rabbit/broker/broker.py @@ -18,7 +18,6 @@ from faststream.__about__ import SERVICE_NAME from faststream._internal.broker.broker import BrokerUsecase from faststream._internal.constants import EMPTY -from faststream.exceptions import NOT_CONNECTED_YET from faststream.message import gen_cor_id from faststream.rabbit.helpers.declarer import RabbitDeclarer from faststream.rabbit.publisher.producer import AioPikaFastProducer @@ -69,9 +68,10 @@ class RabbitBroker( """A class to represent a RabbitMQ broker.""" url: str - _producer: Optional["AioPikaFastProducer"] - declarer: Optional[RabbitDeclarer] + _producer: "AioPikaFastProducer" + declarer: RabbitDeclarer + _channel: Optional["RobustChannel"] def __init__( @@ -290,7 +290,13 @@ def __init__( self.app_id = app_id self._channel = None - self.declarer = None + + declarer = self.declarer = RabbitDeclarer() + self._state.producer = AioPikaFastProducer( + declarer=declarer, + decoder=self._decoder, + parser=self._parser, + ) @property def _subscriber_setup_extra(self) -> "AnyDict": @@ -461,18 +467,14 @@ async def _connect( # type: ignore[override] ), ) - declarer = self.declarer = RabbitDeclarer(channel) - await declarer.declare_queue(RABBIT_REPLY) - - self._producer = AioPikaFastProducer( - declarer=declarer, - decoder=self._decoder, - parser=self._parser, - ) - if self._max_consumers: await channel.set_qos(prefetch_count=int(self._max_consumers)) + self.declarer.connect(connection=connection, channel=channel) + await self.declarer.declare_queue(RABBIT_REPLY) + + self._producer.connect() + return connection async def close( @@ -493,25 +495,23 @@ async def close( await self._connection.close() self._connection = None - self.declarer = None - self._producer = None + self.declarer.disconnect() + self._producer.disconnect() async def start(self) -> None: """Connect broker to RabbitMQ and startup all subscribers.""" await self.connect() self._setup() - if self._max_consumers: - self._state.logger_state.log(f"Set max consumers to {self._max_consumers}") - - assert self.declarer, NOT_CONNECTED_YET # nosec B101 - for publisher in self._publishers: if publisher.exchange is not None: await self.declare_exchange(publisher.exchange) await super().start() + if self._max_consumers: + self._state.logger_state.log(f"Set max consumers to {self._max_consumers}") + @override async def publish( # type: ignore[override] self, @@ -639,7 +639,7 @@ async def publish( # type: ignore[override] user_id=user_id, timeout=timeout, priority=priority, - _publish_type=PublishType.Publish, + _publish_type=PublishType.PUBLISH, ) return await super()._basic_publish(cmd, producer=self._producer) @@ -757,7 +757,7 @@ async def request( # type: ignore[override] user_id=user_id, timeout=timeout, priority=priority, - _publish_type=PublishType.Request, + _publish_type=PublishType.REQUEST, ) msg: RabbitMessage = await super()._basic_request(cmd, producer=self._producer) @@ -771,7 +771,6 @@ async def declare_queue( ], ) -> "RobustQueue": """Declares queue object in **RabbitMQ**.""" - assert self.declarer, NOT_CONNECTED_YET # nosec B101 return await self.declarer.declare_queue(queue) async def declare_exchange( @@ -782,7 +781,6 @@ async def declare_exchange( ], ) -> "RobustExchange": """Declares exchange object in **RabbitMQ**.""" - assert self.declarer, NOT_CONNECTED_YET # nosec B101 return await self.declarer.declare_exchange(exchange) @override diff --git a/faststream/rabbit/broker/logging.py b/faststream/rabbit/broker/logging.py index 1d1451cca2..21b0172004 100644 --- a/faststream/rabbit/broker/logging.py +++ b/faststream/rabbit/broker/logging.py @@ -1,8 +1,9 @@ +import logging from functools import partial from typing import TYPE_CHECKING, Optional from faststream._internal.log.logging import get_broker_logger -from faststream._internal.setup.logger import ( +from faststream._internal.state.logger import ( DefaultLoggerStorage, make_logger_state, ) @@ -22,6 +23,11 @@ def __init__( self._max_exchange_len = 4 self._max_queue_len = 4 + self.logger_log_level = logging.INFO + + def set_level(self, level: int) -> None: + self.logger_log_level = level + def setup_log_contest(self, params: "AnyDict") -> None: self._max_exchange_len = max( self._max_exchange_len, @@ -52,10 +58,11 @@ def get_logger(self, *, context: "ContextRepo") -> "LoggerProto": "- %(message)s" ), context=context, + log_level=self.logger_log_level, ) make_rabbit_logger_state = partial( make_logger_state, - default_storag_cls=RabbitParamsStorage, + default_storage_cls=RabbitParamsStorage, ) diff --git a/faststream/rabbit/broker/registrator.py b/faststream/rabbit/broker/registrator.py index 117aafc1de..e3e861124c 100644 --- a/faststream/rabbit/broker/registrator.py +++ b/faststream/rabbit/broker/registrator.py @@ -112,7 +112,7 @@ def subscriber( # type: ignore[override] # subscriber args ack_policy=ack_policy, no_reply=no_reply, - broker_middlewares=self._middlewares, + broker_middlewares=self.middlewares, broker_dependencies=self._dependencies, # AsyncAPI title_=title, @@ -269,7 +269,7 @@ def publisher( # type: ignore[override] exchange=RabbitExchange.validate(exchange), message_kwargs=message_kwargs, # Specific - broker_middlewares=self._middlewares, + broker_middlewares=self.middlewares, middlewares=middlewares, # AsyncAPI title_=title, diff --git a/faststream/rabbit/helpers/declarer.py b/faststream/rabbit/helpers/declarer.py index b7bf52165c..dc890617d0 100644 --- a/faststream/rabbit/helpers/declarer.py +++ b/faststream/rabbit/helpers/declarer.py @@ -1,5 +1,7 @@ from typing import TYPE_CHECKING, cast +from .state import ConnectedState, ConnectionState, EmptyConnectionState + if TYPE_CHECKING: import aio_pika @@ -9,12 +11,22 @@ class RabbitDeclarer: """An utility class to declare RabbitMQ queues and exchanges.""" - __channel: "aio_pika.RobustChannel" - __queues: dict["RabbitQueue", "aio_pika.RobustQueue"] - __exchanges: dict["RabbitExchange", "aio_pika.RobustExchange"] + def __init__(self) -> None: + self.__queues: dict[RabbitQueue, aio_pika.RobustQueue] = {} + self.__exchanges: dict[RabbitExchange, aio_pika.RobustExchange] = {} + + self.__connection: ConnectionState = EmptyConnectionState() + + def __repr__(self) -> str: + return f"{self.__class__.__name__}(<{self.__connection.__class__.__name__}>, queues={list(self.__queues.keys())}, exchanges={list(self.__exchanges.keys())})" + + def connect( + self, connection: "aio_pika.RobustConnection", channel: "aio_pika.RobustChannel" + ) -> None: + self.__connection = ConnectedState(connection=connection, channel=channel) - def __init__(self, channel: "aio_pika.RobustChannel") -> None: - self.__channel = channel + def disconnect(self) -> None: + self.__connection = EmptyConnectionState() self.__queues = {} self.__exchanges = {} @@ -27,7 +39,7 @@ async def declare_queue( if (q := self.__queues.get(queue)) is None: self.__queues[queue] = q = cast( "aio_pika.RobustQueue", - await self.__channel.declare_queue( + await self.__connection.channel.declare_queue( name=queue.name, durable=queue.durable, exclusive=queue.exclusive, @@ -48,12 +60,12 @@ async def declare_exchange( ) -> "aio_pika.RobustExchange": """Declare an exchange, parent exchanges and bind them each other.""" if not exchange.name: - return self.__channel.default_exchange + return self.__connection.channel.default_exchange if (exch := self.__exchanges.get(exchange)) is None: self.__exchanges[exchange] = exch = cast( "aio_pika.RobustExchange", - await self.__channel.declare_exchange( + await self.__connection.channel.declare_exchange( name=exchange.name, type=exchange.type.value, durable=exchange.durable, diff --git a/faststream/rabbit/helpers/state.py b/faststream/rabbit/helpers/state.py new file mode 100644 index 0000000000..182b588557 --- /dev/null +++ b/faststream/rabbit/helpers/state.py @@ -0,0 +1,35 @@ +from typing import TYPE_CHECKING, Protocol + +from faststream.exceptions import IncorrectState + +if TYPE_CHECKING: + from aio_pika import RobustChannel, RobustConnection + + +class ConnectionState(Protocol): + connection: "RobustConnection" + channel: "RobustChannel" + + +class EmptyConnectionState(ConnectionState): + __slots__ = () + + error_msg = "You should connect broker first." + + @property + def connection(self) -> "RobustConnection": + raise IncorrectState(self.error_msg) + + @property + def channel(self) -> "RobustChannel": + raise IncorrectState(self.error_msg) + + +class ConnectedState(ConnectionState): + __slots__ = ("channel", "connection") + + def __init__( + self, connection: "RobustConnection", channel: "RobustChannel" + ) -> None: + self.connection = connection + self.channel = channel diff --git a/faststream/rabbit/publisher/producer.py b/faststream/rabbit/publisher/producer.py index ec509842a3..55fe050c19 100644 --- a/faststream/rabbit/publisher/producer.py +++ b/faststream/rabbit/publisher/producer.py @@ -1,6 +1,7 @@ from typing import ( TYPE_CHECKING, Optional, + Protocol, cast, ) @@ -9,7 +10,7 @@ from faststream._internal.publisher.proto import ProducerProto from faststream._internal.subscriber.utils import resolve_custom_func -from faststream.exceptions import FeatureNotSupportedException +from faststream.exceptions import FeatureNotSupportedException, IncorrectState from faststream.rabbit.parser import AioPikaParser from faststream.rabbit.schemas import RABBIT_REPLY, RabbitExchange @@ -30,6 +31,26 @@ from faststream.rabbit.types import AioPikaSendableMessage +class LockState(Protocol): + lock: "anyio.Lock" + + +class LockUnset(LockState): + __slots__ = () + + @property + def lock(self) -> "anyio.Lock": + msg = "You should call `producer.connect()` method at first." + raise IncorrectState(msg) + + +class RealLock(LockState): + __slots__ = ("lock",) + + def __init__(self) -> None: + self.lock = anyio.Lock() + + class AioPikaFastProducer(ProducerProto): """A class for fast producing messages using aio-pika.""" @@ -45,12 +66,22 @@ def __init__( ) -> None: self.declarer = declarer - self._rpc_lock = anyio.Lock() + self.__lock: LockState = LockUnset() default_parser = AioPikaParser() self._parser = resolve_custom_func(parser, default_parser.parse_message) self._decoder = resolve_custom_func(decoder, default_parser.decode_message) + def connect(self) -> None: + """Lock initialization. + + Should be called in async context due `anyio.Lock` object can't be created outside event loop. + """ + self.__lock = RealLock() + + def disconnect(self) -> None: + self.__lock = LockUnset() + @override async def publish( # type: ignore[override] self, @@ -75,7 +106,7 @@ async def request( # type: ignore[override] ) -> "IncomingMessage": """Publish a message to a RabbitMQ queue.""" async with _RPCCallback( - self._rpc_lock, + self.__lock.lock, await self.declarer.declare_queue(RABBIT_REPLY), ) as response_queue: with anyio.fail_after(cmd.timeout): diff --git a/faststream/rabbit/publisher/usecase.py b/faststream/rabbit/publisher/usecase.py index 71a357576f..bc24c1af48 100644 --- a/faststream/rabbit/publisher/usecase.py +++ b/faststream/rabbit/publisher/usecase.py @@ -23,7 +23,7 @@ if TYPE_CHECKING: import aiormq - from faststream._internal.setup import SetupState + from faststream._internal.state import BrokerState from faststream._internal.types import BrokerMiddleware, PublisherMiddleware from faststream.rabbit.message import RabbitMessage from faststream.rabbit.publisher.producer import AioPikaFastProducer @@ -108,7 +108,7 @@ def _setup( # type: ignore[override] producer: Optional["AioPikaFastProducer"], app_id: Optional[str], virtual_host: str, - state: "SetupState", + state: "BrokerState", ) -> None: if app_id: self.message_options["app_id"] = app_id @@ -167,7 +167,7 @@ async def publish( exchange=RabbitExchange.validate(exchange or self.exchange), correlation_id=correlation_id or gen_cor_id(), headers=headers, - _publish_type=PublishType.Publish, + _publish_type=PublishType.PUBLISH, **(self.publish_options | self.message_options | publish_kwargs), ) @@ -242,7 +242,7 @@ async def request( exchange=RabbitExchange.validate(exchange or self.exchange), correlation_id=correlation_id or gen_cor_id(), headers=headers, - _publish_type=PublishType.Publish, + _publish_type=PublishType.PUBLISH, **(self.publish_options | self.message_options | publish_kwargs), ) diff --git a/faststream/rabbit/response.py b/faststream/rabbit/response.py index 560a45bb57..9bac3f6417 100644 --- a/faststream/rabbit/response.py +++ b/faststream/rabbit/response.py @@ -45,7 +45,7 @@ def as_publish_command(self) -> "RabbitPublishCommand": message=self.body, headers=self.headers, correlation_id=self.correlation_id, - _publish_type=PublishType.Reply, + _publish_type=PublishType.REPLY, # RMQ specific routing_key="", **self.publish_options, diff --git a/faststream/rabbit/schemas/exchange.py b/faststream/rabbit/schemas/exchange.py index a95f78bba8..af146f78b0 100644 --- a/faststream/rabbit/schemas/exchange.py +++ b/faststream/rabbit/schemas/exchange.py @@ -28,6 +28,14 @@ class RabbitExchange(NameRequired): "type", ) + def __repr__(self) -> str: + if self.passive: + body = "" + else: + body = f", robust={self.robust}, durable={self.durable}, auto_delete={self.auto_delete})" + + return f"{self.__class__.__name__}({self.name}, type={self.type}, routing_key='{self.routing}'{body})" + def __hash__(self) -> int: """Supports hash to store real objects in declarer.""" return sum( diff --git a/faststream/rabbit/schemas/queue.py b/faststream/rabbit/schemas/queue.py index 6a26a64dba..35f9955750 100644 --- a/faststream/rabbit/schemas/queue.py +++ b/faststream/rabbit/schemas/queue.py @@ -34,6 +34,14 @@ class RabbitQueue(NameRequired): "timeout", ) + def __repr__(self) -> str: + if self.passive: + body = "" + else: + body = f", robust={self.robust}, durable={self.durable}, exclusive={self.exclusive}, auto_delete={self.auto_delete})" + + return f"{self.__class__.__name__}({self.name}, routing_key='{self.routing}'{body})" + def __hash__(self) -> int: """Supports hash to store real objects in declarer.""" return sum( diff --git a/faststream/rabbit/subscriber/usecase.py b/faststream/rabbit/subscriber/usecase.py index 119938afb5..8bad07afad 100644 --- a/faststream/rabbit/subscriber/usecase.py +++ b/faststream/rabbit/subscriber/usecase.py @@ -20,9 +20,9 @@ from aio_pika import IncomingMessage, RobustQueue from fast_depends.dependencies import Dependant - from faststream._internal.basic_types import AnyDict, LoggerProto + from faststream._internal.basic_types import AnyDict from faststream._internal.publisher.proto import BasePublisherProto - from faststream._internal.setup import SetupState + from faststream._internal.state import BrokerState from faststream._internal.types import BrokerMiddleware, CustomCallable from faststream.message import StreamMessage from faststream.rabbit.helpers.declarer import RabbitDeclarer @@ -100,24 +100,18 @@ def _setup( # type: ignore[override] virtual_host: str, declarer: "RabbitDeclarer", # basic args - logger: Optional["LoggerProto"], - producer: Optional["AioPikaFastProducer"], - graceful_timeout: Optional[float], extra_context: "AnyDict", # broker options broker_parser: Optional["CustomCallable"], broker_decoder: Optional["CustomCallable"], # dependant args - state: "SetupState", + state: "BrokerState", ) -> None: self.app_id = app_id self.virtual_host = virtual_host self.declarer = declarer super()._setup( - logger=logger, - producer=producer, - graceful_timeout=graceful_timeout, extra_context=extra_context, broker_parser=broker_parser, broker_decoder=broker_decoder, @@ -173,6 +167,7 @@ async def get_one( self, *, timeout: float = 5.0, + # TODO: make it no_ack ack_policy: AckPolicy = AckPolicy.REJECT_ON_ERROR, ) -> "Optional[RabbitMessage]": assert self._queue_obj, "You should start subscriber at first." # nosec B101 @@ -197,7 +192,7 @@ async def get_one( msg: Optional[RabbitMessage] = await process_msg( # type: ignore[assignment] msg=raw_message, middlewares=( - m(raw_message, context=self._state.depends_params.context) + m(raw_message, context=self._state.di_state.context) for m in self._broker_middlewares ), parser=self._parser, @@ -209,12 +204,9 @@ def _make_response_publisher( self, message: "StreamMessage[Any]", ) -> Sequence["BasePublisherProto"]: - if self._producer is None: - return () - return ( RabbitFakePublisher( - self._producer, + self._state.producer, routing_key=message.reply_to, app_id=self.app_id, ), diff --git a/faststream/rabbit/testing.py b/faststream/rabbit/testing.py index 97472fa5fe..3aa50e6dc5 100644 --- a/faststream/rabbit/testing.py +++ b/faststream/rabbit/testing.py @@ -1,4 +1,4 @@ -from collections.abc import Generator, Mapping +from collections.abc import Generator, Iterator, Mapping from contextlib import contextmanager from typing import TYPE_CHECKING, Any, Optional, Union from unittest import mock @@ -56,9 +56,16 @@ def _patch_broker(self, broker: "RabbitBroker") -> Generator[None, None, None]: ): yield + @contextmanager + def _patch_producer(self, broker: RabbitBroker) -> Iterator[None]: + old_producer = broker._state.producer + broker._state.producer = FakeProducer(broker) + yield + broker._state.producer = old_producer + @staticmethod async def _fake_connect(broker: "RabbitBroker", *args: Any, **kwargs: Any) -> None: - broker._producer = FakeProducer(broker) + pass @staticmethod def create_publisher_fake_subscriber( diff --git a/faststream/redis/broker/broker.py b/faststream/redis/broker/broker.py index edfc5774c6..c1982d6236 100644 --- a/faststream/redis/broker/broker.py +++ b/faststream/redis/broker/broker.py @@ -90,7 +90,7 @@ class RedisBroker( """Redis broker.""" url: str - _producer: Optional[RedisFastProducer] + _producer: "RedisFastProducer" def __init__( self, @@ -193,8 +193,6 @@ def __init__( Doc("Any custom decorator to apply to wrapped functions."), ] = (), ) -> None: - self._producer = None - if specification_url is None: specification_url = url @@ -250,6 +248,11 @@ def __init__( _call_decorators=_call_decorators, ) + self._state.producer = RedisFastProducer( + parser=self._parser, + decoder=self._decoder, + ) + @override async def connect( # type: ignore[override] self, @@ -328,11 +331,7 @@ async def _connect( # type: ignore[override] ) client: Redis[bytes] = Redis.from_pool(pool) # type: ignore[attr-defined] - self._producer = RedisFastProducer( - connection=client, - parser=self._parser, - decoder=self._decoder, - ) + self._producer.connect(client) return client async def close( @@ -343,6 +342,8 @@ async def close( ) -> None: await super().close(exc_type, exc_val, exc_tb) + self._producer.disconnect() + if self._connection is not None: await self._connection.aclose() # type: ignore[attr-defined] self._connection = None @@ -418,7 +419,7 @@ async def publish( # type: ignore[override] maxlen=maxlen, reply_to=reply_to, headers=headers, - _publish_type=PublishType.Publish, + _publish_type=PublishType.PUBLISH, ) await super()._basic_publish(cmd, producer=self._producer) @@ -444,7 +445,7 @@ async def request( # type: ignore[override] maxlen=maxlen, headers=headers, timeout=timeout, - _publish_type=PublishType.Request, + _publish_type=PublishType.REQUEST, ) msg: RedisMessage = await super()._basic_request(cmd, producer=self._producer) return msg @@ -482,7 +483,7 @@ async def publish_batch( reply_to=reply_to, headers=headers, correlation_id=correlation_id or gen_cor_id(), - _publish_type=PublishType.Publish, + _publish_type=PublishType.PUBLISH, ) await self._basic_publish_batch(cmd, producer=self._producer) diff --git a/faststream/redis/broker/logging.py b/faststream/redis/broker/logging.py index 3855efbdf8..6fe8f718ae 100644 --- a/faststream/redis/broker/logging.py +++ b/faststream/redis/broker/logging.py @@ -1,8 +1,9 @@ +import logging from functools import partial from typing import TYPE_CHECKING, Optional from faststream._internal.log.logging import get_broker_logger -from faststream._internal.setup.logger import ( +from faststream._internal.state.logger import ( DefaultLoggerStorage, make_logger_state, ) @@ -21,6 +22,11 @@ def __init__( self._max_channel_name = 4 + self.logger_log_level = logging.INFO + + def set_level(self, level: int) -> None: + self.logger_log_level = level + def setup_log_contest(self, params: "AnyDict") -> None: self._max_channel_name = max( ( @@ -47,10 +53,11 @@ def get_logger(self, *, context: "ContextRepo") -> Optional["LoggerProto"]: "- %(message)s" ), context=context, + log_level=self.logger_log_level, ) make_redis_logger_state = partial( make_logger_state, - default_storag_cls=RedisParamsStorage, + default_storage_cls=RedisParamsStorage, ) diff --git a/faststream/redis/broker/registrator.py b/faststream/redis/broker/registrator.py index 1599a10d46..598105ef9b 100644 --- a/faststream/redis/broker/registrator.py +++ b/faststream/redis/broker/registrator.py @@ -103,7 +103,7 @@ def subscriber( # type: ignore[override] # subscriber args ack_policy=ack_policy, no_reply=no_reply, - broker_middlewares=self._middlewares, + broker_middlewares=self.middlewares, broker_dependencies=self._dependencies, # AsyncAPI title_=title, @@ -189,7 +189,7 @@ def publisher( # type: ignore[override] headers=headers, reply_to=reply_to, # Specific - broker_middlewares=self._middlewares, + broker_middlewares=self.middlewares, middlewares=middlewares, # AsyncAPI title_=title, diff --git a/faststream/redis/helpers/__init__.py b/faststream/redis/helpers/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/faststream/redis/helpers/state.py b/faststream/redis/helpers/state.py new file mode 100644 index 0000000000..1d3d2a6bad --- /dev/null +++ b/faststream/redis/helpers/state.py @@ -0,0 +1,27 @@ +from typing import TYPE_CHECKING, Protocol + +from faststream.exceptions import IncorrectState + +if TYPE_CHECKING: + from redis.asyncio.client import Redis + + +class ConnectionState(Protocol): + client: "Redis[bytes]" + + +class EmptyConnectionState(ConnectionState): + __slots__ = () + + error_msg = "You should connect broker first." + + @property + def client(self) -> "Redis[bytes]": + raise IncorrectState(self.error_msg) + + +class ConnectedState(ConnectionState): + __slots__ = ("client",) + + def __init__(self, client: "Redis[bytes]") -> None: + self.client = client diff --git a/faststream/redis/publisher/producer.py b/faststream/redis/publisher/producer.py index 57afef2d31..fe6c050202 100644 --- a/faststream/redis/publisher/producer.py +++ b/faststream/redis/publisher/producer.py @@ -6,6 +6,11 @@ from faststream._internal.publisher.proto import ProducerProto from faststream._internal.subscriber.utils import resolve_custom_func from faststream._internal.utils.nuid import NUID +from faststream.redis.helpers.state import ( + ConnectedState, + ConnectionState, + EmptyConnectionState, +) from faststream.redis.message import DATA_KEY from faststream.redis.parser import RawMessage, RedisPubSubParser from faststream.redis.response import DestinationType, RedisPublishCommand @@ -22,17 +27,15 @@ class RedisFastProducer(ProducerProto): """A class to represent a Redis producer.""" - _connection: "Redis[bytes]" _decoder: "AsyncCallable" _parser: "AsyncCallable" def __init__( self, - connection: "Redis[bytes]", parser: Optional["CustomCallable"], decoder: Optional["CustomCallable"], ) -> None: - self._connection = connection + self._connection: ConnectionState = EmptyConnectionState() default = RedisPubSubParser() self._parser = resolve_custom_func( @@ -44,6 +47,12 @@ def __init__( default.decode_message, ) + def connect(self, client: "Redis[bytes]") -> None: + self._connection = ConnectedState(client) + + def disconnect(self) -> None: + self._connection = EmptyConnectionState() + @override async def publish( # type: ignore[override] self, @@ -65,7 +74,7 @@ async def request( # type: ignore[override] ) -> "Any": nuid = NUID() reply_to = str(nuid.next(), "utf-8") - psub = self._connection.pubsub() + psub = self._connection.client.pubsub() await psub.subscribe(reply_to) msg = RawMessage.encode( @@ -112,15 +121,15 @@ async def publish_batch( ) for msg in cmd.batch_bodies ] - await self._connection.rpush(cmd.destination, *batch) + await self._connection.client.rpush(cmd.destination, *batch) async def __publish(self, msg: bytes, cmd: "RedisPublishCommand") -> None: if cmd.destination_type is DestinationType.Channel: - await self._connection.publish(cmd.destination, msg) + await self._connection.client.publish(cmd.destination, msg) elif cmd.destination_type is DestinationType.List: - await self._connection.rpush(cmd.destination, msg) + await self._connection.client.rpush(cmd.destination, msg) elif cmd.destination_type is DestinationType.Stream: - await self._connection.xadd( + await self._connection.client.xadd( name=cmd.destination, fields={DATA_KEY: msg}, maxlen=cmd.maxlen, diff --git a/faststream/redis/publisher/usecase.py b/faststream/redis/publisher/usecase.py index 34e6f934c6..09c1fae294 100644 --- a/faststream/redis/publisher/usecase.py +++ b/faststream/redis/publisher/usecase.py @@ -134,7 +134,7 @@ async def publish( reply_to=reply_to or self.reply_to, headers=self.headers | (headers or {}), correlation_id=correlation_id or gen_cor_id(), - _publish_type=PublishType.Publish, + _publish_type=PublishType.PUBLISH, ) await self._basic_publish(cmd, _extra_middlewares=()) @@ -188,7 +188,7 @@ async def request( channel=channel or self.channel.name, headers=self.headers | (headers or {}), correlation_id=correlation_id or gen_cor_id(), - _publish_type=PublishType.Request, + _publish_type=PublishType.REQUEST, timeout=timeout, ) @@ -271,7 +271,7 @@ async def publish( reply_to=reply_to or self.reply_to, headers=self.headers | (headers or {}), correlation_id=correlation_id or gen_cor_id(), - _publish_type=PublishType.Publish, + _publish_type=PublishType.PUBLISH, ) return await self._basic_publish(cmd, _extra_middlewares=()) @@ -326,7 +326,7 @@ async def request( list=list or self.list.name, headers=self.headers | (headers or {}), correlation_id=correlation_id or gen_cor_id(), - _publish_type=PublishType.Request, + _publish_type=PublishType.REQUEST, timeout=timeout, ) @@ -368,7 +368,7 @@ async def publish( # type: ignore[override] reply_to=reply_to or self.reply_to, headers=self.headers | (headers or {}), correlation_id=correlation_id or gen_cor_id(), - _publish_type=PublishType.Publish, + _publish_type=PublishType.PUBLISH, ) await self._basic_publish_batch(cmd, _extra_middlewares=()) @@ -475,7 +475,7 @@ async def publish( headers=self.headers | (headers or {}), correlation_id=correlation_id or gen_cor_id(), maxlen=maxlen or self.stream.maxlen, - _publish_type=PublishType.Publish, + _publish_type=PublishType.PUBLISH, ) return await self._basic_publish(cmd, _extra_middlewares=()) @@ -538,7 +538,7 @@ async def request( stream=stream or self.stream.name, headers=self.headers | (headers or {}), correlation_id=correlation_id or gen_cor_id(), - _publish_type=PublishType.Request, + _publish_type=PublishType.REQUEST, maxlen=maxlen or self.stream.maxlen, timeout=timeout, ) diff --git a/faststream/redis/response.py b/faststream/redis/response.py index a0b830b6c9..6328dbbd28 100644 --- a/faststream/redis/response.py +++ b/faststream/redis/response.py @@ -41,7 +41,7 @@ def as_publish_command(self) -> "RedisPublishCommand": self.body, headers=self.headers, correlation_id=self.correlation_id, - _publish_type=PublishType.Reply, + _publish_type=PublishType.REPLY, # Kafka specific channel="fake-channel", # it will be replaced by reply-sender maxlen=self.maxlen, diff --git a/faststream/redis/subscriber/usecase.py b/faststream/redis/subscriber/usecase.py index 995fc70454..9c8ca4ddd5 100644 --- a/faststream/redis/subscriber/usecase.py +++ b/faststream/redis/subscriber/usecase.py @@ -45,9 +45,9 @@ if TYPE_CHECKING: from fast_depends.dependencies import Dependant - from faststream._internal.basic_types import AnyDict, LoggerProto - from faststream._internal.publisher.proto import BasePublisherProto, ProducerProto - from faststream._internal.setup import SetupState + from faststream._internal.basic_types import AnyDict + from faststream._internal.publisher.proto import BasePublisherProto + from faststream._internal.state import BrokerState from faststream._internal.types import ( AsyncCallable, BrokerMiddleware, @@ -104,22 +104,16 @@ def _setup( # type: ignore[override] *, connection: Optional["Redis[bytes]"], # basic args - logger: Optional["LoggerProto"], - producer: Optional["ProducerProto"], - graceful_timeout: Optional[float], extra_context: "AnyDict", # broker options broker_parser: Optional["CustomCallable"], broker_decoder: Optional["CustomCallable"], # dependant args - state: "SetupState", + state: "BrokerState", ) -> None: self._client = connection super()._setup( - logger=logger, - producer=producer, - graceful_timeout=graceful_timeout, extra_context=extra_context, broker_parser=broker_parser, broker_decoder=broker_decoder, @@ -130,12 +124,9 @@ def _make_response_publisher( self, message: "BrokerStreamMessage[UnifyRedisDict]", ) -> Sequence["BasePublisherProto"]: - if self._producer is None: - return () - return ( RedisFakePublisher( - self._producer, + self._state.producer, channel=message.reply_to, ), ) @@ -296,7 +287,7 @@ async def get_one( # type: ignore[override] msg: Optional[RedisMessage] = await process_msg( # type: ignore[assignment] msg=raw_message, middlewares=( - m(raw_message, context=self._state.depends_params.context) + m(raw_message, context=self._state.di_state.context) for m in self._broker_middlewares ), parser=self._parser, @@ -423,7 +414,7 @@ async def get_one( # type: ignore[override] msg: RedisListMessage = await process_msg( # type: ignore[assignment] msg=redis_incoming_msg, middlewares=( - m(redis_incoming_msg, context=self._state.depends_params.context) + m(redis_incoming_msg, context=self._state.di_state.context) for m in self._broker_middlewares ), parser=self._parser, @@ -711,7 +702,7 @@ async def get_one( # type: ignore[override] msg: RedisStreamMessage = await process_msg( # type: ignore[assignment] msg=redis_incoming_msg, middlewares=( - m(redis_incoming_msg, context=self._state.depends_params.context) + m(redis_incoming_msg, context=self._state.di_state.context) for m in self._broker_middlewares ), parser=self._parser, diff --git a/faststream/redis/testing.py b/faststream/redis/testing.py index 2237af768d..e3584fbcb0 100644 --- a/faststream/redis/testing.py +++ b/faststream/redis/testing.py @@ -1,5 +1,6 @@ import re -from collections.abc import Sequence +from collections.abc import Iterator, Sequence +from contextlib import contextmanager from typing import ( TYPE_CHECKING, Any, @@ -72,13 +73,19 @@ def create_publisher_fake_subscriber( return sub, is_real + @contextmanager + def _patch_producer(self, broker: RedisBroker) -> Iterator[None]: + old_producer = broker._state.producer + broker._state.producer = FakeProducer(broker) + yield + broker._state.producer = old_producer + @staticmethod async def _fake_connect( # type: ignore[override] broker: RedisBroker, *args: Any, **kwargs: Any, ) -> AsyncMock: - broker._producer = FakeProducer(broker) connection = MagicMock() pub_sub = AsyncMock() diff --git a/faststream/response/publish_type.py b/faststream/response/publish_type.py index b837b91632..ad74910a1e 100644 --- a/faststream/response/publish_type.py +++ b/faststream/response/publish_type.py @@ -2,11 +2,11 @@ class PublishType(str, Enum): - Publish = "Publish" + PUBLISH = "PUBLISH" """Regular `broker/publisher.publish(...)` call.""" - Reply = "Reply" + REPLY = "REPLY" """Response to RPC/Reply-To request.""" - Request = "Request" + REQUEST = "REQUEST" """RPC request call.""" diff --git a/faststream/response/response.py b/faststream/response/response.py index 09136c8a28..ff44643f35 100644 --- a/faststream/response/response.py +++ b/faststream/response/response.py @@ -24,7 +24,7 @@ def as_publish_command(self) -> "PublishCommand": body=self.body, headers=self.headers, correlation_id=self.correlation_id, - _publish_type=PublishType.Reply, + _publish_type=PublishType.REPLY, ) diff --git a/tests/asgi/testcase.py b/tests/asgi/testcase.py index 20f4ed6fc7..438bd60d49 100644 --- a/tests/asgi/testcase.py +++ b/tests/asgi/testcase.py @@ -49,7 +49,7 @@ def test_asgi_ping_unhealthy(self) -> None: with TestClient(app) as client: response = client.get("/health") - assert response.status_code == 500 + assert response.status_code == 500, response.status_code @pytest.mark.asyncio() async def test_asgi_ping_healthy(self) -> None: diff --git a/tests/brokers/base/router.py b/tests/brokers/base/router.py index 1f50340fb9..92ffbb3269 100644 --- a/tests/brokers/base/router.py +++ b/tests/brokers/base/router.py @@ -448,7 +448,7 @@ def subscriber() -> None: ... sub = next(iter(pub_broker._subscribers)) publisher = next(iter(pub_broker._publishers)) assert len((*sub._broker_middlewares, *sub.calls[0].item_middlewares)) == 5 - assert len((*publisher._broker_middlewares, *publisher._middlewares)) == 4 + assert len((*publisher._broker_middlewares, *publisher.middlewares)) == 4 async def test_router_include_with_middlewares( self, @@ -473,7 +473,7 @@ def subscriber() -> None: ... sub_middlewares = (*sub._broker_middlewares, *sub.calls[0].item_middlewares) assert len(sub_middlewares) == 5, sub_middlewares - assert len((*publisher._broker_middlewares, *publisher._middlewares)) == 4 + assert len((*publisher._broker_middlewares, *publisher.middlewares)) == 4 async def test_router_parser( self, diff --git a/tests/brokers/base/testclient.py b/tests/brokers/base/testclient.py index 6326eacdbb..bd342fcb1f 100644 --- a/tests/brokers/base/testclient.py +++ b/tests/brokers/base/testclient.py @@ -129,17 +129,19 @@ async def test_broker_gets_patched_attrs_within_cm(self, fake_producer_cls) -> N test_broker = self.get_broker() await test_broker.start() + old_producer = test_broker._state.producer + async with self.patch_broker(test_broker) as br: assert isinstance(br.start, Mock) assert isinstance(br._connect, Mock) assert isinstance(br.close, Mock) - assert isinstance(br._producer, fake_producer_cls) + assert isinstance(br._state.producer, fake_producer_cls) assert not isinstance(br.start, Mock) assert not isinstance(br._connect, Mock) assert not isinstance(br.close, Mock) assert br._connection is not None - assert not isinstance(br._producer, fake_producer_cls) + assert br._state.producer == old_producer async def test_broker_with_real_doesnt_get_patched(self) -> None: test_broker = self.get_broker() diff --git a/tests/brokers/rabbit/specific/test_declare.py b/tests/brokers/rabbit/specific/test_declare.py index 02467a1704..874fb403cc 100644 --- a/tests/brokers/rabbit/specific/test_declare.py +++ b/tests/brokers/rabbit/specific/test_declare.py @@ -6,7 +6,8 @@ @pytest.mark.asyncio() async def test_declare_queue(async_mock, queue: str) -> None: - declarer = RabbitDeclarer(async_mock) + declarer = RabbitDeclarer() + declarer.connect(async_mock, async_mock) q1 = await declarer.declare_queue(RabbitQueue(queue)) q2 = await declarer.declare_queue(RabbitQueue(queue)) @@ -20,7 +21,8 @@ async def test_declare_exchange( async_mock, queue: str, ) -> None: - declarer = RabbitDeclarer(async_mock) + declarer = RabbitDeclarer() + declarer.connect(async_mock, async_mock) ex1 = await declarer.declare_exchange(RabbitExchange(queue)) ex2 = await declarer.declare_exchange(RabbitExchange(queue)) @@ -34,7 +36,8 @@ async def test_declare_nested_exchange_cash_nested( async_mock, queue: str, ) -> None: - declarer = RabbitDeclarer(async_mock) + declarer = RabbitDeclarer() + declarer.connect(async_mock, async_mock) exchange = RabbitExchange(queue) @@ -50,7 +53,8 @@ async def test_publisher_declare( async_mock, queue: str, ) -> None: - declarer = RabbitDeclarer(async_mock) + declarer = RabbitDeclarer() + declarer.connect(async_mock, async_mock) broker = RabbitBroker() broker._connection = async_mock diff --git a/tests/cli/rabbit/test_logs.py b/tests/cli/rabbit/test_logs.py index d9abbcd0cc..4cef8e2a76 100644 --- a/tests/cli/rabbit/test_logs.py +++ b/tests/cli/rabbit/test_logs.py @@ -20,8 +20,8 @@ ) def test_set_level(level, app: FastStream) -> None: level = get_log_level(level) - app._setup() set_log_level(level, app) + app.broker._state._setup_logger_state() broker_logger = app.broker._state.logger_state.logger.logger assert app.logger.level is broker_logger.level is level diff --git a/tests/cli/test_publish.py b/tests/cli/test_publish.py index c545a03a72..5d1f57b82a 100644 --- a/tests/cli/test_publish.py +++ b/tests/cli/test_publish.py @@ -31,7 +31,7 @@ def get_mock_app(broker_type, producer_type) -> tuple[FastStream, AsyncMock]: mock_producer.publish = AsyncMock() mock_producer._parser = AsyncMock() mock_producer._decoder = AsyncMock() - broker._producer = mock_producer + broker._state.producer = mock_producer return FastStream(broker), mock_producer @@ -230,4 +230,4 @@ def test_publish_nats_request_command(runner: CliRunner) -> None: assert cmd.destination == "subjectname" assert cmd.timeout == 1.0 - assert cmd.publish_type is PublishType.Request + assert cmd.publish_type is PublishType.REQUEST diff --git a/tests/opentelemetry/basic.py b/tests/opentelemetry/basic.py index 446365895c..30d4ba0895 100644 --- a/tests/opentelemetry/basic.py +++ b/tests/opentelemetry/basic.py @@ -288,7 +288,7 @@ async def handler(m) -> None: async with broker: await broker.start() - broker._middlewares = () + broker.middlewares = () tasks = ( asyncio.create_task(broker.publish(msg, queue)), asyncio.create_task(event.wait()), @@ -560,7 +560,7 @@ async def test_get_baggage_from_headers( queue: str, ): mid = self.telemetry_middleware_class() - broker = self.broker_class(middlewares=(mid,)) + broker = self.get_broker(middlewares=(mid,), apply_types=True) args, kwargs = self.get_subscriber_params(queue) diff --git a/tests/prometheus/confluent/test_provider.py b/tests/prometheus/confluent/test_provider.py index 87d9f5659b..6949a1ff26 100644 --- a/tests/prometheus/confluent/test_provider.py +++ b/tests/prometheus/confluent/test_provider.py @@ -86,7 +86,7 @@ def test_get_consume_attrs_from_message(self, queue: str) -> None: pytest.param( (SimpleNamespace(), SimpleNamespace()), BatchConfluentMetricsSettingsProvider(), - id="message is batch", + id="batch message", ), pytest.param( SimpleNamespace(), @@ -96,7 +96,7 @@ def test_get_consume_attrs_from_message(self, queue: str) -> None: pytest.param( None, ConfluentMetricsSettingsProvider(), - id="message is None", + id="None message", ), ), ) diff --git a/tests/prometheus/kafka/test_provider.py b/tests/prometheus/kafka/test_provider.py index 4127eed58e..1e0c980981 100644 --- a/tests/prometheus/kafka/test_provider.py +++ b/tests/prometheus/kafka/test_provider.py @@ -81,7 +81,7 @@ def test_get_consume_attrs_from_message(self, queue: str) -> None: pytest.param( (SimpleNamespace(), SimpleNamespace()), BatchKafkaMetricsSettingsProvider(), - id="message is batch", + id="batch message", ), pytest.param( SimpleNamespace(), @@ -91,7 +91,7 @@ def test_get_consume_attrs_from_message(self, queue: str) -> None: pytest.param( None, KafkaMetricsSettingsProvider(), - id="message is None", + id="None message", ), ), ) diff --git a/tests/prometheus/redis/test_provider.py b/tests/prometheus/redis/test_provider.py index 9bafd26402..469f5237b8 100644 --- a/tests/prometheus/redis/test_provider.py +++ b/tests/prometheus/redis/test_provider.py @@ -105,7 +105,7 @@ def test_get_consume_attrs_from_message(self, queue: str, destination: str) -> N pytest.param( {"type": "blist"}, BatchRedisMetricsSettingsProvider(), - id="message is batch", + id="batch message", ), pytest.param( {"type": "not_blist"}, @@ -115,7 +115,7 @@ def test_get_consume_attrs_from_message(self, queue: str, destination: str) -> N pytest.param( None, RedisMetricsSettingsProvider(), - id="message is None", + id="None message", ), ), ) From cd87d8c4c079b3129f74ab18687d1021003beb5f Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Wed, 6 Nov 2024 20:50:31 +0300 Subject: [PATCH 187/245] fix: correct RMQ subscriber get_one logic --- faststream/rabbit/subscriber/usecase.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/faststream/rabbit/subscriber/usecase.py b/faststream/rabbit/subscriber/usecase.py index 8bad07afad..29e1d738cd 100644 --- a/faststream/rabbit/subscriber/usecase.py +++ b/faststream/rabbit/subscriber/usecase.py @@ -11,7 +11,6 @@ from faststream._internal.subscriber.usecase import SubscriberUsecase from faststream._internal.subscriber.utils import process_msg from faststream.exceptions import SetupError -from faststream.middlewares import AckPolicy from faststream.rabbit.parser import AioPikaParser from faststream.rabbit.publisher.fake import RabbitFakePublisher from faststream.rabbit.schemas import BaseRMQInformation @@ -25,6 +24,7 @@ from faststream._internal.state import BrokerState from faststream._internal.types import BrokerMiddleware, CustomCallable from faststream.message import StreamMessage + from faststream.middlewares import AckPolicy from faststream.rabbit.helpers.declarer import RabbitDeclarer from faststream.rabbit.message import RabbitMessage from faststream.rabbit.publisher.producer import AioPikaFastProducer @@ -167,8 +167,7 @@ async def get_one( self, *, timeout: float = 5.0, - # TODO: make it no_ack - ack_policy: AckPolicy = AckPolicy.REJECT_ON_ERROR, + no_ack: bool = True, ) -> "Optional[RabbitMessage]": assert self._queue_obj, "You should start subscriber at first." # nosec B101 assert ( # nosec B101 @@ -178,7 +177,6 @@ async def get_one( sleep_interval = timeout / 10 raw_message: Optional[IncomingMessage] = None - no_ack = self.ack_policy is AckPolicy.DO_NOTHING with anyio.move_on_after(timeout): while ( # noqa: ASYNC110 raw_message := await self._queue_obj.get( From aa1562d852cc9ef9d9a24311a2b1b7535a2b611e Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Thu, 7 Nov 2024 23:44:55 +0300 Subject: [PATCH 188/245] chore: fix pydantic 2.10 compatibility --- faststream/_internal/broker/abc_broker.py | 35 ++- faststream/_internal/broker/broker.py | 82 +++--- faststream/_internal/broker/pub_base.py | 25 +- faststream/_internal/broker/router.py | 2 + faststream/_internal/cli/utils/logs.py | 2 +- faststream/_internal/publisher/proto.py | 4 +- faststream/_internal/publisher/usecase.py | 33 ++- faststream/_internal/state/pointer.py | 11 +- faststream/_internal/subscriber/call_item.py | 14 +- faststream/_internal/subscriber/proto.py | 4 +- faststream/_internal/subscriber/usecase.py | 21 +- faststream/_internal/testing/broker.py | 15 +- faststream/confluent/broker/broker.py | 17 +- faststream/confluent/client.py | 3 +- faststream/confluent/publisher/producer.py | 8 +- faststream/confluent/publisher/usecase.py | 12 +- faststream/confluent/subscriber/usecase.py | 7 +- faststream/confluent/testing.py | 6 +- faststream/kafka/broker/broker.py | 22 +- faststream/kafka/publisher/producer.py | 8 +- faststream/kafka/publisher/usecase.py | 14 +- faststream/kafka/subscriber/usecase.py | 7 +- faststream/kafka/testing.py | 6 +- faststream/nats/broker/broker.py | 272 +++++++++---------- faststream/nats/fastapi/fastapi.py | 16 -- faststream/nats/publisher/producer.py | 12 +- faststream/nats/publisher/usecase.py | 124 ++++++--- faststream/nats/subscriber/factory.py | 2 +- faststream/nats/subscriber/usecase.py | 40 +-- faststream/nats/testing.py | 13 +- faststream/rabbit/broker/broker.py | 36 ++- faststream/rabbit/publisher/usecase.py | 3 +- faststream/rabbit/subscriber/usecase.py | 7 +- faststream/rabbit/testing.py | 6 +- faststream/redis/broker/broker.py | 16 +- faststream/redis/publisher/producer.py | 8 +- faststream/redis/publisher/usecase.py | 16 +- faststream/redis/subscriber/usecase.py | 17 +- faststream/redis/testing.py | 6 +- tests/brokers/base/testclient.py | 6 +- tests/brokers/nats/test_consume.py | 10 +- tests/cli/rabbit/test_logs.py | 5 +- tests/cli/test_publish.py | 2 +- 43 files changed, 527 insertions(+), 448 deletions(-) diff --git a/faststream/_internal/broker/abc_broker.py b/faststream/_internal/broker/abc_broker.py index b50b0195c5..0fc795231e 100644 --- a/faststream/_internal/broker/abc_broker.py +++ b/faststream/_internal/broker/abc_broker.py @@ -7,6 +7,7 @@ Optional, ) +from faststream._internal.state import BrokerState, Pointer from faststream._internal.types import BrokerMiddleware, CustomCallable, MsgType if TYPE_CHECKING: @@ -29,6 +30,7 @@ def __init__( parser: Optional["CustomCallable"], decoder: Optional["CustomCallable"], include_in_schema: Optional[bool], + state: "BrokerState", ) -> None: self.prefix = prefix self.include_in_schema = include_in_schema @@ -41,6 +43,8 @@ def __init__( self._parser = parser self._decoder = decoder + self._state = Pointer(state) + def add_middleware(self, middleware: "BrokerMiddleware[MsgType]") -> None: """Append BrokerMiddleware to the end of middlewares list. @@ -58,20 +62,37 @@ def add_middleware(self, middleware: "BrokerMiddleware[MsgType]") -> None: def subscriber( self, subscriber: "SubscriberProto[MsgType]", + is_running: bool = False, ) -> "SubscriberProto[MsgType]": subscriber.add_prefix(self.prefix) - self._subscribers.append(subscriber) + if not is_running: + self._subscribers.append(subscriber) return subscriber @abstractmethod def publisher( self, publisher: "PublisherProto[MsgType]", + is_running: bool = False, ) -> "PublisherProto[MsgType]": publisher.add_prefix(self.prefix) - self._publishers.append(publisher) + + if not is_running: + self._publishers.append(publisher) + return publisher + def setup_publisher( + self, + publisher: "PublisherProto[MsgType]", + **kwargs: Any, + ) -> None: + """Setup the Publisher to prepare it to starting.""" + publisher._setup(**kwargs, state=self._state) + + def _setup(self, state: "Pointer[BrokerState]") -> None: + self._state.set(state) + def include_router( self, router: "ABCBroker[Any]", @@ -82,6 +103,8 @@ def include_router( include_in_schema: Optional[bool] = None, ) -> None: """Includes a router in the current object.""" + router._setup(self._state) + for h in router._subscribers: h.add_prefix(f"{self.prefix}{prefix}") @@ -126,6 +149,8 @@ def include_routers( self.include_router(r) def _solve_include_in_schema(self, include_in_schema: bool) -> bool: - if self.include_in_schema is None or self.include_in_schema: - return include_in_schema - return self.include_in_schema + # should be `is False` to pass `None` case + if self.include_in_schema is False: + return False + + return include_in_schema diff --git a/faststream/_internal/broker/broker.py b/faststream/_internal/broker/broker.py index 73f7aea2c5..591b14d903 100644 --- a/faststream/_internal/broker/broker.py +++ b/faststream/_internal/broker/broker.py @@ -22,7 +22,6 @@ SetupAble, ) from faststream._internal.state.broker import ( - BrokerState, InitialBrokerState, ) from faststream._internal.state.producer import ProducerUnset @@ -137,6 +136,20 @@ def __init__( ], **connection_kwargs: Any, ) -> None: + state = InitialBrokerState( + di_state=DIState( + use_fastdepends=apply_types, + get_dependent=_get_dependant, + call_decorators=_call_decorators, + serializer=serializer, + provider=Provider(), + context=ContextRepo(), + ), + logger_state=logger_state, + graceful_timeout=graceful_timeout, + producer=ProducerUnset(), + ) + super().__init__( middlewares=middlewares, dependencies=dependencies, @@ -151,6 +164,7 @@ def __init__( # Broker is a root router include_in_schema=True, prefix="", + state=state, ) self.running = False @@ -163,20 +177,6 @@ def __init__( *self.middlewares, ) - self._state: BrokerState = InitialBrokerState( - di_state=DIState( - use_fastdepends=apply_types, - get_dependent=_get_dependant, - call_decorators=_call_decorators, - serializer=serializer, - provider=Provider(), - context=ContextRepo(), - ), - logger_state=logger_state, - graceful_timeout=graceful_timeout, - producer=ProducerUnset(), - ) - # AsyncAPI information self.url = specification_url self.protocol = protocol @@ -187,15 +187,15 @@ def __init__( @property def _producer(self) -> "ProducerProto": - return self._state.producer + return self._state.get().producer @property def context(self) -> "ContextRepo": - return self._state.di_state.context + return self._state.get().di_state.context @property def provider(self) -> Provider: - return self._state.di_state.provider + return self._state.get().di_state.provider async def __aenter__(self) -> "Self": await self.connect() @@ -213,20 +213,25 @@ async def __aexit__( async def start(self) -> None: """Start the broker async use case.""" # TODO: filter by already running handlers after TestClient refactor + state = self._state.get() + for subscriber in self._subscribers: log_context = subscriber.get_log_context(None) log_context.pop("message_id", None) - self._state.logger_state.params_storage.setup_log_contest(log_context) + state.logger_state.params_storage.setup_log_contest(log_context) - self._state._setup_logger_state() + state._setup_logger_state() for subscriber in self._subscribers: - self._state.logger_state.log( + state.logger_state.log( f"`{subscriber.call_name}` waiting for messages", extra=subscriber.get_log_context(None), ) await subscriber.start() + if not self.running: + self.running = True + async def connect(self, **kwargs: Any) -> ConnectionType: """Connect to a remote server.""" if self._connection is None: @@ -246,13 +251,15 @@ def _setup(self, di_state: Optional[DIState] = None) -> None: Method should be idempotent due could be called twice """ - broker_serializer = self._state.di_state.serializer + broker_state = self._state.get() + current_di_state = broker_state.di_state + broker_serializer = current_di_state.serializer if di_state is not None: if broker_serializer is EMPTY: broker_serializer = di_state.serializer - self._state.di_state.update( + current_di_state.update( serializer=broker_serializer, provider=di_state.provider, context=di_state.context, @@ -266,15 +273,11 @@ def _setup(self, di_state: Optional[DIState] = None) -> None: broker_serializer = PydanticSerializer() - self._state.di_state.update( + current_di_state.update( serializer=broker_serializer, ) - self._state._setup() - - # TODO: move to start - if not self.running: - self.running = True + broker_state._setup() # TODO: move setup to object creation for h in self._subscribers: @@ -293,16 +296,6 @@ def setup_subscriber( data.update(kwargs) subscriber._setup(**data, state=self._state) - def setup_publisher( - self, - publisher: "PublisherProto[MsgType]", - **kwargs: Any, - ) -> None: - """Setup the Publisher to prepare it to starting.""" - data = self._publisher_setup_extra.copy() - data.update(kwargs) - publisher._setup(**data, state=self._state) - @property def _subscriber_setup_extra(self) -> "AnyDict": return { @@ -314,16 +307,9 @@ def _subscriber_setup_extra(self) -> "AnyDict": "broker_decoder": self._decoder, } - @property - def _publisher_setup_extra(self) -> "AnyDict": - return { - "producer": self._producer, - } - def publisher(self, *args: Any, **kwargs: Any) -> "PublisherProto[MsgType]": - pub = super().publisher(*args, **kwargs) - if self.running: - self.setup_publisher(pub) + pub = super().publisher(*args, **kwargs, is_running=self.running) + self.setup_publisher(pub) return pub async def close( diff --git a/faststream/_internal/broker/pub_base.py b/faststream/_internal/broker/pub_base.py index 000f007d52..8d97050cc8 100644 --- a/faststream/_internal/broker/pub_base.py +++ b/faststream/_internal/broker/pub_base.py @@ -1,7 +1,7 @@ from abc import abstractmethod from collections.abc import Iterable from functools import partial -from typing import TYPE_CHECKING, Any, Generic, Optional +from typing import TYPE_CHECKING, Any, Generic from faststream._internal.subscriber.utils import process_msg from faststream._internal.types import MsgType @@ -25,7 +25,7 @@ async def publish( message: "SendableMessage", queue: str, /, - ) -> None: + ) -> Any: raise NotImplementedError async def _basic_publish( @@ -33,11 +33,12 @@ async def _basic_publish( cmd: "PublishCommand", *, producer: "ProducerProto", - ) -> Optional[Any]: + ) -> Any: publish = producer.publish + context = self.context # caches property for m in self.middlewares: - publish = partial(m(None, context=self.context).publish_scope, publish) + publish = partial(m(None, context=context).publish_scope, publish) return await publish(cmd) @@ -46,7 +47,7 @@ async def publish_batch( self, *messages: "SendableMessage", queue: str, - ) -> None: + ) -> Any: raise NotImplementedError async def _basic_publish_batch( @@ -54,13 +55,14 @@ async def _basic_publish_batch( cmd: "PublishCommand", *, producer: "ProducerProto", - ) -> None: + ) -> Any: publish = producer.publish_batch + context = self.context # caches property for m in self.middlewares: - publish = partial(m(None, context=self.context).publish_scope, publish) + publish = partial(m(None, context=context).publish_scope, publish) - await publish(cmd) + return await publish(cmd) @abstractmethod async def request( @@ -79,17 +81,16 @@ async def _basic_request( producer: "ProducerProto", ) -> Any: request = producer.request + context = self.context # caches property for m in self.middlewares: - request = partial(m(None, context=self.context).publish_scope, request) + request = partial(m(None, context=context).publish_scope, request) published_msg = await request(cmd) response_msg: Any = await process_msg( msg=published_msg, - middlewares=( - m(published_msg, context=self.context) for m in self.middlewares - ), + middlewares=(m(published_msg, context=context) for m in self.middlewares), parser=producer._parser, decoder=producer._decoder, source_type=SourceType.RESPONSE, diff --git a/faststream/_internal/broker/router.py b/faststream/_internal/broker/router.py index 6daa2f245a..c2fe269e1d 100644 --- a/faststream/_internal/broker/router.py +++ b/faststream/_internal/broker/router.py @@ -6,6 +6,7 @@ Optional, ) +from faststream._internal.state.broker import EmptyBrokerState from faststream._internal.types import ( BrokerMiddleware, CustomCallable, @@ -81,6 +82,7 @@ def __init__( parser=parser, decoder=decoder, include_in_schema=include_in_schema, + state=EmptyBrokerState("You should include router to any broker."), ) for h in handlers: diff --git a/faststream/_internal/cli/utils/logs.py b/faststream/_internal/cli/utils/logs.py index cd2aa47ea5..d2e5d61b78 100644 --- a/faststream/_internal/cli/utils/logs.py +++ b/faststream/_internal/cli/utils/logs.py @@ -68,4 +68,4 @@ def set_log_level(level: int, app: "FastStream") -> None: if app.logger and getattr(app.logger, "setLevel", None): app.logger.setLevel(level) # type: ignore[attr-defined] - app.broker._state.logger_state.set_level(level) + app.broker._state.get().logger_state.set_level(level) diff --git a/faststream/_internal/publisher/proto.py b/faststream/_internal/publisher/proto.py index 49e7b3151c..710cc65944 100644 --- a/faststream/_internal/publisher/proto.py +++ b/faststream/_internal/publisher/proto.py @@ -11,7 +11,7 @@ if TYPE_CHECKING: from faststream._internal.basic_types import SendableMessage - from faststream._internal.state import BrokerState + from faststream._internal.state import BrokerState, Pointer from faststream._internal.types import ( AsyncCallable, BrokerMiddleware, @@ -109,7 +109,7 @@ def _setup( # type: ignore[override] self, *, producer: Optional["ProducerProto"], - state: "BrokerState", + state: "Pointer[BrokerState]", ) -> None: ... @abstractmethod diff --git a/faststream/_internal/publisher/usecase.py b/faststream/_internal/publisher/usecase.py index d487e54859..f1d1e276fb 100644 --- a/faststream/_internal/publisher/usecase.py +++ b/faststream/_internal/publisher/usecase.py @@ -33,7 +33,7 @@ if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict from faststream._internal.publisher.proto import ProducerProto - from faststream._internal.state import BrokerState + from faststream._internal.state import BrokerState, Pointer from faststream._internal.types import ( BrokerMiddleware, PublisherMiddleware, @@ -83,7 +83,7 @@ def __init__( self.middlewares = middlewares self._broker_middlewares = broker_middlewares - self._producer: ProducerProto = ProducerUnset() + self.__producer: Optional[ProducerProto] = ProducerUnset() self._fake_handler = False self.mock = None @@ -97,15 +97,20 @@ def __init__( def add_middleware(self, middleware: "BrokerMiddleware[MsgType]") -> None: self._broker_middlewares = (*self._broker_middlewares, middleware) + @property + def _producer(self) -> "ProducerProto": + return self.__producer or self._state.get().producer + @override def _setup( # type: ignore[override] self, *, - producer: "ProducerProto", - state: Optional["BrokerState"], + state: "Pointer[BrokerState]", + producer: Optional["ProducerProto"] = None, ) -> None: + # TODO: add EmptyBrokerState to init self._state = state - self._producer = producer + self.__producer = producer def set_test( self, @@ -150,11 +155,13 @@ async def _basic_publish( ) -> Any: pub: Callable[..., Awaitable[Any]] = self._producer.publish + context = self._state.get().di_state.context + for pub_m in chain( ( _extra_middlewares or ( - m(None, context=self._state.di_state.context).publish_scope + m(None, context=context).publish_scope for m in self._broker_middlewares ) ), @@ -168,10 +175,10 @@ async def _basic_request( self, cmd: "PublishCommand", ) -> Optional[Any]: - context = self._state.di_state.context - request = self._producer.request + context = self._state.get().di_state.context + for pub_m in chain( (m(None, context=context).publish_scope for m in self._broker_middlewares), self.middlewares, @@ -199,11 +206,13 @@ async def _basic_publish_batch( ) -> Optional[Any]: pub = self._producer.publish_batch + context = self._state.get().di_state.context + for pub_m in chain( ( _extra_middlewares or ( - m(None, context=self._state.di_state.context).publish_scope + m(None, context=context).publish_scope for m in self._broker_middlewares ) ), @@ -230,11 +239,13 @@ def get_payloads(self) -> list[tuple["AnyDict", str]]: payloads.append((body, "")) else: + di_state = self._state.get().di_state + for call in self.calls: call_model = build_call_model( call, - dependency_provider=self._state.di_state.provider, - serializer_cls=self._state.di_state.serializer, + dependency_provider=di_state.provider, + serializer_cls=di_state.serializer, ) response_type = next( diff --git a/faststream/_internal/state/pointer.py b/faststream/_internal/state/pointer.py index 68a41de65b..dbe927d5f9 100644 --- a/faststream/_internal/state/pointer.py +++ b/faststream/_internal/state/pointer.py @@ -1,7 +1,10 @@ -from typing import Generic, TypeVar +from typing import TYPE_CHECKING, Generic, TypeVar from typing_extensions import Self +if TYPE_CHECKING: + from faststream._internal.basic_types import AnyDict + T = TypeVar("T") @@ -11,9 +14,13 @@ class Pointer(Generic[T]): def __init__(self, value: T) -> None: self.__value = value - def change(self, new_value: T) -> "Self": + def set(self, new_value: T) -> "Self": self.__value = new_value return self def get(self) -> T: return self.__value + + def patch_value(self, **kwargs: "AnyDict") -> None: + for k, v in kwargs.items(): + setattr(self.__value, k, v) diff --git a/faststream/_internal/subscriber/call_item.py b/faststream/_internal/subscriber/call_item.py index 3a172dd432..ddcddacd01 100644 --- a/faststream/_internal/subscriber/call_item.py +++ b/faststream/_internal/subscriber/call_item.py @@ -20,7 +20,7 @@ from fast_depends.dependencies import Dependant from faststream._internal.basic_types import AsyncFuncAny, Decorator - from faststream._internal.state import DIState + from faststream._internal.state import BrokerState, Pointer from faststream._internal.subscriber.call_wrapper.call import HandlerCallWrapper from faststream._internal.types import ( AsyncCallable, @@ -75,11 +75,13 @@ def _setup( # type: ignore[override] *, parser: "AsyncCallable", decoder: "AsyncCallable", + state: "Pointer[BrokerState]", broker_dependencies: Iterable["Dependant"], - fast_depends_state: "DIState", _call_decorators: Iterable["Decorator"], ) -> None: if self.dependant is None: + di_state = state.get().di_state + self.item_parser = parser self.item_decoder = decoder @@ -87,14 +89,14 @@ def _setup( # type: ignore[override] dependant = self.handler.set_wrapped( dependencies=dependencies, - _call_decorators=_call_decorators, - state=fast_depends_state, + _call_decorators=(*_call_decorators, *di_state.call_decorators), + state=di_state, ) - if fast_depends_state.get_dependent is None: + if di_state.get_dependent is None: self.dependant = dependant else: - self.dependant = fast_depends_state.get_dependent( + self.dependant = di_state.get_dependent( self.handler._original_call, dependencies, ) diff --git a/faststream/_internal/subscriber/proto.py b/faststream/_internal/subscriber/proto.py index 14e9e51f4c..547c04f51c 100644 --- a/faststream/_internal/subscriber/proto.py +++ b/faststream/_internal/subscriber/proto.py @@ -17,7 +17,7 @@ BasePublisherProto, ProducerProto, ) - from faststream._internal.state import BrokerState + from faststream._internal.state import BrokerState, Pointer from faststream._internal.subscriber.call_item import HandlerItem from faststream._internal.types import ( BrokerMiddleware, @@ -61,7 +61,7 @@ def _setup( # type: ignore[override] broker_parser: Optional["CustomCallable"], broker_decoder: Optional["CustomCallable"], # dependant args - state: "BrokerState", + state: "Pointer[BrokerState]", ) -> None: ... @abstractmethod diff --git a/faststream/_internal/subscriber/usecase.py b/faststream/_internal/subscriber/usecase.py index 60ac9f1b83..622578fc22 100644 --- a/faststream/_internal/subscriber/usecase.py +++ b/faststream/_internal/subscriber/usecase.py @@ -40,7 +40,7 @@ from faststream._internal.publisher.proto import ( BasePublisherProto, ) - from faststream._internal.state import BrokerState + from faststream._internal.state import BrokerState, Pointer from faststream._internal.types import ( AsyncCallable, BrokerMiddleware, @@ -148,8 +148,9 @@ def _setup( # type: ignore[override] broker_parser: Optional["CustomCallable"], broker_decoder: Optional["CustomCallable"], # dependant args - state: "BrokerState", + state: "Pointer[BrokerState]", ) -> None: + # TODO: add EmptyBrokerState to init self._state = state self.extra_context = extra_context @@ -171,12 +172,9 @@ def _setup( # type: ignore[override] call._setup( parser=async_parser, decoder=async_decoder, - fast_depends_state=state.di_state, - _call_decorators=( - *self._call_decorators, - *state.di_state.call_decorators, - ), + state=state, broker_dependencies=self._broker_dependencies, + _call_decorators=self._call_decorators, ) call.handler.refresh(with_mock=False) @@ -196,7 +194,7 @@ async def close(self) -> None: """ self.running = False if isinstance(self.lock, MultiLock): - await self.lock.wait_release(self._state.graceful_timeout) + await self.lock.wait_release(self._state.get().graceful_timeout) def add_call( self, @@ -303,7 +301,7 @@ async def consume(self, msg: MsgType) -> Any: # Stop handler at `exit()` call await self.close() - if app := self._state.di_state.context.get("app"): + if app := self._state.get().di_state.context.get("app"): app.exit() except Exception: # nosec B110 @@ -312,14 +310,15 @@ async def consume(self, msg: MsgType) -> Any: async def process_message(self, msg: MsgType) -> "Response": """Execute all message processing stages.""" - context: ContextRepo = self._state.di_state.context + broker_state = self._state.get() + context: ContextRepo = broker_state.di_state.context async with AsyncExitStack() as stack: stack.enter_context(self.lock) # Enter context before middlewares stack.enter_context( - context.scope("logger", self._state.logger_state.logger.logger) + context.scope("logger", broker_state.logger_state.logger.logger) ) for k, v in self.extra_context.items(): stack.enter_context(context.scope(k, v)) diff --git a/faststream/_internal/testing/broker.py b/faststream/_internal/testing/broker.py index 00468fa947..ac57846c80 100644 --- a/faststream/_internal/testing/broker.py +++ b/faststream/_internal/testing/broker.py @@ -100,10 +100,17 @@ def _patch_producer(self, broker: Broker) -> Iterator[None]: @contextmanager def _patch_logger(self, broker: Broker) -> Iterator[None]: - old_logger = broker._state.logger_state.logger - broker._state.logger_state.logger = RealLoggerObject(MagicMock()) - yield - broker._state.logger_state.logger = old_logger + state = broker._state.get() + state._setup_logger_state() + + logger_state = state.logger_state + old_log_object = logger_state.logger + + logger_state.logger = RealLoggerObject(MagicMock()) + try: + yield + finally: + logger_state.logger = old_log_object @contextmanager def _patch_broker(self, broker: Broker) -> Generator[None, None, None]: diff --git a/faststream/confluent/broker/broker.py b/faststream/confluent/broker/broker.py index 9f57f8217e..d8a1cd6671 100644 --- a/faststream/confluent/broker/broker.py +++ b/faststream/confluent/broker/broker.py @@ -33,6 +33,7 @@ from .registrator import KafkaRegistrator if TYPE_CHECKING: + import asyncio from types import TracebackType from confluent_kafka import Message @@ -401,9 +402,11 @@ def __init__( self.config = ConfluentFastConfig(config) - self._state.producer = AsyncConfluentFastProducer( - parser=self._parser, - decoder=self._decoder, + self._state.patch_value( + producer=AsyncConfluentFastProducer( + parser=self._parser, + decoder=self._decoder, + ) ) async def close( @@ -452,7 +455,7 @@ async def _connect( # type: ignore[override] return partial( AsyncConfluentConsumer, **filter_by_dict(ConsumerConnectionParams, kwargs), - logger=self._state.logger_state, + logger=self._state.get().logger_state, config=self.config, ) @@ -503,7 +506,7 @@ async def publish( # type: ignore[override] bool, Doc("Do not wait for Kafka publish confirmation."), ] = False, - ) -> None: + ) -> "asyncio.Future": """Publish message directly. This method allows you to publish message in not AsyncAPI-documented way. You can use it in another frameworks @@ -523,7 +526,7 @@ async def publish( # type: ignore[override] correlation_id=correlation_id or gen_cor_id(), _publish_type=PublishType.PUBLISH, ) - await super()._basic_publish(cmd, producer=self._producer) + return await super()._basic_publish(cmd, producer=self._producer) @override async def request( # type: ignore[override] @@ -576,7 +579,7 @@ async def publish_batch( _publish_type=PublishType.PUBLISH, ) - await self._basic_publish_batch(cmd, producer=self._producer) + return await self._basic_publish_batch(cmd, producer=self._producer) @override async def ping(self, timeout: Optional[float]) -> bool: diff --git a/faststream/confluent/client.py b/faststream/confluent/client.py index 32afc81c36..7b7b0b8fe2 100644 --- a/faststream/confluent/client.py +++ b/faststream/confluent/client.py @@ -134,7 +134,7 @@ async def send( timestamp_ms: Optional[int] = None, headers: Optional[list[tuple[str, Union[str, bytes]]]] = None, no_confirm: bool = False, - ) -> None: + ) -> "asyncio.Future": """Sends a single message to a Kafka topic.""" kwargs: _SendKwargs = { "value": value, @@ -164,6 +164,7 @@ def ack_callback(err: Any, msg: Optional[Message]) -> None: if not no_confirm: await result_future + return result_future def create_batch(self) -> "BatchBuilder": """Creates a batch for sending multiple messages.""" diff --git a/faststream/confluent/publisher/producer.py b/faststream/confluent/publisher/producer.py index 0aa22e9eba..8c6144586b 100644 --- a/faststream/confluent/publisher/producer.py +++ b/faststream/confluent/publisher/producer.py @@ -11,6 +11,8 @@ from .state import EmptyProducerState, ProducerState, RealProducer if TYPE_CHECKING: + import asyncio + from faststream._internal.types import CustomCallable from faststream.confluent.client import AsyncConfluentProducer from faststream.confluent.response import KafkaPublishCommand @@ -48,7 +50,7 @@ async def ping(self, timeout: float) -> None: async def publish( # type: ignore[override] self, cmd: "KafkaPublishCommand", - ) -> None: + ) -> "asyncio.Future": """Publish a message to a topic.""" message, content_type = encode_message(cmd.body) @@ -57,7 +59,7 @@ async def publish( # type: ignore[override] **cmd.headers_to_publish(), } - await self._producer.producer.send( + return await self._producer.producer.send( topic=cmd.destination, value=message, key=cmd.key, @@ -105,6 +107,6 @@ async def publish_batch( async def request( self, cmd: "KafkaPublishCommand", - ) -> Optional[Any]: + ) -> Any: msg = "Kafka doesn't support `request` method without test client." raise FeatureNotSupportedException(msg) diff --git a/faststream/confluent/publisher/usecase.py b/faststream/confluent/publisher/usecase.py index 1416632dc6..d6b7132155 100644 --- a/faststream/confluent/publisher/usecase.py +++ b/faststream/confluent/publisher/usecase.py @@ -16,6 +16,8 @@ from faststream.response.publish_type import PublishType if TYPE_CHECKING: + import asyncio + from faststream._internal.basic_types import SendableMessage from faststream._internal.types import BrokerMiddleware, PublisherMiddleware from faststream.confluent.message import KafkaMessage @@ -26,7 +28,7 @@ class LogicPublisher(PublisherUsecase[MsgType]): """A class to publish messages to a Kafka topic.""" - _producer: Optional["AsyncConfluentFastProducer"] + _producer: "AsyncConfluentFastProducer" def __init__( self, @@ -59,8 +61,6 @@ def __init__( self.reply_to = reply_to self.headers = headers or {} - self._producer = None - def add_prefix(self, prefix: str) -> None: self.topic = f"{prefix}{self.topic}" @@ -141,7 +141,7 @@ async def publish( correlation_id: Optional[str] = None, reply_to: str = "", no_confirm: bool = False, - ) -> None: + ) -> "asyncio.Future": cmd = KafkaPublishCommand( message, topic=topic or self.topic, @@ -154,7 +154,7 @@ async def publish( no_confirm=no_confirm, _publish_type=PublishType.PUBLISH, ) - await self._basic_publish(cmd, _extra_middlewares=()) + return await self._basic_publish(cmd, _extra_middlewares=()) @override async def _publish( @@ -226,7 +226,7 @@ async def publish( _publish_type=PublishType.PUBLISH, ) - await self._basic_publish_batch(cmd, _extra_middlewares=()) + return await self._basic_publish_batch(cmd, _extra_middlewares=()) @override async def _publish( diff --git a/faststream/confluent/subscriber/usecase.py b/faststream/confluent/subscriber/usecase.py index c02b016b10..adb321dd4a 100644 --- a/faststream/confluent/subscriber/usecase.py +++ b/faststream/confluent/subscriber/usecase.py @@ -165,11 +165,12 @@ async def get_one( raw_message = await self.consumer.getone(timeout=timeout) + context = self._state.get().di_state.context + return await process_msg( msg=raw_message, middlewares=( - m(raw_message, context=self._state.di_state.context) - for m in self._broker_middlewares + m(raw_message, context=context) for m in self._broker_middlewares ), parser=self._parser, decoder=self._decoder, @@ -181,7 +182,7 @@ def _make_response_publisher( ) -> Sequence["BasePublisherProto"]: return ( KafkaFakePublisher( - self._state.producer, + self._state.get().producer, topic=message.reply_to, ), ) diff --git a/faststream/confluent/testing.py b/faststream/confluent/testing.py index c254098d25..92676d6e7a 100644 --- a/faststream/confluent/testing.py +++ b/faststream/confluent/testing.py @@ -38,10 +38,10 @@ class TestKafkaBroker(TestBroker[KafkaBroker]): @contextmanager def _patch_producer(self, broker: KafkaBroker) -> Iterator[None]: - old_producer = broker._state.producer - broker._state.producer = FakeProducer(broker) + old_producer = broker._state.get().producer + broker._state.patch_value(producer=FakeProducer(broker)) yield - broker._state.producer = old_producer + broker._state.patch_value(producer=old_producer) @staticmethod async def _fake_connect( # type: ignore[override] diff --git a/faststream/kafka/broker/broker.py b/faststream/kafka/broker/broker.py index 0c03172e93..0f962f0d3b 100644 --- a/faststream/kafka/broker/broker.py +++ b/faststream/kafka/broker/broker.py @@ -36,7 +36,7 @@ Partition = TypeVar("Partition") if TYPE_CHECKING: - from asyncio import AbstractEventLoop + import asyncio from types import TracebackType from aiokafka import ConsumerRecord @@ -95,7 +95,7 @@ class KafkaInitKwargs(TypedDict, total=False): Optional[AbstractTokenProvider], Doc("OAuthBearer token provider instance."), ] - loop: Optional[AbstractEventLoop] + loop: Optional[asyncio.AbstractEventLoop] client_id: Annotated[ Optional[str], Doc( @@ -292,7 +292,7 @@ def __init__( Optional["AbstractTokenProvider"], Doc("OAuthBearer token provider instance."), ] = None, - loop: Optional["AbstractEventLoop"] = None, + loop: Optional["asyncio.AbstractEventLoop"] = None, client_id: Annotated[ Optional[str], Doc( @@ -580,9 +580,11 @@ def __init__( ) self.client_id = client_id - self._state.producer = AioKafkaFastProducer( - parser=self._parser, - decoder=self._decoder, + self._state.patch_value( + producer=AioKafkaFastProducer( + parser=self._parser, + decoder=self._decoder, + ) ) async def close( @@ -720,7 +722,7 @@ async def publish( # type: ignore[override] bool, Doc("Do not wait for Kafka publish confirmation."), ] = False, - ) -> None: + ) -> "asyncio.Future": """Publish message directly. This method allows you to publish message in not AsyncAPI-documented way. You can use it in another frameworks @@ -740,7 +742,7 @@ async def publish( # type: ignore[override] correlation_id=correlation_id or gen_cor_id(), _publish_type=PublishType.PUBLISH, ) - await super()._basic_publish(cmd, producer=self._producer) + return await super()._basic_publish(cmd, producer=self._producer) @override async def request( # type: ignore[override] @@ -864,7 +866,7 @@ async def publish_batch( bool, Doc("Do not wait for Kafka publish confirmation."), ] = False, - ) -> None: + ) -> "asyncio.Future": assert self._producer, NOT_CONNECTED_YET # nosec B101 cmd = KafkaPublishCommand( @@ -879,7 +881,7 @@ async def publish_batch( _publish_type=PublishType.PUBLISH, ) - await self._basic_publish_batch(cmd, producer=self._producer) + return await self._basic_publish_batch(cmd, producer=self._producer) @override async def ping(self, timeout: Optional[float]) -> bool: diff --git a/faststream/kafka/publisher/producer.py b/faststream/kafka/publisher/producer.py index eba2276e6b..a6574e104d 100644 --- a/faststream/kafka/publisher/producer.py +++ b/faststream/kafka/publisher/producer.py @@ -12,6 +12,8 @@ from .state import EmptyProducerState, ProducerState, RealProducer if TYPE_CHECKING: + import asyncio + from aiokafka import AIOKafkaProducer from faststream._internal.types import CustomCallable @@ -56,7 +58,7 @@ def closed(self) -> bool: async def publish( # type: ignore[override] self, cmd: "KafkaPublishCommand", - ) -> None: + ) -> "asyncio.Future": """Publish a message to a topic.""" message, content_type = encode_message(cmd.body) @@ -76,11 +78,12 @@ async def publish( # type: ignore[override] if not cmd.no_confirm: await send_future + return send_future async def publish_batch( self, cmd: "KafkaPublishCommand", - ) -> None: + ) -> "asyncio.Future": """Publish a batch of messages to a topic.""" batch = self._producer.producer.create_batch() @@ -111,6 +114,7 @@ async def publish_batch( ) if not cmd.no_confirm: await send_future + return send_future @override async def request( diff --git a/faststream/kafka/publisher/usecase.py b/faststream/kafka/publisher/usecase.py index 7174237e49..0f005770de 100644 --- a/faststream/kafka/publisher/usecase.py +++ b/faststream/kafka/publisher/usecase.py @@ -18,6 +18,8 @@ from faststream.response.publish_type import PublishType if TYPE_CHECKING: + import asyncio + from faststream._internal.basic_types import SendableMessage from faststream._internal.types import BrokerMiddleware, PublisherMiddleware from faststream.kafka.message import KafkaMessage @@ -28,7 +30,7 @@ class LogicPublisher(PublisherUsecase[MsgType]): """A class to publish messages to a Kafka topic.""" - _producer: Optional["AioKafkaFastProducer"] + _producer: "AioKafkaFastProducer" def __init__( self, @@ -61,8 +63,6 @@ def __init__( self.reply_to = reply_to self.headers = headers or {} - self._producer = None - def add_prefix(self, prefix: str) -> None: self.topic = f"{prefix}{self.topic}" @@ -240,7 +240,7 @@ async def publish( bool, Doc("Do not wait for Kafka publish confirmation."), ] = False, - ) -> None: + ) -> "asyncio.Future": cmd = KafkaPublishCommand( message, topic=topic or self.topic, @@ -253,7 +253,7 @@ async def publish( no_confirm=no_confirm, _publish_type=PublishType.PUBLISH, ) - await self._basic_publish(cmd, _extra_middlewares=()) + return await self._basic_publish(cmd, _extra_middlewares=()) @override async def _publish( @@ -395,7 +395,7 @@ async def publish( bool, Doc("Do not wait for Kafka publish confirmation."), ] = False, - ) -> None: + ) -> "asyncio.Future": cmd = KafkaPublishCommand( *messages, key=None, @@ -409,7 +409,7 @@ async def publish( _publish_type=PublishType.PUBLISH, ) - await self._basic_publish_batch(cmd, _extra_middlewares=()) + return await self._basic_publish_batch(cmd, _extra_middlewares=()) @override async def _publish( diff --git a/faststream/kafka/subscriber/usecase.py b/faststream/kafka/subscriber/usecase.py index f622ad6b9d..fab52a66f2 100644 --- a/faststream/kafka/subscriber/usecase.py +++ b/faststream/kafka/subscriber/usecase.py @@ -188,11 +188,12 @@ async def get_one( ((raw_message,),) = raw_messages.values() + context = self._state.get().di_state.context + msg: StreamMessage[MsgType] = await process_msg( msg=raw_message, middlewares=( - m(raw_message, context=self._state.di_state.context) - for m in self._broker_middlewares + m(raw_message, context=context) for m in self._broker_middlewares ), parser=self._parser, decoder=self._decoder, @@ -205,7 +206,7 @@ def _make_response_publisher( ) -> Sequence["BasePublisherProto"]: return ( KafkaFakePublisher( - self._state.producer, + self._state.get().producer, topic=message.reply_to, ), ) diff --git a/faststream/kafka/testing.py b/faststream/kafka/testing.py index 90c097eac1..96e0614183 100755 --- a/faststream/kafka/testing.py +++ b/faststream/kafka/testing.py @@ -40,10 +40,10 @@ class TestKafkaBroker(TestBroker[KafkaBroker]): @contextmanager def _patch_producer(self, broker: KafkaBroker) -> Iterator[None]: - old_producer = broker._state.producer - broker._state.producer = FakeProducer(broker) + old_producer = broker._state.get().producer + broker._state.patch_value(producer=FakeProducer(broker)) yield - broker._state.producer = old_producer + broker._state.patch_value(producer=old_producer) @staticmethod async def _fake_connect( # type: ignore[override] diff --git a/faststream/nats/broker/broker.py b/faststream/nats/broker/broker.py index 72e9687580..f6d24fa15f 100644 --- a/faststream/nats/broker/broker.py +++ b/faststream/nats/broker/broker.py @@ -1,5 +1,4 @@ import logging -import warnings from collections.abc import Iterable from typing import ( TYPE_CHECKING, @@ -27,7 +26,7 @@ from nats.aio.msg import Msg from nats.errors import Error from nats.js.errors import BadRequestError -from typing_extensions import Doc, override +from typing_extensions import Doc, Literal, overload, override from faststream.__about__ import SERVICE_NAME from faststream._internal.broker.broker import BrokerUsecase @@ -45,7 +44,6 @@ from .state import BrokerState, ConnectedState, EmptyBrokerState if TYPE_CHECKING: - import ssl from types import TracebackType from fast_depends.dependencies import Dependant @@ -57,7 +55,7 @@ JWTCallback, SignatureCallback, ) - from nats.js.api import Placement, RePublish, StorageType + from nats.js.api import Placement, PubAck, RePublish, StorageType from nats.js.kv import KeyValue from nats.js.object_store import ObjectStore from typing_extensions import TypedDict, Unpack @@ -153,22 +151,10 @@ class NatsInitKwargs(TypedDict, total=False): bool, Doc("Boolean indicating should commands be echoed."), ] - tls: Annotated[ - Optional["ssl.SSLContext"], - Doc("Some SSL context to make NATS connections secure."), - ] tls_hostname: Annotated[ Optional[str], Doc("Hostname for TLS."), ] - user: Annotated[ - Optional[str], - Doc("Username for NATS auth."), - ] - password: Annotated[ - Optional[str], - Doc("Username password for NATS auth."), - ] token: Annotated[ Optional[str], Doc("Auth token for NATS auth."), @@ -309,22 +295,10 @@ def __init__( bool, Doc("Boolean indicating should commands be echoed."), ] = False, - tls: Annotated[ - Optional["ssl.SSLContext"], - Doc("Some SSL context to make NATS connections secure."), - ] = None, tls_hostname: Annotated[ Optional[str], Doc("Hostname for TLS."), ] = None, - user: Annotated[ - Optional[str], - Doc("Username for NATS auth."), - ] = None, - password: Annotated[ - Optional[str], - Doc("Username password for NATS auth."), - ] = None, token: Annotated[ Optional[str], Doc("Auth token for NATS auth."), @@ -449,32 +423,7 @@ def __init__( ] = (), ) -> None: """Initialize the NatsBroker object.""" - if tls: # pragma: no cover - warnings.warn( - ( - "\nNATS `tls` option was deprecated and will be removed in 0.6.0" - "\nPlease, use `security` with `BaseSecurity` or `SASLPlaintext` instead" - ), - DeprecationWarning, - stacklevel=2, - ) - - if user or password: - warnings.warn( - ( - "\nNATS `user` and `password` options were deprecated and will be removed in 0.6.0" - "\nPlease, use `security` with `SASLPlaintext` instead" - ), - DeprecationWarning, - stacklevel=2, - ) - - secure_kwargs = { - "tls": tls, - "user": user, - "password": password, - **parse_security(security), - } + secure_kwargs = parse_security(security) servers = [servers] if isinstance(servers, str) else list(servers) @@ -546,9 +495,11 @@ def __init__( _call_decorators=_call_decorators, ) - self._state.producer = NatsFastProducer( - parser=self._parser, - decoder=self._decoder, + self._state.patch_value( + producer=NatsFastProducer( + parser=self._parser, + decoder=self._decoder, + ) ) self._js_producer = NatsJSFastProducer( @@ -564,15 +515,19 @@ def __init__( @override async def connect( # type: ignore[override] self, - servers: Annotated[ - Union[str, Iterable[str]], - Doc("NATS cluster addresses to connect."), - ] = EMPTY, + servers: Union[str, Iterable[str]] = EMPTY, **kwargs: "Unpack[NatsInitKwargs]", ) -> "Client": """Connect broker object to NATS cluster. To startup subscribers too you should use `broker.start()` after/instead this method. + + Args: + servers: NATS cluster addresses to connect. + **kwargs: all other options from connection signature. + + Returns: + `nats.aio.Client` connected object. """ if servers is not EMPTY: connect_kwargs: AnyDict = { @@ -589,7 +544,7 @@ async def _connect(self, **kwargs: Any) -> "Client": stream = connection.jetstream() - self._state.producer.connect(connection) + self._producer.connect(connection) self._js_producer.connect(stream) self._kv_declarer.connect(stream) @@ -611,7 +566,7 @@ async def close( await self._connection.drain() self._connection = None - self._state.producer.disconnect() + self._producer.disconnect() self._js_producer.disconnect() self._kv_declarer.disconnect() self._os_declarer.disconnect() @@ -643,13 +598,15 @@ async def start(self) -> None: stream=stream.name, ) + logger_state = self._state.get().logger_state + if ( e.description == "stream name already in use with a different configuration" ): old_config = (await stream_context.stream_info(stream.name)).config - self._state.logger_state.log(str(e), logging.WARNING, log_context) + logger_state.log(str(e), logging.WARNING, log_context) for subject in old_config.subjects or (): stream.add_subject(subject) @@ -657,7 +614,7 @@ async def start(self) -> None: await stream_context.update_stream(config=stream.config) else: # pragma: no cover - self._state.logger_state.log( + logger_state.log( str(e), logging.ERROR, log_context, @@ -670,56 +627,71 @@ async def start(self) -> None: await super().start() + @overload + async def publish( + self, + message: "SendableMessage", + subject: str, + headers: Optional[dict[str, str]] = None, + reply_to: str = "", + correlation_id: Optional[str] = None, + stream: Literal[None] = None, + timeout: Optional[float] = None, + ) -> None: ... + + @overload + async def publish( + self, + message: "SendableMessage", + subject: str, + headers: Optional[dict[str, str]] = None, + reply_to: str = "", + correlation_id: Optional[str] = None, + stream: Optional[str] = None, + timeout: Optional[float] = None, + ) -> "PubAck": ... + @override - async def publish( # type: ignore[override] + async def publish( self, - message: Annotated[ - "SendableMessage", - Doc( - "Message body to send. " - "Can be any encodable object (native python types or `pydantic.BaseModel`).", - ), - ], - subject: Annotated[ - str, - Doc("NATS subject to send message."), - ], - headers: Annotated[ - Optional[dict[str, str]], - Doc( - "Message headers to store metainformation. " - "**content-type** and **correlation_id** will be set automatically by framework anyway.", - ), - ] = None, - reply_to: Annotated[ - str, - Doc("NATS subject name to send response."), - ] = "", - correlation_id: Annotated[ - Optional[str], - Doc( - "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages.", - ), - ] = None, - stream: Annotated[ - Optional[str], - Doc( - "This option validates that the target subject is in presented stream. " - "Can be omitted without any effect.", - ), - ] = None, - timeout: Annotated[ - Optional[float], - Doc("Timeout to send message to NATS."), - ] = None, - ) -> None: + message: "SendableMessage", + subject: str, + headers: Optional[dict[str, str]] = None, + reply_to: str = "", + correlation_id: Optional[str] = None, + stream: Optional[str] = None, + timeout: Optional[float] = None, + ) -> Optional["PubAck"]: """Publish message directly. This method allows you to publish message in not AsyncAPI-documented way. You can use it in another frameworks applications or to publish messages from time to time. Please, use `@broker.publisher(...)` or `broker.publisher(...).publish(...)` instead in a regular way. + + Args: + message: + Message body to send. + Can be any encodable object (native python types or `pydantic.BaseModel`). + subject: + NATS subject to send message. + headers: + Message headers to store metainformation. + **content-type** and **correlation_id** will be set automatically by framework anyway. + reply_to: + NATS subject name to send response. + correlation_id: + Manual message **correlation_id** setter. + **correlation_id** is a useful option to trace messages. + stream: + This option validates that the target subject is in presented stream. + Can be omitted without any effect if you doesn't want PubAck frame. + timeout: + Timeout to send message to NATS. + + Returns: + `None` if you publishes a regular message. + `nats.js.api.PubAck` if you publishes a message to stream. """ cmd = NatsPublishCommand( message=message, @@ -732,50 +704,48 @@ async def publish( # type: ignore[override] _publish_type=PublishType.PUBLISH, ) - producer = self._state.producer if stream is None else self._js_producer + producer = self._js_producer if stream is not None else self._producer - await super()._basic_publish(cmd, producer=producer) + return await super()._basic_publish(cmd, producer=producer) @override async def request( # type: ignore[override] self, - message: Annotated[ - "SendableMessage", - Doc( - "Message body to send. " - "Can be any encodable object (native python types or `pydantic.BaseModel`).", - ), - ], - subject: Annotated[ - str, - Doc("NATS subject to send message."), - ], - headers: Annotated[ - Optional[dict[str, str]], - Doc( - "Message headers to store metainformation. " - "**content-type** and **correlation_id** will be set automatically by framework anyway.", - ), - ] = None, - correlation_id: Annotated[ - Optional[str], - Doc( - "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages.", - ), - ] = None, - stream: Annotated[ - Optional[str], - Doc( - "This option validates that the target subject is in presented stream. " - "Can be omitted without any effect.", - ), - ] = None, - timeout: Annotated[ - float, - Doc("Timeout to send message to NATS."), - ] = 0.5, + message: "SendableMessage", + subject: str, + headers: Optional[dict[str, str]] = None, + correlation_id: Optional[str] = None, + stream: Optional[str] = None, + timeout: float = 0.5, ) -> "NatsMessage": + """Make a synchronous request to outer subscriber. + + If out subscriber listens subject by stream, you should setup the same **stream** explicitly. + Another way you will reseave confirmation frame as a response. + + Args: + message: + Message body to send. + Can be any encodable object (native python types or `pydantic.BaseModel`). + subject: + NATS subject to send message. + headers: + Message headers to store metainformation. + **content-type** and **correlation_id** will be set automatically by framework anyway. + reply_to: + NATS subject name to send response. + correlation_id: + Manual message **correlation_id** setter. + **correlation_id** is a useful option to trace messages. + stream: + This option validates that the target subject is in presented stream. + Can be omitted without any effect if you doesn't want PubAck frame. + timeout: + Timeout to send message to NATS. + + Returns: + `faststream.nats.message.NatsMessage` object as an outer subscriber response. + """ cmd = NatsPublishCommand( message=message, correlation_id=correlation_id or gen_cor_id(), @@ -786,7 +756,7 @@ async def request( # type: ignore[override] _publish_type=PublishType.REQUEST, ) - producer = self._state.producer if stream is None else self._js_producer + producer = self._js_producer if stream is not None else self._producer msg: NatsMessage = await super()._basic_request(cmd, producer=producer) return msg @@ -808,9 +778,7 @@ def setup_publisher( # type: ignore[override] self, publisher: "SpecificationPublisher", ) -> None: - producer = ( - self._state.producer if publisher.stream is None else self._js_producer - ) + producer = self._js_producer if publisher.stream is not None else self._producer super().setup_publisher(publisher, producer=producer) @@ -881,7 +849,7 @@ async def wrapper(err: Exception) -> None: await error_cb(err) if isinstance(err, Error) and self._connection_state: - self._state.logger_state.log( + self._state.get().logger_state.log( f"Connection broken with {err!r}", logging.WARNING, c, @@ -902,7 +870,9 @@ async def wrapper() -> None: await cb() if not self._connection_state: - self._state.logger_state.log("Connection established", logging.INFO, c) + self._state.get().logger_state.log( + "Connection established", logging.INFO, c + ) self._connection_state = self._connection_state.reconnect() return wrapper diff --git a/faststream/nats/fastapi/fastapi.py b/faststream/nats/fastapi/fastapi.py index aa449acde7..31adeca227 100644 --- a/faststream/nats/fastapi/fastapi.py +++ b/faststream/nats/fastapi/fastapi.py @@ -37,7 +37,6 @@ from faststream.nats.subscriber.specified import SpecificationSubscriber if TYPE_CHECKING: - import ssl from enum import Enum from fastapi import params @@ -154,22 +153,10 @@ def __init__( bool, Doc("Boolean indicating should commands be echoed."), ] = False, - tls: Annotated[ - Optional["ssl.SSLContext"], - Doc("Some SSL context to make NATS connections secure."), - ] = None, tls_hostname: Annotated[ Optional[str], Doc("Hostname for TLS."), ] = None, - user: Annotated[ - Optional[str], - Doc("Username for NATS auth."), - ] = None, - password: Annotated[ - Optional[str], - Doc("Username password for NATS auth."), - ] = None, token: Annotated[ Optional[str], Doc("Auth token for NATS auth."), @@ -521,10 +508,7 @@ def __init__( dont_randomize=dont_randomize, flusher_queue_size=flusher_queue_size, no_echo=no_echo, - tls=tls, tls_hostname=tls_hostname, - user=user, - password=password, token=token, drain_timeout=drain_timeout, signature_cb=signature_cb, diff --git a/faststream/nats/publisher/producer.py b/faststream/nats/publisher/producer.py index a90bf89ff0..35cf40028e 100644 --- a/faststream/nats/publisher/producer.py +++ b/faststream/nats/publisher/producer.py @@ -1,5 +1,5 @@ import asyncio -from typing import TYPE_CHECKING, Any, Optional +from typing import TYPE_CHECKING, Optional import anyio import nats @@ -20,7 +20,7 @@ if TYPE_CHECKING: from nats.aio.client import Client from nats.aio.msg import Msg - from nats.js import JetStreamContext + from nats.js import JetStreamContext, api from faststream._internal.types import ( AsyncCallable, @@ -64,7 +64,7 @@ async def publish( # type: ignore[override] **cmd.headers_to_publish(), } - await self.__state.connection.publish( + return await self.__state.connection.publish( subject=cmd.destination, payload=payload, reply=cmd.reply_to, @@ -127,7 +127,7 @@ def disconnect(self) -> None: async def publish( # type: ignore[override] self, cmd: "NatsPublishCommand", - ) -> Optional[Any]: + ) -> "api.PubAck": payload, content_type = encode_message(cmd.body) headers_to_send = { @@ -135,7 +135,7 @@ async def publish( # type: ignore[override] **cmd.headers_to_publish(js=True), } - await self.__state.connection.publish( + return await self.__state.connection.publish( subject=cmd.destination, payload=payload, headers=headers_to_send, @@ -143,8 +143,6 @@ async def publish( # type: ignore[override] timeout=cmd.timeout, ) - return None - @override async def request( # type: ignore[override] self, diff --git a/faststream/nats/publisher/usecase.py b/faststream/nats/publisher/usecase.py index b2ca2b3c3e..9d3ccd92dc 100644 --- a/faststream/nats/publisher/usecase.py +++ b/faststream/nats/publisher/usecase.py @@ -1,14 +1,13 @@ from collections.abc import Iterable from typing import ( TYPE_CHECKING, - Annotated, Any, Optional, Union, ) from nats.aio.msg import Msg -from typing_extensions import Doc, override +from typing_extensions import Literal, overload, override from faststream._internal.publisher.usecase import PublisherUsecase from faststream.message import gen_cor_id @@ -16,6 +15,8 @@ from faststream.response.publish_type import PublishType if TYPE_CHECKING: + from nats.js import api + from faststream._internal.basic_types import SendableMessage from faststream._internal.types import BrokerMiddleware, PublisherMiddleware from faststream.nats.message import NatsMessage @@ -63,34 +64,66 @@ def __init__( self.headers = headers or {} self.reply_to = reply_to + @overload + async def publish( + self, + message: "SendableMessage", + subject: str = "", + headers: Optional[dict[str, str]] = None, + reply_to: str = "", + correlation_id: Optional[str] = None, + stream: Literal[None] = None, + timeout: Optional[float] = None, + ) -> None: ... + + @overload + async def publish( + self, + message: "SendableMessage", + subject: str = "", + headers: Optional[dict[str, str]] = None, + reply_to: str = "", + correlation_id: Optional[str] = None, + stream: Optional[str] = None, + timeout: Optional[float] = None, + ) -> "api.PubAck": ... + @override async def publish( self, message: "SendableMessage", subject: str = "", - *, headers: Optional[dict[str, str]] = None, reply_to: str = "", correlation_id: Optional[str] = None, stream: Optional[str] = None, timeout: Optional[float] = None, - ) -> None: + ) -> Optional["api.PubAck"]: """Publish message directly. Args: - message (SendableMessage): Message body to send. + message: + Message body to send. Can be any encodable object (native python types or `pydantic.BaseModel`). - subject (str): NATS subject to send message (default is `''`). - headers (:obj:`dict` of :obj:`str`: :obj:`str`, optional): Message headers to store metainformation (default is `None`). + subject: + NATS subject to send message. + headers: + Message headers to store metainformation. **content-type** and **correlation_id** will be set automatically by framework anyway. - - reply_to (str): NATS subject name to send response (default is `None`). - correlation_id (str, optional): Manual message **correlation_id** setter (default is `None`). + reply_to: + NATS subject name to send response. + correlation_id: + Manual message **correlation_id** setter. **correlation_id** is a useful option to trace messages. - - stream (str, optional): This option validates that the target subject is in presented stream (default is `None`). - Can be omitted without any effect. - timeout (float, optional): Timeout to send message to NATS in seconds (default is `None`). + stream: + This option validates that the target subject is in presented stream. + Can be omitted without any effect if you doesn't want PubAck frame. + timeout: + Timeout to send message to NATS. + + Returns: + `None` if you publishes a regular message. + `nats.js.api.PubAck` if you publishes a message to stream. """ cmd = NatsPublishCommand( message, @@ -127,37 +160,40 @@ async def _publish( @override async def request( self, - message: Annotated[ - "SendableMessage", - Doc( - "Message body to send. " - "Can be any encodable object (native python types or `pydantic.BaseModel`).", - ), - ], - subject: Annotated[ - str, - Doc("NATS subject to send message."), - ] = "", - *, - headers: Annotated[ - Optional[dict[str, str]], - Doc( - "Message headers to store metainformation. " - "**content-type** and **correlation_id** will be set automatically by framework anyway.", - ), - ] = None, - correlation_id: Annotated[ - Optional[str], - Doc( - "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages.", - ), - ] = None, - timeout: Annotated[ - float, - Doc("Timeout to send message to NATS."), - ] = 0.5, + message: "SendableMessage", + subject: str = "", + headers: Optional[dict[str, str]] = None, + correlation_id: Optional[str] = None, + timeout: float = 0.5, ) -> "NatsMessage": + """Make a synchronous request to outer subscriber. + + If out subscriber listens subject by stream, you should setup the same **stream** explicitly. + Another way you will reseave confirmation frame as a response. + + Note: + To setup **stream** option, please use `__init__` method. + + Args: + message: + Message body to send. + Can be any encodable object (native python types or `pydantic.BaseModel`). + subject: + NATS subject to send message. + headers: + Message headers to store metainformation. + **content-type** and **correlation_id** will be set automatically by framework anyway. + reply_to: + NATS subject name to send response. + correlation_id: + Manual message **correlation_id** setter. + **correlation_id** is a useful option to trace messages. + timeout: + Timeout to send message to NATS. + + Returns: + `faststream.nats.message.NatsMessage` object as an outer subscriber response. + """ cmd = NatsPublishCommand( message=message, subject=subject or self.subject, diff --git a/faststream/nats/subscriber/factory.py b/faststream/nats/subscriber/factory.py index deb852bcfd..a679353c65 100644 --- a/faststream/nats/subscriber/factory.py +++ b/faststream/nats/subscriber/factory.py @@ -1,6 +1,6 @@ +import warnings from collections.abc import Iterable from typing import TYPE_CHECKING, Any, Optional, Union -import warnings from nats.aio.subscription import ( DEFAULT_SUB_PENDING_BYTES_LIMIT, diff --git a/faststream/nats/subscriber/usecase.py b/faststream/nats/subscriber/usecase.py index b04c5cc6d0..7dc7cd1cc1 100644 --- a/faststream/nats/subscriber/usecase.py +++ b/faststream/nats/subscriber/usecase.py @@ -52,7 +52,10 @@ SendableMessage, ) from faststream._internal.publisher.proto import BasePublisherProto, ProducerProto - from faststream._internal.state import BrokerState as BasicState + from faststream._internal.state import ( + BrokerState as BasicState, + Pointer, + ) from faststream._internal.types import ( AsyncCallable, BrokerMiddleware, @@ -128,7 +131,7 @@ def _setup( # type: ignore[override] broker_parser: Optional["CustomCallable"], broker_decoder: Optional["CustomCallable"], # dependant args - state: "BasicState", + state: "Pointer[BasicState]", ) -> None: self._connection_state = ConnectedSubscriberState( parent_state=connection_state, @@ -260,7 +263,7 @@ def _make_response_publisher( """Create Publisher objects to use it as one of `publishers` in `self.consume` scope.""" return ( NatsFakePublisher( - producer=self._state.producer, + producer=self._state.get().producer, subject=message.reply_to, ), ) @@ -347,11 +350,12 @@ async def get_one( except TimeoutError: return None + context = self._state.get().di_state.context + msg: NatsMessage = await process_msg( # type: ignore[assignment] msg=raw_message, middlewares=( - m(raw_message, context=self._state.di_state.context) - for m in self._broker_middlewares + m(raw_message, context=context) for m in self._broker_middlewares ), parser=self._parser, decoder=self._decoder, @@ -539,11 +543,12 @@ async def get_one( except (TimeoutError, ConnectionClosedError): return None + context = self._state.get().di_state.context + msg: NatsMessage = await process_msg( # type: ignore[assignment] msg=raw_message, middlewares=( - m(raw_message, context=self._state.di_state.context) - for m in self._broker_middlewares + m(raw_message, context=context) for m in self._broker_middlewares ), parser=self._parser, decoder=self._decoder, @@ -849,13 +854,14 @@ async def get_one( except TimeoutError: return None + context = self._state.get().di_state.context + return cast( NatsMessage, await process_msg( msg=raw_message, middlewares=( - m(raw_message, context=self._state.di_state.context) - for m in self._broker_middlewares + m(raw_message, context=context) for m in self._broker_middlewares ), parser=self._parser, decoder=self._decoder, @@ -966,11 +972,12 @@ async def get_one( ) is None: await anyio.sleep(sleep_interval) + context = self._state.get().di_state.context + msg: NatsKvMessage = await process_msg( msg=raw_message, middlewares=( - m(raw_message, context=self._state.di_state.context) - for m in self._broker_middlewares + m(raw_message, context=context) for m in self._broker_middlewares ), parser=self._parser, decoder=self._decoder, @@ -1120,11 +1127,12 @@ async def get_one( ) is None: await anyio.sleep(sleep_interval) + context = self._state.get().di_state.context + msg: NatsObjMessage = await process_msg( msg=raw_message, middlewares=( - m(raw_message, context=self._state.di_state.context) - for m in self._broker_middlewares + m(raw_message, context=context) for m in self._broker_middlewares ), parser=self._parser, decoder=self._decoder, @@ -1155,6 +1163,8 @@ async def __consume_watch(self) -> None: self.subscription = UnsubscribeAdapter["ObjectStore.ObjectWatcher"](obj_watch) + context = self._state.get().di_state.context + while self.running: with suppress(TimeoutError): message = cast( @@ -1164,9 +1174,7 @@ async def __consume_watch(self) -> None: ) if message: - with self._state.di_state.context.scope( - OBJECT_STORAGE_CONTEXT_KEY, self.bucket - ): + with context.scope(OBJECT_STORAGE_CONTEXT_KEY, self.bucket): await self.consume(message) def _make_response_publisher( diff --git a/faststream/nats/testing.py b/faststream/nats/testing.py index c91fd5529b..f417d9e63e 100644 --- a/faststream/nats/testing.py +++ b/faststream/nats/testing.py @@ -57,10 +57,15 @@ def create_publisher_fake_subscriber( @contextmanager def _patch_producer(self, broker: NatsBroker) -> Iterator[None]: - old_js_producer, old_producer = broker._js_producer, broker._state.producer - broker._js_producer = broker._state.producer = FakeProducer(broker) - yield - broker._js_producer, broker._state.producer = old_js_producer, old_producer + old_js_producer, old_producer = broker._js_producer, broker._producer + fake_producer = broker._js_producer = FakeProducer(broker) + + broker._state.patch_value(producer=fake_producer) + try: + yield + finally: + broker._js_producer = old_js_producer + broker._state.patch_value(producer=old_producer) async def _fake_connect( self, diff --git a/faststream/rabbit/broker/broker.py b/faststream/rabbit/broker/broker.py index 7ba92c36c1..b0e60e62cf 100644 --- a/faststream/rabbit/broker/broker.py +++ b/faststream/rabbit/broker/broker.py @@ -18,6 +18,7 @@ from faststream.__about__ import SERVICE_NAME from faststream._internal.broker.broker import BrokerUsecase from faststream._internal.constants import EMPTY +from faststream._internal.publisher.proto import PublisherProto from faststream.message import gen_cor_id from faststream.rabbit.helpers.declarer import RabbitDeclarer from faststream.rabbit.publisher.producer import AioPikaFastProducer @@ -292,10 +293,12 @@ def __init__( self._channel = None declarer = self.declarer = RabbitDeclarer() - self._state.producer = AioPikaFastProducer( - declarer=declarer, - decoder=self._decoder, - parser=self._parser, + self._state.patch_value( + producer=AioPikaFastProducer( + declarer=declarer, + decoder=self._decoder, + parser=self._parser, + ) ) @property @@ -307,13 +310,21 @@ def _subscriber_setup_extra(self) -> "AnyDict": "declarer": self.declarer, } - @property - def _publisher_setup_extra(self) -> "AnyDict": - return { - **super()._publisher_setup_extra, - "app_id": self.app_id, - "virtual_host": self.virtual_host, - } + def setup_publisher( + self, + publisher: PublisherProto[IncomingMessage], + **kwargs: Any, + ) -> None: + return super().setup_publisher( + publisher, + **( + { + "app_id": self.app_id, + "virtual_host": self.virtual_host, + } + | kwargs + ), + ) @override async def connect( # type: ignore[override] @@ -509,8 +520,9 @@ async def start(self) -> None: await super().start() + logger_state = self._state.get().logger_state if self._max_consumers: - self._state.logger_state.log(f"Set max consumers to {self._max_consumers}") + logger_state.log(f"Set max consumers to {self._max_consumers}") @override async def publish( # type: ignore[override] diff --git a/faststream/rabbit/publisher/usecase.py b/faststream/rabbit/publisher/usecase.py index bc24c1af48..f34cf06b3c 100644 --- a/faststream/rabbit/publisher/usecase.py +++ b/faststream/rabbit/publisher/usecase.py @@ -105,7 +105,6 @@ def __init__( def _setup( # type: ignore[override] self, *, - producer: Optional["AioPikaFastProducer"], app_id: Optional[str], virtual_host: str, state: "BrokerState", @@ -116,7 +115,7 @@ def _setup( # type: ignore[override] self.virtual_host = virtual_host - super()._setup(producer=producer, state=state) + super()._setup(state=state) @property def routing(self) -> str: diff --git a/faststream/rabbit/subscriber/usecase.py b/faststream/rabbit/subscriber/usecase.py index 29e1d738cd..d659977ddf 100644 --- a/faststream/rabbit/subscriber/usecase.py +++ b/faststream/rabbit/subscriber/usecase.py @@ -187,11 +187,12 @@ async def get_one( ) is None: await anyio.sleep(sleep_interval) + context = self._state.get().di_state.context + msg: Optional[RabbitMessage] = await process_msg( # type: ignore[assignment] msg=raw_message, middlewares=( - m(raw_message, context=self._state.di_state.context) - for m in self._broker_middlewares + m(raw_message, context=context) for m in self._broker_middlewares ), parser=self._parser, decoder=self._decoder, @@ -204,7 +205,7 @@ def _make_response_publisher( ) -> Sequence["BasePublisherProto"]: return ( RabbitFakePublisher( - self._state.producer, + self._state.get().producer, routing_key=message.reply_to, app_id=self.app_id, ), diff --git a/faststream/rabbit/testing.py b/faststream/rabbit/testing.py index 3aa50e6dc5..97b5619184 100644 --- a/faststream/rabbit/testing.py +++ b/faststream/rabbit/testing.py @@ -58,10 +58,10 @@ def _patch_broker(self, broker: "RabbitBroker") -> Generator[None, None, None]: @contextmanager def _patch_producer(self, broker: RabbitBroker) -> Iterator[None]: - old_producer = broker._state.producer - broker._state.producer = FakeProducer(broker) + old_producer = broker._state.get().producer + broker._state.patch_value(producer=FakeProducer(broker)) yield - broker._state.producer = old_producer + broker._state.patch_value(producer=old_producer) @staticmethod async def _fake_connect(broker: "RabbitBroker", *args: Any, **kwargs: Any) -> None: diff --git a/faststream/redis/broker/broker.py b/faststream/redis/broker/broker.py index c1982d6236..8b5a0a0017 100644 --- a/faststream/redis/broker/broker.py +++ b/faststream/redis/broker/broker.py @@ -248,9 +248,11 @@ def __init__( _call_decorators=_call_decorators, ) - self._state.producer = RedisFastProducer( - parser=self._parser, - decoder=self._decoder, + self._state.patch_value( + producer=RedisFastProducer( + parser=self._parser, + decoder=self._decoder, + ) ) @override @@ -402,7 +404,7 @@ async def publish( # type: ignore[override] "Remove eldest message if maxlen exceeded.", ), ] = None, - ) -> None: + ) -> int: """Publish message directly. This method allows you to publish message in not AsyncAPI-documented way. You can use it in another frameworks @@ -421,7 +423,7 @@ async def publish( # type: ignore[override] headers=headers, _publish_type=PublishType.PUBLISH, ) - await super()._basic_publish(cmd, producer=self._producer) + return await super()._basic_publish(cmd, producer=self._producer) @override async def request( # type: ignore[override] @@ -475,7 +477,7 @@ async def publish_batch( Optional["AnyDict"], Doc("Message headers to store metainformation."), ] = None, - ) -> None: + ) -> int: """Publish multiple messages to Redis List by one request.""" cmd = RedisPublishCommand( *messages, @@ -486,7 +488,7 @@ async def publish_batch( _publish_type=PublishType.PUBLISH, ) - await self._basic_publish_batch(cmd, producer=self._producer) + return await self._basic_publish_batch(cmd, producer=self._producer) @override async def ping(self, timeout: Optional[float]) -> bool: diff --git a/faststream/redis/publisher/producer.py b/faststream/redis/publisher/producer.py index fe6c050202..77fa98f5ca 100644 --- a/faststream/redis/publisher/producer.py +++ b/faststream/redis/publisher/producer.py @@ -57,7 +57,7 @@ def disconnect(self) -> None: async def publish( # type: ignore[override] self, cmd: "RedisPublishCommand", - ) -> None: + ) -> int: msg = RawMessage.encode( message=cmd.body, reply_to=cmd.reply_to, @@ -65,7 +65,7 @@ async def publish( # type: ignore[override] correlation_id=cmd.correlation_id, ) - await self.__publish(msg, cmd) + return await self.__publish(msg, cmd) @override async def request( # type: ignore[override] @@ -111,7 +111,7 @@ async def request( # type: ignore[override] async def publish_batch( self, cmd: "RedisPublishCommand", - ) -> None: + ) -> int: batch = [ RawMessage.encode( message=msg, @@ -121,7 +121,7 @@ async def publish_batch( ) for msg in cmd.batch_bodies ] - await self._connection.client.rpush(cmd.destination, *batch) + return await self._connection.client.rpush(cmd.destination, *batch) async def __publish(self, msg: bytes, cmd: "RedisPublishCommand") -> None: if cmd.destination_type is DestinationType.Channel: diff --git a/faststream/redis/publisher/usecase.py b/faststream/redis/publisher/usecase.py index 09c1fae294..479b9ccf66 100644 --- a/faststream/redis/publisher/usecase.py +++ b/faststream/redis/publisher/usecase.py @@ -23,7 +23,7 @@ class LogicPublisher(PublisherUsecase[UnifyRedisDict]): """A class to represent a Redis publisher.""" - _producer: Optional["RedisFastProducer"] + _producer: "RedisFastProducer" def __init__( self, @@ -52,8 +52,6 @@ def __init__( self.reply_to = reply_to self.headers = headers or {} - self._producer = None - @abstractmethod def subscriber_property(self, *, name_only: bool) -> "AnyDict": raise NotImplementedError @@ -127,7 +125,7 @@ async def publish( "**correlation_id** is a useful option to trace messages.", ), ] = None, - ) -> None: + ) -> int: cmd = RedisPublishCommand( message, channel=channel or self.channel.name, @@ -136,7 +134,7 @@ async def publish( correlation_id=correlation_id or gen_cor_id(), _publish_type=PublishType.PUBLISH, ) - await self._basic_publish(cmd, _extra_middlewares=()) + return await self._basic_publish(cmd, _extra_middlewares=()) @override async def _publish( @@ -264,7 +262,7 @@ async def publish( "**correlation_id** is a useful option to trace messages.", ), ] = None, - ) -> None: + ) -> int: cmd = RedisPublishCommand( message, list=list or self.list.name, @@ -361,7 +359,7 @@ async def publish( # type: ignore[override] Optional["AnyDict"], Doc("Message headers to store metainformation."), ] = None, - ) -> None: + ) -> int: cmd = RedisPublishCommand( *messages, list=list or self.list.name, @@ -371,7 +369,7 @@ async def publish( # type: ignore[override] _publish_type=PublishType.PUBLISH, ) - await self._basic_publish_batch(cmd, _extra_middlewares=()) + return await self._basic_publish_batch(cmd, _extra_middlewares=()) @override async def _publish( # type: ignore[override] @@ -467,7 +465,7 @@ async def publish( "Remove eldest message if maxlen exceeded.", ), ] = None, - ) -> None: + ) -> Any: cmd = RedisPublishCommand( message, stream=stream or self.stream.name, diff --git a/faststream/redis/subscriber/usecase.py b/faststream/redis/subscriber/usecase.py index 9c8ca4ddd5..a424e409b2 100644 --- a/faststream/redis/subscriber/usecase.py +++ b/faststream/redis/subscriber/usecase.py @@ -126,7 +126,7 @@ def _make_response_publisher( ) -> Sequence["BasePublisherProto"]: return ( RedisFakePublisher( - self._state.producer, + self._state.get().producer, channel=message.reply_to, ), ) @@ -284,11 +284,12 @@ async def get_one( # type: ignore[override] while (raw_message := await self._get_message(self.subscription)) is None: # noqa: ASYNC110 await anyio.sleep(sleep_interval) + context = self._state.get().di_state.context + msg: Optional[RedisMessage] = await process_msg( # type: ignore[assignment] msg=raw_message, middlewares=( - m(raw_message, context=self._state.di_state.context) - for m in self._broker_middlewares + m(raw_message, context=context) for m in self._broker_middlewares ), parser=self._parser, decoder=self._decoder, @@ -411,11 +412,12 @@ async def get_one( # type: ignore[override] channel=self.list_sub.name, ) + context = self._state.get().di_state.context + msg: RedisListMessage = await process_msg( # type: ignore[assignment] msg=redis_incoming_msg, middlewares=( - m(redis_incoming_msg, context=self._state.di_state.context) - for m in self._broker_middlewares + m(redis_incoming_msg, context=context) for m in self._broker_middlewares ), parser=self._parser, decoder=self._decoder, @@ -699,11 +701,12 @@ async def get_one( # type: ignore[override] data=raw_message, ) + context = self._state.get().di_state.context + msg: RedisStreamMessage = await process_msg( # type: ignore[assignment] msg=redis_incoming_msg, middlewares=( - m(redis_incoming_msg, context=self._state.di_state.context) - for m in self._broker_middlewares + m(redis_incoming_msg, context=context) for m in self._broker_middlewares ), parser=self._parser, decoder=self._decoder, diff --git a/faststream/redis/testing.py b/faststream/redis/testing.py index e3584fbcb0..558a0fd5ae 100644 --- a/faststream/redis/testing.py +++ b/faststream/redis/testing.py @@ -75,10 +75,10 @@ def create_publisher_fake_subscriber( @contextmanager def _patch_producer(self, broker: RedisBroker) -> Iterator[None]: - old_producer = broker._state.producer - broker._state.producer = FakeProducer(broker) + old_producer = broker._state.get().producer + broker._state.patch_value(producer=FakeProducer(broker)) yield - broker._state.producer = old_producer + broker._state.patch_value(producer=old_producer) @staticmethod async def _fake_connect( # type: ignore[override] diff --git a/tests/brokers/base/testclient.py b/tests/brokers/base/testclient.py index bd342fcb1f..63a15c4343 100644 --- a/tests/brokers/base/testclient.py +++ b/tests/brokers/base/testclient.py @@ -129,19 +129,19 @@ async def test_broker_gets_patched_attrs_within_cm(self, fake_producer_cls) -> N test_broker = self.get_broker() await test_broker.start() - old_producer = test_broker._state.producer + old_producer = test_broker._producer async with self.patch_broker(test_broker) as br: assert isinstance(br.start, Mock) assert isinstance(br._connect, Mock) assert isinstance(br.close, Mock) - assert isinstance(br._state.producer, fake_producer_cls) + assert isinstance(br._producer, fake_producer_cls) assert not isinstance(br.start, Mock) assert not isinstance(br._connect, Mock) assert not isinstance(br.close, Mock) assert br._connection is not None - assert br._state.producer == old_producer + assert br._producer == old_producer async def test_broker_with_real_doesnt_get_patched(self) -> None: test_broker = self.get_broker() diff --git a/tests/brokers/nats/test_consume.py b/tests/brokers/nats/test_consume.py index d253bcb716..c7359c2ba5 100644 --- a/tests/brokers/nats/test_consume.py +++ b/tests/brokers/nats/test_consume.py @@ -4,6 +4,7 @@ import pytest from nats.aio.msg import Msg +from nats.js.api import PubAck from faststream import AckPolicy from faststream.exceptions import AckMessage @@ -32,7 +33,7 @@ def subscriber(m) -> None: async with self.patch_broker(consume_broker) as br: await br.start() - await asyncio.wait( + completed, _ = await asyncio.wait( ( asyncio.create_task(br.publish("hello", queue, stream=stream.name)), asyncio.create_task(event.wait()), @@ -40,7 +41,14 @@ def subscriber(m) -> None: timeout=3, ) + publish_with_stream_returns_ack_frame = False + for task in completed: + if isinstance(task.result(), PubAck): + publish_with_stream_returns_ack_frame = True + break + assert event.is_set() + assert publish_with_stream_returns_ack_frame async def test_consume_with_filter( self, diff --git a/tests/cli/rabbit/test_logs.py b/tests/cli/rabbit/test_logs.py index 4cef8e2a76..4ac67ae728 100644 --- a/tests/cli/rabbit/test_logs.py +++ b/tests/cli/rabbit/test_logs.py @@ -21,8 +21,9 @@ def test_set_level(level, app: FastStream) -> None: level = get_log_level(level) set_log_level(level, app) - app.broker._state._setup_logger_state() - broker_logger = app.broker._state.logger_state.logger.logger + broker_state = app.broker._state.get() + broker_state._setup_logger_state() + broker_logger = broker_state.logger_state.logger.logger assert app.logger.level is broker_logger.level is level diff --git a/tests/cli/test_publish.py b/tests/cli/test_publish.py index 5d1f57b82a..3f55bd6e82 100644 --- a/tests/cli/test_publish.py +++ b/tests/cli/test_publish.py @@ -31,7 +31,7 @@ def get_mock_app(broker_type, producer_type) -> tuple[FastStream, AsyncMock]: mock_producer.publish = AsyncMock() mock_producer._parser = AsyncMock() mock_producer._decoder = AsyncMock() - broker._state.producer = mock_producer + broker._state.patch_value(producer=mock_producer) return FastStream(broker), mock_producer From 362f6c9a9e54f451b8525696d25a3da5984a5d73 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Fri, 8 Nov 2024 19:18:36 +0300 Subject: [PATCH 189/245] refactor: create default middlewares in runtime --- faststream/_internal/_compat.py | 5 - faststream/_internal/broker/broker.py | 6 - faststream/_internal/publisher/proto.py | 4 - faststream/_internal/publisher/specified.py | 88 ++++++++++ faststream/_internal/publisher/usecase.py | 150 +++++------------- .../_internal/state/logger/logger_proxy.py | 55 +++---- .../_internal/state/logger/params_storage.py | 2 +- faststream/_internal/state/logger/state.py | 4 +- .../_internal/subscriber/call_wrapper/call.py | 39 +++-- faststream/_internal/subscriber/proto.py | 2 - faststream/_internal/subscriber/specified.py | 70 ++++++++ faststream/_internal/subscriber/usecase.py | 114 +++++-------- faststream/confluent/response.py | 21 ++- faststream/kafka/response.py | 21 ++- .../middlewares/acknowledgement/middleware.py | 52 +++--- faststream/middlewares/logging.py | 1 + faststream/redis/response.py | 21 ++- faststream/redis/schemas/proto.py | 4 +- faststream/redis/subscriber/usecase.py | 14 +- faststream/specification/base/proto.py | 2 +- tests/brokers/base/router.py | 27 ++-- tests/brokers/base/testclient.py | 19 +++ .../brokers/confluent/test_publish_command.py | 1 + tests/brokers/kafka/test_publish_command.py | 1 + tests/brokers/redis/test_publish_command.py | 1 + 25 files changed, 410 insertions(+), 314 deletions(-) create mode 100644 faststream/_internal/publisher/specified.py create mode 100644 faststream/_internal/subscriber/specified.py diff --git a/faststream/_internal/_compat.py b/faststream/_internal/_compat.py index fd0ab263fb..8965fc951b 100644 --- a/faststream/_internal/_compat.py +++ b/faststream/_internal/_compat.py @@ -1,5 +1,4 @@ import json -import os import sys import warnings from collections.abc import Iterable, Mapping @@ -28,10 +27,6 @@ ModelVar = TypeVar("ModelVar", bound=BaseModel) -def is_test_env() -> bool: - return bool(os.getenv("PYTEST_CURRENT_TEST")) - - json_dumps: Callable[..., bytes] orjson: Any ujson: Any diff --git a/faststream/_internal/broker/broker.py b/faststream/_internal/broker/broker.py index 591b14d903..9914040cb3 100644 --- a/faststream/_internal/broker/broker.py +++ b/faststream/_internal/broker/broker.py @@ -34,7 +34,6 @@ MsgType, ) from faststream._internal.utils.functions import to_async -from faststream.middlewares.logging import CriticalLogMiddleware from .abc_broker import ABCBroker from .pub_base import BrokerPublishMixin @@ -172,11 +171,6 @@ def __init__( self._connection_kwargs = connection_kwargs self._connection = None - self.middlewares = ( - CriticalLogMiddleware(logger_state), - *self.middlewares, - ) - # AsyncAPI information self.url = specification_url self.protocol = protocol diff --git a/faststream/_internal/publisher/proto.py b/faststream/_internal/publisher/proto.py index 710cc65944..31d66c0268 100644 --- a/faststream/_internal/publisher/proto.py +++ b/faststream/_internal/publisher/proto.py @@ -7,7 +7,6 @@ from faststream._internal.proto import Endpoint from faststream._internal.types import MsgType from faststream.response.response import PublishCommand -from faststream.specification.base.proto import EndpointProto if TYPE_CHECKING: from faststream._internal.basic_types import SendableMessage @@ -89,13 +88,10 @@ async def request( class PublisherProto( - EndpointProto, Endpoint, BasePublisherProto, Generic[MsgType], ): - schema_: Any - _broker_middlewares: Iterable["BrokerMiddleware[MsgType]"] _middlewares: Iterable["PublisherMiddleware"] _producer: Optional["ProducerProto"] diff --git a/faststream/_internal/publisher/specified.py b/faststream/_internal/publisher/specified.py new file mode 100644 index 0000000000..8ad62a1d00 --- /dev/null +++ b/faststream/_internal/publisher/specified.py @@ -0,0 +1,88 @@ +from inspect import Parameter, unwrap +from typing import TYPE_CHECKING, Any, Optional + +from fast_depends.core import build_call_model +from fast_depends.pydantic._compat import create_model, get_config_base + +from faststream._internal.publisher.proto import PublisherProto +from faststream._internal.subscriber.call_wrapper.call import HandlerCallWrapper +from faststream._internal.types import ( + MsgType, + P_HandlerParams, + T_HandlerReturn, +) +from faststream.specification.asyncapi.message import get_model_schema +from faststream.specification.asyncapi.utils import to_camelcase +from faststream.specification.base.proto import SpecificationEndpoint + +if TYPE_CHECKING: + from faststream._internal.basic_types import AnyDict + + +class BaseSpicificationPublisher(SpecificationEndpoint, PublisherProto[MsgType]): + """A base class for publishers in an asynchronous API.""" + + def __init__( + self, + *, + schema_: Optional[Any], + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, + ) -> None: + self.calls = [] + + self.title_ = title_ + self.description_ = description_ + self.include_in_schema = include_in_schema + self.schema_ = schema_ + + def __call__( + self, + func: HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn], + ) -> HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]: + self.calls.append(func._original_call) + return func + + def get_payloads(self) -> list[tuple["AnyDict", str]]: + payloads: list[tuple[AnyDict, str]] = [] + + if self.schema_: + body = get_model_schema( + call=create_model( + "", + __config__=get_config_base(), + response__=(self.schema_, ...), + ), + prefix=f"{self.name}:Message", + ) + + if body: # pragma: no branch + payloads.append((body, "")) + + else: + di_state = self._state.get().di_state + + for call in self.calls: + call_model = build_call_model( + call, + dependency_provider=di_state.provider, + serializer_cls=di_state.serializer, + ) + + response_type = next( + iter(call_model.serializer.response_option.values()) + ).field_type + if response_type is not None and response_type is not Parameter.empty: + body = get_model_schema( + create_model( + "", + __config__=get_config_base(), + response__=(response_type, ...), + ), + prefix=f"{self.name}:Message", + ) + if body: + payloads.append((body, to_camelcase(unwrap(call).__name__))) + + return payloads diff --git a/faststream/_internal/publisher/usecase.py b/faststream/_internal/publisher/usecase.py index f1d1e276fb..c729a5b13d 100644 --- a/faststream/_internal/publisher/usecase.py +++ b/faststream/_internal/publisher/usecase.py @@ -1,23 +1,24 @@ from collections.abc import Awaitable, Iterable from functools import partial -from inspect import Parameter, unwrap from itertools import chain from typing import ( TYPE_CHECKING, - Annotated, Any, Callable, Optional, + Union, ) from unittest.mock import MagicMock -from fast_depends.core import build_call_model -from fast_depends.pydantic._compat import create_model, get_config_base -from typing_extensions import Doc, override +from typing_extensions import override from faststream._internal.publisher.proto import PublisherProto +from faststream._internal.state import BrokerState, EmptyBrokerState, Pointer from faststream._internal.state.producer import ProducerUnset -from faststream._internal.subscriber.call_wrapper.call import HandlerCallWrapper +from faststream._internal.subscriber.call_wrapper.call import ( + HandlerCallWrapper, + ensure_call_wrapper, +) from faststream._internal.subscriber.utils import process_msg from faststream._internal.types import ( MsgType, @@ -25,15 +26,11 @@ T_HandlerReturn, ) from faststream.message.source_type import SourceType -from faststream.specification.asyncapi.message import ( - get_model_schema, -) -from faststream.specification.asyncapi.utils import to_camelcase + +from .specified import BaseSpicificationPublisher if TYPE_CHECKING: - from faststream._internal.basic_types import AnyDict from faststream._internal.publisher.proto import ProducerProto - from faststream._internal.state import BrokerState, Pointer from faststream._internal.types import ( BrokerMiddleware, PublisherMiddleware, @@ -41,58 +38,38 @@ from faststream.response.response import PublishCommand -class PublisherUsecase(PublisherProto[MsgType]): +class PublisherUsecase(BaseSpicificationPublisher, PublisherProto[MsgType]): """A base class for publishers in an asynchronous API.""" - mock: Optional[MagicMock] - calls: list[Callable[..., Any]] - def __init__( self, *, - broker_middlewares: Annotated[ - Iterable["BrokerMiddleware[MsgType]"], - Doc("Top-level middlewares to use in direct `.publish` call."), - ], - middlewares: Annotated[ - Iterable["PublisherMiddleware"], - Doc("Publisher middlewares."), - ], + broker_middlewares: Iterable["BrokerMiddleware[MsgType]"], + middlewares: Iterable["PublisherMiddleware"], # AsyncAPI args - schema_: Annotated[ - Optional[Any], - Doc( - "AsyncAPI publishing message type" - "Should be any python-native object annotation or `pydantic.BaseModel`.", - ), - ], - title_: Annotated[ - Optional[str], - Doc("AsyncAPI object title."), - ], - description_: Annotated[ - Optional[str], - Doc("AsyncAPI object description."), - ], - include_in_schema: Annotated[ - bool, - Doc("Whetever to include operation in AsyncAPI schema or not."), - ], + schema_: Optional[Any], + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, ) -> None: - self.calls = [] self.middlewares = middlewares self._broker_middlewares = broker_middlewares self.__producer: Optional[ProducerProto] = ProducerUnset() self._fake_handler = False - self.mock = None + self.mock: Optional[MagicMock] = None - # AsyncAPI - self.title_ = title_ - self.description_ = description_ - self.include_in_schema = include_in_schema - self.schema_ = schema_ + super().__init__( + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + schema_=schema_, + ) + + self._state: Pointer[BrokerState] = Pointer( + EmptyBrokerState("You should include publisher to any broker.") + ) def add_middleware(self, middleware: "BrokerMiddleware[MsgType]") -> None: self._broker_middlewares = (*self._broker_middlewares, middleware) @@ -108,21 +85,14 @@ def _setup( # type: ignore[override] state: "Pointer[BrokerState]", producer: Optional["ProducerProto"] = None, ) -> None: - # TODO: add EmptyBrokerState to init self._state = state self.__producer = producer def set_test( self, *, - mock: Annotated[ - MagicMock, - Doc("Mock object to check in tests."), - ], - with_fake: Annotated[ - bool, - Doc("Whetevet publisher's fake subscriber created or not."), - ], + mock: MagicMock, + with_fake: bool, ) -> None: """Turn publisher to testing mode.""" self.mock = mock @@ -135,17 +105,18 @@ def reset_test(self) -> None: def __call__( self, - func: Callable[P_HandlerParams, T_HandlerReturn], + func: Union[ + Callable[P_HandlerParams, T_HandlerReturn], + HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn], + ], ) -> HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]: """Decorate user's function by current publisher.""" - handler_call = HandlerCallWrapper[ - MsgType, - P_HandlerParams, - T_HandlerReturn, - ](func) - handler_call._publishers.append(self) - self.calls.append(handler_call._original_call) - return handler_call + handler: HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn] = ( + ensure_call_wrapper(func) + ) + handler._publishers.append(self) + super().__call__(handler) + return handler async def _basic_publish( self, @@ -221,46 +192,3 @@ async def _basic_publish_batch( pub = partial(pub_m, pub) await pub(cmd) - - def get_payloads(self) -> list[tuple["AnyDict", str]]: - payloads: list[tuple[AnyDict, str]] = [] - - if self.schema_: - body = get_model_schema( - call=create_model( - "", - __config__=get_config_base(), - response__=(self.schema_, ...), - ), - prefix=f"{self.name}:Message", - ) - - if body: # pragma: no branch - payloads.append((body, "")) - - else: - di_state = self._state.get().di_state - - for call in self.calls: - call_model = build_call_model( - call, - dependency_provider=di_state.provider, - serializer_cls=di_state.serializer, - ) - - response_type = next( - iter(call_model.serializer.response_option.values()) - ).field_type - if response_type is not None and response_type is not Parameter.empty: - body = get_model_schema( - create_model( - "", - __config__=get_config_base(), - response__=(response_type, ...), - ), - prefix=f"{self.name}:Message", - ) - if body: - payloads.append((body, to_camelcase(unwrap(call).__name__))) - - return payloads diff --git a/faststream/_internal/state/logger/logger_proxy.py b/faststream/_internal/state/logger/logger_proxy.py index a7ca07b920..690a42c6dd 100644 --- a/faststream/_internal/state/logger/logger_proxy.py +++ b/faststream/_internal/state/logger/logger_proxy.py @@ -1,24 +1,15 @@ -from typing import TYPE_CHECKING, Optional, Protocol +from collections.abc import Mapping +from typing import Any, Optional +from faststream._internal.basic_types import LoggerProto from faststream.exceptions import IncorrectState -if TYPE_CHECKING: - from faststream._internal.basic_types import AnyDict, LoggerProto - -class LoggerObject(Protocol): +class LoggerObject(LoggerProto): logger: Optional["LoggerProto"] def __bool__(self) -> bool: ... - def log( - self, - message: str, - log_level: int, - extra: Optional["AnyDict"] = None, - exc_info: Optional[Exception] = None, - ) -> None: ... - class NotSetLoggerObject(LoggerObject): """Default logger proxy for state. @@ -37,13 +28,15 @@ def __repr__(self) -> str: def log( self, - message: str, - log_level: int, - extra: Optional["AnyDict"] = None, - exc_info: Optional[Exception] = None, + level: int, + msg: Any, + /, + *, + exc_info: Any = None, + extra: Optional[Mapping[str, Any]] = None, ) -> None: - msg = "Logger object not set. Please, call `_setup_logger_state` of parent broker state." - raise IncorrectState(msg) + err_msg = "Logger object not set. Please, call `_setup_logger_state` of parent broker state." + raise IncorrectState(err_msg) class EmptyLoggerObject(LoggerObject): @@ -63,10 +56,12 @@ def __repr__(self) -> str: def log( self, - message: str, - log_level: int, - extra: Optional["AnyDict"] = None, - exc_info: Optional[Exception] = None, + level: int, + msg: Any, + /, + *, + exc_info: Any = None, + extra: Optional[Mapping[str, Any]] = None, ) -> None: pass @@ -89,14 +84,16 @@ def __repr__(self) -> str: def log( self, - message: str, - log_level: int, - extra: Optional["AnyDict"] = None, - exc_info: Optional[Exception] = None, + level: int, + msg: Any, + /, + *, + exc_info: Any = None, + extra: Optional[Mapping[str, Any]] = None, ) -> None: self.logger.log( - log_level, - message, + level, + msg, extra=extra, exc_info=exc_info, ) diff --git a/faststream/_internal/state/logger/params_storage.py b/faststream/_internal/state/logger/params_storage.py index c63e0b8e99..ee12344a7a 100644 --- a/faststream/_internal/state/logger/params_storage.py +++ b/faststream/_internal/state/logger/params_storage.py @@ -12,7 +12,7 @@ def make_logger_storage( logger: Optional["LoggerProto"], log_fmt: Optional[str], - default_storage_cls: type["DefaultLoggerStorage"], + default_storage_cls: type["LoggerParamsStorage"], ) -> "LoggerParamsStorage": if logger is EMPTY: return default_storage_cls(log_fmt) diff --git a/faststream/_internal/state/logger/state.py b/faststream/_internal/state/logger/state.py index 132cedf7c5..2fc29707b8 100644 --- a/faststream/_internal/state/logger/state.py +++ b/faststream/_internal/state/logger/state.py @@ -58,8 +58,8 @@ def log( exc_info: Optional[Exception] = None, ) -> None: self.logger.log( - log_level=(log_level or self.log_level), - message=message, + (log_level or self.log_level), + message, extra=extra, exc_info=exc_info, ) diff --git a/faststream/_internal/subscriber/call_wrapper/call.py b/faststream/_internal/subscriber/call_wrapper/call.py index dcb93f8a42..e7ad845024 100644 --- a/faststream/_internal/subscriber/call_wrapper/call.py +++ b/faststream/_internal/subscriber/call_wrapper/call.py @@ -32,6 +32,18 @@ from faststream.message import StreamMessage +def ensure_call_wrapper( + call: Union[ + "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]", + Callable[P_HandlerParams, T_HandlerReturn], + ], +) -> "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]": + if isinstance(call, HandlerCallWrapper): + return call + + return HandlerCallWrapper(call) + + class HandlerCallWrapper(Generic[MsgType, P_HandlerParams, T_HandlerReturn]): """A generic class to wrap handler calls.""" @@ -52,31 +64,18 @@ class HandlerCallWrapper(Generic[MsgType, P_HandlerParams, T_HandlerReturn]): "mock", ) - def __new__( - cls, - call: Union[ - "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]", - Callable[P_HandlerParams, T_HandlerReturn], - ], - ) -> "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]": - """Create a new instance of the class.""" - if isinstance(call, cls): - return call - return super().__new__(cls) - def __init__( self, call: Callable[P_HandlerParams, T_HandlerReturn], ) -> None: """Initialize a handler.""" - if not isinstance(call, HandlerCallWrapper): - self._original_call = call - self._wrapped_call = None - self._publishers = [] - - self.mock = None - self.future = None - self.is_test = False + self._original_call = call + self._wrapped_call = None + self._publishers = [] + + self.mock = None + self.future = None + self.is_test = False def __call__( self, diff --git a/faststream/_internal/subscriber/proto.py b/faststream/_internal/subscriber/proto.py index 547c04f51c..a402009407 100644 --- a/faststream/_internal/subscriber/proto.py +++ b/faststream/_internal/subscriber/proto.py @@ -7,7 +7,6 @@ from faststream._internal.proto import Endpoint from faststream._internal.subscriber.call_wrapper.proto import WrapperProto from faststream._internal.types import MsgType -from faststream.specification.base.proto import EndpointProto if TYPE_CHECKING: from fast_depends.dependencies import Dependant @@ -30,7 +29,6 @@ class SubscriberProto( - EndpointProto, Endpoint, WrapperProto[MsgType], ): diff --git a/faststream/_internal/subscriber/specified.py b/faststream/_internal/subscriber/specified.py new file mode 100644 index 0000000000..e6dec70970 --- /dev/null +++ b/faststream/_internal/subscriber/specified.py @@ -0,0 +1,70 @@ +from typing import ( + TYPE_CHECKING, + Optional, +) + +from faststream._internal.subscriber.proto import SubscriberProto +from faststream._internal.types import MsgType +from faststream.exceptions import SetupError +from faststream.specification.asyncapi.message import parse_handler_params +from faststream.specification.asyncapi.utils import to_camelcase +from faststream.specification.base.proto import SpecificationEndpoint + +if TYPE_CHECKING: + from faststream._internal.basic_types import AnyDict + + +class BaseSpicificationSubscriber(SpecificationEndpoint, SubscriberProto[MsgType]): + def __init__( + self, + *, + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, + ) -> None: + self.title_ = title_ + self.description_ = description_ + self.include_in_schema = include_in_schema + + @property + def call_name(self) -> str: + """Returns the name of the handler call.""" + if not self.calls: + return "Subscriber" + + return to_camelcase(self.calls[0].call_name) + + def get_description(self) -> Optional[str]: + """Returns the description of the handler.""" + if not self.calls: # pragma: no cover + return None + + return self.calls[0].description + + def get_payloads(self) -> list[tuple["AnyDict", str]]: + """Get the payloads of the handler.""" + payloads: list[tuple[AnyDict, str]] = [] + + for h in self.calls: + if h.dependant is None: + msg = "You should setup `Handler` at first." + raise SetupError(msg) + + body = parse_handler_params( + h.dependant, + prefix=f"{self.title_ or self.call_name}:Message", + ) + + payloads.append((body, to_camelcase(h.call_name))) + + if not self.calls: + payloads.append( + ( + { + "title": f"{self.title_ or self.call_name}:Message:Payload", + }, + to_camelcase(self.call_name), + ), + ) + + return payloads diff --git a/faststream/_internal/subscriber/usecase.py b/faststream/_internal/subscriber/usecase.py index 622578fc22..c8ee25678a 100644 --- a/faststream/_internal/subscriber/usecase.py +++ b/faststream/_internal/subscriber/usecase.py @@ -13,7 +13,10 @@ from typing_extensions import Self, override from faststream._internal.subscriber.call_item import HandlerItem -from faststream._internal.subscriber.call_wrapper.call import HandlerCallWrapper +from faststream._internal.subscriber.call_wrapper.call import ( + HandlerCallWrapper, + ensure_call_wrapper, +) from faststream._internal.subscriber.proto import SubscriberProto from faststream._internal.subscriber.utils import ( MultiLock, @@ -28,9 +31,10 @@ from faststream._internal.utils.functions import sync_fake_context, to_async from faststream.exceptions import SetupError, StopConsume, SubscriberNotFound from faststream.middlewares import AckPolicy, AcknowledgementMiddleware +from faststream.middlewares.logging import CriticalLogMiddleware from faststream.response import ensure_response -from faststream.specification.asyncapi.message import parse_handler_params -from faststream.specification.asyncapi.utils import to_camelcase + +from .specified import BaseSpicificationSubscriber if TYPE_CHECKING: from fast_depends.dependencies import Dependant @@ -75,7 +79,7 @@ def __init__( self.dependencies = dependencies -class SubscriberUsecase(SubscriberProto[MsgType]): +class SubscriberUsecase(BaseSpicificationSubscriber, SubscriberProto[MsgType]): """A class representing an asynchronous handler.""" lock: "AbstractContextManager[Any]" @@ -102,6 +106,12 @@ def __init__( include_in_schema: bool, ) -> None: """Initialize a new instance of the class.""" + super().__init__( + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + ) + self.calls = [] self._parser = default_parser @@ -111,6 +121,7 @@ def __init__( self._call_options = None self._call_decorators = () + self.running = False self.lock = sync_fake_context() @@ -122,20 +133,6 @@ def __init__( self.extra_context = {} self.extra_watcher_options = {} - # AsyncAPI - self.title_ = title_ - self.description_ = description_ - self.include_in_schema = include_in_schema - - if self.ack_policy is not AckPolicy.DO_NOTHING: - self._broker_middlewares = ( - AcknowledgementMiddleware( - self.ack_policy, - self.extra_watcher_options, - ), - *self._broker_middlewares, - ) - def add_middleware(self, middleware: "BrokerMiddleware[MsgType]") -> None: self._broker_middlewares = (*self._broker_middlewares, middleware) @@ -264,8 +261,8 @@ def __call__( def real_wrapper( func: Callable[P_HandlerParams, T_HandlerReturn], ) -> "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]": - handler = HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]( - func, + handler: HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn] = ( + ensure_call_wrapper(func) ) self.calls.append( HandlerItem[MsgType]( @@ -312,22 +309,19 @@ async def process_message(self, msg: MsgType) -> "Response": """Execute all message processing stages.""" broker_state = self._state.get() context: ContextRepo = broker_state.di_state.context + logger_state = broker_state.logger_state async with AsyncExitStack() as stack: stack.enter_context(self.lock) # Enter context before middlewares - stack.enter_context( - context.scope("logger", broker_state.logger_state.logger.logger) - ) + stack.enter_context(context.scope("logger", logger_state.logger.logger)) for k, v in self.extra_context.items(): stack.enter_context(context.scope(k, v)) - stack.enter_context(context.scope("handler_", self)) - # enter all middlewares middlewares: list[BaseMiddleware] = [] - for base_m in self._broker_middlewares: + for base_m in self.__build__middlewares_stack(): middleware = base_m(msg, context=context) middlewares.append(middleware) await middleware.__aenter__() @@ -379,6 +373,7 @@ async def process_message(self, msg: MsgType) -> "Response": for m in middlewares: stack.push_async_exit(m.__aexit__) + # Reraise it to catch in tests if parsing_error: raise parsing_error @@ -388,6 +383,28 @@ async def process_message(self, msg: MsgType) -> "Response": # An error was raised and processed by some middleware return ensure_response(None) + def __build__middlewares_stack(self) -> tuple["BaseMiddleware", ...]: + logger_state = self._state.get().logger_state + + if self.ack_policy is AckPolicy.DO_NOTHING: + broker_middlewares = ( + CriticalLogMiddleware(logger_state), + *self._broker_middlewares, + ) + + else: + broker_middlewares = ( + AcknowledgementMiddleware( + logger=logger_state, + ack_policy=self.ack_policy, + extra_options=self.extra_watcher_options, + ), + CriticalLogMiddleware(logger_state), + *self._broker_middlewares, + ) + + return broker_middlewares + def __get_response_publisher( self, message: "StreamMessage[MsgType]", @@ -405,48 +422,3 @@ def get_log_context( return { "message_id": getattr(message, "message_id", ""), } - - # AsyncAPI methods - - @property - def call_name(self) -> str: - """Returns the name of the handler call.""" - if not self.calls: - return "Subscriber" - - return to_camelcase(self.calls[0].call_name) - - def get_description(self) -> Optional[str]: - """Returns the description of the handler.""" - if not self.calls: # pragma: no cover - return None - - return self.calls[0].description - - def get_payloads(self) -> list[tuple["AnyDict", str]]: - """Get the payloads of the handler.""" - payloads: list[tuple[AnyDict, str]] = [] - - for h in self.calls: - if h.dependant is None: - msg = "You should setup `Handler` at first." - raise SetupError(msg) - - body = parse_handler_params( - h.dependant, - prefix=f"{self.title_ or self.call_name}:Message", - ) - - payloads.append((body, to_camelcase(h.call_name))) - - if not self.calls: - payloads.append( - ( - { - "title": f"{self.title_ or self.call_name}:Message:Payload", - }, - to_camelcase(self.call_name), - ), - ) - - return payloads diff --git a/faststream/confluent/response.py b/faststream/confluent/response.py index 2d487484f4..3473e291bc 100644 --- a/faststream/confluent/response.py +++ b/faststream/confluent/response.py @@ -3,6 +3,7 @@ from typing_extensions import override +from faststream._internal.constants import EMPTY from faststream.response.publish_type import PublishType from faststream.response.response import PublishCommand, Response @@ -88,9 +89,9 @@ def __init__( @property def batch_bodies(self) -> tuple["SendableMessage", ...]: - if self.body: - return (self.body, *self.extra_bodies) - return self.extra_bodies + if self.body is EMPTY: + return self.extra_bodies + return (self.body, *self.extra_bodies) @classmethod def from_cmd( @@ -104,11 +105,15 @@ def from_cmd( return cmd body, extra_bodies = cmd.body, [] - if batch and isinstance(body, Sequence) and not isinstance(body, str): - if body: - body, extra_bodies = body[0], body[1:] - else: - body = None + if batch: + if body is None: + body = EMPTY + + if isinstance(body, Sequence) and not isinstance(body, str): + if body: + body, extra_bodies = body[0], body[1:] + else: + body = EMPTY return cls( body, diff --git a/faststream/kafka/response.py b/faststream/kafka/response.py index 4f1b46dc3e..13d3c186bf 100644 --- a/faststream/kafka/response.py +++ b/faststream/kafka/response.py @@ -3,6 +3,7 @@ from typing_extensions import override +from faststream._internal.constants import EMPTY from faststream.response.publish_type import PublishType from faststream.response.response import PublishCommand, Response @@ -80,9 +81,9 @@ def __init__( @property def batch_bodies(self) -> tuple["SendableMessage", ...]: - if self.body: - return (self.body, *self.extra_bodies) - return self.extra_bodies + if self.body is EMPTY: + return self.extra_bodies + return (self.body, *self.extra_bodies) @classmethod def from_cmd( @@ -96,11 +97,15 @@ def from_cmd( return cmd body, extra_bodies = cmd.body, [] - if batch and isinstance(body, Sequence) and not isinstance(body, str): - if body: - body, extra_bodies = body[0], body[1:] - else: - body = None + if batch: + if body is None: + body = EMPTY + + if isinstance(body, Sequence) and not isinstance(body, str): + if body: + body, extra_bodies = body[0], body[1:] + else: + body = EMPTY return cls( body, diff --git a/faststream/middlewares/acknowledgement/middleware.py b/faststream/middlewares/acknowledgement/middleware.py index 409bc28262..dd04e9c22e 100644 --- a/faststream/middlewares/acknowledgement/middleware.py +++ b/faststream/middlewares/acknowledgement/middleware.py @@ -15,19 +15,24 @@ from faststream._internal.basic_types import AnyDict, AsyncFuncAny from faststream._internal.context.repository import ContextRepo + from faststream._internal.state import LoggerState from faststream.message import StreamMessage class AcknowledgementMiddleware: - def __init__(self, ack_policy: AckPolicy, extra_options: "AnyDict") -> None: + def __init__( + self, logger: "LoggerState", ack_policy: "AckPolicy", extra_options: "AnyDict" + ) -> None: self.ack_policy = ack_policy self.extra_options = extra_options + self.logger = logger def __call__( self, msg: Optional[Any], context: "ContextRepo" ) -> "_AcknowledgementMiddleware": return _AcknowledgementMiddleware( msg, + logger=self.logger, ack_policy=self.ack_policy, extra_options=self.extra_options, context=context, @@ -40,14 +45,19 @@ def __init__( msg: Optional[Any], /, *, + logger: "LoggerState", context: "ContextRepo", - ack_policy: AckPolicy, extra_options: "AnyDict", + # can't be created with AckPolicy.DO_NOTHING + ack_policy: AckPolicy, ) -> None: super().__init__(msg, context=context) + self.ack_policy = ack_policy self.extra_options = extra_options - self.logger = context.get_local("logger") + self.logger = logger + + self.message: Optional[StreamMessage[Any]] = None async def consume_scope( self, @@ -63,9 +73,6 @@ async def __aexit__( exc_val: Optional[BaseException] = None, exc_tb: Optional["TracebackType"] = None, ) -> Optional[bool]: - if self.ack_policy is AckPolicy.DO_NOTHING: - return False - if not exc_type: await self.__ack() @@ -92,22 +99,25 @@ async def __aexit__( return False async def __ack(self, **exc_extra_options: Any) -> None: - try: - await self.message.ack(**exc_extra_options, **self.extra_options) - except Exception as er: - if self.logger is not None: - self.logger.log(logging.ERROR, er, exc_info=er) + if self.message: + try: + await self.message.ack(**exc_extra_options, **self.extra_options) + except Exception as er: + if self.logger is not None: + self.logger.log(er, logging.CRITICAL, exc_info=er) async def __nack(self, **exc_extra_options: Any) -> None: - try: - await self.message.nack(**exc_extra_options, **self.extra_options) - except Exception as er: - if self.logger is not None: - self.logger.log(logging.ERROR, er, exc_info=er) + if self.message: + try: + await self.message.nack(**exc_extra_options, **self.extra_options) + except Exception as er: + if self.logger is not None: + self.logger.log(er, logging.CRITICAL, exc_info=er) async def __reject(self, **exc_extra_options: Any) -> None: - try: - await self.message.reject(**exc_extra_options, **self.extra_options) - except Exception as er: - if self.logger is not None: - self.logger.log(logging.ERROR, er, exc_info=er) + if self.message: + try: + await self.message.reject(**exc_extra_options, **self.extra_options) + except Exception as er: + if self.logger is not None: + self.logger.log(er, logging.CRITICAL, exc_info=er) diff --git a/faststream/middlewares/logging.py b/faststream/middlewares/logging.py index 2fa5987a0e..fbc7412507 100644 --- a/faststream/middlewares/logging.py +++ b/faststream/middlewares/logging.py @@ -74,6 +74,7 @@ async def __aexit__( c = self.context.get_local("log_context", {}) if exc_type: + # TODO: move critical logging to `subscriber.consume()` method if issubclass(exc_type, IgnoredException): self.logger.log( log_level=logging.INFO, diff --git a/faststream/redis/response.py b/faststream/redis/response.py index 6328dbbd28..d48ee0ba1a 100644 --- a/faststream/redis/response.py +++ b/faststream/redis/response.py @@ -4,6 +4,7 @@ from typing_extensions import override +from faststream._internal.constants import EMPTY from faststream.exceptions import SetupError from faststream.redis.schemas import INCORRECT_SETUP_MSG from faststream.response.publish_type import PublishType @@ -109,9 +110,9 @@ def set_destination( @property def batch_bodies(self) -> tuple["SendableMessage", ...]: - if self.body: - return (self.body, *self.extra_bodies) - return self.extra_bodies + if self.body is EMPTY: + return self.extra_bodies + return (self.body, *self.extra_bodies) @classmethod def from_cmd( @@ -125,11 +126,15 @@ def from_cmd( return cmd body, extra_bodies = cmd.body, [] - if batch and isinstance(body, Sequence) and not isinstance(body, str): - if body: - body, extra_bodies = body[0], body[1:] - else: - body = None + if batch: + if body is None: + body = EMPTY + + if isinstance(body, Sequence) and not isinstance(body, str): + if body: + body, extra_bodies = body[0], body[1:] + else: + body = EMPTY return cls( body, diff --git a/faststream/redis/schemas/proto.py b/faststream/redis/schemas/proto.py index 2644432dcd..685d4aa679 100644 --- a/faststream/redis/schemas/proto.py +++ b/faststream/redis/schemas/proto.py @@ -2,14 +2,14 @@ from typing import TYPE_CHECKING, Any, Union from faststream.exceptions import SetupError -from faststream.specification.base.proto import EndpointProto +from faststream.specification.base.proto import SpecificationEndpoint if TYPE_CHECKING: from faststream.redis.schemas import ListSub, PubSub, StreamSub from faststream.specification.schema.bindings import redis -class RedisSpecificationProtocol(EndpointProto): +class RedisSpecificationProtocol(SpecificationEndpoint): @property @abstractmethod def channel_binding(self) -> "redis.ChannelBinding": ... diff --git a/faststream/redis/subscriber/usecase.py b/faststream/redis/subscriber/usecase.py index a424e409b2..40a3c3a4f6 100644 --- a/faststream/redis/subscriber/usecase.py +++ b/faststream/redis/subscriber/usecase.py @@ -462,19 +462,21 @@ def __init__( ) async def _get_msgs(self, client: "Redis[bytes]") -> None: - raw_msg = await client.lpop(name=self.list_sub.name) + raw_msg = await client.blpop( + self.list_sub.name, + timeout=self.list_sub.polling_interval, + ) if raw_msg: + _, msg_data = raw_msg + msg = DefaultListMessage( type="list", - data=raw_msg, + data=msg_data, channel=self.list_sub.name, ) - await self.consume(msg) # type: ignore[arg-type] - - else: - await anyio.sleep(self.list_sub.polling_interval) + await self.consume(msg) class BatchListSubscriber(_ListHandlerMixin): diff --git a/faststream/specification/base/proto.py b/faststream/specification/base/proto.py index 09d6e36366..42d118c46c 100644 --- a/faststream/specification/base/proto.py +++ b/faststream/specification/base/proto.py @@ -4,7 +4,7 @@ from faststream.specification.schema.channel import Channel -class EndpointProto(Protocol): +class SpecificationEndpoint(Protocol): """A class representing an asynchronous API operation.""" title_: Optional[str] diff --git a/tests/brokers/base/router.py b/tests/brokers/base/router.py index 92ffbb3269..7b8628172d 100644 --- a/tests/brokers/base/router.py +++ b/tests/brokers/base/router.py @@ -3,7 +3,7 @@ import pytest -from faststream import BaseMiddleware, Depends +from faststream import Depends from faststream._internal.broker.router import ( ArgsContainer, BrokerRouter, @@ -433,8 +433,8 @@ async def test_router_middlewares( ) -> None: pub_broker = self.get_broker() - router = type(router)(middlewares=(BaseMiddleware,)) - router2 = type(router)(middlewares=(BaseMiddleware,)) + router = type(router)(middlewares=(1,)) + router2 = type(router)(middlewares=(2,)) args, kwargs = self.get_subscriber_params(queue, middlewares=(3,)) @@ -447,8 +447,15 @@ def subscriber() -> None: ... sub = next(iter(pub_broker._subscribers)) publisher = next(iter(pub_broker._publishers)) - assert len((*sub._broker_middlewares, *sub.calls[0].item_middlewares)) == 5 - assert len((*publisher._broker_middlewares, *publisher.middlewares)) == 4 + + subscriber_middlewares = ( + *sub._broker_middlewares, + *sub.calls[0].item_middlewares, + ) + assert subscriber_middlewares == (1, 2, 3) + + publisher_middlewares = (*publisher._broker_middlewares, *publisher.middlewares) + assert publisher_middlewares == (1, 2, 3) async def test_router_include_with_middlewares( self, @@ -465,15 +472,17 @@ async def test_router_include_with_middlewares( @router2.publisher(queue, middlewares=(3,)) def subscriber() -> None: ... - router.include_router(router2, middlewares=(BaseMiddleware,)) - pub_broker.include_router(router, middlewares=(BaseMiddleware,)) + router.include_router(router2, middlewares=(2,)) + pub_broker.include_router(router, middlewares=(1,)) sub = next(iter(pub_broker._subscribers)) publisher = next(iter(pub_broker._publishers)) sub_middlewares = (*sub._broker_middlewares, *sub.calls[0].item_middlewares) - assert len(sub_middlewares) == 5, sub_middlewares - assert len((*publisher._broker_middlewares, *publisher.middlewares)) == 4 + assert sub_middlewares == (1, 2, 3), sub_middlewares + + publisher_middlewares = (*publisher._broker_middlewares, *publisher.middlewares) + assert publisher_middlewares == (1, 2, 3) async def test_router_parser( self, diff --git a/tests/brokers/base/testclient.py b/tests/brokers/base/testclient.py index 63a15c4343..2076561581 100644 --- a/tests/brokers/base/testclient.py +++ b/tests/brokers/base/testclient.py @@ -125,6 +125,25 @@ async def m(msg): # pragma: no cover with pytest.raises(ValueError): # noqa: PT011 await br.publish("hello", queue) + @pytest.mark.asyncio() + async def test_parser_exception_raises(self, queue: str) -> None: + test_broker = self.get_broker() + + def parser(msg): + raise ValueError + + args, kwargs = self.get_subscriber_params(queue, parser=parser) + + @test_broker.subscriber(*args, **kwargs) + async def m(msg): # pragma: no cover + pass + + async with self.patch_broker(test_broker) as br: + await br.start() + + with pytest.raises(ValueError): # noqa: PT011 + await br.publish("hello", queue) + async def test_broker_gets_patched_attrs_within_cm(self, fake_producer_cls) -> None: test_broker = self.get_broker() await test_broker.start() diff --git a/tests/brokers/confluent/test_publish_command.py b/tests/brokers/confluent/test_publish_command.py index 0f21843038..43e089afbb 100644 --- a/tests/brokers/confluent/test_publish_command.py +++ b/tests/brokers/confluent/test_publish_command.py @@ -35,6 +35,7 @@ def test_kafka_response_class(): pytest.param((), (), id="Empty Sequence"), pytest.param("123", ("123",), id="String Response"), pytest.param([1, 2, 3], (1, 2, 3), id="Sequence Data"), + pytest.param([0, 1, 2], (0, 1, 2), id="Sequence Data with False first element"), ), ) def test_batch_response(data: Any, expected_body: Any): diff --git a/tests/brokers/kafka/test_publish_command.py b/tests/brokers/kafka/test_publish_command.py index 0c2b43b781..912989aa1c 100644 --- a/tests/brokers/kafka/test_publish_command.py +++ b/tests/brokers/kafka/test_publish_command.py @@ -35,6 +35,7 @@ def test_kafka_response_class(): pytest.param((), (), id="Empty Sequence"), pytest.param("123", ("123",), id="String Response"), pytest.param([1, 2, 3], (1, 2, 3), id="Sequence Data"), + pytest.param([0, 1, 2], (0, 1, 2), id="Sequence Data with False first element"), ), ) def test_batch_response(data: Any, expected_body: Any): diff --git a/tests/brokers/redis/test_publish_command.py b/tests/brokers/redis/test_publish_command.py index 78c272e26e..6539ee0b62 100644 --- a/tests/brokers/redis/test_publish_command.py +++ b/tests/brokers/redis/test_publish_command.py @@ -35,6 +35,7 @@ def test_kafka_response_class(): pytest.param((), (), id="Empty Sequence"), pytest.param("123", ("123",), id="String Response"), pytest.param([1, 2, 3], (1, 2, 3), id="Sequence Data"), + pytest.param([0, 1, 2], (0, 1, 2), id="Sequence Data with False first element"), ), ) def test_batch_response(data: Any, expected_body: Any): From 69f19854afc6538bb11a4ac6e1daebdc936357ac Mon Sep 17 00:00:00 2001 From: Vladislav Tumko <56307628+vectorvp@users.noreply.github.com> Date: Wed, 13 Nov 2024 00:04:55 +0400 Subject: [PATCH 190/245] refactor: add ack handling for brokers (#1897) * refactor: add ack handling for brokers * fix: warnings arguments and is_manual flag * refactor: complete NATS * docs: generate API References * fix: update ack_policy * refactor: new tests * refactor: move ack_policy reject outside of return functions * tests: fix NATS tests * refactor: validate warnings * chore: remove loguru usage * chore: remove deprecated type option * chore: correct warnings stacklevel --------- Co-authored-by: vectorvp Co-authored-by: Pastukhov Nikita --- .secrets.baseline | 2 +- docs/docs/SUMMARY.md | 36 +++-- .../publisher/state/EmptyProducerState.md} | 2 +- .../publisher/state/ProducerState.md} | 2 +- .../publisher/state/RealProducer.md} | 2 +- .../publisher/state/EmptyProducerState.md} | 2 +- .../kafka/publisher/state/ProducerState.md | 11 ++ .../kafka/publisher/state/RealProducer.md | 11 ++ .../SpecificationPushStreamSubscriber.md} | 2 +- .../rabbit/helpers/state/ConnectedState.md | 11 ++ .../rabbit/helpers/state/ConnectionState.md | 11 ++ .../helpers/state/EmptyConnectionState.md | 11 ++ .../rabbit/publisher/producer/LockState.md | 11 ++ .../rabbit/publisher/producer/LockUnset.md | 11 ++ .../rabbit/publisher/producer/RealLock.md | 11 ++ .../redis/helpers/state/ConnectedState.md | 11 ++ .../redis/helpers/state/ConnectionState.md | 11 ++ .../helpers/state/EmptyConnectionState.md | 11 ++ .../SpecificationChannelSubscriber.md} | 2 +- .../SpecificationListBatchSubscriber.md | 11 ++ ...iber.md => SpecificationListSubscriber.md} | 2 +- .../SpecificationStreamBatchSubscriber.md | 11 ++ ...er.md => SpecificationStreamSubscriber.md} | 2 +- .../usecase/StreamBatchSubscriber.md | 11 ++ .../base/proto/SpecificationEndpoint.md | 11 ++ faststream/_internal/broker/pub_base.py | 1 - faststream/_internal/cli/main.py | 3 - faststream/confluent/broker/registrator.py | 9 +- faststream/confluent/fastapi/fastapi.py | 6 +- faststream/confluent/router.py | 3 +- faststream/confluent/subscriber/factory.py | 14 +- faststream/kafka/broker/registrator.py | 9 +- faststream/kafka/fastapi/fastapi.py | 8 +- faststream/kafka/router.py | 3 +- faststream/kafka/subscriber/factory.py | 14 +- faststream/nats/broker/registrator.py | 3 +- faststream/nats/fastapi/fastapi.py | 2 +- faststream/nats/parser.py | 7 +- faststream/nats/publisher/producer.py | 5 +- faststream/nats/response.py | 13 ++ faststream/nats/router.py | 3 +- faststream/nats/subscriber/factory.py | 130 ++++++++++-------- faststream/nats/subscriber/specified.py | 2 +- faststream/nats/subscriber/usecase.py | 7 +- faststream/nats/testing.py | 11 +- faststream/rabbit/broker/registrator.py | 3 +- faststream/rabbit/fastapi/fastapi.py | 2 +- faststream/rabbit/router.py | 3 +- faststream/rabbit/subscriber/factory.py | 6 +- faststream/rabbit/subscriber/usecase.py | 7 +- faststream/redis/broker/registrator.py | 3 +- faststream/redis/fastapi/fastapi.py | 2 +- faststream/redis/router.py | 3 +- faststream/redis/subscriber/factory.py | 74 +++++++--- faststream/redis/subscriber/specified.py | 12 +- faststream/redis/subscriber/usecase.py | 13 +- tests/brokers/base/consume.py | 11 +- tests/brokers/base/fastapi.py | 29 ++-- tests/brokers/base/middlewares.py | 40 ++++-- tests/brokers/base/parser.py | 18 ++- tests/brokers/base/publish.py | 30 ++-- tests/brokers/base/requests.py | 4 +- tests/brokers/base/router.py | 42 ++++-- tests/brokers/confluent/test_consume.py | 21 ++- tests/brokers/confluent/test_fastapi.py | 6 +- tests/brokers/confluent/test_publish.py | 3 +- tests/brokers/confluent/test_test_client.py | 3 +- tests/brokers/kafka/test_consume.py | 24 ++-- tests/brokers/kafka/test_fastapi.py | 6 +- tests/brokers/kafka/test_publish.py | 3 +- tests/brokers/kafka/test_test_client.py | 3 +- tests/brokers/nats/test_consume.py | 68 ++++----- tests/brokers/nats/test_fastapi.py | 9 +- tests/brokers/nats/test_publish.py | 4 +- tests/brokers/nats/test_router.py | 3 +- tests/brokers/nats/test_test_client.py | 3 +- tests/brokers/rabbit/test_consume.py | 33 +++-- tests/brokers/rabbit/test_fastapi.py | 3 +- tests/brokers/rabbit/test_publish.py | 7 +- tests/brokers/rabbit/test_router.py | 9 +- tests/brokers/rabbit/test_test_client.py | 3 +- tests/brokers/redis/test_consume.py | 43 ++++-- tests/brokers/redis/test_fastapi.py | 18 ++- tests/brokers/redis/test_publish.py | 13 +- tests/brokers/redis/test_router.py | 9 +- tests/brokers/redis/test_test_client.py | 3 +- tests/opentelemetry/basic.py | 30 ++-- .../opentelemetry/confluent/test_confluent.py | 6 +- tests/opentelemetry/kafka/test_kafka.py | 6 +- tests/opentelemetry/nats/test_nats.py | 3 +- tests/opentelemetry/redis/test_redis.py | 6 +- tests/prometheus/basic.py | 14 +- tests/prometheus/confluent/test_confluent.py | 3 +- tests/prometheus/kafka/test_kafka.py | 3 +- tests/prometheus/nats/test_nats.py | 3 +- tests/prometheus/redis/test_redis.py | 3 +- tests/utils/context/test_path.py | 3 +- 97 files changed, 800 insertions(+), 351 deletions(-) rename docs/docs/en/api/faststream/{redis/subscriber/usecase/BatchStreamSubscriber.md => confluent/publisher/state/EmptyProducerState.md} (63%) rename docs/docs/en/api/faststream/{redis/subscriber/specified/AsyncAPIListSubscriber.md => confluent/publisher/state/ProducerState.md} (62%) rename docs/docs/en/api/faststream/{specification/base/proto/EndpointProto.md => confluent/publisher/state/RealProducer.md} (67%) rename docs/docs/en/api/faststream/{redis/subscriber/specified/AsyncAPIStreamSubscriber.md => kafka/publisher/state/EmptyProducerState.md} (62%) create mode 100644 docs/docs/en/api/faststream/kafka/publisher/state/ProducerState.md create mode 100644 docs/docs/en/api/faststream/kafka/publisher/state/RealProducer.md rename docs/docs/en/api/faststream/{redis/subscriber/specified/AsyncAPIChannelSubscriber.md => nats/subscriber/specified/SpecificationPushStreamSubscriber.md} (59%) create mode 100644 docs/docs/en/api/faststream/rabbit/helpers/state/ConnectedState.md create mode 100644 docs/docs/en/api/faststream/rabbit/helpers/state/ConnectionState.md create mode 100644 docs/docs/en/api/faststream/rabbit/helpers/state/EmptyConnectionState.md create mode 100644 docs/docs/en/api/faststream/rabbit/publisher/producer/LockState.md create mode 100644 docs/docs/en/api/faststream/rabbit/publisher/producer/LockUnset.md create mode 100644 docs/docs/en/api/faststream/rabbit/publisher/producer/RealLock.md create mode 100644 docs/docs/en/api/faststream/redis/helpers/state/ConnectedState.md create mode 100644 docs/docs/en/api/faststream/redis/helpers/state/ConnectionState.md create mode 100644 docs/docs/en/api/faststream/redis/helpers/state/EmptyConnectionState.md rename docs/docs/en/api/faststream/{nats/subscriber/specified/SpecificationStreamSubscriber.md => redis/subscriber/specified/SpecificationChannelSubscriber.md} (60%) create mode 100644 docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationListBatchSubscriber.md rename docs/docs/en/api/faststream/redis/subscriber/specified/{AsyncAPIListBatchSubscriber.md => SpecificationListSubscriber.md} (64%) create mode 100644 docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationStreamBatchSubscriber.md rename docs/docs/en/api/faststream/redis/subscriber/specified/{AsyncAPIStreamBatchSubscriber.md => SpecificationStreamSubscriber.md} (64%) create mode 100644 docs/docs/en/api/faststream/redis/subscriber/usecase/StreamBatchSubscriber.md create mode 100644 docs/docs/en/api/faststream/specification/base/proto/SpecificationEndpoint.md diff --git a/.secrets.baseline b/.secrets.baseline index 65fa5ef883..c2189a1f8f 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -178,5 +178,5 @@ } ] }, - "generated_at": "2024-11-07T20:55:07Z" + "generated_at": "2024-11-08T12:39:15Z" } diff --git a/docs/docs/SUMMARY.md b/docs/docs/SUMMARY.md index 5c5b4db5b4..d8cc349c03 100644 --- a/docs/docs/SUMMARY.md +++ b/docs/docs/SUMMARY.md @@ -316,6 +316,10 @@ search: - [SpecificationBatchPublisher](api/faststream/confluent/publisher/specified/SpecificationBatchPublisher.md) - [SpecificationDefaultPublisher](api/faststream/confluent/publisher/specified/SpecificationDefaultPublisher.md) - [SpecificationPublisher](api/faststream/confluent/publisher/specified/SpecificationPublisher.md) + - state + - [EmptyProducerState](api/faststream/confluent/publisher/state/EmptyProducerState.md) + - [ProducerState](api/faststream/confluent/publisher/state/ProducerState.md) + - [RealProducer](api/faststream/confluent/publisher/state/RealProducer.md) - usecase - [BatchPublisher](api/faststream/confluent/publisher/usecase/BatchPublisher.md) - [DefaultPublisher](api/faststream/confluent/publisher/usecase/DefaultPublisher.md) @@ -426,6 +430,10 @@ search: - [SpecificationBatchPublisher](api/faststream/kafka/publisher/specified/SpecificationBatchPublisher.md) - [SpecificationDefaultPublisher](api/faststream/kafka/publisher/specified/SpecificationDefaultPublisher.md) - [SpecificationPublisher](api/faststream/kafka/publisher/specified/SpecificationPublisher.md) + - state + - [EmptyProducerState](api/faststream/kafka/publisher/state/EmptyProducerState.md) + - [ProducerState](api/faststream/kafka/publisher/state/ProducerState.md) + - [RealProducer](api/faststream/kafka/publisher/state/RealProducer.md) - usecase - [BatchPublisher](api/faststream/kafka/publisher/usecase/BatchPublisher.md) - [DefaultPublisher](api/faststream/kafka/publisher/usecase/DefaultPublisher.md) @@ -628,7 +636,7 @@ search: - [SpecificationKeyValueWatchSubscriber](api/faststream/nats/subscriber/specified/SpecificationKeyValueWatchSubscriber.md) - [SpecificationObjStoreWatchSubscriber](api/faststream/nats/subscriber/specified/SpecificationObjStoreWatchSubscriber.md) - [SpecificationPullStreamSubscriber](api/faststream/nats/subscriber/specified/SpecificationPullStreamSubscriber.md) - - [SpecificationStreamSubscriber](api/faststream/nats/subscriber/specified/SpecificationStreamSubscriber.md) + - [SpecificationPushStreamSubscriber](api/faststream/nats/subscriber/specified/SpecificationPushStreamSubscriber.md) - [SpecificationSubscriber](api/faststream/nats/subscriber/specified/SpecificationSubscriber.md) - state - [ConnectedSubscriberState](api/faststream/nats/subscriber/state/ConnectedSubscriberState.md) @@ -716,6 +724,10 @@ search: - helpers - declarer - [RabbitDeclarer](api/faststream/rabbit/helpers/declarer/RabbitDeclarer.md) + - state + - [ConnectedState](api/faststream/rabbit/helpers/state/ConnectedState.md) + - [ConnectionState](api/faststream/rabbit/helpers/state/ConnectionState.md) + - [EmptyConnectionState](api/faststream/rabbit/helpers/state/EmptyConnectionState.md) - message - [RabbitMessage](api/faststream/rabbit/message/RabbitMessage.md) - opentelemetry @@ -742,6 +754,9 @@ search: - [PublishOptions](api/faststream/rabbit/publisher/options/PublishOptions.md) - producer - [AioPikaFastProducer](api/faststream/rabbit/publisher/producer/AioPikaFastProducer.md) + - [LockState](api/faststream/rabbit/publisher/producer/LockState.md) + - [LockUnset](api/faststream/rabbit/publisher/producer/LockUnset.md) + - [RealLock](api/faststream/rabbit/publisher/producer/RealLock.md) - specified - [SpecificationPublisher](api/faststream/rabbit/publisher/specified/SpecificationPublisher.md) - usecase @@ -809,6 +824,11 @@ search: - [RedisRouter](api/faststream/redis/fastapi/RedisRouter.md) - fastapi - [RedisRouter](api/faststream/redis/fastapi/fastapi/RedisRouter.md) + - helpers + - state + - [ConnectedState](api/faststream/redis/helpers/state/ConnectedState.md) + - [ConnectionState](api/faststream/redis/helpers/state/ConnectionState.md) + - [EmptyConnectionState](api/faststream/redis/helpers/state/EmptyConnectionState.md) - message - [BatchListMessage](api/faststream/redis/message/BatchListMessage.md) - [BatchStreamMessage](api/faststream/redis/message/BatchStreamMessage.md) @@ -893,18 +913,18 @@ search: - factory - [create_subscriber](api/faststream/redis/subscriber/factory/create_subscriber.md) - specified - - [AsyncAPIChannelSubscriber](api/faststream/redis/subscriber/specified/AsyncAPIChannelSubscriber.md) - - [AsyncAPIListBatchSubscriber](api/faststream/redis/subscriber/specified/AsyncAPIListBatchSubscriber.md) - - [AsyncAPIListSubscriber](api/faststream/redis/subscriber/specified/AsyncAPIListSubscriber.md) - - [AsyncAPIStreamBatchSubscriber](api/faststream/redis/subscriber/specified/AsyncAPIStreamBatchSubscriber.md) - - [AsyncAPIStreamSubscriber](api/faststream/redis/subscriber/specified/AsyncAPIStreamSubscriber.md) + - [SpecificationChannelSubscriber](api/faststream/redis/subscriber/specified/SpecificationChannelSubscriber.md) + - [SpecificationListBatchSubscriber](api/faststream/redis/subscriber/specified/SpecificationListBatchSubscriber.md) + - [SpecificationListSubscriber](api/faststream/redis/subscriber/specified/SpecificationListSubscriber.md) + - [SpecificationStreamBatchSubscriber](api/faststream/redis/subscriber/specified/SpecificationStreamBatchSubscriber.md) + - [SpecificationStreamSubscriber](api/faststream/redis/subscriber/specified/SpecificationStreamSubscriber.md) - [SpecificationSubscriber](api/faststream/redis/subscriber/specified/SpecificationSubscriber.md) - usecase - [BatchListSubscriber](api/faststream/redis/subscriber/usecase/BatchListSubscriber.md) - - [BatchStreamSubscriber](api/faststream/redis/subscriber/usecase/BatchStreamSubscriber.md) - [ChannelSubscriber](api/faststream/redis/subscriber/usecase/ChannelSubscriber.md) - [ListSubscriber](api/faststream/redis/subscriber/usecase/ListSubscriber.md) - [LogicSubscriber](api/faststream/redis/subscriber/usecase/LogicSubscriber.md) + - [StreamBatchSubscriber](api/faststream/redis/subscriber/usecase/StreamBatchSubscriber.md) - [StreamSubscriber](api/faststream/redis/subscriber/usecase/StreamSubscriber.md) - testing - [ChannelVisitor](api/faststream/redis/testing/ChannelVisitor.md) @@ -1156,7 +1176,7 @@ search: - info - [BaseInfo](api/faststream/specification/base/info/BaseInfo.md) - proto - - [EndpointProto](api/faststream/specification/base/proto/EndpointProto.md) + - [SpecificationEndpoint](api/faststream/specification/base/proto/SpecificationEndpoint.md) - schema - [BaseSchema](api/faststream/specification/base/schema/BaseSchema.md) - specification diff --git a/docs/docs/en/api/faststream/redis/subscriber/usecase/BatchStreamSubscriber.md b/docs/docs/en/api/faststream/confluent/publisher/state/EmptyProducerState.md similarity index 63% rename from docs/docs/en/api/faststream/redis/subscriber/usecase/BatchStreamSubscriber.md rename to docs/docs/en/api/faststream/confluent/publisher/state/EmptyProducerState.md index 0f8e4f2e1b..a72476a6d3 100644 --- a/docs/docs/en/api/faststream/redis/subscriber/usecase/BatchStreamSubscriber.md +++ b/docs/docs/en/api/faststream/confluent/publisher/state/EmptyProducerState.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.redis.subscriber.usecase.BatchStreamSubscriber +::: faststream.confluent.publisher.state.EmptyProducerState diff --git a/docs/docs/en/api/faststream/redis/subscriber/specified/AsyncAPIListSubscriber.md b/docs/docs/en/api/faststream/confluent/publisher/state/ProducerState.md similarity index 62% rename from docs/docs/en/api/faststream/redis/subscriber/specified/AsyncAPIListSubscriber.md rename to docs/docs/en/api/faststream/confluent/publisher/state/ProducerState.md index 3f22c7ce0a..5a5a35dddd 100644 --- a/docs/docs/en/api/faststream/redis/subscriber/specified/AsyncAPIListSubscriber.md +++ b/docs/docs/en/api/faststream/confluent/publisher/state/ProducerState.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.redis.subscriber.specified.AsyncAPIListSubscriber +::: faststream.confluent.publisher.state.ProducerState diff --git a/docs/docs/en/api/faststream/specification/base/proto/EndpointProto.md b/docs/docs/en/api/faststream/confluent/publisher/state/RealProducer.md similarity index 67% rename from docs/docs/en/api/faststream/specification/base/proto/EndpointProto.md rename to docs/docs/en/api/faststream/confluent/publisher/state/RealProducer.md index 81046fdcfd..52143d1596 100644 --- a/docs/docs/en/api/faststream/specification/base/proto/EndpointProto.md +++ b/docs/docs/en/api/faststream/confluent/publisher/state/RealProducer.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.base.proto.EndpointProto +::: faststream.confluent.publisher.state.RealProducer diff --git a/docs/docs/en/api/faststream/redis/subscriber/specified/AsyncAPIStreamSubscriber.md b/docs/docs/en/api/faststream/kafka/publisher/state/EmptyProducerState.md similarity index 62% rename from docs/docs/en/api/faststream/redis/subscriber/specified/AsyncAPIStreamSubscriber.md rename to docs/docs/en/api/faststream/kafka/publisher/state/EmptyProducerState.md index 7b1af12b55..0152ee7c2f 100644 --- a/docs/docs/en/api/faststream/redis/subscriber/specified/AsyncAPIStreamSubscriber.md +++ b/docs/docs/en/api/faststream/kafka/publisher/state/EmptyProducerState.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.redis.subscriber.specified.AsyncAPIStreamSubscriber +::: faststream.kafka.publisher.state.EmptyProducerState diff --git a/docs/docs/en/api/faststream/kafka/publisher/state/ProducerState.md b/docs/docs/en/api/faststream/kafka/publisher/state/ProducerState.md new file mode 100644 index 0000000000..c937179471 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/publisher/state/ProducerState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.publisher.state.ProducerState diff --git a/docs/docs/en/api/faststream/kafka/publisher/state/RealProducer.md b/docs/docs/en/api/faststream/kafka/publisher/state/RealProducer.md new file mode 100644 index 0000000000..a576226b3c --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/publisher/state/RealProducer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.publisher.state.RealProducer diff --git a/docs/docs/en/api/faststream/redis/subscriber/specified/AsyncAPIChannelSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationPushStreamSubscriber.md similarity index 59% rename from docs/docs/en/api/faststream/redis/subscriber/specified/AsyncAPIChannelSubscriber.md rename to docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationPushStreamSubscriber.md index 32d5362469..ef20892652 100644 --- a/docs/docs/en/api/faststream/redis/subscriber/specified/AsyncAPIChannelSubscriber.md +++ b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationPushStreamSubscriber.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.redis.subscriber.specified.AsyncAPIChannelSubscriber +::: faststream.nats.subscriber.specified.SpecificationPushStreamSubscriber diff --git a/docs/docs/en/api/faststream/rabbit/helpers/state/ConnectedState.md b/docs/docs/en/api/faststream/rabbit/helpers/state/ConnectedState.md new file mode 100644 index 0000000000..db97303aa3 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/helpers/state/ConnectedState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.helpers.state.ConnectedState diff --git a/docs/docs/en/api/faststream/rabbit/helpers/state/ConnectionState.md b/docs/docs/en/api/faststream/rabbit/helpers/state/ConnectionState.md new file mode 100644 index 0000000000..36b3d4d4d1 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/helpers/state/ConnectionState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.helpers.state.ConnectionState diff --git a/docs/docs/en/api/faststream/rabbit/helpers/state/EmptyConnectionState.md b/docs/docs/en/api/faststream/rabbit/helpers/state/EmptyConnectionState.md new file mode 100644 index 0000000000..7b0af42897 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/helpers/state/EmptyConnectionState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.helpers.state.EmptyConnectionState diff --git a/docs/docs/en/api/faststream/rabbit/publisher/producer/LockState.md b/docs/docs/en/api/faststream/rabbit/publisher/producer/LockState.md new file mode 100644 index 0000000000..4d7b37ba46 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/publisher/producer/LockState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.publisher.producer.LockState diff --git a/docs/docs/en/api/faststream/rabbit/publisher/producer/LockUnset.md b/docs/docs/en/api/faststream/rabbit/publisher/producer/LockUnset.md new file mode 100644 index 0000000000..95df1a10e7 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/publisher/producer/LockUnset.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.publisher.producer.LockUnset diff --git a/docs/docs/en/api/faststream/rabbit/publisher/producer/RealLock.md b/docs/docs/en/api/faststream/rabbit/publisher/producer/RealLock.md new file mode 100644 index 0000000000..570a279a0a --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/publisher/producer/RealLock.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.publisher.producer.RealLock diff --git a/docs/docs/en/api/faststream/redis/helpers/state/ConnectedState.md b/docs/docs/en/api/faststream/redis/helpers/state/ConnectedState.md new file mode 100644 index 0000000000..793fdb055e --- /dev/null +++ b/docs/docs/en/api/faststream/redis/helpers/state/ConnectedState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.helpers.state.ConnectedState diff --git a/docs/docs/en/api/faststream/redis/helpers/state/ConnectionState.md b/docs/docs/en/api/faststream/redis/helpers/state/ConnectionState.md new file mode 100644 index 0000000000..0a27d849dc --- /dev/null +++ b/docs/docs/en/api/faststream/redis/helpers/state/ConnectionState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.helpers.state.ConnectionState diff --git a/docs/docs/en/api/faststream/redis/helpers/state/EmptyConnectionState.md b/docs/docs/en/api/faststream/redis/helpers/state/EmptyConnectionState.md new file mode 100644 index 0000000000..70273722e0 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/helpers/state/EmptyConnectionState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.helpers.state.EmptyConnectionState diff --git a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationStreamSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationChannelSubscriber.md similarity index 60% rename from docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationStreamSubscriber.md rename to docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationChannelSubscriber.md index 4b9dba3b61..538babd05f 100644 --- a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationStreamSubscriber.md +++ b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationChannelSubscriber.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.nats.subscriber.specified.SpecificationStreamSubscriber +::: faststream.redis.subscriber.specified.SpecificationChannelSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationListBatchSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationListBatchSubscriber.md new file mode 100644 index 0000000000..60e7fa385d --- /dev/null +++ b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationListBatchSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.subscriber.specified.SpecificationListBatchSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/specified/AsyncAPIListBatchSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationListSubscriber.md similarity index 64% rename from docs/docs/en/api/faststream/redis/subscriber/specified/AsyncAPIListBatchSubscriber.md rename to docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationListSubscriber.md index 5cd13a9eeb..988ffccb3c 100644 --- a/docs/docs/en/api/faststream/redis/subscriber/specified/AsyncAPIListBatchSubscriber.md +++ b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationListSubscriber.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.redis.subscriber.specified.AsyncAPIListBatchSubscriber +::: faststream.redis.subscriber.specified.SpecificationListSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationStreamBatchSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationStreamBatchSubscriber.md new file mode 100644 index 0000000000..76a6aff457 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationStreamBatchSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.subscriber.specified.SpecificationStreamBatchSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/specified/AsyncAPIStreamBatchSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationStreamSubscriber.md similarity index 64% rename from docs/docs/en/api/faststream/redis/subscriber/specified/AsyncAPIStreamBatchSubscriber.md rename to docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationStreamSubscriber.md index f4857d8585..f1bfe8a520 100644 --- a/docs/docs/en/api/faststream/redis/subscriber/specified/AsyncAPIStreamBatchSubscriber.md +++ b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationStreamSubscriber.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.redis.subscriber.specified.AsyncAPIStreamBatchSubscriber +::: faststream.redis.subscriber.specified.SpecificationStreamSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/usecase/StreamBatchSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/usecase/StreamBatchSubscriber.md new file mode 100644 index 0000000000..3500cc21e2 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/subscriber/usecase/StreamBatchSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.subscriber.usecase.StreamBatchSubscriber diff --git a/docs/docs/en/api/faststream/specification/base/proto/SpecificationEndpoint.md b/docs/docs/en/api/faststream/specification/base/proto/SpecificationEndpoint.md new file mode 100644 index 0000000000..a6a2658fc4 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/base/proto/SpecificationEndpoint.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.base.proto.SpecificationEndpoint diff --git a/faststream/_internal/broker/pub_base.py b/faststream/_internal/broker/pub_base.py index 8d97050cc8..31cfb476fd 100644 --- a/faststream/_internal/broker/pub_base.py +++ b/faststream/_internal/broker/pub_base.py @@ -42,7 +42,6 @@ async def _basic_publish( return await publish(cmd) - @abstractmethod async def publish_batch( self, *messages: "SendableMessage", diff --git a/faststream/_internal/cli/main.py b/faststream/_internal/cli/main.py index 732db2c2e6..48b113c8c3 100644 --- a/faststream/_internal/cli/main.py +++ b/faststream/_internal/cli/main.py @@ -104,7 +104,6 @@ def run( False, "-f", "--factory", - is_flag=True, help="Treat APP as an application factory.", ), ) -> None: @@ -240,13 +239,11 @@ def publish( ), rpc: bool = typer.Option( False, - is_flag=True, help="Enable RPC mode and system output.", ), is_factory: bool = typer.Option( False, "--factory", - is_flag=True, help="Treat APP as an application factory.", ), ) -> None: diff --git a/faststream/confluent/broker/registrator.py b/faststream/confluent/broker/registrator.py index bf49f8b68a..3bcc604719 100644 --- a/faststream/confluent/broker/registrator.py +++ b/faststream/confluent/broker/registrator.py @@ -13,6 +13,7 @@ from typing_extensions import Doc, override from faststream._internal.broker.abc_broker import ABCBroker +from faststream._internal.constants import EMPTY from faststream.confluent.publisher.factory import create_publisher from faststream.confluent.subscriber.factory import create_subscriber from faststream.exceptions import SetupError @@ -298,7 +299,7 @@ def subscriber( ack_policy: Annotated[ AckPolicy, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + ] = EMPTY, no_reply: Annotated[ bool, Doc( @@ -565,7 +566,7 @@ def subscriber( ack_policy: Annotated[ AckPolicy, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + ] = EMPTY, no_reply: Annotated[ bool, Doc( @@ -832,7 +833,7 @@ def subscriber( ack_policy: Annotated[ AckPolicy, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + ] = EMPTY, no_reply: Annotated[ bool, Doc( @@ -1102,7 +1103,7 @@ def subscriber( ack_policy: Annotated[ AckPolicy, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + ] = EMPTY, no_reply: Annotated[ bool, Doc( diff --git a/faststream/confluent/fastapi/fastapi.py b/faststream/confluent/fastapi/fastapi.py index ac24669769..5bdc96cf6c 100644 --- a/faststream/confluent/fastapi/fastapi.py +++ b/faststream/confluent/fastapi/fastapi.py @@ -837,7 +837,7 @@ def subscriber( ack_policy: Annotated[ AckPolicy, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + ] = EMPTY, no_reply: Annotated[ bool, Doc( @@ -1607,7 +1607,7 @@ def subscriber( ack_policy: Annotated[ AckPolicy, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + ] = EMPTY, no_reply: Annotated[ bool, Doc( @@ -2000,7 +2000,7 @@ def subscriber( ack_policy: Annotated[ AckPolicy, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + ] = EMPTY, no_reply: Annotated[ bool, Doc( diff --git a/faststream/confluent/router.py b/faststream/confluent/router.py index c4d36fd7e0..a1039fc72f 100644 --- a/faststream/confluent/router.py +++ b/faststream/confluent/router.py @@ -16,6 +16,7 @@ BrokerRouter, SubscriberRoute, ) +from faststream._internal.constants import EMPTY from faststream.confluent.broker.registrator import KafkaRegistrator from faststream.middlewares import AckPolicy @@ -384,7 +385,7 @@ def __init__( ack_policy: Annotated[ AckPolicy, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + ] = EMPTY, no_reply: Annotated[ bool, Doc( diff --git a/faststream/confluent/subscriber/factory.py b/faststream/confluent/subscriber/factory.py index 744a47f744..ed6ae75690 100644 --- a/faststream/confluent/subscriber/factory.py +++ b/faststream/confluent/subscriber/factory.py @@ -1,3 +1,4 @@ +import warnings from collections.abc import Iterable, Sequence from typing import ( TYPE_CHECKING, @@ -7,10 +8,12 @@ overload, ) +from faststream._internal.constants import EMPTY from faststream.confluent.subscriber.specified import ( SpecificationBatchSubscriber, SpecificationDefaultSubscriber, ) +from faststream.middlewares import AckPolicy if TYPE_CHECKING: from confluent_kafka import Message as ConfluentMsg @@ -19,7 +22,6 @@ from faststream._internal.basic_types import AnyDict from faststream._internal.types import BrokerMiddleware from faststream.confluent.schemas import TopicPartition - from faststream.middlewares import AckPolicy @overload @@ -121,6 +123,16 @@ def create_subscriber( "SpecificationDefaultSubscriber", "SpecificationBatchSubscriber", ]: + if ack_policy is not EMPTY and not is_manual: + warnings.warn( + "You can't use acknowledgement policy with `is_manual=False` subscriber", + RuntimeWarning, + stacklevel=3, + ) + + if ack_policy is EMPTY: + ack_policy = AckPolicy.REJECT_ON_ERROR + if batch: return SpecificationBatchSubscriber( *topics, diff --git a/faststream/kafka/broker/registrator.py b/faststream/kafka/broker/registrator.py index bd2c4bd735..3523c2bed7 100644 --- a/faststream/kafka/broker/registrator.py +++ b/faststream/kafka/broker/registrator.py @@ -16,6 +16,7 @@ from typing_extensions import Doc, override from faststream._internal.broker.abc_broker import ABCBroker +from faststream._internal.constants import EMPTY from faststream.kafka.publisher.factory import create_publisher from faststream.kafka.subscriber.factory import create_subscriber from faststream.middlewares import AckPolicy @@ -400,7 +401,7 @@ def subscriber( ack_policy: Annotated[ AckPolicy, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + ] = EMPTY, no_reply: Annotated[ bool, Doc( @@ -766,7 +767,7 @@ def subscriber( ack_policy: Annotated[ AckPolicy, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + ] = EMPTY, no_reply: Annotated[ bool, Doc( @@ -1132,7 +1133,7 @@ def subscriber( ack_policy: Annotated[ AckPolicy, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + ] = EMPTY, no_reply: Annotated[ bool, Doc( @@ -1501,7 +1502,7 @@ def subscriber( ack_policy: Annotated[ AckPolicy, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + ] = EMPTY, no_reply: Annotated[ bool, Doc( diff --git a/faststream/kafka/fastapi/fastapi.py b/faststream/kafka/fastapi/fastapi.py index 3cd73426db..5601c05f6c 100644 --- a/faststream/kafka/fastapi/fastapi.py +++ b/faststream/kafka/fastapi/fastapi.py @@ -948,7 +948,7 @@ def subscriber( ack_policy: Annotated[ AckPolicy, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + ] = EMPTY, no_reply: Annotated[ bool, Doc( @@ -1434,7 +1434,7 @@ def subscriber( ack_policy: Annotated[ AckPolicy, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + ] = EMPTY, no_reply: Annotated[ bool, Doc( @@ -1920,7 +1920,7 @@ def subscriber( ack_policy: Annotated[ AckPolicy, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + ] = EMPTY, no_reply: Annotated[ bool, Doc( @@ -2409,7 +2409,7 @@ def subscriber( ack_policy: Annotated[ AckPolicy, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + ] = EMPTY, no_reply: Annotated[ bool, Doc( diff --git a/faststream/kafka/router.py b/faststream/kafka/router.py index 416d23df20..b4fecbe3e0 100644 --- a/faststream/kafka/router.py +++ b/faststream/kafka/router.py @@ -17,6 +17,7 @@ BrokerRouter, SubscriberRoute, ) +from faststream._internal.constants import EMPTY from faststream.kafka.broker.registrator import KafkaRegistrator from faststream.middlewares import AckPolicy @@ -487,7 +488,7 @@ def __init__( ack_policy: Annotated[ AckPolicy, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + ] = EMPTY, no_reply: Annotated[ bool, Doc( diff --git a/faststream/kafka/subscriber/factory.py b/faststream/kafka/subscriber/factory.py index 7542a11cd6..d623fa4f7a 100644 --- a/faststream/kafka/subscriber/factory.py +++ b/faststream/kafka/subscriber/factory.py @@ -1,3 +1,4 @@ +import warnings from collections.abc import Iterable from typing import ( TYPE_CHECKING, @@ -7,11 +8,13 @@ overload, ) +from faststream._internal.constants import EMPTY from faststream.exceptions import SetupError from faststream.kafka.subscriber.specified import ( SpecificationBatchSubscriber, SpecificationDefaultSubscriber, ) +from faststream.middlewares import AckPolicy if TYPE_CHECKING: from aiokafka import ConsumerRecord, TopicPartition @@ -20,7 +23,6 @@ from faststream._internal.basic_types import AnyDict from faststream._internal.types import BrokerMiddleware - from faststream.middlewares import AckPolicy @overload @@ -130,6 +132,13 @@ def create_subscriber( "SpecificationDefaultSubscriber", "SpecificationBatchSubscriber", ]: + if ack_policy is not EMPTY and not is_manual: + warnings.warn( + "You can't use acknowledgement policy with `is_manual=False` subscriber", + RuntimeWarning, + stacklevel=3, + ) + if is_manual and not group_id: msg = "You must use `group_id` with manual commit mode." raise SetupError(msg) @@ -149,6 +158,9 @@ def create_subscriber( msg = "You can't provide both `partitions` and `pattern`." raise SetupError(msg) + if ack_policy is EMPTY: + ack_policy = AckPolicy.REJECT_ON_ERROR + if batch: return SpecificationBatchSubscriber( *topics, diff --git a/faststream/nats/broker/registrator.py b/faststream/nats/broker/registrator.py index 1ee9c27fb2..365c114dcb 100644 --- a/faststream/nats/broker/registrator.py +++ b/faststream/nats/broker/registrator.py @@ -5,6 +5,7 @@ from typing_extensions import Doc, override from faststream._internal.broker.abc_broker import ABCBroker +from faststream._internal.constants import EMPTY from faststream.middlewares import AckPolicy from faststream.nats.helpers import StreamBuilder from faststream.nats.publisher.factory import create_publisher @@ -164,7 +165,7 @@ def subscriber( # type: ignore[override] ack_policy: Annotated[ AckPolicy, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + ] = EMPTY, no_reply: Annotated[ bool, Doc( diff --git a/faststream/nats/fastapi/fastapi.py b/faststream/nats/fastapi/fastapi.py index f48d729df6..a62318c82b 100644 --- a/faststream/nats/fastapi/fastapi.py +++ b/faststream/nats/fastapi/fastapi.py @@ -680,7 +680,7 @@ def subscriber( # type: ignore[override] ack_policy: Annotated[ AckPolicy, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + ] = EMPTY, no_reply: Annotated[ bool, Doc( diff --git a/faststream/nats/parser.py b/faststream/nats/parser.py index 3cb2c695a8..d5ddcfe316 100644 --- a/faststream/nats/parser.py +++ b/faststream/nats/parser.py @@ -4,7 +4,6 @@ StreamMessage, decode_message, ) -from faststream.middlewares import AckPolicy from faststream.nats.message import ( NatsBatchMessage, NatsKvMessage, @@ -55,9 +54,8 @@ async def decode_message( class NatsParser(NatsBaseParser): """A class to parse NATS core messages.""" - def __init__(self, *, pattern: str, ack_policy: AckPolicy) -> None: + def __init__(self, *, pattern: str) -> None: super().__init__(pattern=pattern) - self.ack_policy = ack_policy async def parse_message( self, @@ -70,8 +68,7 @@ async def parse_message( headers = message.header or {} - if self.ack_policy is not AckPolicy.DO_NOTHING: - message._ackd = True # prevent message from acking + message._ackd = True # prevent Core message from acknowledgement return NatsMessage( raw_message=message, diff --git a/faststream/nats/publisher/producer.py b/faststream/nats/publisher/producer.py index 35cf40028e..aba0f78349 100644 --- a/faststream/nats/publisher/producer.py +++ b/faststream/nats/publisher/producer.py @@ -5,7 +5,6 @@ import nats from typing_extensions import override -from faststream import AckPolicy from faststream._internal.publisher.proto import ProducerProto from faststream._internal.subscriber.utils import resolve_custom_func from faststream.exceptions import FeatureNotSupportedException @@ -40,7 +39,7 @@ def __init__( parser: Optional["CustomCallable"], decoder: Optional["CustomCallable"], ) -> None: - default = NatsParser(pattern="", ack_policy=AckPolicy.REJECT_ON_ERROR) + default = NatsParser(pattern="") self._parser = resolve_custom_func(parser, default.parse_message) self._decoder = resolve_custom_func(decoder, default.decode_message) @@ -111,7 +110,7 @@ def __init__( parser: Optional["CustomCallable"], decoder: Optional["CustomCallable"], ) -> None: - default = NatsParser(pattern="", ack_policy=AckPolicy.REJECT_ON_ERROR) + default = NatsParser(pattern="") # core parser to serializer responses self._parser = resolve_custom_func(parser, default.parse_message) self._decoder = resolve_custom_func(decoder, default.decode_message) diff --git a/faststream/nats/response.py b/faststream/nats/response.py index 40289436f5..f8121bf883 100644 --- a/faststream/nats/response.py +++ b/faststream/nats/response.py @@ -91,3 +91,16 @@ def from_cmd( reply_to=cmd.reply_to, _publish_type=cmd.publish_type, ) + + def __repr__(self) -> str: + body = [f"body='{self.body}'", f"subject='{self.destination}'"] + if self.stream: + body.append(f"stream={self.stream}") + if self.reply_to: + body.append(f"reply_to='{self.reply_to}'") + body.extend(( + f"headers={self.headers}", + f"correlation_id='{self.correlation_id}'", + f"publish_type={self.publish_type}", + )) + return f"{self.__class__.__name__}({', '.join(body)})" diff --git a/faststream/nats/router.py b/faststream/nats/router.py index 5f0b338462..be895eb8af 100644 --- a/faststream/nats/router.py +++ b/faststream/nats/router.py @@ -16,6 +16,7 @@ BrokerRouter, SubscriberRoute, ) +from faststream._internal.constants import EMPTY from faststream.middlewares import AckPolicy from faststream.nats.broker.registrator import NatsRegistrator @@ -254,7 +255,7 @@ def __init__( ack_policy: Annotated[ AckPolicy, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + ] = EMPTY, no_reply: Annotated[ bool, Doc( diff --git a/faststream/nats/subscriber/factory.py b/faststream/nats/subscriber/factory.py index 4844ff1d94..35062e4eed 100644 --- a/faststream/nats/subscriber/factory.py +++ b/faststream/nats/subscriber/factory.py @@ -12,7 +12,9 @@ DEFAULT_JS_SUB_PENDING_MSGS_LIMIT, ) +from faststream._internal.constants import EMPTY from faststream.exceptions import SetupError +from faststream.middlewares import AckPolicy from faststream.nats.subscriber.specified import ( SpecificationBatchPullStreamSubscriber, SpecificationConcurrentCoreSubscriber, @@ -22,7 +24,7 @@ SpecificationKeyValueWatchSubscriber, SpecificationObjStoreWatchSubscriber, SpecificationPullStreamSubscriber, - SpecificationStreamSubscriber, + SpecificationPushStreamSubscriber, ) if TYPE_CHECKING: @@ -31,7 +33,6 @@ from faststream._internal.basic_types import AnyDict from faststream._internal.types import BrokerMiddleware - from faststream.middlewares import AckPolicy from faststream.nats.schemas import JStream, KvWatch, ObjWatch, PullSub @@ -72,7 +73,7 @@ def create_subscriber( ) -> Union[ "SpecificationCoreSubscriber", "SpecificationConcurrentCoreSubscriber", - "SpecificationStreamSubscriber", + "SpecificationPushStreamSubscriber", "SpecificationConcurrentPushStreamSubscriber", "SpecificationPullStreamSubscriber", "SpecificationConcurrentPullStreamSubscriber", @@ -94,6 +95,7 @@ def create_subscriber( deliver_policy=deliver_policy, headers_only=headers_only, pull_sub=pull_sub, + ack_policy=ack_policy, kv_watch=kv_watch, obj_watch=obj_watch, ack_first=ack_first, @@ -101,6 +103,9 @@ def create_subscriber( stream=stream, ) + if ack_policy is EMPTY: + ack_policy = AckPolicy.REJECT_ON_ERROR + config = config or ConsumerConfig(filter_subjects=[]) if config.durable_name is None: config.durable_name = durable @@ -182,7 +187,6 @@ def create_subscriber( # basic args extra_options=extra_options, # Subscriber args - ack_policy=ack_policy, no_reply=no_reply, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, @@ -199,7 +203,6 @@ def create_subscriber( # basic args extra_options=extra_options, # Subscriber args - ack_policy=ack_policy, no_reply=no_reply, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, @@ -287,8 +290,7 @@ def create_subscriber( include_in_schema=include_in_schema, ) - - return SpecificationStreamSubscriber( + return SpecificationPushStreamSubscriber( stream=stream, subject=subject, queue=queue, @@ -307,7 +309,7 @@ def create_subscriber( ) -def _validate_input_for_misconfigure( +def _validate_input_for_misconfigure( # noqa: PLR0915 subject: str, queue: str, # default "" pending_msgs_limit: Optional[int], @@ -323,32 +325,54 @@ def _validate_input_for_misconfigure( pull_sub: Optional["PullSub"], kv_watch: Optional["KvWatch"], obj_watch: Optional["ObjWatch"], + ack_policy: "AckPolicy", # default EMPTY ack_first: bool, # default False max_workers: int, # default 1 stream: Optional["JStream"], ) -> None: if not subject and not config: - raise SetupError("You must provide either the `subject` or `config` option.") + msg = "You must provide either the `subject` or `config` option." + raise SetupError(msg) if stream and kv_watch: - raise SetupError( - "You can't use both the `stream` and `kv_watch` options simultaneously." - ) + msg = "You can't use both the `stream` and `kv_watch` options simultaneously." + raise SetupError(msg) if stream and obj_watch: - raise SetupError( - "You can't use both the `stream` and `obj_watch` options simultaneously." - ) + msg = "You can't use both the `stream` and `obj_watch` options simultaneously." + raise SetupError(msg) if kv_watch and obj_watch: - raise SetupError( + msg = ( "You can't use both the `kv_watch` and `obj_watch` options simultaneously." ) + raise SetupError(msg) if pull_sub and not stream: - raise SetupError( - "The pull subscriber can only be used with the `stream` option." - ) + msg = "The pull subscriber can only be used with the `stream` option." + raise SetupError(msg) + + if ack_policy is not EMPTY: + if obj_watch is not None: + warnings.warn( + "You can't use acknowledgement policy with ObjectStorage watch subscriber.", + RuntimeWarning, + stacklevel=4, + ) + + elif kv_watch is not None: + warnings.warn( + "You can't use acknowledgement policy with KeyValue watch subscriber.", + RuntimeWarning, + stacklevel=4, + ) + + elif stream is None: + warnings.warn( + "You can't use acknowledgement policy with core subscriber. Use JetStream instead.", + RuntimeWarning, + stacklevel=4, + ) if max_msgs > 0 and any((stream, kv_watch, obj_watch)): warnings.warn( @@ -445,42 +469,40 @@ def _validate_input_for_misconfigure( stacklevel=4, ) - else: - # JetStream Subscribers - if pull_sub: - if queue: - warnings.warn( - message="The `queue` option has no effect with JetStream Pull Subscription. You probably wanted to use the `durable` option instead.", - category=RuntimeWarning, - stacklevel=4, - ) + # JetStream Subscribers + elif pull_sub: + if queue: + warnings.warn( + message="The `queue` option has no effect with JetStream Pull Subscription. You probably wanted to use the `durable` option instead.", + category=RuntimeWarning, + stacklevel=4, + ) - if ordered_consumer: - warnings.warn( - "The `ordered_consumer` option has no effect with JetStream Pull Subscription. It can only be used with JetStream Push Subscription.", - RuntimeWarning, - stacklevel=4, - ) + if ordered_consumer: + warnings.warn( + "The `ordered_consumer` option has no effect with JetStream Pull Subscription. It can only be used with JetStream Push Subscription.", + RuntimeWarning, + stacklevel=4, + ) - if ack_first: - warnings.warn( - message="The `ack_first` option has no effect with JetStream Pull Subscription. It can only be used with JetStream Push Subscription.", - category=RuntimeWarning, - stacklevel=4, - ) + if ack_first: + warnings.warn( + message="The `ack_first` option has no effect with JetStream Pull Subscription. It can only be used with JetStream Push Subscription.", + category=RuntimeWarning, + stacklevel=4, + ) - if flow_control: - warnings.warn( - message="The `flow_control` option has no effect with JetStream Pull Subscription. It can only be used with JetStream Push Subscription.", - category=RuntimeWarning, - stacklevel=4, - ) + if flow_control: + warnings.warn( + message="The `flow_control` option has no effect with JetStream Pull Subscription. It can only be used with JetStream Push Subscription.", + category=RuntimeWarning, + stacklevel=4, + ) - else: - # JS PushSub - if durable is not None: - warnings.warn( - message="The JetStream Push consumer with the `durable` option can't be scaled horizontally across multiple instances. You probably wanted to use the `queue` option instead. Also, we strongly recommend using the Jetstream PullSubsriber with the `durable` option as the default.", - category=RuntimeWarning, - stacklevel=4, - ) + # JS PushSub + elif durable is not None: + warnings.warn( + message="The JetStream Push consumer with the `durable` option can't be scaled horizontally across multiple instances. You probably wanted to use the `queue` option instead. Also, we strongly recommend using the Jetstream PullSubsriber with the `durable` option as the default.", + category=RuntimeWarning, + stacklevel=4, + ) diff --git a/faststream/nats/subscriber/specified.py b/faststream/nats/subscriber/specified.py index ee3bf32bdb..8862f47ab3 100644 --- a/faststream/nats/subscriber/specified.py +++ b/faststream/nats/subscriber/specified.py @@ -66,7 +66,7 @@ class SpecificationConcurrentCoreSubscriber( """One-message core concurrent consumer with Specification methods.""" -class SpecificationStreamSubscriber( +class SpecificationPushStreamSubscriber( SpecificationSubscriber, PushStreamSubscription, ): diff --git a/faststream/nats/subscriber/usecase.py b/faststream/nats/subscriber/usecase.py index 7dc7cd1cc1..e2c6b207e1 100644 --- a/faststream/nats/subscriber/usecase.py +++ b/faststream/nats/subscriber/usecase.py @@ -295,7 +295,6 @@ def __init__( queue: str, extra_options: Optional["AnyDict"], # Subscriber args - ack_policy: "AckPolicy", no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[Msg]"], @@ -304,7 +303,7 @@ def __init__( description_: Optional[str], include_in_schema: bool, ) -> None: - parser_ = NatsParser(pattern=subject, ack_policy=ack_policy) + parser_ = NatsParser(pattern=subject) self.queue = queue @@ -316,7 +315,7 @@ def __init__( default_parser=parser_.parse_message, default_decoder=parser_.decode_message, # Propagated args - ack_policy=ack_policy, + ack_policy=AckPolicy.DO_NOTHING, no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, @@ -404,7 +403,6 @@ def __init__( queue: str, extra_options: Optional["AnyDict"], # Subscriber args - ack_policy: "AckPolicy", no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[Msg]"], @@ -421,7 +419,6 @@ def __init__( queue=queue, extra_options=extra_options, # Propagated args - ack_policy=ack_policy, no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, diff --git a/faststream/nats/testing.py b/faststream/nats/testing.py index f417d9e63e..b3c57d7541 100644 --- a/faststream/nats/testing.py +++ b/faststream/nats/testing.py @@ -12,7 +12,6 @@ from nats.aio.msg import Msg from typing_extensions import override -from faststream import AckPolicy from faststream._internal.subscriber.utils import resolve_custom_func from faststream._internal.testing.broker import TestBroker from faststream.exceptions import SubscriberNotFound @@ -73,15 +72,21 @@ async def _fake_connect( *args: Any, **kwargs: Any, ) -> AsyncMock: - broker._connection_state = ConnectedState(AsyncMock(), AsyncMock()) + if not broker._connection_state: + broker._connection_state = ConnectedState(AsyncMock(), AsyncMock()) return AsyncMock() + def _fake_start(self, broker: NatsBroker, *args: Any, **kwargs: Any) -> None: + if not broker._connection_state: + broker._connection_state = ConnectedState(AsyncMock(), AsyncMock()) + return super()._fake_start(broker, *args, **kwargs) + class FakeProducer(NatsFastProducer): def __init__(self, broker: NatsBroker) -> None: self.broker = broker - default = NatsParser(pattern="", ack_policy=AckPolicy.REJECT_ON_ERROR) + default = NatsParser(pattern="") self._parser = resolve_custom_func(broker._parser, default.parse_message) self._decoder = resolve_custom_func(broker._decoder, default.decode_message) diff --git a/faststream/rabbit/broker/registrator.py b/faststream/rabbit/broker/registrator.py index e3e861124c..37ca0066f7 100644 --- a/faststream/rabbit/broker/registrator.py +++ b/faststream/rabbit/broker/registrator.py @@ -4,6 +4,7 @@ from typing_extensions import Doc, override from faststream._internal.broker.abc_broker import ABCBroker +from faststream._internal.constants import EMPTY from faststream.middlewares import AckPolicy from faststream.rabbit.publisher.factory import create_publisher from faststream.rabbit.publisher.specified import SpecificationPublisher @@ -61,7 +62,7 @@ def subscriber( # type: ignore[override] ack_policy: Annotated[ AckPolicy, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + ] = EMPTY, # broker arguments dependencies: Annotated[ Iterable["Dependant"], diff --git a/faststream/rabbit/fastapi/fastapi.py b/faststream/rabbit/fastapi/fastapi.py index 6411dbc949..6e32718447 100644 --- a/faststream/rabbit/fastapi/fastapi.py +++ b/faststream/rabbit/fastapi/fastapi.py @@ -515,7 +515,7 @@ def subscriber( # type: ignore[override] ack_policy: Annotated[ AckPolicy, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + ] = EMPTY, no_reply: Annotated[ bool, Doc( diff --git a/faststream/rabbit/router.py b/faststream/rabbit/router.py index 3edbf447b7..8eaec725ef 100644 --- a/faststream/rabbit/router.py +++ b/faststream/rabbit/router.py @@ -8,6 +8,7 @@ BrokerRouter, SubscriberRoute, ) +from faststream._internal.constants import EMPTY from faststream.middlewares import AckPolicy from faststream.rabbit.broker.registrator import RabbitRegistrator @@ -233,7 +234,7 @@ def __init__( ack_policy: Annotated[ AckPolicy, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + ] = EMPTY, no_reply: Annotated[ bool, Doc( diff --git a/faststream/rabbit/subscriber/factory.py b/faststream/rabbit/subscriber/factory.py index 4554f9c9c5..823844aeae 100644 --- a/faststream/rabbit/subscriber/factory.py +++ b/faststream/rabbit/subscriber/factory.py @@ -1,6 +1,8 @@ from collections.abc import Iterable from typing import TYPE_CHECKING, Optional +from faststream._internal.constants import EMPTY +from faststream.middlewares import AckPolicy from faststream.rabbit.subscriber.specified import SpecificationSubscriber if TYPE_CHECKING: @@ -9,7 +11,6 @@ from faststream._internal.basic_types import AnyDict from faststream._internal.types import BrokerMiddleware - from faststream.middlewares import AckPolicy from faststream.rabbit.schemas import RabbitExchange, RabbitQueue @@ -28,6 +29,9 @@ def create_subscriber( description_: Optional[str], include_in_schema: bool, ) -> SpecificationSubscriber: + if ack_policy is EMPTY: + ack_policy = AckPolicy.REJECT_ON_ERROR + return SpecificationSubscriber( queue=queue, exchange=exchange, diff --git a/faststream/rabbit/subscriber/usecase.py b/faststream/rabbit/subscriber/usecase.py index d659977ddf..e91333ed25 100644 --- a/faststream/rabbit/subscriber/usecase.py +++ b/faststream/rabbit/subscriber/usecase.py @@ -1,3 +1,5 @@ +import asyncio +import contextlib from collections.abc import Iterable, Sequence from typing import ( TYPE_CHECKING, @@ -177,7 +179,10 @@ async def get_one( sleep_interval = timeout / 10 raw_message: Optional[IncomingMessage] = None - with anyio.move_on_after(timeout): + with ( + contextlib.suppress(asyncio.exceptions.CancelledError), + anyio.move_on_after(timeout), + ): while ( # noqa: ASYNC110 raw_message := await self._queue_obj.get( fail=False, diff --git a/faststream/redis/broker/registrator.py b/faststream/redis/broker/registrator.py index 598105ef9b..10cf4afe98 100644 --- a/faststream/redis/broker/registrator.py +++ b/faststream/redis/broker/registrator.py @@ -4,6 +4,7 @@ from typing_extensions import Doc, override from faststream._internal.broker.abc_broker import ABCBroker +from faststream._internal.constants import EMPTY from faststream.middlewares import AckPolicy from faststream.redis.message import UnifyRedisDict from faststream.redis.publisher.factory import create_publisher @@ -69,7 +70,7 @@ def subscriber( # type: ignore[override] ack_policy: Annotated[ AckPolicy, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + ] = EMPTY, no_reply: Annotated[ bool, Doc( diff --git a/faststream/redis/fastapi/fastapi.py b/faststream/redis/fastapi/fastapi.py index 01a5432f5e..c64968aac8 100644 --- a/faststream/redis/fastapi/fastapi.py +++ b/faststream/redis/fastapi/fastapi.py @@ -465,7 +465,7 @@ def subscriber( # type: ignore[override] ack_policy: Annotated[ AckPolicy, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + ] = EMPTY, no_reply: Annotated[ bool, Doc( diff --git a/faststream/redis/router.py b/faststream/redis/router.py index 32d937dcce..fb155829a0 100644 --- a/faststream/redis/router.py +++ b/faststream/redis/router.py @@ -8,6 +8,7 @@ BrokerRouter, SubscriberRoute, ) +from faststream._internal.constants import EMPTY from faststream.middlewares import AckPolicy from faststream.redis.broker.registrator import RedisRegistrator from faststream.redis.message import BaseMessage @@ -151,7 +152,7 @@ def __init__( ack_policy: Annotated[ AckPolicy, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + ] = EMPTY, no_reply: Annotated[ bool, Doc( diff --git a/faststream/redis/subscriber/factory.py b/faststream/redis/subscriber/factory.py index e46d3d6646..378b561348 100644 --- a/faststream/redis/subscriber/factory.py +++ b/faststream/redis/subscriber/factory.py @@ -1,32 +1,34 @@ +import warnings from collections.abc import Iterable from typing import TYPE_CHECKING, Optional, Union from typing_extensions import TypeAlias +from faststream._internal.constants import EMPTY from faststream.exceptions import SetupError +from faststream.middlewares import AckPolicy from faststream.redis.schemas import INCORRECT_SETUP_MSG, ListSub, PubSub, StreamSub from faststream.redis.schemas.proto import validate_options from faststream.redis.subscriber.specified import ( - AsyncAPIChannelSubscriber, - AsyncAPIListBatchSubscriber, - AsyncAPIListSubscriber, - AsyncAPIStreamBatchSubscriber, - AsyncAPIStreamSubscriber, + SpecificationChannelSubscriber, + SpecificationListBatchSubscriber, + SpecificationListSubscriber, + SpecificationStreamBatchSubscriber, + SpecificationStreamSubscriber, ) if TYPE_CHECKING: from fast_depends.dependencies import Dependant from faststream._internal.types import BrokerMiddleware - from faststream.middlewares import AckPolicy from faststream.redis.message import UnifyRedisDict SubsciberType: TypeAlias = Union[ - "AsyncAPIChannelSubscriber", - "AsyncAPIStreamBatchSubscriber", - "AsyncAPIStreamSubscriber", - "AsyncAPIListBatchSubscriber", - "AsyncAPIListSubscriber", + "SpecificationChannelSubscriber", + "SpecificationStreamBatchSubscriber", + "SpecificationStreamSubscriber", + "SpecificationListBatchSubscriber", + "SpecificationListSubscriber", ] @@ -45,13 +47,20 @@ def create_subscriber( description_: Optional[str] = None, include_in_schema: bool = True, ) -> SubsciberType: - validate_options(channel=channel, list=list, stream=stream) + _validate_input_for_misconfigure( + channel=channel, + list=list, + stream=stream, + ack_policy=ack_policy, + ) + + if ack_policy is EMPTY: + ack_policy = AckPolicy.REJECT_ON_ERROR if (channel_sub := PubSub.validate(channel)) is not None: - return AsyncAPIChannelSubscriber( + return SpecificationChannelSubscriber( channel=channel_sub, # basic args - ack_policy=ack_policy, no_reply=no_reply, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, @@ -63,7 +72,7 @@ def create_subscriber( if (stream_sub := StreamSub.validate(stream)) is not None: if stream_sub.batch: - return AsyncAPIStreamBatchSubscriber( + return SpecificationStreamBatchSubscriber( stream=stream_sub, # basic args ack_policy=ack_policy, @@ -75,7 +84,8 @@ def create_subscriber( description_=description_, include_in_schema=include_in_schema, ) - return AsyncAPIStreamSubscriber( + + return SpecificationStreamSubscriber( stream=stream_sub, # basic args ack_policy=ack_policy, @@ -90,10 +100,9 @@ def create_subscriber( if (list_sub := ListSub.validate(list)) is not None: if list_sub.batch: - return AsyncAPIListBatchSubscriber( + return SpecificationListBatchSubscriber( list=list_sub, # basic args - ack_policy=ack_policy, no_reply=no_reply, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, @@ -102,10 +111,10 @@ def create_subscriber( description_=description_, include_in_schema=include_in_schema, ) - return AsyncAPIListSubscriber( + + return SpecificationListSubscriber( list=list_sub, # basic args - ack_policy=ack_policy, no_reply=no_reply, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, @@ -116,3 +125,28 @@ def create_subscriber( ) raise SetupError(INCORRECT_SETUP_MSG) + + +def _validate_input_for_misconfigure( + *, + channel: Union["PubSub", str, None], + list: Union["ListSub", str, None], + stream: Union["StreamSub", str, None], + ack_policy: AckPolicy, +) -> None: + validate_options(channel=channel, list=list, stream=stream) + + if ack_policy is not EMPTY: + if channel: + warnings.warn( + "You can't use acknowledgement policy with PubSub subscriber.", + RuntimeWarning, + stacklevel=4, + ) + + if list: + warnings.warn( + "You can't use acknowledgement policy with List subscriber.", + RuntimeWarning, + stacklevel=4, + ) diff --git a/faststream/redis/subscriber/specified.py b/faststream/redis/subscriber/specified.py index 3c62aa3168..800e5b1f02 100644 --- a/faststream/redis/subscriber/specified.py +++ b/faststream/redis/subscriber/specified.py @@ -2,10 +2,10 @@ from faststream.redis.schemas.proto import RedisSpecificationProtocol from faststream.redis.subscriber.usecase import ( BatchListSubscriber, - BatchStreamSubscriber, ChannelSubscriber, ListSubscriber, LogicSubscriber, + StreamBatchSubscriber, StreamSubscriber, ) from faststream.specification.asyncapi.utils import resolve_payloads @@ -40,7 +40,7 @@ def get_schema(self) -> dict[str, Channel]: } -class AsyncAPIChannelSubscriber(ChannelSubscriber, SpecificationSubscriber): +class SpecificationChannelSubscriber(ChannelSubscriber, SpecificationSubscriber): def get_name(self) -> str: return f"{self.channel.name}:{self.call_name}" @@ -68,11 +68,11 @@ def channel_binding(self) -> "redis.ChannelBinding": ) -class AsyncAPIStreamSubscriber(StreamSubscriber, _StreamSubscriberMixin): +class SpecificationStreamSubscriber(StreamSubscriber, _StreamSubscriberMixin): pass -class AsyncAPIStreamBatchSubscriber(BatchStreamSubscriber, _StreamSubscriberMixin): +class SpecificationStreamBatchSubscriber(StreamBatchSubscriber, _StreamSubscriberMixin): pass @@ -90,9 +90,9 @@ def channel_binding(self) -> "redis.ChannelBinding": ) -class AsyncAPIListSubscriber(ListSubscriber, _ListSubscriberMixin): +class SpecificationListSubscriber(ListSubscriber, _ListSubscriberMixin): pass -class AsyncAPIListBatchSubscriber(BatchListSubscriber, _ListSubscriberMixin): +class SpecificationListBatchSubscriber(BatchListSubscriber, _ListSubscriberMixin): pass diff --git a/faststream/redis/subscriber/usecase.py b/faststream/redis/subscriber/usecase.py index 40a3c3a4f6..1f89ca54b4 100644 --- a/faststream/redis/subscriber/usecase.py +++ b/faststream/redis/subscriber/usecase.py @@ -21,6 +21,7 @@ from faststream._internal.subscriber.usecase import SubscriberUsecase from faststream._internal.subscriber.utils import process_msg +from faststream.middlewares import AckPolicy from faststream.redis.message import ( BatchListMessage, BatchStreamMessage, @@ -54,7 +55,6 @@ CustomCallable, ) from faststream.message import StreamMessage as BrokerStreamMessage - from faststream.middlewares import AckPolicy TopicName: TypeAlias = bytes @@ -205,7 +205,6 @@ def __init__( *, channel: "PubSub", # Subscriber args - ack_policy: "AckPolicy", no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], @@ -219,7 +218,7 @@ def __init__( default_parser=parser.parse_message, default_decoder=parser.decode_message, # Propagated options - ack_policy=ack_policy, + ack_policy=AckPolicy.DO_NOTHING, no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, @@ -436,7 +435,6 @@ def __init__( *, list: ListSub, # Subscriber args - ack_policy: "AckPolicy", no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], @@ -451,7 +449,7 @@ def __init__( default_parser=parser.parse_message, default_decoder=parser.decode_message, # Propagated options - ack_policy=ack_policy, + ack_policy=AckPolicy.DO_NOTHING, no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, @@ -485,7 +483,6 @@ def __init__( *, list: ListSub, # Subscriber args - ack_policy: "AckPolicy", no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], @@ -500,7 +497,7 @@ def __init__( default_parser=parser.parse_message, default_decoder=parser.decode_message, # Propagated options - ack_policy=ack_policy, + ack_policy=AckPolicy.DO_NOTHING, no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, @@ -788,7 +785,7 @@ async def _get_msgs( await self.consume(msg) # type: ignore[arg-type] -class BatchStreamSubscriber(_StreamHandlerMixin): +class StreamBatchSubscriber(_StreamHandlerMixin): def __init__( self, *, diff --git a/tests/brokers/base/consume.py b/tests/brokers/base/consume.py index 62d68072ca..4fdb0e118d 100644 --- a/tests/brokers/base/consume.py +++ b/tests/brokers/base/consume.py @@ -16,8 +16,8 @@ class BrokerConsumeTestcase(BaseTestcaseConfig): async def test_consume( self, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() consume_broker = self.get_broker() args, kwargs = self.get_subscriber_params(queue) @@ -200,9 +200,10 @@ async def handler2(m) -> None: async def test_consume_validate_false( self, queue: str, - event: asyncio.Event, mock: MagicMock, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker( apply_types=True, serializer=None, @@ -240,8 +241,9 @@ async def handler( async def test_dynamic_sub( self, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker() async def subscriber(m) -> None: @@ -334,9 +336,10 @@ async def test_get_one_timeout( async def test_stop_consume_exc( self, queue: str, - event: asyncio.Event, mock: MagicMock, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker() args, kwargs = self.get_subscriber_params(queue) diff --git a/tests/brokers/base/fastapi.py b/tests/brokers/base/fastapi.py index e1e9c15954..d9b4582742 100644 --- a/tests/brokers/base/fastapi.py +++ b/tests/brokers/base/fastapi.py @@ -24,9 +24,9 @@ class FastAPITestcase(BaseTestcaseConfig): router_class: type[StreamRouter[BrokerUsecase]] broker_router_class: type[BrokerRouter[Any]] - async def test_base_real( - self, mock: Mock, queue: str, event: asyncio.Event - ) -> None: + async def test_base_real(self, mock: Mock, queue: str) -> None: + event = asyncio.Event() + router = self.router_class() args, kwargs = self.get_subscriber_params(queue) @@ -50,8 +50,12 @@ async def hello(msg): mock.assert_called_with("hi") async def test_background( - self, mock: Mock, queue: str, event: asyncio.Event + self, + mock: Mock, + queue: str, ) -> None: + event = asyncio.Event() + router = self.router_class() def task(msg): @@ -77,7 +81,9 @@ async def hello(msg, tasks: BackgroundTasks) -> None: assert event.is_set() mock.assert_called_with("hi") - async def test_context(self, mock: Mock, queue: str, event: asyncio.Event) -> None: + async def test_context(self, mock: Mock, queue: str) -> None: + event = asyncio.Event() + router = self.router_class() context = router.context @@ -108,7 +114,9 @@ async def hello(msg=Context(context_key)): assert event.is_set() mock.assert_called_with(True) - async def test_initial_context(self, queue: str, event: asyncio.Event) -> None: + async def test_initial_context(self, queue: str) -> None: + event = asyncio.Event() + router = self.router_class() context = router.context @@ -136,10 +144,10 @@ async def hello(msg: int, data=Context(queue, initial=set)) -> None: assert context.get(queue) == {1, 2} context.reset_global(queue) - async def test_double_real( - self, mock: Mock, queue: str, event: asyncio.Event - ) -> None: + async def test_double_real(self, mock: Mock, queue: str) -> None: + event = asyncio.Event() event2 = asyncio.Event() + router = self.router_class() args, kwargs = self.get_subscriber_params(queue) @@ -176,8 +184,9 @@ async def test_base_publisher_real( self, mock: Mock, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + router = self.router_class() args, kwargs = self.get_subscriber_params(queue) diff --git a/tests/brokers/base/middlewares.py b/tests/brokers/base/middlewares.py index dbde16432f..47e07c6398 100644 --- a/tests/brokers/base/middlewares.py +++ b/tests/brokers/base/middlewares.py @@ -16,10 +16,11 @@ class LocalMiddlewareTestcase(BaseTestcaseConfig): async def test_subscriber_middleware( self, - event: asyncio.Event, queue: str, mock: Mock, ) -> None: + event = asyncio.Event() + async def mid(call_next, msg): mock.start(await msg.decode()) result = await call_next(msg) @@ -54,10 +55,11 @@ async def handler(m) -> str: async def test_publisher_middleware( self, - event: asyncio.Event, queue: str, mock: Mock, ) -> None: + event = asyncio.Event() + async def mid(call_next, msg, **kwargs): mock.enter() result = await call_next(msg, **kwargs) @@ -194,7 +196,9 @@ async def handler2(m) -> str: mock.end.assert_called_once() assert mock.call_count == 2 - async def test_error_traceback(self, queue: str, mock: Mock, event) -> None: + async def test_error_traceback(self, queue: str, mock: Mock) -> None: + event = asyncio.Event() + async def mid(call_next, msg): try: result = await call_next(msg) @@ -232,10 +236,11 @@ async def handler2(m): class MiddlewareTestcase(LocalMiddlewareTestcase): async def test_global_middleware( self, - event: asyncio.Event, queue: str, mock: Mock, ) -> None: + event = asyncio.Event() + class mid(BaseMiddleware): # noqa: N801 async def on_receive(self): mock.start(self.msg) @@ -272,10 +277,11 @@ async def handler(m) -> str: async def test_add_global_middleware( self, - event: asyncio.Event, queue: str, mock: Mock, ) -> None: + event = asyncio.Event() + class mid(BaseMiddleware): # noqa: N801 async def on_receive(self): mock.start(self.msg) @@ -328,8 +334,9 @@ async def test_patch_publish( self, queue: str, mock: Mock, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + class Mid(BaseMiddleware): async def on_publish(self, msg: PublishCommand) -> PublishCommand: msg.body *= 2 @@ -366,10 +373,11 @@ async def handler_resp(m) -> None: async def test_global_publisher_middleware( self, - event: asyncio.Event, queue: str, mock: Mock, ) -> None: + event = asyncio.Event() + class Mid(BaseMiddleware): async def on_publish(self, msg: PublishCommand) -> PublishCommand: msg.body *= 2 @@ -413,10 +421,11 @@ async def handler(m): class ExceptionMiddlewareTestcase(BaseTestcaseConfig): async def test_exception_middleware_default_msg( self, - event: asyncio.Event, queue: str, mock: Mock, ) -> None: + event = asyncio.Event() + mid = ExceptionMiddleware() @mid.add_handler(ValueError, publish=True) @@ -455,10 +464,11 @@ async def subscriber2(msg=Context("message")) -> None: async def test_exception_middleware_skip_msg( self, - event: asyncio.Event, queue: str, mock: Mock, ) -> None: + event = asyncio.Event() + mid = ExceptionMiddleware() @mid.add_handler(ValueError, publish=True) @@ -495,10 +505,11 @@ async def subscriber2(msg=Context("message")) -> None: async def test_exception_middleware_do_not_catch_skip_msg( self, - event: asyncio.Event, queue: str, mock: Mock, ) -> None: + event = asyncio.Event() + mid = ExceptionMiddleware() @mid.add_handler(Exception) @@ -529,10 +540,11 @@ async def subscriber(m): async def test_exception_middleware_reraise( self, - event: asyncio.Event, queue: str, mock: Mock, ) -> None: + event = asyncio.Event() + mid = ExceptionMiddleware() @mid.add_handler(ValueError, publish=True) @@ -569,10 +581,11 @@ async def subscriber2(msg=Context("message")) -> None: async def test_exception_middleware_different_handler( self, - event: asyncio.Event, queue: str, mock: Mock, ) -> None: + event = asyncio.Event() + mid = ExceptionMiddleware() @mid.add_handler(ZeroDivisionError, publish=True) @@ -649,10 +662,11 @@ async def value_error_handler(exc) -> str: async def test_exception_middleware_decoder_error( self, - event: asyncio.Event, queue: str, mock: Mock, ) -> None: + event = asyncio.Event() + async def decoder( msg, original_decoder, diff --git a/tests/brokers/base/parser.py b/tests/brokers/base/parser.py index 143dc24b75..859c508c53 100644 --- a/tests/brokers/base/parser.py +++ b/tests/brokers/base/parser.py @@ -12,8 +12,9 @@ async def test_local_parser( self, mock: Mock, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + broker = self.get_broker() async def custom_parser(msg, original): @@ -45,8 +46,9 @@ async def test_local_sync_decoder( self, mock: Mock, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + broker = self.get_broker() def custom_decoder(msg): @@ -77,8 +79,9 @@ async def test_global_sync_decoder( self, mock: Mock, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + def custom_decoder(msg): mock(msg.body) return msg @@ -107,10 +110,11 @@ async def handle(m) -> None: async def test_local_parser_no_share_between_subscribers( self, - event: asyncio.Event, mock: Mock, queue: str, ) -> None: + event = asyncio.Event() + event2 = asyncio.Event() broker = self.get_broker() @@ -151,8 +155,9 @@ async def test_local_parser_no_share_between_handlers( self, mock: Mock, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + broker = self.get_broker() args, kwargs = self.get_subscriber_params(queue) @@ -196,8 +201,9 @@ async def test_global_parser( self, mock: Mock, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + async def custom_parser(msg, original): msg = await original(msg) mock(msg.body) diff --git a/tests/brokers/base/publish.py b/tests/brokers/base/publish.py index 75154bd9f2..feac1efac4 100644 --- a/tests/brokers/base/publish.py +++ b/tests/brokers/base/publish.py @@ -141,9 +141,10 @@ async def test_serialize( message, message_type, expected_message, - event: asyncio.Event, mock: Mock, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker(apply_types=True) args, kwargs = self.get_subscriber_params(queue) @@ -171,9 +172,10 @@ async def handler(m: message_type) -> None: async def test_response( self, queue: str, - event: asyncio.Event, mock: Mock, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker(apply_types=True) args, kwargs = self.get_subscriber_params(queue) @@ -215,9 +217,10 @@ async def m_next(msg=Context("message")) -> None: async def test_unwrap_dict( self, queue: str, - event: asyncio.Event, mock: Mock, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker(apply_types=True) args, kwargs = self.get_subscriber_params(queue) @@ -250,8 +253,9 @@ async def test_unwrap_list( self, mock: Mock, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker(apply_types=True) args, kwargs = self.get_subscriber_params(queue) @@ -278,9 +282,10 @@ async def m(a: int, b: int, *args: tuple[int, ...]) -> None: async def test_base_publisher( self, queue: str, - event: asyncio.Event, mock: Mock, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker(apply_types=True) args, kwargs = self.get_subscriber_params(queue) @@ -314,9 +319,10 @@ async def resp(msg) -> None: async def test_publisher_object( self, queue: str, - event: asyncio.Event, mock: Mock, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker(apply_types=True) publisher = pub_broker.publisher(queue + "resp") @@ -352,9 +358,10 @@ async def resp(msg) -> None: async def test_publish_manual( self, queue: str, - event: asyncio.Event, mock: Mock, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker(apply_types=True) publisher = pub_broker.publisher(queue + "resp") @@ -491,9 +498,10 @@ async def resp() -> None: async def test_reply_to( self, queue: str, - event: asyncio.Event, mock: Mock, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker(apply_types=True) args, kwargs = self.get_subscriber_params(queue + "reply") @@ -529,9 +537,10 @@ async def handler(m): async def test_no_reply( self, queue: str, - event: asyncio.Event, mock: Mock, ) -> None: + event = asyncio.Event() + class Mid(BaseMiddleware): async def after_processed(self, *args: Any, **kwargs: Any): event.set() @@ -573,9 +582,10 @@ async def handler(m): async def test_publisher_after_start( self, queue: str, - event: asyncio.Event, mock: Mock, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker(apply_types=True) args, kwargs = self.get_subscriber_params(queue) diff --git a/tests/brokers/base/requests.py b/tests/brokers/base/requests.py index 9cb8296fa9..16414f47d3 100644 --- a/tests/brokers/base/requests.py +++ b/tests/brokers/base/requests.py @@ -1,3 +1,5 @@ +import asyncio + import anyio import pytest @@ -24,7 +26,7 @@ async def handler(msg) -> str: async with self.patch_broker(broker): await broker.start() - with pytest.raises(TimeoutError): + with pytest.raises((TimeoutError, asyncio.TimeoutError)): await broker.request( None, queue, diff --git a/tests/brokers/base/router.py b/tests/brokers/base/router.py index 7b8628172d..382f54dc0c 100644 --- a/tests/brokers/base/router.py +++ b/tests/brokers/base/router.py @@ -25,8 +25,9 @@ async def test_empty_prefix( self, router: BrokerRouter, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker() args, kwargs = self.get_subscriber_params(queue) @@ -53,8 +54,9 @@ async def test_not_empty_prefix( self, router: BrokerRouter, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker() router.prefix = "test_" @@ -83,8 +85,9 @@ async def test_include_with_prefix( self, router: BrokerRouter, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker() args, kwargs = self.get_subscriber_params(queue) @@ -111,8 +114,9 @@ async def test_empty_prefix_publisher( self, router: BrokerRouter, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker() args, kwargs = self.get_subscriber_params(queue) @@ -146,8 +150,9 @@ async def test_not_empty_prefix_publisher( self, router: BrokerRouter, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker() router.prefix = "test_" @@ -183,8 +188,9 @@ async def test_manual_publisher( self, router: BrokerRouter, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker() router.prefix = "test_" @@ -219,10 +225,11 @@ def response(m) -> None: async def test_delayed_handlers( self, - event: asyncio.Event, router: BrokerRouter, queue: str, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker() def response(m) -> None: @@ -251,11 +258,12 @@ def response(m) -> None: async def test_delayed_publishers( self, - event: asyncio.Event, router: BrokerRouter, queue: str, mock: Mock, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker() def response(m): @@ -303,9 +311,10 @@ async def test_nested_routers_sub( self, router: BrokerRouter, queue: str, - event: asyncio.Event, mock: Mock, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker() core_router = type(router)(prefix="test1_") @@ -340,8 +349,9 @@ async def test_nested_routers_pub( self, router: BrokerRouter, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker() core_router = type(router)(prefix="test1_") @@ -488,9 +498,10 @@ async def test_router_parser( self, router: BrokerRouter, queue: str, - event: asyncio.Event, mock: Mock, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker() async def parser(msg, original): @@ -532,9 +543,10 @@ async def test_router_parser_override( self, router: BrokerRouter, queue: str, - event: asyncio.Event, mock: Mock, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker() async def global_parser(msg, original): # pragma: no cover @@ -588,8 +600,9 @@ async def test_publisher_mock( self, router: BrokerRouter, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker() pub = router.publisher(queue + "resp") @@ -621,8 +634,9 @@ async def test_subscriber_mock( self, router: BrokerRouter, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker() args, kwargs = self.get_subscriber_params(queue) diff --git a/tests/brokers/confluent/test_consume.py b/tests/brokers/confluent/test_consume.py index 9bb954ee2f..2e886bc1f6 100644 --- a/tests/brokers/confluent/test_consume.py +++ b/tests/brokers/confluent/test_consume.py @@ -50,9 +50,10 @@ async def handler(msg) -> None: async def test_consume_batch_headers( self, mock, - event: asyncio.Event, queue: str, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) args, kwargs = self.get_subscriber_params(queue, batch=True) @@ -88,8 +89,9 @@ def subscriber(m, msg: KafkaMessage) -> None: async def test_consume_ack( self, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) args, kwargs = self.get_subscriber_params( @@ -131,8 +133,9 @@ async def handler(msg: KafkaMessage) -> None: async def test_consume_ack_manual( self, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) args, kwargs = self.get_subscriber_params( @@ -170,8 +173,9 @@ async def handler(msg: KafkaMessage) -> None: async def test_consume_ack_raise( self, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) args, kwargs = self.get_subscriber_params( @@ -209,8 +213,9 @@ async def handler(msg: KafkaMessage): async def test_nack( self, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) args, kwargs = self.get_subscriber_params( @@ -248,8 +253,9 @@ async def handler(msg: KafkaMessage) -> None: async def test_consume_no_ack( self, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) args, kwargs = self.get_subscriber_params( @@ -289,8 +295,9 @@ async def handler(msg: KafkaMessage) -> None: async def test_consume_with_no_auto_commit( self, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) args, kwargs = self.get_subscriber_params( diff --git a/tests/brokers/confluent/test_fastapi.py b/tests/brokers/confluent/test_fastapi.py index 6d2944ce94..d47612c91e 100644 --- a/tests/brokers/confluent/test_fastapi.py +++ b/tests/brokers/confluent/test_fastapi.py @@ -21,8 +21,9 @@ async def test_batch_real( self, mock: Mock, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + router = self.router_class() args, kwargs = self.get_subscriber_params(queue, batch=True) @@ -57,8 +58,9 @@ async def test_batch_testclient( self, mock: Mock, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + router = self.router_class() args, kwargs = self.get_subscriber_params(queue, batch=True) diff --git a/tests/brokers/confluent/test_publish.py b/tests/brokers/confluent/test_publish.py index f4c7b2e251..0d6fc9f4e1 100644 --- a/tests/brokers/confluent/test_publish.py +++ b/tests/brokers/confluent/test_publish.py @@ -110,9 +110,10 @@ async def pub(m): async def test_response( self, queue: str, - event: asyncio.Event, mock: Mock, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker(apply_types=True) args, kwargs = self.get_subscriber_params(queue) diff --git a/tests/brokers/confluent/test_test_client.py b/tests/brokers/confluent/test_test_client.py index e5d915404c..73077ec147 100644 --- a/tests/brokers/confluent/test_test_client.py +++ b/tests/brokers/confluent/test_test_client.py @@ -52,8 +52,9 @@ async def m(msg: KafkaMessage) -> None: async def test_with_real_testclient( self, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + broker = self.get_broker() args, kwargs = self.get_subscriber_params(queue) diff --git a/tests/brokers/kafka/test_consume.py b/tests/brokers/kafka/test_consume.py index cb0f32db43..f725f90371 100644 --- a/tests/brokers/kafka/test_consume.py +++ b/tests/brokers/kafka/test_consume.py @@ -22,8 +22,9 @@ def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: async def test_consume_by_pattern( self, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker() @consume_broker.subscriber(queue) @@ -79,9 +80,10 @@ async def handler(msg) -> None: async def test_consume_batch_headers( self, mock, - event: asyncio.Event, queue: str, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber(queue, batch=True) @@ -115,8 +117,9 @@ def subscriber(m, msg: KafkaMessage) -> None: async def test_consume_ack( self, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber(queue, group_id="test", auto_commit=False) @@ -151,8 +154,9 @@ async def handler(msg: KafkaMessage) -> None: async def test_manual_partition_consume( self, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker() tp1 = TopicPartition(queue, partition=0) @@ -179,8 +183,9 @@ async def handler_tp1(msg) -> None: async def test_consume_ack_manual( self, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber(queue, group_id="test", auto_commit=False) @@ -217,8 +222,9 @@ async def handler(msg: KafkaMessage) -> None: async def test_consume_ack_raise( self, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber(queue, group_id="test", auto_commit=False) @@ -255,8 +261,9 @@ async def handler(msg: KafkaMessage): async def test_nack( self, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber(queue, group_id="test", auto_commit=False) @@ -293,8 +300,9 @@ async def handler(msg: KafkaMessage) -> None: async def test_consume_no_ack( self, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber( diff --git a/tests/brokers/kafka/test_fastapi.py b/tests/brokers/kafka/test_fastapi.py index 442e9517f2..899deaffce 100644 --- a/tests/brokers/kafka/test_fastapi.py +++ b/tests/brokers/kafka/test_fastapi.py @@ -18,8 +18,9 @@ async def test_batch_real( self, mock: Mock, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + router = self.router_class() @router.subscriber(queue, batch=True) @@ -52,8 +53,9 @@ async def test_batch_testclient( self, mock: Mock, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + router = self.router_class() @router.subscriber(queue, batch=True) diff --git a/tests/brokers/kafka/test_publish.py b/tests/brokers/kafka/test_publish.py index 19946156fa..80cb7b017b 100644 --- a/tests/brokers/kafka/test_publish.py +++ b/tests/brokers/kafka/test_publish.py @@ -100,9 +100,10 @@ async def pub(m): async def test_response( self, queue: str, - event: asyncio.Event, mock: Mock, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker(apply_types=True) @pub_broker.subscriber(queue) diff --git a/tests/brokers/kafka/test_test_client.py b/tests/brokers/kafka/test_test_client.py index b27444656b..b490604453 100644 --- a/tests/brokers/kafka/test_test_client.py +++ b/tests/brokers/kafka/test_test_client.py @@ -94,8 +94,9 @@ async def m(msg: KafkaMessage) -> None: async def test_with_real_testclient( self, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + broker = self.get_broker() @broker.subscriber(queue) diff --git a/tests/brokers/nats/test_consume.py b/tests/brokers/nats/test_consume.py index c7359c2ba5..8a6cd3917e 100644 --- a/tests/brokers/nats/test_consume.py +++ b/tests/brokers/nats/test_consume.py @@ -23,8 +23,9 @@ async def test_consume_js( self, queue: str, stream: JStream, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker() @consume_broker.subscriber(queue, stream=stream) @@ -54,8 +55,9 @@ async def test_consume_with_filter( self, queue, mock: Mock, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker() @consume_broker.subscriber( @@ -83,9 +85,10 @@ async def test_consume_pull( self, queue: str, stream: JStream, - event: asyncio.Event, mock, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker() @consume_broker.subscriber( @@ -115,9 +118,10 @@ async def test_consume_batch( self, queue: str, stream: JStream, - event: asyncio.Event, mock, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker() @consume_broker.subscriber( @@ -146,9 +150,10 @@ def subscriber(m) -> None: async def test_consume_ack( self, queue: str, - event: asyncio.Event, stream: JStream, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber(queue, stream=stream) @@ -173,35 +178,38 @@ async def handler(msg: NatsMessage) -> None: async def test_core_consume_no_ack( self, queue: str, - event: asyncio.Event, stream: JStream, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber(queue, ack_policy=AckPolicy.DO_NOTHING) async def handler(msg: NatsMessage) -> None: - if not msg.raw_message._ackd: - event.set() + event.set() async with self.patch_broker(consume_broker) as br: await br.start() - await asyncio.wait( - ( - asyncio.create_task(br.publish("hello", queue)), - asyncio.create_task(event.wait()), - ), - timeout=3, - ) + with patch.object(Msg, "ack", spy_decorator(Msg.ack)) as m: + await asyncio.wait( + ( + asyncio.create_task(br.publish("hello", queue)), + asyncio.create_task(event.wait()), + ), + timeout=3, + ) + assert not m.mock.called assert event.is_set() async def test_consume_ack_manual( self, queue: str, - event: asyncio.Event, stream: JStream, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber(queue, stream=stream) @@ -227,9 +235,10 @@ async def handler(msg: NatsMessage) -> None: async def test_consume_ack_raise( self, queue: str, - event: asyncio.Event, stream: JStream, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber(queue, stream=stream) @@ -255,9 +264,10 @@ async def handler(msg: NatsMessage): async def test_nack( self, queue: str, - event: asyncio.Event, stream: JStream, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber(queue, stream=stream) @@ -283,8 +293,9 @@ async def handler(msg: NatsMessage) -> None: async def test_consume_no_ack( self, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber(queue, ack_policy=AckPolicy.DO_NOTHING) @@ -310,9 +321,10 @@ async def test_consume_batch_headers( self, queue: str, stream: JStream, - event: asyncio.Event, mock, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber( @@ -348,9 +360,10 @@ def subscriber(m, msg: NatsMessage) -> None: async def test_consume_kv( self, queue: str, - event: asyncio.Event, mock, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber(queue, kv_watch=queue + "1") @@ -382,9 +395,10 @@ async def handler(m) -> None: async def test_consume_os( self, queue: str, - event: asyncio.Event, mock, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber(queue, obj_watch=True) @@ -415,7 +429,6 @@ async def handler(filename: str) -> None: async def test_get_one_js( self, queue: str, - event: asyncio.Event, stream: JStream, ) -> None: broker = self.get_broker(apply_types=True) @@ -462,7 +475,6 @@ async def test_get_one_timeout_js( async def test_get_one_pull( self, queue: str, - event: asyncio.Event, stream: JStream, ) -> None: broker = self.get_broker(apply_types=True) @@ -498,7 +510,6 @@ async def publish() -> None: async def test_get_one_pull_timeout( self, queue: str, - event: asyncio.Event, stream: JStream, mock: Mock, ) -> None: @@ -518,7 +529,6 @@ async def test_get_one_pull_timeout( async def test_get_one_batch( self, queue: str, - event: asyncio.Event, stream: JStream, ) -> None: broker = self.get_broker(apply_types=True) @@ -554,7 +564,6 @@ async def publish() -> None: async def test_get_one_batch_timeout( self, queue: str, - event: asyncio.Event, stream: JStream, mock: Mock, ) -> None: @@ -574,7 +583,6 @@ async def test_get_one_batch_timeout( async def test_get_one_with_filter( self, queue: str, - event: asyncio.Event, stream: JStream, ) -> None: broker = self.get_broker(apply_types=True) @@ -609,7 +617,6 @@ async def publish() -> None: async def test_get_one_kv( self, queue: str, - event: asyncio.Event, stream: JStream, ) -> None: broker = self.get_broker(apply_types=True) @@ -642,7 +649,6 @@ async def publish() -> None: async def test_get_one_kv_timeout( self, queue: str, - event: asyncio.Event, stream: JStream, mock: Mock, ) -> None: @@ -658,7 +664,6 @@ async def test_get_one_kv_timeout( async def test_get_one_os( self, queue: str, - event: asyncio.Event, stream: JStream, ) -> None: broker = self.get_broker(apply_types=True) @@ -692,7 +697,6 @@ async def publish() -> None: async def test_get_one_os_timeout( self, queue: str, - event: asyncio.Event, stream: JStream, mock: Mock, ) -> None: diff --git a/tests/brokers/nats/test_fastapi.py b/tests/brokers/nats/test_fastapi.py index d5a421a8a4..bbcdac2113 100644 --- a/tests/brokers/nats/test_fastapi.py +++ b/tests/brokers/nats/test_fastapi.py @@ -17,9 +17,10 @@ class TestRouter(FastAPITestcase): async def test_path( self, queue: str, - event: asyncio.Event, mock: MagicMock, ) -> None: + event = asyncio.Event() + router = self.router_class() @router.subscriber(queue + ".{name}") @@ -46,9 +47,10 @@ async def test_consume_batch( self, queue: str, stream: JStream, - event: asyncio.Event, mock: MagicMock, ) -> None: + event = asyncio.Event() + router = self.router_class() @router.subscriber( @@ -85,9 +87,10 @@ async def test_consume_batch( self, queue: str, stream: JStream, - event: asyncio.Event, mock: MagicMock, ) -> None: + event = asyncio.Event() + router = self.router_class() @router.subscriber( diff --git a/tests/brokers/nats/test_publish.py b/tests/brokers/nats/test_publish.py index 3b92b0673e..c7367ac389 100644 --- a/tests/brokers/nats/test_publish.py +++ b/tests/brokers/nats/test_publish.py @@ -19,9 +19,10 @@ def get_broker(self, apply_types: bool = False, **kwargs) -> NatsBroker: async def test_response( self, queue: str, - event: asyncio.Event, mock: Mock, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker(apply_types=True) @pub_broker.subscriber(queue) @@ -58,7 +59,6 @@ async def handle_next(msg=Context("message")) -> None: async def test_response_for_rpc( self, queue: str, - event: asyncio.Event, ) -> None: pub_broker = self.get_broker(apply_types=True) diff --git a/tests/brokers/nats/test_router.py b/tests/brokers/nats/test_router.py index c424aa4da1..8af70bcfa0 100644 --- a/tests/brokers/nats/test_router.py +++ b/tests/brokers/nats/test_router.py @@ -128,10 +128,11 @@ async def h( async def test_delayed_handlers_with_queue( self, - event, router: NatsRouter, queue: str, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker() def response(m) -> None: diff --git a/tests/brokers/nats/test_test_client.py b/tests/brokers/nats/test_test_client.py index cc4a3106e7..7ca172e6ce 100644 --- a/tests/brokers/nats/test_test_client.py +++ b/tests/brokers/nats/test_test_client.py @@ -55,8 +55,9 @@ async def m(msg) -> None: ... async def test_with_real_testclient( self, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + broker = self.get_broker() @broker.subscriber(queue) diff --git a/tests/brokers/rabbit/test_consume.py b/tests/brokers/rabbit/test_consume.py index 4f51bb4899..19317948fa 100644 --- a/tests/brokers/rabbit/test_consume.py +++ b/tests/brokers/rabbit/test_consume.py @@ -23,8 +23,9 @@ async def test_consume_from_exchange( self, queue: str, exchange: RabbitExchange, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker() @consume_broker.subscriber(queue=queue, exchange=exchange) @@ -50,8 +51,9 @@ async def test_consume_with_get_old( self, queue: str, exchange: RabbitExchange, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker() @consume_broker.subscriber( @@ -88,8 +90,9 @@ async def test_consume_ack( self, queue: str, exchange: RabbitExchange, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber(queue=queue, exchange=exchange) @@ -122,8 +125,9 @@ async def test_consume_manual_ack( self, queue: str, exchange: RabbitExchange, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber(queue=queue, exchange=exchange) @@ -156,8 +160,9 @@ async def test_consume_exception_ack( self, queue: str, exchange: RabbitExchange, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber(queue=queue, exchange=exchange) @@ -192,8 +197,9 @@ async def test_consume_manual_nack( self, queue: str, exchange: RabbitExchange, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber(queue=queue, exchange=exchange) @@ -227,8 +233,9 @@ async def test_consume_exception_nack( self, queue: str, exchange: RabbitExchange, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber(queue=queue, exchange=exchange) @@ -263,8 +270,9 @@ async def test_consume_manual_reject( self, queue: str, exchange: RabbitExchange, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber(queue=queue, exchange=exchange) @@ -298,8 +306,9 @@ async def test_consume_exception_reject( self, queue: str, exchange: RabbitExchange, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber(queue=queue, exchange=exchange) @@ -333,8 +342,9 @@ async def handler(msg: RabbitMessage) -> None: async def test_consume_skip_message( self, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber(queue) @@ -382,8 +392,9 @@ async def test_consume_no_ack( self, queue: str, exchange: RabbitExchange, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber( diff --git a/tests/brokers/rabbit/test_fastapi.py b/tests/brokers/rabbit/test_fastapi.py index df20f2fdeb..3bd99eae62 100644 --- a/tests/brokers/rabbit/test_fastapi.py +++ b/tests/brokers/rabbit/test_fastapi.py @@ -18,9 +18,10 @@ class TestRouter(FastAPITestcase): async def test_path( self, queue: str, - event: asyncio.Event, mock: MagicMock, ) -> None: + event = asyncio.Event() + router = self.router_class() @router.subscriber( diff --git a/tests/brokers/rabbit/test_publish.py b/tests/brokers/rabbit/test_publish.py index 4e9b7b3121..f5000d9104 100644 --- a/tests/brokers/rabbit/test_publish.py +++ b/tests/brokers/rabbit/test_publish.py @@ -23,9 +23,10 @@ def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RabbitBroker: async def test_reply_config( self, queue: str, - event: asyncio.Event, mock: Mock, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker() reply_queue = queue + "reply" @@ -68,9 +69,10 @@ async def handler(m): async def test_response( self, queue: str, - event: asyncio.Event, mock: Mock, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker(apply_types=True) @pub_broker.subscriber(queue) @@ -110,7 +112,6 @@ async def handle_next(msg=Context("message")) -> None: async def test_response_for_rpc( self, queue: str, - event: asyncio.Event, ) -> None: pub_broker = self.get_broker(apply_types=True) diff --git a/tests/brokers/rabbit/test_router.py b/tests/brokers/rabbit/test_router.py index d037375900..0fb2b8babf 100644 --- a/tests/brokers/rabbit/test_router.py +++ b/tests/brokers/rabbit/test_router.py @@ -112,8 +112,9 @@ async def test_queue_obj( self, router: RabbitRouter, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + broker = self.get_broker() router.prefix = "test/" @@ -145,8 +146,9 @@ async def test_queue_obj_with_routing_key( self, router: RabbitRouter, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + broker = self.get_broker() router.prefix = "test/" @@ -177,10 +179,11 @@ def subscriber(m) -> None: async def test_delayed_handlers_with_queue( self, - event: asyncio.Event, router: RabbitRouter, queue: str, ) -> None: + event = asyncio.Event() + def response(m) -> None: event.set() diff --git a/tests/brokers/rabbit/test_test_client.py b/tests/brokers/rabbit/test_test_client.py index cf76669716..0784da9bf3 100644 --- a/tests/brokers/rabbit/test_test_client.py +++ b/tests/brokers/rabbit/test_test_client.py @@ -31,8 +31,9 @@ def patch_broker(self, broker: RabbitBroker, **kwargs: Any) -> RabbitBroker: async def test_with_real_testclient( self, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + broker = self.get_broker() @broker.subscriber(queue) diff --git a/tests/brokers/redis/test_consume.py b/tests/brokers/redis/test_consume.py index 899a941813..7c7a1e4152 100644 --- a/tests/brokers/redis/test_consume.py +++ b/tests/brokers/redis/test_consume.py @@ -18,10 +18,11 @@ def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RedisBroker: async def test_consume_native( self, - event: asyncio.Event, mock: MagicMock, queue: str, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker() @consume_broker.subscriber(queue) @@ -44,9 +45,10 @@ async def handler(msg) -> None: async def test_pattern_with_path( self, - event: asyncio.Event, mock: MagicMock, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker() @consume_broker.subscriber("test.{name}") @@ -69,9 +71,10 @@ async def handler(msg) -> None: async def test_pattern_without_path( self, - event: asyncio.Event, mock: MagicMock, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker() @consume_broker.subscriber(PubSub("test.*", pattern=True)) @@ -104,10 +107,11 @@ def patch_broker(self, broker): async def test_consume_list( self, - event: asyncio.Event, queue: str, mock: MagicMock, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker() @consume_broker.subscriber(list=queue) @@ -130,10 +134,11 @@ async def handler(msg) -> None: async def test_consume_list_native( self, - event: asyncio.Event, queue: str, mock: MagicMock, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker() @consume_broker.subscriber(list=queue) @@ -158,9 +163,10 @@ async def handler(msg) -> None: async def test_consume_list_batch_with_one( self, queue: str, - event: asyncio.Event, mock, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker() @consume_broker.subscriber( @@ -187,9 +193,10 @@ async def handler(msg) -> None: async def test_consume_list_batch_headers( self, queue: str, - event: asyncio.Event, mock, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber( @@ -314,7 +321,6 @@ async def handler(msg) -> None: async def test_get_one( self, queue: str, - event: asyncio.Event, ) -> None: broker = self.get_broker(apply_types=True) subscriber = broker.subscriber(list=queue) @@ -369,10 +375,11 @@ def patch_broker(self, broker): @pytest.mark.slow() async def test_consume_stream( self, - event: asyncio.Event, mock: MagicMock, queue, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker() @consume_broker.subscriber(stream=StreamSub(queue, polling_interval=10)) @@ -396,10 +403,11 @@ async def handler(msg) -> None: @pytest.mark.slow() async def test_consume_stream_native( self, - event: asyncio.Event, mock: MagicMock, queue, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker() @consume_broker.subscriber(stream=StreamSub(queue, polling_interval=10)) @@ -425,10 +433,11 @@ async def handler(msg) -> None: @pytest.mark.slow() async def test_consume_stream_batch( self, - event: asyncio.Event, mock: MagicMock, queue, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker() @consume_broker.subscriber( @@ -455,9 +464,10 @@ async def handler(msg) -> None: async def test_consume_stream_batch_headers( self, queue: str, - event: asyncio.Event, mock, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber( @@ -525,10 +535,11 @@ async def handler(msg: list[Data]) -> None: @pytest.mark.slow() async def test_consume_stream_batch_native( self, - event: asyncio.Event, mock: MagicMock, queue, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker() @consume_broker.subscriber( @@ -582,8 +593,9 @@ async def handler(msg: RedisMessage) -> None: ... async def test_consume_nack( self, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber( @@ -612,8 +624,9 @@ async def handler(msg: RedisMessage) -> None: async def test_consume_ack( self, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber( diff --git a/tests/brokers/redis/test_fastapi.py b/tests/brokers/redis/test_fastapi.py index 41de233318..9c66a73230 100644 --- a/tests/brokers/redis/test_fastapi.py +++ b/tests/brokers/redis/test_fastapi.py @@ -18,9 +18,10 @@ class TestRouter(FastAPITestcase): async def test_path( self, queue: str, - event: asyncio.Event, mock: Mock, ) -> None: + event = asyncio.Event() + router = self.router_class() @router.subscriber("in.{name}") @@ -57,8 +58,9 @@ async def test_batch_real( self, mock: Mock, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + router = self.router_class() @router.subscriber(list=ListSub(queue, batch=True, max_records=1)) @@ -82,10 +84,11 @@ async def hello(msg: list[str]): @pytest.mark.slow() async def test_consume_stream( self, - event: asyncio.Event, mock: Mock, queue, ) -> None: + event = asyncio.Event() + router = self.router_class() @router.subscriber(stream=StreamSub(queue, polling_interval=10)) @@ -110,10 +113,11 @@ async def handler(msg) -> None: @pytest.mark.slow() async def test_consume_stream_batch( self, - event: asyncio.Event, mock: Mock, queue, ) -> None: + event = asyncio.Event() + router = self.router_class() @router.subscriber(stream=StreamSub(queue, polling_interval=10, batch=True)) @@ -147,8 +151,9 @@ async def test_batch_testclient( self, mock: Mock, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + router = self.router_class() @router.subscriber(list=ListSub(queue, batch=True, max_records=1)) @@ -172,8 +177,9 @@ async def test_stream_batch_testclient( self, mock: Mock, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + router = self.router_class() @router.subscriber(stream=StreamSub(queue, batch=True)) diff --git a/tests/brokers/redis/test_publish.py b/tests/brokers/redis/test_publish.py index 25bf9023d0..8967aa0778 100644 --- a/tests/brokers/redis/test_publish.py +++ b/tests/brokers/redis/test_publish.py @@ -20,9 +20,10 @@ def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RedisBroker: async def test_list_publisher( self, queue: str, - event: asyncio.Event, mock: MagicMock, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker() @pub_broker.subscriber(list=queue) @@ -79,9 +80,10 @@ async def handler(msg) -> None: async def test_batch_list_publisher( self, queue: str, - event: asyncio.Event, mock: MagicMock, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker() batch_list = ListSub(queue + "resp", batch=True) @@ -113,9 +115,10 @@ async def resp(msg) -> None: async def test_publisher_with_maxlen( self, queue: str, - event: asyncio.Event, mock: MagicMock, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker() stream = StreamSub(queue + "resp", maxlen=1) @@ -150,9 +153,10 @@ async def resp(msg) -> None: async def test_response( self, queue: str, - event: asyncio.Event, mock: MagicMock, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker(apply_types=True) @pub_broker.subscriber(list=queue) @@ -188,7 +192,6 @@ async def resp(msg=Context("message")) -> None: async def test_response_for_rpc( self, queue: str, - event: asyncio.Event, ) -> None: pub_broker = self.get_broker(apply_types=True) diff --git a/tests/brokers/redis/test_router.py b/tests/brokers/redis/test_router.py index 5b6af70eee..ef53e47a37 100644 --- a/tests/brokers/redis/test_router.py +++ b/tests/brokers/redis/test_router.py @@ -118,9 +118,10 @@ async def h( async def test_delayed_channel_handlers( self, - event: asyncio.Event, queue: str, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker() def response(m) -> None: @@ -145,9 +146,10 @@ def response(m) -> None: async def test_delayed_list_handlers( self, - event: asyncio.Event, queue: str, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker() def response(m) -> None: @@ -172,9 +174,10 @@ def response(m) -> None: async def test_delayed_stream_handlers( self, - event: asyncio.Event, queue: str, ) -> None: + event = asyncio.Event() + pub_broker = self.get_broker() def response(m) -> None: diff --git a/tests/brokers/redis/test_test_client.py b/tests/brokers/redis/test_test_client.py index 2eb6ecaf3c..c9bcbe5527 100644 --- a/tests/brokers/redis/test_test_client.py +++ b/tests/brokers/redis/test_test_client.py @@ -23,8 +23,9 @@ def patch_broker(self, broker: RedisBroker, **kwargs: Any) -> TestRedisBroker: async def test_with_real_testclient( self, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + broker = self.get_broker() @broker.subscriber(queue) diff --git a/tests/opentelemetry/basic.py b/tests/opentelemetry/basic.py index 30d4ba0895..9a8f4dd176 100644 --- a/tests/opentelemetry/basic.py +++ b/tests/opentelemetry/basic.py @@ -168,12 +168,13 @@ def assert_metrics( async def test_subscriber_create_publish_process_span( self, - event: asyncio.Event, queue: str, mock: Mock, tracer_provider: TracerProvider, trace_exporter: InMemorySpanExporter, ) -> None: + event = asyncio.Event() + mid = self.telemetry_middleware_class(tracer_provider=tracer_provider) broker = self.get_broker(middlewares=(mid,)) @@ -207,12 +208,13 @@ async def handler(m) -> None: async def test_chain_subscriber_publisher( self, - event: asyncio.Event, queue: str, mock: Mock, tracer_provider: TracerProvider, trace_exporter: InMemorySpanExporter, ) -> None: + event = asyncio.Event() + mid = self.telemetry_middleware_class(tracer_provider=tracer_provider) broker = self.get_broker(middlewares=(mid,)) @@ -267,12 +269,13 @@ async def handler2(m) -> None: async def test_no_trace_context_create_process_span( self, - event: asyncio.Event, queue: str, mock: Mock, tracer_provider: TracerProvider, trace_exporter: InMemorySpanExporter, ) -> None: + event = asyncio.Event() + mid = self.telemetry_middleware_class(tracer_provider=tracer_provider) broker = self.get_broker(middlewares=(mid,)) @@ -306,12 +309,13 @@ async def handler(m) -> None: async def test_metrics( self, - event: asyncio.Event, queue: str, mock: Mock, meter_provider: MeterProvider, metric_reader: InMemoryMetricReader, ) -> None: + event = asyncio.Event() + mid = self.telemetry_middleware_class(meter_provider=meter_provider) broker = self.get_broker(middlewares=(mid,)) @@ -342,12 +346,13 @@ async def handler(m) -> None: async def test_error_metrics( self, - event: asyncio.Event, queue: str, mock: Mock, meter_provider: MeterProvider, metric_reader: InMemoryMetricReader, ) -> None: + event = asyncio.Event() + mid = self.telemetry_middleware_class(meter_provider=meter_provider) broker = self.get_broker(middlewares=(mid,)) expected_value_type = "ValueError" @@ -382,12 +387,13 @@ async def handler(m) -> None: async def test_span_in_context( self, - event: asyncio.Event, queue: str, mock: Mock, tracer_provider: TracerProvider, trace_exporter: InMemorySpanExporter, ) -> None: + event = asyncio.Event() + mid = self.telemetry_middleware_class(tracer_provider=tracer_provider) broker = self.get_broker(middlewares=(mid,), apply_types=True) @@ -415,10 +421,11 @@ async def handler(m, span: CurrentSpan) -> None: async def test_get_baggage( self, - event: asyncio.Event, queue: str, mock: Mock, ) -> None: + event = asyncio.Event() + mid = self.telemetry_middleware_class() broker = self.get_broker(middlewares=(mid,), apply_types=True) expected_baggage = {"foo": "bar"} @@ -456,10 +463,11 @@ async def handler1(m, baggage: CurrentBaggage) -> None: async def test_clear_baggage( self, - event: asyncio.Event, queue: str, mock: Mock, ) -> None: + event = asyncio.Event() + mid = self.telemetry_middleware_class() broker = self.get_broker(middlewares=(mid,), apply_types=True) @@ -505,10 +513,11 @@ async def handler2(m, baggage: CurrentBaggage) -> None: async def test_modify_baggage( self, - event: asyncio.Event, queue: str, mock: Mock, ) -> None: + event = asyncio.Event() + mid = self.telemetry_middleware_class() broker = self.get_broker(middlewares=(mid,), apply_types=True) expected_baggage = {"baz": "bar", "bar": "baz"} @@ -556,9 +565,10 @@ async def handler2(m, baggage: CurrentBaggage) -> None: async def test_get_baggage_from_headers( self, - event: asyncio.Event, queue: str, ): + event = asyncio.Event() + mid = self.telemetry_middleware_class() broker = self.get_broker(middlewares=(mid,), apply_types=True) diff --git a/tests/opentelemetry/confluent/test_confluent.py b/tests/opentelemetry/confluent/test_confluent.py index e3f6a697bb..088e1d551c 100644 --- a/tests/opentelemetry/confluent/test_confluent.py +++ b/tests/opentelemetry/confluent/test_confluent.py @@ -64,7 +64,6 @@ def assert_span( async def test_batch( self, - event: asyncio.Event, queue: str, mock: Mock, meter_provider: MeterProvider, @@ -72,6 +71,8 @@ async def test_batch( tracer_provider: TracerProvider, trace_exporter: InMemorySpanExporter, ) -> None: + event = asyncio.Event() + mid = self.telemetry_middleware_class( meter_provider=meter_provider, tracer_provider=tracer_provider, @@ -198,7 +199,6 @@ async def handler(msg, baggage: CurrentBaggage) -> None: async def test_single_publish_with_batch_consume( self, - event: asyncio.Event, queue: str, mock: Mock, meter_provider: MeterProvider, @@ -206,6 +206,8 @@ async def test_single_publish_with_batch_consume( tracer_provider: TracerProvider, trace_exporter: InMemorySpanExporter, ) -> None: + event = asyncio.Event() + mid = self.telemetry_middleware_class( meter_provider=meter_provider, tracer_provider=tracer_provider, diff --git a/tests/opentelemetry/kafka/test_kafka.py b/tests/opentelemetry/kafka/test_kafka.py index 3f05cda5b1..79e93b82df 100644 --- a/tests/opentelemetry/kafka/test_kafka.py +++ b/tests/opentelemetry/kafka/test_kafka.py @@ -65,7 +65,6 @@ def assert_span( async def test_batch( self, - event: asyncio.Event, queue: str, mock: Mock, meter_provider: MeterProvider, @@ -73,6 +72,8 @@ async def test_batch( tracer_provider: TracerProvider, trace_exporter: InMemorySpanExporter, ) -> None: + event = asyncio.Event() + mid = self.telemetry_middleware_class( meter_provider=meter_provider, tracer_provider=tracer_provider, @@ -199,7 +200,6 @@ async def handler(msg, baggage: CurrentBaggage) -> None: async def test_single_publish_with_batch_consume( self, - event: asyncio.Event, queue: str, mock: Mock, meter_provider: MeterProvider, @@ -207,6 +207,8 @@ async def test_single_publish_with_batch_consume( tracer_provider: TracerProvider, trace_exporter: InMemorySpanExporter, ) -> None: + event = asyncio.Event() + mid = self.telemetry_middleware_class( meter_provider=meter_provider, tracer_provider=tracer_provider, diff --git a/tests/opentelemetry/nats/test_nats.py b/tests/opentelemetry/nats/test_nats.py index 8dd8238e15..efa5153a50 100644 --- a/tests/opentelemetry/nats/test_nats.py +++ b/tests/opentelemetry/nats/test_nats.py @@ -32,7 +32,6 @@ def get_broker(self, apply_types: bool = False, **kwargs: Any) -> NatsBroker: async def test_batch( self, - event: asyncio.Event, queue: str, mock: Mock, stream: JStream, @@ -41,6 +40,8 @@ async def test_batch( tracer_provider: TracerProvider, trace_exporter: InMemorySpanExporter, ) -> None: + event = asyncio.Event() + mid = self.telemetry_middleware_class( meter_provider=meter_provider, tracer_provider=tracer_provider, diff --git a/tests/opentelemetry/redis/test_redis.py b/tests/opentelemetry/redis/test_redis.py index cbe1a107b8..bdfc49ceb1 100644 --- a/tests/opentelemetry/redis/test_redis.py +++ b/tests/opentelemetry/redis/test_redis.py @@ -32,7 +32,6 @@ def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RedisBroker: async def test_batch( self, - event: asyncio.Event, queue: str, mock: Mock, meter_provider: MeterProvider, @@ -40,6 +39,8 @@ async def test_batch( tracer_provider: TracerProvider, trace_exporter: InMemorySpanExporter, ) -> None: + event = asyncio.Event() + mid = self.telemetry_middleware_class( meter_provider=meter_provider, tracer_provider=tracer_provider, @@ -151,7 +152,6 @@ async def handler(msg, baggage: CurrentBaggage) -> None: async def test_single_publish_with_batch_consume( self, - event: asyncio.Event, queue: str, mock: Mock, meter_provider: MeterProvider, @@ -159,6 +159,8 @@ async def test_single_publish_with_batch_consume( tracer_provider: TracerProvider, trace_exporter: InMemorySpanExporter, ) -> None: + event = asyncio.Event() + mid = self.telemetry_middleware_class( meter_provider=meter_provider, tracer_provider=tracer_provider, diff --git a/tests/prometheus/basic.py b/tests/prometheus/basic.py index 2c4d8a2028..6a5f0e303e 100644 --- a/tests/prometheus/basic.py +++ b/tests/prometheus/basic.py @@ -47,22 +47,27 @@ def settings_provider_factory(self): id="acked status with reject message exception", ), pytest.param( - AckStatus.ACKED, Exception, id="acked status with not handler exception" + AckStatus.ACKED, + Exception, + id="acked status with not handler exception", ), pytest.param(AckStatus.ACKED, None, id="acked status without exception"), pytest.param(AckStatus.NACKED, None, id="nacked status without exception"), pytest.param( - AckStatus.REJECTED, None, id="rejected status without exception" + AckStatus.REJECTED, + None, + id="rejected status without exception", ), ), ) async def test_metrics( self, - event: asyncio.Event, queue: str, status: AckStatus, exception_class: Optional[type[Exception]], ): + event = asyncio.Event() + middleware = self.get_middleware(registry=CollectorRegistry()) metrics_manager_mock = Mock() middleware._metrics_manager = metrics_manager_mock @@ -210,8 +215,9 @@ class LocalRPCPrometheusTestcase: async def test_rpc_request( self, queue: str, - event: asyncio.Event, ) -> None: + event = asyncio.Event() + middleware = self.get_middleware(registry=CollectorRegistry()) metrics_manager_mock = Mock() middleware._metrics_manager = metrics_manager_mock diff --git a/tests/prometheus/confluent/test_confluent.py b/tests/prometheus/confluent/test_confluent.py index 0b0deabf88..84714bd280 100644 --- a/tests/prometheus/confluent/test_confluent.py +++ b/tests/prometheus/confluent/test_confluent.py @@ -23,9 +23,10 @@ def get_middleware(self, **kwargs): async def test_metrics_batch( self, - event: asyncio.Event, queue: str, ): + event = asyncio.Event() + middleware = self.get_middleware(registry=CollectorRegistry()) metrics_manager_mock = Mock() middleware._metrics_manager = metrics_manager_mock diff --git a/tests/prometheus/kafka/test_kafka.py b/tests/prometheus/kafka/test_kafka.py index 85e9e7a0eb..7ba5ba6f82 100644 --- a/tests/prometheus/kafka/test_kafka.py +++ b/tests/prometheus/kafka/test_kafka.py @@ -22,9 +22,10 @@ def get_middleware(self, **kwargs): async def test_metrics_batch( self, - event: asyncio.Event, queue: str, ): + event = asyncio.Event() + middleware = self.get_middleware(registry=CollectorRegistry()) metrics_manager_mock = Mock() middleware._metrics_manager = metrics_manager_mock diff --git a/tests/prometheus/nats/test_nats.py b/tests/prometheus/nats/test_nats.py index 4af2685a7d..117b696922 100644 --- a/tests/prometheus/nats/test_nats.py +++ b/tests/prometheus/nats/test_nats.py @@ -27,10 +27,11 @@ def get_middleware(self, **kwargs): async def test_metrics_batch( self, - event: asyncio.Event, queue: str, stream: JStream, ): + event = asyncio.Event() + middleware = self.get_middleware(registry=CollectorRegistry()) metrics_manager_mock = Mock() middleware._metrics_manager = metrics_manager_mock diff --git a/tests/prometheus/redis/test_redis.py b/tests/prometheus/redis/test_redis.py index ce7f81f49f..ee7f62cfd2 100644 --- a/tests/prometheus/redis/test_redis.py +++ b/tests/prometheus/redis/test_redis.py @@ -22,9 +22,10 @@ def get_middleware(self, **kwargs): async def test_metrics_batch( self, - event: asyncio.Event, queue: str, ): + event = asyncio.Event() + middleware = self.get_middleware(registry=CollectorRegistry()) metrics_manager_mock = Mock() middleware._metrics_manager = metrics_manager_mock diff --git a/tests/utils/context/test_path.py b/tests/utils/context/test_path.py index f4bb59ed5d..ff135cb1a3 100644 --- a/tests/utils/context/test_path.py +++ b/tests/utils/context/test_path.py @@ -70,9 +70,10 @@ async def h( @require_nats async def test_nats_kv_path( queue: str, - event: asyncio.Event, mock: Mock, ) -> None: + event = asyncio.Event() + from faststream.nats import NatsBroker broker = NatsBroker() From 736baba25ba3bdce4ef264c590f9d7e86ba5fa80 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Wed, 13 Nov 2024 19:45:50 +0300 Subject: [PATCH 191/245] feat: lazy decoder --- CITATION.cff | 2 +- examples/e10_middlewares.py | 2 +- faststream/_internal/application.py | 3 +- faststream/_internal/broker/abc_broker.py | 7 +- faststream/_internal/broker/broker.py | 7 +- faststream/_internal/cli/docs/app.py | 4 +- faststream/_internal/cli/main.py | 2 +- faststream/_internal/state/broker.py | 20 +- faststream/_internal/subscriber/call_item.py | 5 +- .../_internal/subscriber/call_wrapper/call.py | 6 +- faststream/_internal/subscriber/mixins.py | 5 +- faststream/_internal/subscriber/utils.py | 2 +- faststream/_internal/types.py | 9 +- faststream/confluent/subscriber/factory.py | 20 +- faststream/kafka/subscriber/factory.py | 68 ++-- faststream/message/message.py | 29 +- faststream/nats/annotations.py | 4 +- faststream/nats/subscriber/factory.py | 2 +- faststream/nats/subscriber/specified.py | 2 +- .../nats/subscriber/usecases/__init__.py | 26 ++ faststream/nats/subscriber/usecases/basic.py | 247 +++++++++++++++ .../subscriber/usecases/core_subscriber.py | 186 +++++++++++ .../usecases/key_value_subscriber.py | 188 +++++++++++ .../usecases/object_storage_subscriber.py | 192 +++++++++++ .../nats/subscriber/usecases/stream_basic.py | 142 +++++++++ .../usecases/stream_pull_subscriber.py | 298 ++++++++++++++++++ .../usecases/stream_push_subscriber.py | 106 +++++++ faststream/nats/testing.py | 2 +- faststream/opentelemetry/baggage.py | 3 +- faststream/rabbit/subscriber/factory.py | 6 + faststream/redis/message.py | 14 +- faststream/redis/opentelemetry/provider.py | 3 +- faststream/redis/prometheus/provider.py | 5 +- tests/brokers/base/fastapi.py | 8 +- tests/brokers/confluent/test_requests.py | 2 +- tests/brokers/kafka/test_requests.py | 2 +- tests/brokers/nats/test_consume.py | 8 +- tests/brokers/nats/test_requests.py | 2 +- tests/brokers/rabbit/test_requests.py | 2 +- tests/brokers/redis/test_requests.py | 2 +- tests/prometheus/redis/test_provider.py | 55 +++- 41 files changed, 1587 insertions(+), 111 deletions(-) create mode 100644 faststream/nats/subscriber/usecases/__init__.py create mode 100644 faststream/nats/subscriber/usecases/basic.py create mode 100644 faststream/nats/subscriber/usecases/core_subscriber.py create mode 100644 faststream/nats/subscriber/usecases/key_value_subscriber.py create mode 100644 faststream/nats/subscriber/usecases/object_storage_subscriber.py create mode 100644 faststream/nats/subscriber/usecases/stream_basic.py create mode 100644 faststream/nats/subscriber/usecases/stream_pull_subscriber.py create mode 100644 faststream/nats/subscriber/usecases/stream_push_subscriber.py diff --git a/CITATION.cff b/CITATION.cff index cfc7b23a6a..9e01da744e 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -10,7 +10,7 @@ type: software authors: - given-names: Nikita family-names: Pastukhov - email: diementros@yandex.com + email: nikita@pastukhov-dev.ru - given-names: Davor family-names: Runje email: davor@airt.ai diff --git a/examples/e10_middlewares.py b/examples/e10_middlewares.py index 03a0519d79..31a2a257c9 100644 --- a/examples/e10_middlewares.py +++ b/examples/e10_middlewares.py @@ -25,7 +25,7 @@ async def subscriber_middleware( msg: RabbitMessage, ) -> Any: print(f"call handler middleware with body: {msg}") - msg._decoded_body = "fake message" + msg.body = b"fake message" result = await call_next(msg) print("handler middleware out") return result diff --git a/faststream/_internal/application.py b/faststream/_internal/application.py index d74f1c4a76..85e0ba43d0 100644 --- a/faststream/_internal/application.py +++ b/faststream/_internal/application.py @@ -17,6 +17,7 @@ from faststream._internal.context import ContextRepo from faststream._internal.log import logger from faststream._internal.state import DIState +from faststream._internal.state.broker import OuterBrokerState from faststream._internal.utils import apply_types from faststream._internal.utils.functions import ( drop_response_type, @@ -112,7 +113,7 @@ def _init_setupable_( # noqa: PLW3201 self._setup() def _setup(self) -> None: - self.broker._setup(di_state=self._state) + self.broker._setup(OuterBrokerState(di_state=self._state)) async def _start_broker(self) -> None: await self.broker.start() diff --git a/faststream/_internal/broker/abc_broker.py b/faststream/_internal/broker/abc_broker.py index 0fc795231e..f92b8c2358 100644 --- a/faststream/_internal/broker/abc_broker.py +++ b/faststream/_internal/broker/abc_broker.py @@ -90,8 +90,9 @@ def setup_publisher( """Setup the Publisher to prepare it to starting.""" publisher._setup(**kwargs, state=self._state) - def _setup(self, state: "Pointer[BrokerState]") -> None: - self._state.set(state) + def _setup(self, state: Optional["BrokerState"]) -> None: + if state is not None: + self._state.set(state) def include_router( self, @@ -103,7 +104,7 @@ def include_router( include_in_schema: Optional[bool] = None, ) -> None: """Includes a router in the current object.""" - router._setup(self._state) + router._setup(self._state.get()) for h in router._subscribers: h.add_prefix(f"{self.prefix}{prefix}") diff --git a/faststream/_internal/broker/broker.py b/faststream/_internal/broker/broker.py index 9914040cb3..b3621d34ee 100644 --- a/faststream/_internal/broker/broker.py +++ b/faststream/_internal/broker/broker.py @@ -22,6 +22,7 @@ SetupAble, ) from faststream._internal.state.broker import ( + BrokerState, InitialBrokerState, ) from faststream._internal.state.producer import ProducerUnset @@ -240,7 +241,7 @@ async def _connect(self) -> ConnectionType: """Connect to a resource.""" raise NotImplementedError - def _setup(self, di_state: Optional[DIState] = None) -> None: + def _setup(self, state: Optional["BrokerState"] = None) -> None: """Prepare all Broker entities to startup. Method should be idempotent due could be called twice @@ -249,7 +250,9 @@ def _setup(self, di_state: Optional[DIState] = None) -> None: current_di_state = broker_state.di_state broker_serializer = current_di_state.serializer - if di_state is not None: + if state is not None: + di_state = state.di_state + if broker_serializer is EMPTY: broker_serializer = di_state.serializer diff --git a/faststream/_internal/cli/docs/app.py b/faststream/_internal/cli/docs/app.py index 3e56a99536..d85f53de9c 100644 --- a/faststream/_internal/cli/docs/app.py +++ b/faststream/_internal/cli/docs/app.py @@ -134,7 +134,7 @@ def gen( _, asyncapi_obj = import_from_string(asyncapi, is_factory=is_factory) - assert isinstance(asyncapi_obj, Specification) + assert isinstance(asyncapi_obj, Specification) # nosec B101 raw_schema = asyncapi_obj.schema @@ -169,7 +169,7 @@ def _parse_and_serve( if ":" in docs: _, docs_obj = import_from_string(docs, is_factory=is_factory) - assert isinstance(docs_obj, Specification) + assert isinstance(docs_obj, Specification) # nosec B101 raw_schema = docs_obj diff --git a/faststream/_internal/cli/main.py b/faststream/_internal/cli/main.py index 48b113c8c3..95fb8037c6 100644 --- a/faststream/_internal/cli/main.py +++ b/faststream/_internal/cli/main.py @@ -262,7 +262,7 @@ def publish( try: _, app_obj = import_from_string(app, is_factory=is_factory) - assert isinstance(app_obj, FastStream), app_obj + assert isinstance(app_obj, FastStream), app_obj # nosec B101 if not app_obj.broker: msg = "Broker instance not found in the app." diff --git a/faststream/_internal/state/broker.py b/faststream/_internal/state/broker.py index 920daeedec..374b0e8c3b 100644 --- a/faststream/_internal/state/broker.py +++ b/faststream/_internal/state/broker.py @@ -26,15 +26,11 @@ def _setup_logger_state(self) -> None: ... def __bool__(self) -> bool: ... -class EmptyBrokerState(BrokerState): +class _EmptyBrokerState(BrokerState): def __init__(self, error_msg: str) -> None: self.error_msg = error_msg self.producer = ProducerUnset() - @property - def di_state(self) -> "DIState": - raise IncorrectState(self.error_msg) - @property def logger_state(self) -> "DIState": raise IncorrectState(self.error_msg) @@ -53,6 +49,20 @@ def __bool__(self) -> bool: return False +class EmptyBrokerState(_EmptyBrokerState): + @property + def di_state(self) -> "DIState": + raise IncorrectState(self.error_msg) + + +class OuterBrokerState(_EmptyBrokerState): + def __init__(self, *, di_state: "DIState") -> None: + self.di_state = di_state + + def __bool__(self) -> bool: + return True + + class InitialBrokerState(BrokerState): def __init__( self, diff --git a/faststream/_internal/subscriber/call_item.py b/faststream/_internal/subscriber/call_item.py index ddcddacd01..48814e9ea0 100644 --- a/faststream/_internal/subscriber/call_item.py +++ b/faststream/_internal/subscriber/call_item.py @@ -136,9 +136,8 @@ async def is_suitable( cache.get(parser) or await parser(msg), ) - message._decoded_body = cache[decoder] = cache.get(decoder) or await decoder( - message, - ) + # NOTE: final decoder will be set for success filter + message.set_decoder(decoder) if await self.filter(message): return message diff --git a/faststream/_internal/subscriber/call_wrapper/call.py b/faststream/_internal/subscriber/call_wrapper/call.py index e7ad845024..14d081b52f 100644 --- a/faststream/_internal/subscriber/call_wrapper/call.py +++ b/faststream/_internal/subscriber/call_wrapper/call.py @@ -85,7 +85,7 @@ def __call__( """Calls the object as a function.""" return self._original_call(*args, **kwargs) - def call_wrapped( + async def call_wrapped( self, message: "StreamMessage[MsgType]", ) -> Awaitable[Any]: @@ -93,8 +93,8 @@ def call_wrapped( assert self._wrapped_call, "You should use `set_wrapped` first" # nosec B101 if self.is_test: assert self.mock # nosec B101 - self.mock(message._decoded_body) - return self._wrapped_call(message) + self.mock(await message.decode()) + return await self._wrapped_call(message) async def wait_call(self, timeout: Optional[float] = None) -> None: """Waits for a call with an optional timeout.""" diff --git a/faststream/_internal/subscriber/mixins.py b/faststream/_internal/subscriber/mixins.py index 27c8f60f47..412f8f2c79 100644 --- a/faststream/_internal/subscriber/mixins.py +++ b/faststream/_internal/subscriber/mixins.py @@ -63,10 +63,7 @@ async def _serve_consume_queue( async for msg in self.receive_stream: tg.start_soon(self._consume_msg, msg) - async def _consume_msg( - self, - msg: "Msg", - ) -> None: + async def _consume_msg(self, msg: "Msg") -> None: """Proxy method to call `self.consume` with semaphore block.""" async with self.limiter: await self.consume(msg) diff --git a/faststream/_internal/subscriber/utils.py b/faststream/_internal/subscriber/utils.py index 5f3d6719c2..213a52c414 100644 --- a/faststream/_internal/subscriber/utils.py +++ b/faststream/_internal/subscriber/utils.py @@ -73,7 +73,7 @@ async def process_msg( parsed_msg = await parser(msg) parsed_msg._source_type = source_type - parsed_msg._decoded_body = await decoder(parsed_msg) + parsed_msg.set_decoder(decoder) return await return_msg(parsed_msg) msg = "unreachable" diff --git a/faststream/_internal/types.py b/faststream/_internal/types.py index fad8c62f95..ea1ecd3dbf 100644 --- a/faststream/_internal/types.py +++ b/faststream/_internal/types.py @@ -32,14 +32,11 @@ [Any], Any, ] -AsyncCallable: TypeAlias = Callable[ - [Any], - Awaitable[Any], -] +AsyncCallable: TypeAlias = AsyncFuncAny AsyncCustomCallable: TypeAlias = Union[ - AsyncCallable, + AsyncFuncAny, Callable[ - [Any, AsyncCallable], + [Any, AsyncFuncAny], Awaitable[Any], ], ] diff --git a/faststream/confluent/subscriber/factory.py b/faststream/confluent/subscriber/factory.py index ed6ae75690..b6edea0456 100644 --- a/faststream/confluent/subscriber/factory.py +++ b/faststream/confluent/subscriber/factory.py @@ -123,12 +123,7 @@ def create_subscriber( "SpecificationDefaultSubscriber", "SpecificationBatchSubscriber", ]: - if ack_policy is not EMPTY and not is_manual: - warnings.warn( - "You can't use acknowledgement policy with `is_manual=False` subscriber", - RuntimeWarning, - stacklevel=3, - ) + _validate_input_for_misconfigure(ack_policy=ack_policy, is_manual=is_manual) if ack_policy is EMPTY: ack_policy = AckPolicy.REJECT_ON_ERROR @@ -165,3 +160,16 @@ def create_subscriber( description_=description_, include_in_schema=include_in_schema, ) + + +def _validate_input_for_misconfigure( + *, + ack_policy: "AckPolicy", + is_manual: bool, +) -> None: + if ack_policy is not EMPTY and not is_manual: + warnings.warn( + "You can't use acknowledgement policy with `is_manual=False` subscriber", + RuntimeWarning, + stacklevel=4, + ) diff --git a/faststream/kafka/subscriber/factory.py b/faststream/kafka/subscriber/factory.py index d623fa4f7a..bb559873cc 100644 --- a/faststream/kafka/subscriber/factory.py +++ b/faststream/kafka/subscriber/factory.py @@ -132,31 +132,14 @@ def create_subscriber( "SpecificationDefaultSubscriber", "SpecificationBatchSubscriber", ]: - if ack_policy is not EMPTY and not is_manual: - warnings.warn( - "You can't use acknowledgement policy with `is_manual=False` subscriber", - RuntimeWarning, - stacklevel=3, - ) - - if is_manual and not group_id: - msg = "You must use `group_id` with manual commit mode." - raise SetupError(msg) - - if not topics and not partitions and not pattern: - msg = "You should provide either `topics` or `partitions` or `pattern`." - raise SetupError( - msg, - ) - if topics and partitions: - msg = "You can't provide both `topics` and `partitions`." - raise SetupError(msg) - if topics and pattern: - msg = "You can't provide both `topics` and `pattern`." - raise SetupError(msg) - if partitions and pattern: - msg = "You can't provide both `partitions` and `pattern`." - raise SetupError(msg) + _validate_input_for_misconfigure( + *topics, + pattern=pattern, + partitions=partitions, + ack_policy=ack_policy, + is_manual=is_manual, + group_id=group_id, + ) if ack_policy is EMPTY: ack_policy = AckPolicy.REJECT_ON_ERROR @@ -197,3 +180,38 @@ def create_subscriber( description_=description_, include_in_schema=include_in_schema, ) + + +def _validate_input_for_misconfigure( + *topics: str, + partitions: Iterable["TopicPartition"], + pattern: Optional[str], + ack_policy: "AckPolicy", + is_manual: bool, + group_id: Optional[str], +) -> None: + if ack_policy is not EMPTY and not is_manual: + warnings.warn( + "You can't use acknowledgement policy with `is_manual=False` subscriber", + RuntimeWarning, + stacklevel=4, + ) + + if is_manual and not group_id: + msg = "You must use `group_id` with manual commit mode." + raise SetupError(msg) + + if not topics and not partitions and not pattern: + msg = "You should provide either `topics` or `partitions` or `pattern`." + raise SetupError( + msg, + ) + if topics and partitions: + msg = "You can't provide both `topics` and `partitions`." + raise SetupError(msg) + if topics and pattern: + msg = "You can't provide both `topics` and `pattern`." + raise SetupError(msg) + if partitions and pattern: + msg = "You can't provide both `partitions` and `pattern`." + raise SetupError(msg) diff --git a/faststream/message/message.py b/faststream/message/message.py index cdba65b5bb..a7db6f895d 100644 --- a/faststream/message/message.py +++ b/faststream/message/message.py @@ -13,6 +13,7 @@ if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict, DecodedMessage + from faststream._internal.types import AsyncCallable # prevent circular imports MsgType = TypeVar("MsgType") @@ -53,11 +54,21 @@ def __init__( self.correlation_id = correlation_id or str(uuid4()) self.message_id = message_id or self.correlation_id - # Setup later - self._decoded_body: Optional[DecodedMessage] = None self.committed: Optional[AckStatus] = None self.processed = False + # Setup later + self.__decoder: Optional[AsyncCallable] = None + self.__decoded_caches: dict[ + Any, Any + ] = {} # Cache values between filters and tests + + def set_decoder(self, decoder: "AsyncCallable") -> None: + self.__decoder = decoder + + def clear_cache(self) -> None: + self.__decoded_caches.clear() + def __repr__(self) -> str: inner = ", ".join( filter( @@ -79,9 +90,17 @@ def __repr__(self) -> str: return f"{self.__class__.__name__}({inner})" async def decode(self) -> Optional["DecodedMessage"]: - """Serialize the message by lazy decoder.""" - # TODO: make it lazy after `decoded_body` removed - return self._decoded_body + """Serialize the message by lazy decoder. + + Returns a cache after first usage. To prevent such behavior, please call + `message.clear_cache()` after `message.body` changes. + """ + assert self.__decoder, "You should call `set_decoder()` method first." # nosec B101 + + if (result := self.__decoded_caches.get(self.__decoder)) is None: + result = self.__decoded_caches[self.__decoder] = await self.__decoder(self) + + return result async def ack(self) -> None: if self.committed is None: diff --git a/faststream/nats/annotations.py b/faststream/nats/annotations.py index 5aa74aa8d0..aead2fe490 100644 --- a/faststream/nats/annotations.py +++ b/faststream/nats/annotations.py @@ -8,7 +8,9 @@ from faststream.annotations import ContextRepo, Logger from faststream.nats.broker import NatsBroker as _Broker from faststream.nats.message import NatsMessage as _Message -from faststream.nats.subscriber.usecase import OBJECT_STORAGE_CONTEXT_KEY +from faststream.nats.subscriber.usecases.object_storage_subscriber import ( + OBJECT_STORAGE_CONTEXT_KEY, +) __all__ = ( "Client", diff --git a/faststream/nats/subscriber/factory.py b/faststream/nats/subscriber/factory.py index 35062e4eed..c17e6e808d 100644 --- a/faststream/nats/subscriber/factory.py +++ b/faststream/nats/subscriber/factory.py @@ -349,7 +349,7 @@ def _validate_input_for_misconfigure( # noqa: PLR0915 raise SetupError(msg) if pull_sub and not stream: - msg = "The pull subscriber can only be used with the `stream` option." + msg = "JetStream Pull Subscriber can only be used with the `stream` option." raise SetupError(msg) if ack_policy is not EMPTY: diff --git a/faststream/nats/subscriber/specified.py b/faststream/nats/subscriber/specified.py index 8862f47ab3..2c3387ded3 100644 --- a/faststream/nats/subscriber/specified.py +++ b/faststream/nats/subscriber/specified.py @@ -2,7 +2,7 @@ from typing_extensions import override -from faststream.nats.subscriber.usecase import ( +from faststream.nats.subscriber.usecases import ( BatchPullStreamSubscriber, ConcurrentCoreSubscriber, ConcurrentPullStreamSubscriber, diff --git a/faststream/nats/subscriber/usecases/__init__.py b/faststream/nats/subscriber/usecases/__init__.py new file mode 100644 index 0000000000..040a9f9680 --- /dev/null +++ b/faststream/nats/subscriber/usecases/__init__.py @@ -0,0 +1,26 @@ +from .basic import LogicSubscriber +from .core_subscriber import ConcurrentCoreSubscriber, CoreSubscriber +from .key_value_subscriber import KeyValueWatchSubscriber +from .object_storage_subscriber import ObjStoreWatchSubscriber +from .stream_pull_subscriber import ( + BatchPullStreamSubscriber, + ConcurrentPullStreamSubscriber, + PullStreamSubscriber, +) +from .stream_push_subscriber import ( + ConcurrentPushStreamSubscriber, + PushStreamSubscription, +) + +__all__ = ( + "BatchPullStreamSubscriber", + "ConcurrentCoreSubscriber", + "ConcurrentPullStreamSubscriber", + "ConcurrentPushStreamSubscriber", + "CoreSubscriber", + "KeyValueWatchSubscriber", + "LogicSubscriber", + "ObjStoreWatchSubscriber", + "PullStreamSubscriber", + "PushStreamSubscription", +) diff --git a/faststream/nats/subscriber/usecases/basic.py b/faststream/nats/subscriber/usecases/basic.py new file mode 100644 index 0000000000..3b5f30e1fc --- /dev/null +++ b/faststream/nats/subscriber/usecases/basic.py @@ -0,0 +1,247 @@ +from abc import abstractmethod +from collections.abc import Iterable +from typing import ( + TYPE_CHECKING, + Any, + Generic, + Optional, +) + +from typing_extensions import override + +from faststream._internal.subscriber.usecase import SubscriberUsecase +from faststream._internal.types import MsgType +from faststream.nats.helpers import KVBucketDeclarer, OSBucketDeclarer +from faststream.nats.publisher.fake import NatsFakePublisher +from faststream.nats.schemas.js_stream import compile_nats_wildcard +from faststream.nats.subscriber.adapters import ( + Unsubscriptable, +) +from faststream.nats.subscriber.state import ( + ConnectedSubscriberState, + EmptySubscriberState, + SubscriberState, +) + +if TYPE_CHECKING: + from fast_depends.dependencies import Dependant + from nats.js.api import ConsumerConfig + + from faststream._internal.basic_types import ( + AnyDict, + ) + from faststream._internal.publisher.proto import BasePublisherProto, ProducerProto + from faststream._internal.state import ( + BrokerState as BasicState, + Pointer, + ) + from faststream._internal.types import ( + AsyncCallable, + BrokerMiddleware, + CustomCallable, + ) + from faststream.message import StreamMessage + from faststream.middlewares import AckPolicy + from faststream.nats.broker.state import BrokerState + from faststream.nats.helpers import KVBucketDeclarer, OSBucketDeclarer + + +class LogicSubscriber(SubscriberUsecase[MsgType], Generic[MsgType]): + """Basic class for all NATS Subscriber types (KeyValue, ObjectStorage, Core & JetStream).""" + + subscription: Optional[Unsubscriptable] + _fetch_sub: Optional[Unsubscriptable] + producer: Optional["ProducerProto"] + + def __init__( + self, + *, + subject: str, + config: "ConsumerConfig", + extra_options: Optional["AnyDict"], + # Subscriber args + default_parser: "AsyncCallable", + default_decoder: "AsyncCallable", + ack_policy: "AckPolicy", + no_reply: bool, + broker_dependencies: Iterable["Dependant"], + broker_middlewares: Iterable["BrokerMiddleware[MsgType]"], + # AsyncAPI args + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, + ) -> None: + self.subject = subject + self.config = config + + self.extra_options = extra_options or {} + + super().__init__( + default_parser=default_parser, + default_decoder=default_decoder, + # Propagated args + ack_policy=ack_policy, + no_reply=no_reply, + broker_middlewares=broker_middlewares, + broker_dependencies=broker_dependencies, + # AsyncAPI args + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + ) + + self._fetch_sub = None + self.subscription = None + self.producer = None + + self._connection_state: SubscriberState = EmptySubscriberState() + + @override + def _setup( # type: ignore[override] + self, + *, + connection_state: "BrokerState", + os_declarer: "OSBucketDeclarer", + kv_declarer: "KVBucketDeclarer", + # basic args + extra_context: "AnyDict", + # broker options + broker_parser: Optional["CustomCallable"], + broker_decoder: Optional["CustomCallable"], + # dependant args + state: "Pointer[BasicState]", + ) -> None: + self._connection_state = ConnectedSubscriberState( + parent_state=connection_state, + os_declarer=os_declarer, + kv_declarer=kv_declarer, + ) + + super()._setup( + extra_context=extra_context, + broker_parser=broker_parser, + broker_decoder=broker_decoder, + state=state, + ) + + @property + def clear_subject(self) -> str: + """Compile `test.{name}` to `test.*` subject.""" + _, path = compile_nats_wildcard(self.subject) + return path + + async def start(self) -> None: + """Create NATS subscription and start consume tasks.""" + await super().start() + + if self.calls: + await self._create_subscription() + + async def close(self) -> None: + """Clean up handler subscription, cancel consume task in graceful mode.""" + await super().close() + + if self.subscription is not None: + await self.subscription.unsubscribe() + self.subscription = None + + if self._fetch_sub is not None: + await self._fetch_sub.unsubscribe() + self.subscription = None + + @abstractmethod + async def _create_subscription(self) -> None: + """Create NATS subscription object to consume messages.""" + raise NotImplementedError + + @staticmethod + def build_log_context( + message: Optional["StreamMessage[MsgType]"], + subject: str, + *, + queue: str = "", + stream: str = "", + ) -> dict[str, str]: + """Static method to build log context out of `self.consume` scope.""" + return { + "subject": subject, + "queue": queue, + "stream": stream, + "message_id": getattr(message, "message_id", ""), + } + + def add_prefix(self, prefix: str) -> None: + """Include Subscriber in router.""" + if self.subject: + self.subject = f"{prefix}{self.subject}" + else: + self.config.filter_subjects = [ + f"{prefix}{subject}" for subject in (self.config.filter_subjects or ()) + ] + + @property + def _resolved_subject_string(self) -> str: + return self.subject or ", ".join(self.config.filter_subjects or ()) + + +class DefaultSubscriber(LogicSubscriber[MsgType]): + """Basic class for Core & JetStream Subscribers.""" + + def __init__( + self, + *, + subject: str, + config: "ConsumerConfig", + # default args + extra_options: Optional["AnyDict"], + # Subscriber args + default_parser: "AsyncCallable", + default_decoder: "AsyncCallable", + ack_policy: "AckPolicy", + no_reply: bool, + broker_dependencies: Iterable["Dependant"], + broker_middlewares: Iterable["BrokerMiddleware[MsgType]"], + # AsyncAPI args + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, + ) -> None: + super().__init__( + subject=subject, + config=config, + extra_options=extra_options, + # subscriber args + default_parser=default_parser, + default_decoder=default_decoder, + # Propagated args + ack_policy=ack_policy, + no_reply=no_reply, + broker_middlewares=broker_middlewares, + broker_dependencies=broker_dependencies, + # AsyncAPI args + description_=description_, + title_=title_, + include_in_schema=include_in_schema, + ) + + def _make_response_publisher( + self, + message: "StreamMessage[Any]", + ) -> Iterable["BasePublisherProto"]: + """Create Publisher objects to use it as one of `publishers` in `self.consume` scope.""" + return ( + NatsFakePublisher( + producer=self._state.get().producer, + subject=message.reply_to, + ), + ) + + def get_log_context( + self, + message: Optional["StreamMessage[MsgType]"], + ) -> dict[str, str]: + """Log context factory using in `self.consume` scope.""" + return self.build_log_context( + message=message, + subject=self.subject, + ) diff --git a/faststream/nats/subscriber/usecases/core_subscriber.py b/faststream/nats/subscriber/usecases/core_subscriber.py new file mode 100644 index 0000000000..3cff6547d2 --- /dev/null +++ b/faststream/nats/subscriber/usecases/core_subscriber.py @@ -0,0 +1,186 @@ +from collections.abc import Iterable +from typing import ( + TYPE_CHECKING, + Annotated, + Optional, +) + +from nats.errors import TimeoutError +from typing_extensions import Doc, override + +from faststream._internal.subscriber.mixins import ConcurrentMixin +from faststream._internal.subscriber.utils import process_msg +from faststream.middlewares import AckPolicy +from faststream.nats.parser import NatsParser + +from .basic import DefaultSubscriber + +if TYPE_CHECKING: + from fast_depends.dependencies import Dependant + from nats.aio.msg import Msg + from nats.aio.subscription import Subscription + from nats.js.api import ConsumerConfig + + from faststream._internal.basic_types import AnyDict + from faststream._internal.types import BrokerMiddleware + from faststream.message import StreamMessage + from faststream.nats.message import NatsMessage + + +class CoreSubscriber(DefaultSubscriber["Msg"]): + subscription: Optional["Subscription"] + _fetch_sub: Optional["Subscription"] + + def __init__( + self, + *, + # default args + subject: str, + config: "ConsumerConfig", + queue: str, + extra_options: Optional["AnyDict"], + # Subscriber args + no_reply: bool, + broker_dependencies: Iterable["Dependant"], + broker_middlewares: Iterable["BrokerMiddleware[Msg]"], + # AsyncAPI args + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, + ) -> None: + parser_ = NatsParser(pattern=subject) + + self.queue = queue + + super().__init__( + subject=subject, + config=config, + extra_options=extra_options, + # subscriber args + default_parser=parser_.parse_message, + default_decoder=parser_.decode_message, + # Propagated args + ack_policy=AckPolicy.DO_NOTHING, + no_reply=no_reply, + broker_middlewares=broker_middlewares, + broker_dependencies=broker_dependencies, + # AsyncAPI args + description_=description_, + title_=title_, + include_in_schema=include_in_schema, + ) + + @override + async def get_one( + self, + *, + timeout: float = 5.0, + ) -> "Optional[NatsMessage]": + assert ( # nosec B101 + not self.calls + ), "You can't use `get_one` method if subscriber has registered handlers." + + if self._fetch_sub is None: + fetch_sub = self._fetch_sub = await self._connection_state.client.subscribe( + subject=self.clear_subject, + queue=self.queue, + **self.extra_options, + ) + else: + fetch_sub = self._fetch_sub + + try: + raw_message = await fetch_sub.next_msg(timeout=timeout) + except TimeoutError: + return None + + context = self._state.get().di_state.context + + msg: NatsMessage = await process_msg( # type: ignore[assignment] + msg=raw_message, + middlewares=( + m(raw_message, context=context) for m in self._broker_middlewares + ), + parser=self._parser, + decoder=self._decoder, + ) + return msg + + @override + async def _create_subscription(self) -> None: + """Create NATS subscription and start consume task.""" + if self.subscription: + return + + self.subscription = await self._connection_state.client.subscribe( + subject=self.clear_subject, + queue=self.queue, + cb=self.consume, + **self.extra_options, + ) + + def get_log_context( + self, + message: Annotated[ + Optional["StreamMessage[Msg]"], + Doc("Message which we are building context for"), + ], + ) -> dict[str, str]: + """Log context factory using in `self.consume` scope.""" + return self.build_log_context( + message=message, + subject=self.subject, + queue=self.queue, + ) + + +class ConcurrentCoreSubscriber(ConcurrentMixin, CoreSubscriber): + def __init__( + self, + *, + max_workers: int, + # default args + subject: str, + config: "ConsumerConfig", + queue: str, + extra_options: Optional["AnyDict"], + # Subscriber args + no_reply: bool, + broker_dependencies: Iterable["Dependant"], + broker_middlewares: Iterable["BrokerMiddleware[Msg]"], + # AsyncAPI args + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, + ) -> None: + super().__init__( + max_workers=max_workers, + # basic args + subject=subject, + config=config, + queue=queue, + extra_options=extra_options, + # Propagated args + no_reply=no_reply, + broker_middlewares=broker_middlewares, + broker_dependencies=broker_dependencies, + # AsyncAPI args + description_=description_, + title_=title_, + include_in_schema=include_in_schema, + ) + + @override + async def _create_subscription(self) -> None: + """Create NATS subscription and start consume task.""" + if self.subscription: + return + + self.start_consume_task() + + self.subscription = await self._connection_state.client.subscribe( + subject=self.clear_subject, + queue=self.queue, + cb=self._put_msg, + **self.extra_options, + ) diff --git a/faststream/nats/subscriber/usecases/key_value_subscriber.py b/faststream/nats/subscriber/usecases/key_value_subscriber.py new file mode 100644 index 0000000000..cf4a2a3f4e --- /dev/null +++ b/faststream/nats/subscriber/usecases/key_value_subscriber.py @@ -0,0 +1,188 @@ +from collections.abc import Iterable +from contextlib import suppress +from typing import ( + TYPE_CHECKING, + Annotated, + Optional, + cast, +) + +import anyio +from nats.errors import ConnectionClosedError, TimeoutError +from typing_extensions import Doc, override + +from faststream._internal.subscriber.mixins import TasksMixin +from faststream._internal.subscriber.utils import process_msg +from faststream.middlewares import AckPolicy +from faststream.nats.parser import ( + KvParser, +) +from faststream.nats.subscriber.adapters import ( + UnsubscribeAdapter, +) + +from .basic import LogicSubscriber + +if TYPE_CHECKING: + from fast_depends.dependencies import Dependant + from nats.js.api import ConsumerConfig + from nats.js.kv import KeyValue + + from faststream._internal.publisher.proto import BasePublisherProto + from faststream._internal.types import ( + BrokerMiddleware, + ) + from faststream.message import StreamMessage + from faststream.nats.message import NatsKvMessage + from faststream.nats.schemas import KvWatch + + +class KeyValueWatchSubscriber( + TasksMixin, + LogicSubscriber["KeyValue.Entry"], +): + subscription: Optional["UnsubscribeAdapter[KeyValue.KeyWatcher]"] + _fetch_sub: Optional[UnsubscribeAdapter["KeyValue.KeyWatcher"]] + + def __init__( + self, + *, + subject: str, + config: "ConsumerConfig", + kv_watch: "KvWatch", + broker_dependencies: Iterable["Dependant"], + broker_middlewares: Iterable["BrokerMiddleware[KeyValue.Entry]"], + # AsyncAPI args + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, + ) -> None: + parser = KvParser(pattern=subject) + self.kv_watch = kv_watch + + super().__init__( + subject=subject, + config=config, + extra_options=None, + ack_policy=AckPolicy.DO_NOTHING, + no_reply=True, + default_parser=parser.parse_message, + default_decoder=parser.decode_message, + broker_middlewares=broker_middlewares, + broker_dependencies=broker_dependencies, + # AsyncAPI args + description_=description_, + title_=title_, + include_in_schema=include_in_schema, + ) + + @override + async def get_one( + self, + *, + timeout: float = 5, + ) -> Optional["NatsKvMessage"]: + assert ( # nosec B101 + not self.calls + ), "You can't use `get_one` method if subscriber has registered handlers." + + if not self._fetch_sub: + bucket = await self._connection_state.kv_declarer.create_key_value( + bucket=self.kv_watch.name, + declare=self.kv_watch.declare, + ) + + fetch_sub = self._fetch_sub = UnsubscribeAdapter["KeyValue.KeyWatcher"]( + await bucket.watch( + keys=self.clear_subject, + headers_only=self.kv_watch.headers_only, + include_history=self.kv_watch.include_history, + ignore_deletes=self.kv_watch.ignore_deletes, + meta_only=self.kv_watch.meta_only, + ), + ) + else: + fetch_sub = self._fetch_sub + + raw_message = None + sleep_interval = timeout / 10 + with anyio.move_on_after(timeout): + while ( # noqa: ASYNC110 + # type: ignore[no-untyped-call] + raw_message := await fetch_sub.obj.updates(timeout) + ) is None: + await anyio.sleep(sleep_interval) + + context = self._state.get().di_state.context + + msg: NatsKvMessage = await process_msg( + msg=raw_message, + middlewares=( + m(raw_message, context=context) for m in self._broker_middlewares + ), + parser=self._parser, + decoder=self._decoder, + ) + return msg + + @override + async def _create_subscription(self) -> None: + if self.subscription: + return + + bucket = await self._connection_state.kv_declarer.create_key_value( + bucket=self.kv_watch.name, + declare=self.kv_watch.declare, + ) + + self.subscription = UnsubscribeAdapter["KeyValue.KeyWatcher"]( + await bucket.watch( + keys=self.clear_subject, + headers_only=self.kv_watch.headers_only, + include_history=self.kv_watch.include_history, + ignore_deletes=self.kv_watch.ignore_deletes, + meta_only=self.kv_watch.meta_only, + ), + ) + + self.add_task(self.__consume_watch()) + + async def __consume_watch(self) -> None: + assert self.subscription, "You should call `create_subscription` at first." # nosec B101 + + key_watcher = self.subscription.obj + + while self.running: + with suppress(ConnectionClosedError, TimeoutError): + message = cast( + Optional["KeyValue.Entry"], + # type: ignore[no-untyped-call] + await key_watcher.updates(self.kv_watch.timeout), + ) + + if message: + await self.consume(message) + + def _make_response_publisher( + self, + message: Annotated[ + "StreamMessage[KeyValue.Entry]", + Doc("Message requiring reply"), + ], + ) -> Iterable["BasePublisherProto"]: + """Create Publisher objects to use it as one of `publishers` in `self.consume` scope.""" + return () + + def get_log_context( + self, + message: Annotated[ + Optional["StreamMessage[KeyValue.Entry]"], + Doc("Message which we are building context for"), + ], + ) -> dict[str, str]: + """Log context factory using in `self.consume` scope.""" + return self.build_log_context( + message=message, + subject=self.subject, + stream=self.kv_watch.name, + ) diff --git a/faststream/nats/subscriber/usecases/object_storage_subscriber.py b/faststream/nats/subscriber/usecases/object_storage_subscriber.py new file mode 100644 index 0000000000..a1d5bace48 --- /dev/null +++ b/faststream/nats/subscriber/usecases/object_storage_subscriber.py @@ -0,0 +1,192 @@ +from collections.abc import Iterable +from contextlib import suppress +from typing import ( + TYPE_CHECKING, + Annotated, + Optional, + cast, +) + +import anyio +from nats.errors import TimeoutError +from nats.js.api import ConsumerConfig, ObjectInfo +from typing_extensions import Doc, override + +from faststream._internal.subscriber.mixins import TasksMixin +from faststream._internal.subscriber.utils import process_msg +from faststream.middlewares import AckPolicy +from faststream.nats.parser import ( + ObjParser, +) +from faststream.nats.subscriber.adapters import ( + UnsubscribeAdapter, +) + +from .basic import LogicSubscriber + +if TYPE_CHECKING: + from fast_depends.dependencies import Dependant + from nats.aio.msg import Msg + from nats.js.object_store import ObjectStore + + from faststream._internal.publisher.proto import BasePublisherProto + from faststream._internal.types import ( + BrokerMiddleware, + ) + from faststream.message import StreamMessage + from faststream.nats.message import NatsObjMessage + from faststream.nats.schemas import ObjWatch + + +OBJECT_STORAGE_CONTEXT_KEY = "__object_storage" + + +class ObjStoreWatchSubscriber( + TasksMixin, + LogicSubscriber[ObjectInfo], +): + subscription: Optional["UnsubscribeAdapter[ObjectStore.ObjectWatcher]"] + _fetch_sub: Optional[UnsubscribeAdapter["ObjectStore.ObjectWatcher"]] + + def __init__( + self, + *, + subject: str, + config: "ConsumerConfig", + obj_watch: "ObjWatch", + broker_dependencies: Iterable["Dependant"], + broker_middlewares: Iterable["BrokerMiddleware[list[Msg]]"], + # AsyncAPI args + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, + ) -> None: + parser = ObjParser(pattern="") + + self.obj_watch = obj_watch + self.obj_watch_conn = None + + super().__init__( + subject=subject, + config=config, + extra_options=None, + ack_policy=AckPolicy.DO_NOTHING, + no_reply=True, + default_parser=parser.parse_message, + default_decoder=parser.decode_message, + broker_middlewares=broker_middlewares, + broker_dependencies=broker_dependencies, + # AsyncAPI args + description_=description_, + title_=title_, + include_in_schema=include_in_schema, + ) + + @override + async def get_one( + self, + *, + timeout: float = 5, + ) -> Optional["NatsObjMessage"]: + assert ( # nosec B101 + not self.calls + ), "You can't use `get_one` method if subscriber has registered handlers." + + if not self._fetch_sub: + self.bucket = await self._connection_state.os_declarer.create_object_store( + bucket=self.subject, + declare=self.obj_watch.declare, + ) + + obj_watch = await self.bucket.watch( + ignore_deletes=self.obj_watch.ignore_deletes, + include_history=self.obj_watch.include_history, + meta_only=self.obj_watch.meta_only, + ) + fetch_sub = self._fetch_sub = UnsubscribeAdapter[ + "ObjectStore.ObjectWatcher" + ](obj_watch) + else: + fetch_sub = self._fetch_sub + + raw_message = None + sleep_interval = timeout / 10 + with anyio.move_on_after(timeout): + while ( # noqa: ASYNC110 + # type: ignore[no-untyped-call] + raw_message := await fetch_sub.obj.updates(timeout) + ) is None: + await anyio.sleep(sleep_interval) + + context = self._state.get().di_state.context + + msg: NatsObjMessage = await process_msg( + msg=raw_message, + middlewares=( + m(raw_message, context=context) for m in self._broker_middlewares + ), + parser=self._parser, + decoder=self._decoder, + ) + return msg + + @override + async def _create_subscription(self) -> None: + if self.subscription: + return + + self.bucket = await self._connection_state.os_declarer.create_object_store( + bucket=self.subject, + declare=self.obj_watch.declare, + ) + + self.add_task(self.__consume_watch()) + + async def __consume_watch(self) -> None: + assert self.bucket, "You should call `create_subscription` at first." # nosec B101 + + # Should be created inside task to avoid nats-py lock + obj_watch = await self.bucket.watch( + ignore_deletes=self.obj_watch.ignore_deletes, + include_history=self.obj_watch.include_history, + meta_only=self.obj_watch.meta_only, + ) + + self.subscription = UnsubscribeAdapter["ObjectStore.ObjectWatcher"](obj_watch) + + context = self._state.get().di_state.context + + while self.running: + with suppress(TimeoutError): + message = cast( + Optional["ObjectInfo"], + # type: ignore[no-untyped-call] + await obj_watch.updates(self.obj_watch.timeout), + ) + + if message: + with context.scope(OBJECT_STORAGE_CONTEXT_KEY, self.bucket): + await self.consume(message) + + def _make_response_publisher( + self, + message: Annotated[ + "StreamMessage[ObjectInfo]", + Doc("Message requiring reply"), + ], + ) -> Iterable["BasePublisherProto"]: + """Create Publisher objects to use it as one of `publishers` in `self.consume` scope.""" + return () + + def get_log_context( + self, + message: Annotated[ + Optional["StreamMessage[ObjectInfo]"], + Doc("Message which we are building context for"), + ], + ) -> dict[str, str]: + """Log context factory using in `self.consume` scope.""" + return self.build_log_context( + message=message, + subject=self.subject, + ) diff --git a/faststream/nats/subscriber/usecases/stream_basic.py b/faststream/nats/subscriber/usecases/stream_basic.py new file mode 100644 index 0000000000..c053f2ce5e --- /dev/null +++ b/faststream/nats/subscriber/usecases/stream_basic.py @@ -0,0 +1,142 @@ +from collections.abc import Iterable +from typing import ( + TYPE_CHECKING, + Annotated, + Optional, +) + +from nats.errors import ConnectionClosedError, TimeoutError +from typing_extensions import Doc, override + +from faststream._internal.subscriber.utils import process_msg +from faststream.nats.parser import ( + JsParser, +) + +from .basic import DefaultSubscriber + +if TYPE_CHECKING: + from fast_depends.dependencies import Dependant + from nats.aio.msg import Msg + from nats.js import JetStreamContext + from nats.js.api import ConsumerConfig + + from faststream._internal.basic_types import ( + AnyDict, + ) + from faststream._internal.types import ( + BrokerMiddleware, + ) + from faststream.message import StreamMessage + from faststream.middlewares import AckPolicy + from faststream.nats.message import NatsMessage + from faststream.nats.schemas import JStream + + +class StreamSubscriber(DefaultSubscriber["Msg"]): + _fetch_sub: Optional["JetStreamContext.PullSubscription"] + + def __init__( + self, + *, + stream: "JStream", + # default args + subject: str, + config: "ConsumerConfig", + queue: str, + extra_options: Optional["AnyDict"], + # Subscriber args + ack_policy: "AckPolicy", + no_reply: bool, + broker_dependencies: Iterable["Dependant"], + broker_middlewares: Iterable["BrokerMiddleware[Msg]"], + # AsyncAPI args + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, + ) -> None: + parser_ = JsParser(pattern=subject) + + self.queue = queue + self.stream = stream + + super().__init__( + subject=subject, + config=config, + extra_options=extra_options, + # subscriber args + default_parser=parser_.parse_message, + default_decoder=parser_.decode_message, + # Propagated args + ack_policy=ack_policy, + no_reply=no_reply, + broker_middlewares=broker_middlewares, + broker_dependencies=broker_dependencies, + # AsyncAPI args + description_=description_, + title_=title_, + include_in_schema=include_in_schema, + ) + + def get_log_context( + self, + message: Annotated[ + Optional["StreamMessage[Msg]"], + Doc("Message which we are building context for"), + ], + ) -> dict[str, str]: + """Log context factory using in `self.consume` scope.""" + return self.build_log_context( + message=message, + subject=self._resolved_subject_string, + queue=self.queue, + stream=self.stream.name, + ) + + @override + async def get_one( + self, + *, + timeout: float = 5, + ) -> Optional["NatsMessage"]: + assert ( # nosec B101 + not self.calls + ), "You can't use `get_one` method if subscriber has registered handlers." + + if not self._fetch_sub: + extra_options = { + "pending_bytes_limit": self.extra_options["pending_bytes_limit"], + "pending_msgs_limit": self.extra_options["pending_msgs_limit"], + "durable": self.extra_options["durable"], + "stream": self.extra_options["stream"], + } + if inbox_prefix := self.extra_options.get("inbox_prefix"): + extra_options["inbox_prefix"] = inbox_prefix + + self._fetch_sub = await self._connection_state.js.pull_subscribe( + subject=self.clear_subject, + config=self.config, + **extra_options, + ) + + try: + raw_message = ( + await self._fetch_sub.fetch( + batch=1, + timeout=timeout, + ) + )[0] + except (TimeoutError, ConnectionClosedError): + return None + + context = self._state.get().di_state.context + + msg: NatsMessage = await process_msg( # type: ignore[assignment] + msg=raw_message, + middlewares=( + m(raw_message, context=context) for m in self._broker_middlewares + ), + parser=self._parser, + decoder=self._decoder, + ) + return msg diff --git a/faststream/nats/subscriber/usecases/stream_pull_subscriber.py b/faststream/nats/subscriber/usecases/stream_pull_subscriber.py new file mode 100644 index 0000000000..44d82e89dd --- /dev/null +++ b/faststream/nats/subscriber/usecases/stream_pull_subscriber.py @@ -0,0 +1,298 @@ +from collections.abc import Awaitable, Iterable +from contextlib import suppress +from typing import ( + TYPE_CHECKING, + Callable, + Optional, + cast, +) + +import anyio +from nats.errors import ConnectionClosedError, TimeoutError +from typing_extensions import override + +from faststream._internal.subscriber.mixins import ConcurrentMixin, TasksMixin +from faststream._internal.subscriber.utils import process_msg +from faststream.nats.message import NatsMessage +from faststream.nats.parser import ( + BatchParser, +) + +from .basic import DefaultSubscriber +from .stream_basic import StreamSubscriber + +if TYPE_CHECKING: + from fast_depends.dependencies import Dependant + from nats.aio.msg import Msg + from nats.js import JetStreamContext + from nats.js.api import ConsumerConfig + + from faststream._internal.basic_types import ( + AnyDict, + SendableMessage, + ) + from faststream._internal.types import ( + BrokerMiddleware, + ) + from faststream.middlewares import AckPolicy + from faststream.nats.schemas import JStream, PullSub + + +class PullStreamSubscriber( + TasksMixin, + StreamSubscriber, +): + subscription: Optional["JetStreamContext.PullSubscription"] + + def __init__( + self, + *, + pull_sub: "PullSub", + stream: "JStream", + # default args + subject: str, + config: "ConsumerConfig", + extra_options: Optional["AnyDict"], + # Subscriber args + ack_policy: "AckPolicy", + no_reply: bool, + broker_dependencies: Iterable["Dependant"], + broker_middlewares: Iterable["BrokerMiddleware[Msg]"], + # AsyncAPI args + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, + ) -> None: + self.pull_sub = pull_sub + + super().__init__( + # basic args + stream=stream, + subject=subject, + config=config, + extra_options=extra_options, + queue="", + # Propagated args + ack_policy=ack_policy, + no_reply=no_reply, + broker_middlewares=broker_middlewares, + broker_dependencies=broker_dependencies, + # AsyncAPI args + description_=description_, + title_=title_, + include_in_schema=include_in_schema, + ) + + @override + async def _create_subscription(self) -> None: + """Create NATS subscription and start consume task.""" + if self.subscription: + return + + self.subscription = await self._connection_state.js.pull_subscribe( + subject=self.clear_subject, + config=self.config, + **self.extra_options, + ) + self.add_task(self._consume_pull(cb=self.consume)) + + async def _consume_pull( + self, + cb: Callable[["Msg"], Awaitable["SendableMessage"]], + ) -> None: + """Endless task consuming messages using NATS Pull subscriber.""" + assert self.subscription # nosec B101 + + while self.running: # pragma: no branch + messages = [] + with suppress(TimeoutError, ConnectionClosedError): + messages = await self.subscription.fetch( + batch=self.pull_sub.batch_size, + timeout=self.pull_sub.timeout, + ) + + if messages: + async with anyio.create_task_group() as tg: + for msg in messages: + tg.start_soon(cb, msg) + + +class ConcurrentPullStreamSubscriber( + ConcurrentMixin, + PullStreamSubscriber, +): + def __init__( + self, + *, + max_workers: int, + # default args + pull_sub: "PullSub", + stream: "JStream", + subject: str, + config: "ConsumerConfig", + extra_options: Optional["AnyDict"], + # Subscriber args + ack_policy: "AckPolicy", + no_reply: bool, + broker_dependencies: Iterable["Dependant"], + broker_middlewares: Iterable["BrokerMiddleware[Msg]"], + # AsyncAPI args + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, + ) -> None: + super().__init__( + max_workers=max_workers, + # basic args + pull_sub=pull_sub, + stream=stream, + subject=subject, + config=config, + extra_options=extra_options, + # Propagated args + ack_policy=ack_policy, + no_reply=no_reply, + broker_middlewares=broker_middlewares, + broker_dependencies=broker_dependencies, + # AsyncAPI args + description_=description_, + title_=title_, + include_in_schema=include_in_schema, + ) + + @override + async def _create_subscription(self) -> None: + """Create NATS subscription and start consume task.""" + if self.subscription: + return + + self.start_consume_task() + + self.subscription = await self._connection_state.js.pull_subscribe( + subject=self.clear_subject, + config=self.config, + **self.extra_options, + ) + self.add_task(self._consume_pull(cb=self._put_msg)) + + +class BatchPullStreamSubscriber( + TasksMixin, + DefaultSubscriber[list["Msg"]], +): + """Batch-message consumer class.""" + + subscription: Optional["JetStreamContext.PullSubscription"] + _fetch_sub: Optional["JetStreamContext.PullSubscription"] + + def __init__( + self, + *, + # default args + subject: str, + config: "ConsumerConfig", + stream: "JStream", + pull_sub: "PullSub", + extra_options: Optional["AnyDict"], + # Subscriber args + ack_policy: "AckPolicy", + no_reply: bool, + broker_dependencies: Iterable["Dependant"], + broker_middlewares: Iterable["BrokerMiddleware[list[Msg]]"], + # AsyncAPI args + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, + ) -> None: + parser = BatchParser(pattern=subject) + + self.stream = stream + self.pull_sub = pull_sub + + super().__init__( + subject=subject, + config=config, + extra_options=extra_options, + # subscriber args + default_parser=parser.parse_batch, + default_decoder=parser.decode_batch, + # Propagated args + ack_policy=ack_policy, + no_reply=no_reply, + broker_middlewares=broker_middlewares, + broker_dependencies=broker_dependencies, + # AsyncAPI args + description_=description_, + title_=title_, + include_in_schema=include_in_schema, + ) + + @override + async def get_one( + self, + *, + timeout: float = 5, + ) -> Optional["NatsMessage"]: + assert ( # nosec B101 + not self.calls + ), "You can't use `get_one` method if subscriber has registered handlers." + + if not self._fetch_sub: + fetch_sub = ( + self._fetch_sub + ) = await self._connection_state.js.pull_subscribe( + subject=self.clear_subject, + config=self.config, + **self.extra_options, + ) + else: + fetch_sub = self._fetch_sub + + try: + raw_message = await fetch_sub.fetch( + batch=1, + timeout=timeout, + ) + except TimeoutError: + return None + + context = self._state.get().di_state.context + + return cast( + NatsMessage, + await process_msg( + msg=raw_message, + middlewares=( + m(raw_message, context=context) for m in self._broker_middlewares + ), + parser=self._parser, + decoder=self._decoder, + ), + ) + + @override + async def _create_subscription(self) -> None: + """Create NATS subscription and start consume task.""" + if self.subscription: + return + + self.subscription = await self._connection_state.js.pull_subscribe( + subject=self.clear_subject, + config=self.config, + **self.extra_options, + ) + self.add_task(self._consume_pull()) + + async def _consume_pull(self) -> None: + """Endless task consuming messages using NATS Pull subscriber.""" + assert self.subscription, "You should call `create_subscription` at first." # nosec B101 + + while self.running: # pragma: no branch + with suppress(TimeoutError, ConnectionClosedError): + messages = await self.subscription.fetch( + batch=self.pull_sub.batch_size, + timeout=self.pull_sub.timeout, + ) + + if messages: + await self.consume(messages) diff --git a/faststream/nats/subscriber/usecases/stream_push_subscriber.py b/faststream/nats/subscriber/usecases/stream_push_subscriber.py new file mode 100644 index 0000000000..ac14ae3509 --- /dev/null +++ b/faststream/nats/subscriber/usecases/stream_push_subscriber.py @@ -0,0 +1,106 @@ +from collections.abc import Iterable +from typing import ( + TYPE_CHECKING, + Optional, +) + +from typing_extensions import override + +from faststream._internal.subscriber.mixins import ConcurrentMixin + +from .stream_basic import StreamSubscriber + +if TYPE_CHECKING: + from fast_depends.dependencies import Dependant + from nats.aio.msg import Msg + from nats.js import JetStreamContext + from nats.js.api import ConsumerConfig + + from faststream._internal.basic_types import ( + AnyDict, + ) + from faststream._internal.types import ( + BrokerMiddleware, + ) + from faststream.middlewares import AckPolicy + from faststream.nats.schemas import JStream + + +class PushStreamSubscription(StreamSubscriber): + subscription: Optional["JetStreamContext.PushSubscription"] + + @override + async def _create_subscription(self) -> None: + """Create NATS subscription and start consume task.""" + if self.subscription: + return + + self.subscription = await self._connection_state.js.subscribe( + subject=self.clear_subject, + queue=self.queue, + cb=self.consume, + config=self.config, + **self.extra_options, + ) + + +class ConcurrentPushStreamSubscriber( + ConcurrentMixin, + StreamSubscriber, +): + subscription: Optional["JetStreamContext.PushSubscription"] + + def __init__( + self, + *, + max_workers: int, + stream: "JStream", + # default args + subject: str, + config: "ConsumerConfig", + queue: str, + extra_options: Optional["AnyDict"], + # Subscriber args + ack_policy: "AckPolicy", + no_reply: bool, + broker_dependencies: Iterable["Dependant"], + broker_middlewares: Iterable["BrokerMiddleware[Msg]"], + # AsyncAPI args + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, + ) -> None: + super().__init__( + max_workers=max_workers, + # basic args + stream=stream, + subject=subject, + config=config, + queue=queue, + extra_options=extra_options, + # Propagated args + ack_policy=ack_policy, + no_reply=no_reply, + broker_middlewares=broker_middlewares, + broker_dependencies=broker_dependencies, + # AsyncAPI args + description_=description_, + title_=title_, + include_in_schema=include_in_schema, + ) + + @override + async def _create_subscription(self) -> None: + """Create NATS subscription and start consume task.""" + if self.subscription: + return + + self.start_consume_task() + + self.subscription = await self._connection_state.js.subscribe( + subject=self.clear_subject, + queue=self.queue, + cb=self._put_msg, + config=self.config, + **self.extra_options, + ) diff --git a/faststream/nats/testing.py b/faststream/nats/testing.py index b3c57d7541..63c9fb9a22 100644 --- a/faststream/nats/testing.py +++ b/faststream/nats/testing.py @@ -26,7 +26,7 @@ from faststream._internal.basic_types import SendableMessage from faststream.nats.publisher.specified import SpecificationPublisher from faststream.nats.response import NatsPublishCommand - from faststream.nats.subscriber.usecase import LogicSubscriber + from faststream.nats.subscriber.usecases.basic import LogicSubscriber __all__ = ("TestNatsBroker",) diff --git a/faststream/opentelemetry/baggage.py b/faststream/opentelemetry/baggage.py index 214da61e4b..b29f24e1bc 100644 --- a/faststream/opentelemetry/baggage.py +++ b/faststream/opentelemetry/baggage.py @@ -62,8 +62,7 @@ def to_headers(self, headers: Optional["AnyDict"] = None) -> "AnyDict": def from_msg(cls, msg: "StreamMessage[Any]") -> Self: """Create a Baggage instance from a StreamMessage.""" if len(msg.batch_headers) <= 1: - payload = baggage.get_all(_BAGGAGE_PROPAGATOR.extract(msg.headers)) - return cls(cast("AnyDict", payload)) + return cls.from_headers(msg.headers) cumulative_baggage: AnyDict = {} batch_baggage: list[AnyDict] = [] diff --git a/faststream/rabbit/subscriber/factory.py b/faststream/rabbit/subscriber/factory.py index 823844aeae..8a4475ec58 100644 --- a/faststream/rabbit/subscriber/factory.py +++ b/faststream/rabbit/subscriber/factory.py @@ -29,6 +29,8 @@ def create_subscriber( description_: Optional[str], include_in_schema: bool, ) -> SpecificationSubscriber: + _validate_input_for_misconfigure() + if ack_policy is EMPTY: ack_policy = AckPolicy.REJECT_ON_ERROR @@ -44,3 +46,7 @@ def create_subscriber( description_=description_, include_in_schema=include_in_schema, ) + + +def _validate_input_for_misconfigure() -> None: + """Nothing to check yet.""" diff --git a/faststream/redis/message.py b/faststream/redis/message.py index bb4260703e..b4b0d443d4 100644 --- a/faststream/redis/message.py +++ b/faststream/redis/message.py @@ -61,20 +61,20 @@ class RedisMessage(BrokerStreamMessage[PubSubMessage]): pass -class ListMessage(TypedDict): +class _ListMessage(TypedDict): """A class to represent an Abstract List message.""" channel: str -class DefaultListMessage(ListMessage): +class DefaultListMessage(_ListMessage): """A class to represent a single List message.""" type: Literal["list"] data: bytes -class BatchListMessage(ListMessage): +class BatchListMessage(_ListMessage): """A class to represent a List messages batch.""" type: Literal["blist"] @@ -95,22 +95,22 @@ class RedisBatchListMessage(BrokerStreamMessage[BatchListMessage]): bDATA_KEY = DATA_KEY.encode() # noqa: N816 -class StreamMessage(TypedDict): +class _StreamMessage(TypedDict): channel: str message_ids: list[bytes] -class DefaultStreamMessage(StreamMessage): +class DefaultStreamMessage(_StreamMessage): type: Literal["stream"] data: dict[bytes, bytes] -class BatchStreamMessage(StreamMessage): +class BatchStreamMessage(_StreamMessage): type: Literal["bstream"] data: list[dict[bytes, bytes]] -_StreamMsgType = TypeVar("_StreamMsgType", bound=StreamMessage) +_StreamMsgType = TypeVar("_StreamMsgType", bound=_StreamMessage) class _RedisStreamMessageMixin(BrokerStreamMessage[_StreamMsgType]): diff --git a/faststream/redis/opentelemetry/provider.py b/faststream/redis/opentelemetry/provider.py index 852cd8ca5f..d818864973 100644 --- a/faststream/redis/opentelemetry/provider.py +++ b/faststream/redis/opentelemetry/provider.py @@ -1,4 +1,3 @@ -from collections.abc import Sized from typing import TYPE_CHECKING, cast from opentelemetry.semconv.trace import SpanAttributes @@ -32,7 +31,7 @@ def get_consume_attrs_from_message( if cast(str, msg.raw_message.get("type", "")).startswith("b"): attrs[SpanAttributes.MESSAGING_BATCH_MESSAGE_COUNT] = len( - cast(Sized, msg._decoded_body), + msg.raw_message["data"] ) return attrs diff --git a/faststream/redis/prometheus/provider.py b/faststream/redis/prometheus/provider.py index d34227a15e..533905e6a8 100644 --- a/faststream/redis/prometheus/provider.py +++ b/faststream/redis/prometheus/provider.py @@ -1,5 +1,4 @@ -from collections.abc import Sized -from typing import TYPE_CHECKING, Optional, Union, cast +from typing import TYPE_CHECKING, Optional, Union from faststream.prometheus import ( ConsumeAttrs, @@ -45,7 +44,7 @@ def get_consume_attrs_from_message( return { "destination_name": _get_destination(msg.raw_message), "message_size": len(msg.body), - "messages_count": len(cast(Sized, msg._decoded_body)), + "messages_count": len(msg.raw_message["data"]), } diff --git a/tests/brokers/base/fastapi.py b/tests/brokers/base/fastapi.py index d9b4582742..602a040840 100644 --- a/tests/brokers/base/fastapi.py +++ b/tests/brokers/base/fastapi.py @@ -575,8 +575,7 @@ async def hello_router2(dep: None = Depends(dep1)) -> str: mock.assert_called_once() assert not mock.not_call.called - @pytest.mark.xfail(reason="https://github.com/airtai/faststream/issues/1742") - async def test_nested_router(self, mock: Mock, queue: str) -> None: + async def test_nested_router(self, queue: str) -> None: router = self.router_class() router2 = self.router_class() @@ -600,7 +599,4 @@ async def hello_router2() -> str: queue, timeout=0.5, ) - assert await r.decode() == "hi", r - - mock.assert_called_once() - assert not mock.not_call.called + assert r.body == b"hi" diff --git a/tests/brokers/confluent/test_requests.py b/tests/brokers/confluent/test_requests.py index 190cff5df6..a0343ced57 100644 --- a/tests/brokers/confluent/test_requests.py +++ b/tests/brokers/confluent/test_requests.py @@ -14,7 +14,7 @@ async def on_receive(self) -> None: self.msg._raw_msg *= 2 async def consume_scope(self, call_next, msg): - msg._decoded_body *= 2 + msg.body *= 2 return await call_next(msg) diff --git a/tests/brokers/kafka/test_requests.py b/tests/brokers/kafka/test_requests.py index 41a1687b09..f84ba2a5db 100644 --- a/tests/brokers/kafka/test_requests.py +++ b/tests/brokers/kafka/test_requests.py @@ -12,7 +12,7 @@ async def on_receive(self) -> None: self.msg.value *= 2 async def consume_scope(self, call_next, msg): - msg._decoded_body *= 2 + msg.body *= 2 return await call_next(msg) diff --git a/tests/brokers/nats/test_consume.py b/tests/brokers/nats/test_consume.py index 8a6cd3917e..82ff607e4a 100644 --- a/tests/brokers/nats/test_consume.py +++ b/tests/brokers/nats/test_consume.py @@ -178,13 +178,12 @@ async def handler(msg: NatsMessage) -> None: async def test_core_consume_no_ack( self, queue: str, - stream: JStream, ) -> None: event = asyncio.Event() consume_broker = self.get_broker(apply_types=True) - @consume_broker.subscriber(queue, ack_policy=AckPolicy.DO_NOTHING) + @consume_broker.subscriber(queue) async def handler(msg: NatsMessage) -> None: event.set() @@ -293,12 +292,15 @@ async def handler(msg: NatsMessage) -> None: async def test_consume_no_ack( self, queue: str, + stream: str, ) -> None: event = asyncio.Event() consume_broker = self.get_broker(apply_types=True) - @consume_broker.subscriber(queue, ack_policy=AckPolicy.DO_NOTHING) + @consume_broker.subscriber( + queue, stream=stream, ack_policy=AckPolicy.DO_NOTHING + ) async def handler(msg: NatsMessage) -> None: event.set() diff --git a/tests/brokers/nats/test_requests.py b/tests/brokers/nats/test_requests.py index af52ca02da..579f13113d 100644 --- a/tests/brokers/nats/test_requests.py +++ b/tests/brokers/nats/test_requests.py @@ -12,7 +12,7 @@ async def on_receive(self) -> None: self.msg.data *= 2 async def consume_scope(self, call_next, msg): - msg._decoded_body *= 2 + msg.body *= 2 return await call_next(msg) diff --git a/tests/brokers/rabbit/test_requests.py b/tests/brokers/rabbit/test_requests.py index 2d5226a99f..fd5fb93ebf 100644 --- a/tests/brokers/rabbit/test_requests.py +++ b/tests/brokers/rabbit/test_requests.py @@ -13,7 +13,7 @@ async def on_receive(self) -> None: self.msg.body *= 2 async def consume_scope(self, call_next, msg): - msg._decoded_body *= 2 + msg.body *= 2 return await call_next(msg) diff --git a/tests/brokers/redis/test_requests.py b/tests/brokers/redis/test_requests.py index b9d2e3f244..f1d4fc3c0f 100644 --- a/tests/brokers/redis/test_requests.py +++ b/tests/brokers/redis/test_requests.py @@ -14,7 +14,7 @@ async def on_receive(self) -> None: self.msg["data"] = json.dumps(data) async def consume_scope(self, call_next, msg): - msg._decoded_body *= 2 + msg.body *= 2 return await call_next(msg) diff --git a/tests/prometheus/redis/test_provider.py b/tests/prometheus/redis/test_provider.py index 469f5237b8..c1b593b545 100644 --- a/tests/prometheus/redis/test_provider.py +++ b/tests/prometheus/redis/test_provider.py @@ -3,6 +3,13 @@ import pytest from faststream.prometheus import MetricsSettingsProvider +from faststream.redis.message import ( + BatchListMessage, + BatchStreamMessage, + DefaultListMessage, + DefaultStreamMessage, + PubSubMessage, +) from faststream.redis.prometheus.provider import ( BatchRedisMetricsSettingsProvider, RedisMetricsSettingsProvider, @@ -47,8 +54,8 @@ def test_get_consume_attrs_from_message(self, queue: str, destination: str) -> N "message_size": len(body), "messages_count": 1, } - raw_message = {} + raw_message = {"data": body} if destination: raw_message[destination] = queue @@ -79,18 +86,21 @@ def get_provider() -> MetricsSettingsProvider: def test_get_consume_attrs_from_message(self, queue: str, destination: str) -> None: decoded_body = ["Hi ", "again, ", "FastStream!"] body = str(decoded_body).encode() + expected_attrs = { "destination_name": queue if destination else "", "message_size": len(body), "messages_count": len(decoded_body), } - raw_message = {} + + raw_message = {"data": decoded_body} if destination: raw_message[destination] = queue message = SimpleNamespace( - body=body, _decoded_body=decoded_body, raw_message=raw_message + body=body, + raw_message=raw_message, ) provider = self.get_provider() @@ -103,19 +113,44 @@ def test_get_consume_attrs_from_message(self, queue: str, destination: str) -> N ("msg", "expected_provider"), ( pytest.param( - {"type": "blist"}, - BatchRedisMetricsSettingsProvider(), - id="batch message", + PubSubMessage( + type="message", + channel="test-channel", + data=b"", + pattern=None, + ), + RedisMetricsSettingsProvider(), + id="PubSub message", ), pytest.param( - {"type": "not_blist"}, + DefaultListMessage(type="list", channel="test-list", data=b""), RedisMetricsSettingsProvider(), - id="single message", + id="Single List message", ), pytest.param( - None, + BatchListMessage(type="blist", channel="test-list", data=[b"", b""]), + BatchRedisMetricsSettingsProvider(), + id="Batch List message", + ), + pytest.param( + DefaultStreamMessage( + type="stream", + channel="test-stream", + data=b"", + message_ids=[], + ), RedisMetricsSettingsProvider(), - id="None message", + id="Single Stream message", + ), + pytest.param( + BatchStreamMessage( + type="bstream", + channel="test-stream", + data=[{b"": b""}, {b"": b""}], + message_ids=[], + ), + BatchRedisMetricsSettingsProvider(), + id="Batch Stream message", ), ), ) From 9cf95c77e96d6c204e4bb7f0005000045bbe3ad5 Mon Sep 17 00:00:00 2001 From: Ruslan Alimov Date: Thu, 14 Nov 2024 09:56:29 +0300 Subject: [PATCH 192/245] feat: added ack_first --- faststream/confluent/broker/registrator.py | 4 ++++ faststream/confluent/fastapi/fastapi.py | 4 ++++ faststream/confluent/router.py | 4 ++++ faststream/kafka/broker/registrator.py | 4 ++++ faststream/kafka/fastapi/fastapi.py | 4 ++++ faststream/kafka/router.py | 4 ++++ faststream/middlewares/acknowledgement/conf.py | 1 + faststream/middlewares/acknowledgement/middleware.py | 6 ++++++ faststream/nats/subscriber/factory.py | 4 ++++ 9 files changed, 35 insertions(+) diff --git a/faststream/confluent/broker/registrator.py b/faststream/confluent/broker/registrator.py index 3bcc604719..8d250eabc2 100644 --- a/faststream/confluent/broker/registrator.py +++ b/faststream/confluent/broker/registrator.py @@ -1130,6 +1130,10 @@ def subscriber( "SpecificationDefaultSubscriber", "SpecificationBatchSubscriber", ]: + if ack_policy is AckPolicy.ACK_FIRST: + auto_commit = True + ack_policy = AckPolicy.DO_NOTHING + if not auto_commit and not group_id: msg = "You should install `group_id` with manual commit mode" raise SetupError(msg) diff --git a/faststream/confluent/fastapi/fastapi.py b/faststream/confluent/fastapi/fastapi.py index 5bdc96cf6c..5330024443 100644 --- a/faststream/confluent/fastapi/fastapi.py +++ b/faststream/confluent/fastapi/fastapi.py @@ -2150,6 +2150,10 @@ def subscriber( "SpecificationBatchSubscriber", "SpecificationDefaultSubscriber", ]: + if ack_policy is AckPolicy.ACK_FIRST: + auto_commit = True + ack_policy = AckPolicy.DO_NOTHING + subscriber = super().subscriber( *topics, polling_interval=polling_interval, diff --git a/faststream/confluent/router.py b/faststream/confluent/router.py index a1039fc72f..ad0e52ed8c 100644 --- a/faststream/confluent/router.py +++ b/faststream/confluent/router.py @@ -409,6 +409,10 @@ def __init__( Doc("Whetever to include operation in AsyncAPI schema or not."), ] = True, ) -> None: + if ack_policy is AckPolicy.ACK_FIRST: + auto_commit = True + ack_policy = AckPolicy.DO_NOTHING + super().__init__( call, *topics, diff --git a/faststream/kafka/broker/registrator.py b/faststream/kafka/broker/registrator.py index 3523c2bed7..059849d9af 100644 --- a/faststream/kafka/broker/registrator.py +++ b/faststream/kafka/broker/registrator.py @@ -1529,6 +1529,10 @@ def subscriber( "SpecificationDefaultSubscriber", "SpecificationBatchSubscriber", ]: + if ack_policy is AckPolicy.ACK_FIRST: + auto_commit = True + ack_policy = AckPolicy.DO_NOTHING + subscriber = super().subscriber( create_subscriber( *topics, diff --git a/faststream/kafka/fastapi/fastapi.py b/faststream/kafka/fastapi/fastapi.py index 5601c05f6c..dc0689c282 100644 --- a/faststream/kafka/fastapi/fastapi.py +++ b/faststream/kafka/fastapi/fastapi.py @@ -2559,6 +2559,10 @@ def subscriber( "SpecificationBatchSubscriber", "SpecificationDefaultSubscriber", ]: + if ack_policy is AckPolicy.ACK_FIRST: + auto_commit = True + ack_policy = AckPolicy.DO_NOTHING + subscriber = super().subscriber( *topics, group_id=group_id, diff --git a/faststream/kafka/router.py b/faststream/kafka/router.py index b4fecbe3e0..a21278efc7 100644 --- a/faststream/kafka/router.py +++ b/faststream/kafka/router.py @@ -512,6 +512,10 @@ def __init__( Doc("Whetever to include operation in AsyncAPI schema or not."), ] = True, ) -> None: + if ack_policy is AckPolicy.ACK_FIRST: + auto_commit = True + ack_policy = AckPolicy.DO_NOTHING + super().__init__( call, *topics, diff --git a/faststream/middlewares/acknowledgement/conf.py b/faststream/middlewares/acknowledgement/conf.py index 60b910264d..53910c8086 100644 --- a/faststream/middlewares/acknowledgement/conf.py +++ b/faststream/middlewares/acknowledgement/conf.py @@ -2,6 +2,7 @@ class AckPolicy(str, Enum): + ACK_FIRST = "ack_first" ACK = "ack" REJECT_ON_ERROR = "reject_on_error" NACK_ON_ERROR = "nack_on_error" diff --git a/faststream/middlewares/acknowledgement/middleware.py b/faststream/middlewares/acknowledgement/middleware.py index dd04e9c22e..e2d30f5c0c 100644 --- a/faststream/middlewares/acknowledgement/middleware.py +++ b/faststream/middlewares/acknowledgement/middleware.py @@ -65,6 +65,9 @@ async def consume_scope( msg: "StreamMessage[Any]", ) -> Any: self.message = msg + if self.ack_policy is AckPolicy.ACK_FIRST: + await self.__ack() + return await call_next(msg) async def __aexit__( @@ -73,6 +76,9 @@ async def __aexit__( exc_val: Optional[BaseException] = None, exc_tb: Optional["TracebackType"] = None, ) -> Optional[bool]: + if self.ack_policy is AckPolicy.ACK_FIRST: + return False + if not exc_type: await self.__ack() diff --git a/faststream/nats/subscriber/factory.py b/faststream/nats/subscriber/factory.py index c17e6e808d..ac149a1f68 100644 --- a/faststream/nats/subscriber/factory.py +++ b/faststream/nats/subscriber/factory.py @@ -133,6 +133,10 @@ def create_subscriber( else: # JS Push Subscriber + if ack_policy is AckPolicy.ACK_FIRST: + ack_first = True + ack_policy = AckPolicy.DO_NOTHING + extra_options.update( { "ordered_consumer": ordered_consumer, From d64f9f5ea56febe12704c9aed01a978fdf0a3571 Mon Sep 17 00:00:00 2001 From: Rusich90 Date: Thu, 14 Nov 2024 07:00:46 +0000 Subject: [PATCH 193/245] docs: generate API References --- docs/docs/SUMMARY.md | 32 +++++++++++++++++-- .../usecases/BatchPullStreamSubscriber.md | 11 +++++++ .../usecases/ConcurrentCoreSubscriber.md | 11 +++++++ .../ConcurrentPullStreamSubscriber.md | 11 +++++++ .../ConcurrentPushStreamSubscriber.md | 11 +++++++ .../subscriber/usecases/CoreSubscriber.md} | 2 +- .../usecases/KeyValueWatchSubscriber.md | 11 +++++++ .../subscriber/usecases/LogicSubscriber.md} | 2 +- .../usecases/ObjStoreWatchSubscriber.md | 11 +++++++ .../usecases/PullStreamSubscriber.md | 11 +++++++ .../usecases/PushStreamSubscription.md | 11 +++++++ .../usecases/basic/DefaultSubscriber.md | 11 +++++++ .../usecases/basic/LogicSubscriber.md | 11 +++++++ .../ConcurrentCoreSubscriber.md | 11 +++++++ .../core_subscriber/CoreSubscriber.md | 11 +++++++ .../KeyValueWatchSubscriber.md | 11 +++++++ .../ObjStoreWatchSubscriber.md | 11 +++++++ .../usecases/stream_basic/StreamSubscriber.md | 11 +++++++ .../BatchPullStreamSubscriber.md | 11 +++++++ .../ConcurrentPullStreamSubscriber.md | 11 +++++++ .../PullStreamSubscriber.md | 11 +++++++ .../ConcurrentPushStreamSubscriber.md | 11 +++++++ .../PushStreamSubscription.md | 11 +++++++ 23 files changed, 252 insertions(+), 4 deletions(-) create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/BatchPullStreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentCoreSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentPullStreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentPushStreamSubscriber.md rename docs/docs/en/api/faststream/{redis/message/ListMessage.md => nats/subscriber/usecases/CoreSubscriber.md} (66%) create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/KeyValueWatchSubscriber.md rename docs/docs/en/api/faststream/{redis/message/StreamMessage.md => nats/subscriber/usecases/LogicSubscriber.md} (66%) create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/ObjStoreWatchSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/PullStreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/PushStreamSubscription.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/basic/DefaultSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/basic/LogicSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/core_subscriber/ConcurrentCoreSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/core_subscriber/CoreSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/key_value_subscriber/KeyValueWatchSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/object_storage_subscriber/ObjStoreWatchSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/stream_basic/StreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/BatchPullStreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/ConcurrentPullStreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/PullStreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/stream_push_subscriber/ConcurrentPushStreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/stream_push_subscriber/PushStreamSubscription.md diff --git a/docs/docs/SUMMARY.md b/docs/docs/SUMMARY.md index d8cc349c03..cf444fbe1a 100644 --- a/docs/docs/SUMMARY.md +++ b/docs/docs/SUMMARY.md @@ -653,6 +653,36 @@ search: - [ObjStoreWatchSubscriber](api/faststream/nats/subscriber/usecase/ObjStoreWatchSubscriber.md) - [PullStreamSubscriber](api/faststream/nats/subscriber/usecase/PullStreamSubscriber.md) - [PushStreamSubscription](api/faststream/nats/subscriber/usecase/PushStreamSubscription.md) + - usecases + - [BatchPullStreamSubscriber](api/faststream/nats/subscriber/usecases/BatchPullStreamSubscriber.md) + - [ConcurrentCoreSubscriber](api/faststream/nats/subscriber/usecases/ConcurrentCoreSubscriber.md) + - [ConcurrentPullStreamSubscriber](api/faststream/nats/subscriber/usecases/ConcurrentPullStreamSubscriber.md) + - [ConcurrentPushStreamSubscriber](api/faststream/nats/subscriber/usecases/ConcurrentPushStreamSubscriber.md) + - [CoreSubscriber](api/faststream/nats/subscriber/usecases/CoreSubscriber.md) + - [KeyValueWatchSubscriber](api/faststream/nats/subscriber/usecases/KeyValueWatchSubscriber.md) + - [LogicSubscriber](api/faststream/nats/subscriber/usecases/LogicSubscriber.md) + - [ObjStoreWatchSubscriber](api/faststream/nats/subscriber/usecases/ObjStoreWatchSubscriber.md) + - [PullStreamSubscriber](api/faststream/nats/subscriber/usecases/PullStreamSubscriber.md) + - [PushStreamSubscription](api/faststream/nats/subscriber/usecases/PushStreamSubscription.md) + - basic + - [DefaultSubscriber](api/faststream/nats/subscriber/usecases/basic/DefaultSubscriber.md) + - [LogicSubscriber](api/faststream/nats/subscriber/usecases/basic/LogicSubscriber.md) + - core_subscriber + - [ConcurrentCoreSubscriber](api/faststream/nats/subscriber/usecases/core_subscriber/ConcurrentCoreSubscriber.md) + - [CoreSubscriber](api/faststream/nats/subscriber/usecases/core_subscriber/CoreSubscriber.md) + - key_value_subscriber + - [KeyValueWatchSubscriber](api/faststream/nats/subscriber/usecases/key_value_subscriber/KeyValueWatchSubscriber.md) + - object_storage_subscriber + - [ObjStoreWatchSubscriber](api/faststream/nats/subscriber/usecases/object_storage_subscriber/ObjStoreWatchSubscriber.md) + - stream_basic + - [StreamSubscriber](api/faststream/nats/subscriber/usecases/stream_basic/StreamSubscriber.md) + - stream_pull_subscriber + - [BatchPullStreamSubscriber](api/faststream/nats/subscriber/usecases/stream_pull_subscriber/BatchPullStreamSubscriber.md) + - [ConcurrentPullStreamSubscriber](api/faststream/nats/subscriber/usecases/stream_pull_subscriber/ConcurrentPullStreamSubscriber.md) + - [PullStreamSubscriber](api/faststream/nats/subscriber/usecases/stream_pull_subscriber/PullStreamSubscriber.md) + - stream_push_subscriber + - [ConcurrentPushStreamSubscriber](api/faststream/nats/subscriber/usecases/stream_push_subscriber/ConcurrentPushStreamSubscriber.md) + - [PushStreamSubscription](api/faststream/nats/subscriber/usecases/stream_push_subscriber/PushStreamSubscription.md) - testing - [FakeProducer](api/faststream/nats/testing/FakeProducer.md) - [PatchedMessage](api/faststream/nats/testing/PatchedMessage.md) @@ -834,14 +864,12 @@ search: - [BatchStreamMessage](api/faststream/redis/message/BatchStreamMessage.md) - [DefaultListMessage](api/faststream/redis/message/DefaultListMessage.md) - [DefaultStreamMessage](api/faststream/redis/message/DefaultStreamMessage.md) - - [ListMessage](api/faststream/redis/message/ListMessage.md) - [PubSubMessage](api/faststream/redis/message/PubSubMessage.md) - [RedisBatchListMessage](api/faststream/redis/message/RedisBatchListMessage.md) - [RedisBatchStreamMessage](api/faststream/redis/message/RedisBatchStreamMessage.md) - [RedisListMessage](api/faststream/redis/message/RedisListMessage.md) - [RedisMessage](api/faststream/redis/message/RedisMessage.md) - [RedisStreamMessage](api/faststream/redis/message/RedisStreamMessage.md) - - [StreamMessage](api/faststream/redis/message/StreamMessage.md) - [UnifyRedisDict](api/faststream/redis/message/UnifyRedisDict.md) - [UnifyRedisMessage](api/faststream/redis/message/UnifyRedisMessage.md) - opentelemetry diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/BatchPullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/BatchPullStreamSubscriber.md new file mode 100644 index 0000000000..667ff42587 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/BatchPullStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.BatchPullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentCoreSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentCoreSubscriber.md new file mode 100644 index 0000000000..bbd0895a8c --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentCoreSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.ConcurrentCoreSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentPullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentPullStreamSubscriber.md new file mode 100644 index 0000000000..7bb13db682 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentPullStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.ConcurrentPullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentPushStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentPushStreamSubscriber.md new file mode 100644 index 0000000000..c694d41369 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentPushStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.ConcurrentPushStreamSubscriber diff --git a/docs/docs/en/api/faststream/redis/message/ListMessage.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/CoreSubscriber.md similarity index 66% rename from docs/docs/en/api/faststream/redis/message/ListMessage.md rename to docs/docs/en/api/faststream/nats/subscriber/usecases/CoreSubscriber.md index 5e81a9f727..e35ebd3f9d 100644 --- a/docs/docs/en/api/faststream/redis/message/ListMessage.md +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/CoreSubscriber.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.redis.message.ListMessage +::: faststream.nats.subscriber.usecases.CoreSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/KeyValueWatchSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/KeyValueWatchSubscriber.md new file mode 100644 index 0000000000..507c7a33c4 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/KeyValueWatchSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.KeyValueWatchSubscriber diff --git a/docs/docs/en/api/faststream/redis/message/StreamMessage.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/LogicSubscriber.md similarity index 66% rename from docs/docs/en/api/faststream/redis/message/StreamMessage.md rename to docs/docs/en/api/faststream/nats/subscriber/usecases/LogicSubscriber.md index f4e6a5d57e..e97348563d 100644 --- a/docs/docs/en/api/faststream/redis/message/StreamMessage.md +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/LogicSubscriber.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.redis.message.StreamMessage +::: faststream.nats.subscriber.usecases.LogicSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/ObjStoreWatchSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/ObjStoreWatchSubscriber.md new file mode 100644 index 0000000000..25d1434968 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/ObjStoreWatchSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.ObjStoreWatchSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/PullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/PullStreamSubscriber.md new file mode 100644 index 0000000000..ddc3731c6e --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/PullStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.PullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/PushStreamSubscription.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/PushStreamSubscription.md new file mode 100644 index 0000000000..9ea5735afb --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/PushStreamSubscription.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.PushStreamSubscription diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/basic/DefaultSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/basic/DefaultSubscriber.md new file mode 100644 index 0000000000..f0bd5e52aa --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/basic/DefaultSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.basic.DefaultSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/basic/LogicSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/basic/LogicSubscriber.md new file mode 100644 index 0000000000..9dfc93aa9b --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/basic/LogicSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.basic.LogicSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/core_subscriber/ConcurrentCoreSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/core_subscriber/ConcurrentCoreSubscriber.md new file mode 100644 index 0000000000..a684452aa1 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/core_subscriber/ConcurrentCoreSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.core_subscriber.ConcurrentCoreSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/core_subscriber/CoreSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/core_subscriber/CoreSubscriber.md new file mode 100644 index 0000000000..cc1905f58e --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/core_subscriber/CoreSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.core_subscriber.CoreSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/key_value_subscriber/KeyValueWatchSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/key_value_subscriber/KeyValueWatchSubscriber.md new file mode 100644 index 0000000000..26e1b670d0 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/key_value_subscriber/KeyValueWatchSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.key_value_subscriber.KeyValueWatchSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/object_storage_subscriber/ObjStoreWatchSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/object_storage_subscriber/ObjStoreWatchSubscriber.md new file mode 100644 index 0000000000..b1722e57ec --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/object_storage_subscriber/ObjStoreWatchSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.object_storage_subscriber.ObjStoreWatchSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_basic/StreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_basic/StreamSubscriber.md new file mode 100644 index 0000000000..b08fd2abff --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_basic/StreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.stream_basic.StreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/BatchPullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/BatchPullStreamSubscriber.md new file mode 100644 index 0000000000..9e4973cf67 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/BatchPullStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.stream_pull_subscriber.BatchPullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/ConcurrentPullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/ConcurrentPullStreamSubscriber.md new file mode 100644 index 0000000000..6c31f93a20 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/ConcurrentPullStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.stream_pull_subscriber.ConcurrentPullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/PullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/PullStreamSubscriber.md new file mode 100644 index 0000000000..35e7de26de --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/PullStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.stream_pull_subscriber.PullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_push_subscriber/ConcurrentPushStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_push_subscriber/ConcurrentPushStreamSubscriber.md new file mode 100644 index 0000000000..78cffa0a9f --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_push_subscriber/ConcurrentPushStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.stream_push_subscriber.ConcurrentPushStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_push_subscriber/PushStreamSubscription.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_push_subscriber/PushStreamSubscription.md new file mode 100644 index 0000000000..eee1f7aeb7 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_push_subscriber/PushStreamSubscription.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.stream_push_subscriber.PushStreamSubscription From ad8d6b41015b4b49181890eb50faa252559c5ec5 Mon Sep 17 00:00:00 2001 From: Ruslan Alimov Date: Tue, 19 Nov 2024 10:14:19 +0300 Subject: [PATCH 194/245] feat: ack_first added deprecated and docstrings to Ack_Policy --- faststream/confluent/broker/registrator.py | 52 ++++++++++++++++--- faststream/confluent/fastapi/fastapi.py | 24 +++++++++ faststream/confluent/router.py | 8 ++- faststream/kafka/broker/registrator.py | 26 +++++++++- faststream/kafka/fastapi/fastapi.py | 24 +++++++++ faststream/kafka/router.py | 8 ++- .../middlewares/acknowledgement/conf.py | 9 ++++ 7 files changed, 142 insertions(+), 9 deletions(-) diff --git a/faststream/confluent/broker/registrator.py b/faststream/confluent/broker/registrator.py index 8d250eabc2..dc74cdd627 100644 --- a/faststream/confluent/broker/registrator.py +++ b/faststream/confluent/broker/registrator.py @@ -10,7 +10,7 @@ overload, ) -from typing_extensions import Doc, override +from typing_extensions import Doc, deprecated, override from faststream._internal.broker.abc_broker import ABCBroker from faststream._internal.constants import EMPTY @@ -161,7 +161,13 @@ def subscriber( periodically committed in the background. """, ), - ] = True, + deprecated( + """ + This option is deprecated and will be removed in 0.7.0 release. + Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. + """, + ), + ] = EMPTY, auto_commit_interval_ms: Annotated[ int, Doc( @@ -428,7 +434,13 @@ def subscriber( periodically committed in the background. """, ), - ] = True, + deprecated( + """ + This option is deprecated and will be removed in 0.7.0 release. + Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. + """, + ), + ] = EMPTY, auto_commit_interval_ms: Annotated[ int, Doc( @@ -695,7 +707,13 @@ def subscriber( periodically committed in the background. """, ), - ] = True, + deprecated( + """ + This option is deprecated and will be removed in 0.7.0 release. + Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. + """, + ), + ] = EMPTY, auto_commit_interval_ms: Annotated[ int, Doc( @@ -965,7 +983,13 @@ def subscriber( periodically committed in the background. """, ), - ] = True, + deprecated( + """ + This option is deprecated and will be removed in 0.7.0 release. + Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. + """, + ), + ] = EMPTY, auto_commit_interval_ms: Annotated[ int, Doc( @@ -1130,7 +1154,23 @@ def subscriber( "SpecificationDefaultSubscriber", "SpecificationBatchSubscriber", ]: - if ack_policy is AckPolicy.ACK_FIRST: + if ( + auto_commit is not EMPTY and auto_commit + and ack_policy is not EMPTY and ack_policy is not ack_policy.ACK_FIRST + ) or ( + auto_commit is not EMPTY and not auto_commit + and ack_policy is ack_policy.ACK_FIRST + ): + msg = "You can't use conflict settings ('auto_commit' and 'ack_policy')" + raise SetupError(msg) + + if auto_commit is not EMPTY and auto_commit and ack_policy is EMPTY: + ack_policy = AckPolicy.DO_NOTHING + + elif auto_commit is not EMPTY and not auto_commit and ack_policy is EMPTY: + ack_policy = AckPolicy.REJECT_ON_ERROR + + elif ack_policy is AckPolicy.ACK_FIRST: auto_commit = True ack_policy = AckPolicy.DO_NOTHING diff --git a/faststream/confluent/fastapi/fastapi.py b/faststream/confluent/fastapi/fastapi.py index 5330024443..257cd80f8e 100644 --- a/faststream/confluent/fastapi/fastapi.py +++ b/faststream/confluent/fastapi/fastapi.py @@ -699,6 +699,12 @@ def subscriber( periodically committed in the background. """, ), + deprecated( + """ + This option is deprecated and will be removed in 0.7.0 release. + Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. + """, + ), ] = True, auto_commit_interval_ms: Annotated[ int, @@ -1089,6 +1095,12 @@ def subscriber( periodically committed in the background. """, ), + deprecated( + """ + This option is deprecated and will be removed in 0.7.0 release. + Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. + """, + ), ] = True, auto_commit_interval_ms: Annotated[ int, @@ -1469,6 +1481,12 @@ def subscriber( periodically committed in the background. """, ), + deprecated( + """ + This option is deprecated and will be removed in 0.7.0 release. + Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. + """, + ), ] = True, auto_commit_interval_ms: Annotated[ int, @@ -1862,6 +1880,12 @@ def subscriber( periodically committed in the background. """, ), + deprecated( + """ + This option is deprecated and will be removed in 0.7.0 release. + Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. + """, + ), ] = True, auto_commit_interval_ms: Annotated[ int, diff --git a/faststream/confluent/router.py b/faststream/confluent/router.py index ad0e52ed8c..3e4675c351 100644 --- a/faststream/confluent/router.py +++ b/faststream/confluent/router.py @@ -9,7 +9,7 @@ Union, ) -from typing_extensions import Doc +from typing_extensions import Doc, deprecated from faststream._internal.broker.router import ( ArgsContainer, @@ -247,6 +247,12 @@ def __init__( periodically committed in the background. """, ), + deprecated( + """ + This option is deprecated and will be removed in 0.7.0 release. + Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. + """, + ), ] = True, auto_commit_interval_ms: Annotated[ int, diff --git a/faststream/kafka/broker/registrator.py b/faststream/kafka/broker/registrator.py index 059849d9af..898ebc646d 100644 --- a/faststream/kafka/broker/registrator.py +++ b/faststream/kafka/broker/registrator.py @@ -13,7 +13,7 @@ from aiokafka import ConsumerRecord from aiokafka.coordinator.assignors.roundrobin import RoundRobinPartitionAssignor -from typing_extensions import Doc, override +from typing_extensions import Doc, deprecated, override from faststream._internal.broker.abc_broker import ABCBroker from faststream._internal.constants import EMPTY @@ -167,6 +167,12 @@ def subscriber( periodically committed in the background. """, ), + deprecated( + """ + This option is deprecated and will be removed in 0.7.0 release. + Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. + """, + ), ] = True, auto_commit_interval_ms: Annotated[ int, @@ -533,6 +539,12 @@ def subscriber( periodically committed in the background. """, ), + deprecated( + """ + This option is deprecated and will be removed in 0.7.0 release. + Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. + """, + ), ] = True, auto_commit_interval_ms: Annotated[ int, @@ -899,6 +911,12 @@ def subscriber( periodically committed in the background. """, ), + deprecated( + """ + This option is deprecated and will be removed in 0.7.0 release. + Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. + """, + ), ] = True, auto_commit_interval_ms: Annotated[ int, @@ -1268,6 +1286,12 @@ def subscriber( periodically committed in the background. """, ), + deprecated( + """ + This option is deprecated and will be removed in 0.7.0 release. + Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. + """, + ), ] = True, auto_commit_interval_ms: Annotated[ int, diff --git a/faststream/kafka/fastapi/fastapi.py b/faststream/kafka/fastapi/fastapi.py index dc0689c282..5ab2a4f43d 100644 --- a/faststream/kafka/fastapi/fastapi.py +++ b/faststream/kafka/fastapi/fastapi.py @@ -710,6 +710,12 @@ def subscriber( periodically committed in the background. """, ), + deprecated( + """ + This option is deprecated and will be removed in 0.7.0 release. + Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. + """, + ), ] = True, auto_commit_interval_ms: Annotated[ int, @@ -1196,6 +1202,12 @@ def subscriber( periodically committed in the background. """, ), + deprecated( + """ + This option is deprecated and will be removed in 0.7.0 release. + Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. + """, + ), ] = True, auto_commit_interval_ms: Annotated[ int, @@ -1682,6 +1694,12 @@ def subscriber( periodically committed in the background. """, ), + deprecated( + """ + This option is deprecated and will be removed in 0.7.0 release. + Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. + """, + ), ] = True, auto_commit_interval_ms: Annotated[ int, @@ -2171,6 +2189,12 @@ def subscriber( periodically committed in the background. """, ), + deprecated( + """ + This option is deprecated and will be removed in 0.7.0 release. + Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. + """, + ), ] = True, auto_commit_interval_ms: Annotated[ int, diff --git a/faststream/kafka/router.py b/faststream/kafka/router.py index a21278efc7..08ca6c12ee 100644 --- a/faststream/kafka/router.py +++ b/faststream/kafka/router.py @@ -10,7 +10,7 @@ ) from aiokafka.coordinator.assignors.roundrobin import RoundRobinPartitionAssignor -from typing_extensions import Doc +from typing_extensions import Doc, deprecated from faststream._internal.broker.router import ( ArgsContainer, @@ -255,6 +255,12 @@ def __init__( periodically committed in the background. """, ), + deprecated( + """ + This option is deprecated and will be removed in 0.7.0 release. + Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. + """, + ), ] = True, auto_commit_interval_ms: Annotated[ int, diff --git a/faststream/middlewares/acknowledgement/conf.py b/faststream/middlewares/acknowledgement/conf.py index 53910c8086..b8ad83f802 100644 --- a/faststream/middlewares/acknowledgement/conf.py +++ b/faststream/middlewares/acknowledgement/conf.py @@ -3,7 +3,16 @@ class AckPolicy(str, Enum): ACK_FIRST = "ack_first" + """Ack message on consume""" + ACK = "ack" + """Ack message after all process""" + REJECT_ON_ERROR = "reject_on_error" + """Reject message on unhandled exceptions""" + NACK_ON_ERROR = "nack_on_error" + """Nack message on unhandled exceptions""" + DO_NOTHING = "do_nothing" + """Not create AcknowledgementMiddleware""" From 36da6ac335bc614511751328c5f046d4b2b46724 Mon Sep 17 00:00:00 2001 From: Rusich90 Date: Tue, 19 Nov 2024 07:18:47 +0000 Subject: [PATCH 195/245] docs: generate API References --- docs/docs/en/release.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/docs/en/release.md b/docs/docs/en/release.md index 7a8dc7cf4a..efe5d81bf7 100644 --- a/docs/docs/en/release.md +++ b/docs/docs/en/release.md @@ -12,6 +12,21 @@ hide: --- # Release Notes +## 0.5.30 + +### What's Changed +* Introducing FastStream Guru on Gurubase.io by [@kursataktas](https://github.com/kursataktas){.external-link target="_blank"} in [#1903](https://github.com/airtai/faststream/pull/1903){.external-link target="_blank"} +* docs: add gurubase badge to the doc by [@Lancetnik](https://github.com/Lancetnik){.external-link target="_blank"} in [#1905](https://github.com/airtai/faststream/pull/1905){.external-link target="_blank"} +* fix: allow users to pass `nkeys_seed_str` as argument for NATS broker. by [@Drakorgaur](https://github.com/Drakorgaur){.external-link target="_blank"} in [#1908](https://github.com/airtai/faststream/pull/1908){.external-link target="_blank"} +* Add more warning's to nats subscription factory by [@sheldygg](https://github.com/sheldygg){.external-link target="_blank"} in [#1907](https://github.com/airtai/faststream/pull/1907){.external-link target="_blank"} +* fix: correct working with dependencies versions by [@Lancetnik](https://github.com/Lancetnik){.external-link target="_blank"} in [#1918](https://github.com/airtai/faststream/pull/1918){.external-link target="_blank"} + +### New Contributors +* [@kursataktas](https://github.com/kursataktas){.external-link target="_blank"} made their first contribution in [#1903](https://github.com/airtai/faststream/pull/1903){.external-link target="_blank"} +* [@Drakorgaur](https://github.com/Drakorgaur){.external-link target="_blank"} made their first contribution in [#1908](https://github.com/airtai/faststream/pull/1908){.external-link target="_blank"} + +**Full Changelog**: [#0.5.29...0.5.30](https://github.com/airtai/faststream/compare/0.5.29...0.5.30){.external-link target="_blank"} + ## 0.5.29 ### What's Changed From 6c2d155eefcb449fd5b2adfc104fdf42d3e0daa0 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Tue, 19 Nov 2024 18:08:16 +0300 Subject: [PATCH 196/245] docs: fix typo --- docs/docs/en/getting-started/logging.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/docs/en/getting-started/logging.md b/docs/docs/en/getting-started/logging.md index 4c4b9e77b2..c6d56c478a 100644 --- a/docs/docs/en/getting-started/logging.md +++ b/docs/docs/en/getting-started/logging.md @@ -213,9 +213,9 @@ app = FastStream(broker, logger=logger) And the job is done! Now you have a perfectly structured logs using **Structlog**. ```{.shell .no-copy} -TIMESPAMP [info ] FastStream app starting... extra={} -TIMESPAMP [debug ] `Handler` waiting for messages extra={'topic': 'topic', 'group_id': 'group', 'message_id': ''} -TIMESPAMP [debug ] `Handler` waiting for messages extra={'topic': 'topic', 'group_id': 'group2', 'message_id': ''} -TIMESPAMP [info ] FastStream app started successfully! To exit, press CTRL+C extra={'topic': '', 'group_id': '', 'message_id': ''} +TIMESTAMP [info ] FastStream app starting... extra={} +TIMESTAMP [debug ] `Handler` waiting for messages extra={'topic': 'topic', 'group_id': 'group', 'message_id': ''} +TIMESTAMP [debug ] `Handler` waiting for messages extra={'topic': 'topic', 'group_id': 'group2', 'message_id': ''} +TIMESTAMP [info ] FastStream app started successfully! To exit, press CTRL+C extra={'topic': '', 'group_id': '', 'message_id': ''} ``` { data-search-exclude } From 157151bdfdc84215fa2530fd61433e91b17341a4 Mon Sep 17 00:00:00 2001 From: Ruslan Alimov Date: Wed, 20 Nov 2024 09:30:27 +0300 Subject: [PATCH 197/245] feat: ack_first refactored ack_first check --- faststream/confluent/broker/registrator.py | 31 +++------------------- faststream/confluent/fastapi/fastapi.py | 3 --- faststream/confluent/router.py | 3 --- faststream/confluent/subscriber/factory.py | 26 +++++++++++++++--- faststream/kafka/broker/registrator.py | 3 --- faststream/kafka/fastapi/fastapi.py | 3 --- faststream/kafka/router.py | 3 --- faststream/kafka/subscriber/factory.py | 15 ++++++++--- 8 files changed, 38 insertions(+), 49 deletions(-) diff --git a/faststream/confluent/broker/registrator.py b/faststream/confluent/broker/registrator.py index dc74cdd627..c9851d1db4 100644 --- a/faststream/confluent/broker/registrator.py +++ b/faststream/confluent/broker/registrator.py @@ -167,7 +167,7 @@ def subscriber( Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. """, ), - ] = EMPTY, + ] = True, auto_commit_interval_ms: Annotated[ int, Doc( @@ -440,7 +440,7 @@ def subscriber( Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. """, ), - ] = EMPTY, + ] = True, auto_commit_interval_ms: Annotated[ int, Doc( @@ -713,7 +713,7 @@ def subscriber( Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. """, ), - ] = EMPTY, + ] = True, auto_commit_interval_ms: Annotated[ int, Doc( @@ -989,7 +989,7 @@ def subscriber( Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. """, ), - ] = EMPTY, + ] = True, auto_commit_interval_ms: Annotated[ int, Doc( @@ -1154,29 +1154,6 @@ def subscriber( "SpecificationDefaultSubscriber", "SpecificationBatchSubscriber", ]: - if ( - auto_commit is not EMPTY and auto_commit - and ack_policy is not EMPTY and ack_policy is not ack_policy.ACK_FIRST - ) or ( - auto_commit is not EMPTY and not auto_commit - and ack_policy is ack_policy.ACK_FIRST - ): - msg = "You can't use conflict settings ('auto_commit' and 'ack_policy')" - raise SetupError(msg) - - if auto_commit is not EMPTY and auto_commit and ack_policy is EMPTY: - ack_policy = AckPolicy.DO_NOTHING - - elif auto_commit is not EMPTY and not auto_commit and ack_policy is EMPTY: - ack_policy = AckPolicy.REJECT_ON_ERROR - - elif ack_policy is AckPolicy.ACK_FIRST: - auto_commit = True - ack_policy = AckPolicy.DO_NOTHING - - if not auto_commit and not group_id: - msg = "You should install `group_id` with manual commit mode" - raise SetupError(msg) subscriber = super().subscriber( create_subscriber( diff --git a/faststream/confluent/fastapi/fastapi.py b/faststream/confluent/fastapi/fastapi.py index 257cd80f8e..2c7c302365 100644 --- a/faststream/confluent/fastapi/fastapi.py +++ b/faststream/confluent/fastapi/fastapi.py @@ -2174,9 +2174,6 @@ def subscriber( "SpecificationBatchSubscriber", "SpecificationDefaultSubscriber", ]: - if ack_policy is AckPolicy.ACK_FIRST: - auto_commit = True - ack_policy = AckPolicy.DO_NOTHING subscriber = super().subscriber( *topics, diff --git a/faststream/confluent/router.py b/faststream/confluent/router.py index 3e4675c351..52af6078e0 100644 --- a/faststream/confluent/router.py +++ b/faststream/confluent/router.py @@ -415,9 +415,6 @@ def __init__( Doc("Whetever to include operation in AsyncAPI schema or not."), ] = True, ) -> None: - if ack_policy is AckPolicy.ACK_FIRST: - auto_commit = True - ack_policy = AckPolicy.DO_NOTHING super().__init__( call, diff --git a/faststream/confluent/subscriber/factory.py b/faststream/confluent/subscriber/factory.py index b6edea0456..a5e08164b2 100644 --- a/faststream/confluent/subscriber/factory.py +++ b/faststream/confluent/subscriber/factory.py @@ -9,6 +9,7 @@ ) from faststream._internal.constants import EMPTY +from faststream.exceptions import SetupError from faststream.confluent.subscriber.specified import ( SpecificationBatchSubscriber, SpecificationDefaultSubscriber, @@ -123,10 +124,15 @@ def create_subscriber( "SpecificationDefaultSubscriber", "SpecificationBatchSubscriber", ]: - _validate_input_for_misconfigure(ack_policy=ack_policy, is_manual=is_manual) + _validate_input_for_misconfigure( + ack_policy=ack_policy, is_manual=is_manual, group_id=group_id, + ) if ack_policy is EMPTY: - ack_policy = AckPolicy.REJECT_ON_ERROR + if not is_manual: + ack_policy = AckPolicy.DO_NOTHING + else: + ack_policy = AckPolicy.REJECT_ON_ERROR if batch: return SpecificationBatchSubscriber( @@ -166,10 +172,22 @@ def _validate_input_for_misconfigure( *, ack_policy: "AckPolicy", is_manual: bool, + group_id: Optional[str], ) -> None: - if ack_policy is not EMPTY and not is_manual: + if not is_manual and ack_policy is not EMPTY and ack_policy is not AckPolicy.ACK_FIRST: + warnings.warn( + "You can't use ack_policy other then AckPolicy.ACK_FIRST with `auto_commit=True`", + RuntimeWarning, + stacklevel=4, + ) + elif is_manual and ack_policy is not EMPTY and ack_policy is AckPolicy.ACK_FIRST: warnings.warn( - "You can't use acknowledgement policy with `is_manual=False` subscriber", + "You can't use AckPolicy.ACK_FIRST with `auto_commit=False`", RuntimeWarning, stacklevel=4, ) + + if is_manual and not group_id: + msg = "You must use `group_id` with manual commit mode." + raise SetupError(msg) + diff --git a/faststream/kafka/broker/registrator.py b/faststream/kafka/broker/registrator.py index 898ebc646d..5d0cfcb936 100644 --- a/faststream/kafka/broker/registrator.py +++ b/faststream/kafka/broker/registrator.py @@ -1553,9 +1553,6 @@ def subscriber( "SpecificationDefaultSubscriber", "SpecificationBatchSubscriber", ]: - if ack_policy is AckPolicy.ACK_FIRST: - auto_commit = True - ack_policy = AckPolicy.DO_NOTHING subscriber = super().subscriber( create_subscriber( diff --git a/faststream/kafka/fastapi/fastapi.py b/faststream/kafka/fastapi/fastapi.py index 5ab2a4f43d..747103bfea 100644 --- a/faststream/kafka/fastapi/fastapi.py +++ b/faststream/kafka/fastapi/fastapi.py @@ -2583,9 +2583,6 @@ def subscriber( "SpecificationBatchSubscriber", "SpecificationDefaultSubscriber", ]: - if ack_policy is AckPolicy.ACK_FIRST: - auto_commit = True - ack_policy = AckPolicy.DO_NOTHING subscriber = super().subscriber( *topics, diff --git a/faststream/kafka/router.py b/faststream/kafka/router.py index 08ca6c12ee..10d8df303e 100644 --- a/faststream/kafka/router.py +++ b/faststream/kafka/router.py @@ -518,9 +518,6 @@ def __init__( Doc("Whetever to include operation in AsyncAPI schema or not."), ] = True, ) -> None: - if ack_policy is AckPolicy.ACK_FIRST: - auto_commit = True - ack_policy = AckPolicy.DO_NOTHING super().__init__( call, diff --git a/faststream/kafka/subscriber/factory.py b/faststream/kafka/subscriber/factory.py index bb559873cc..da9d859e32 100644 --- a/faststream/kafka/subscriber/factory.py +++ b/faststream/kafka/subscriber/factory.py @@ -142,7 +142,10 @@ def create_subscriber( ) if ack_policy is EMPTY: - ack_policy = AckPolicy.REJECT_ON_ERROR + if not is_manual: + ack_policy = AckPolicy.DO_NOTHING + else: + ack_policy = AckPolicy.REJECT_ON_ERROR if batch: return SpecificationBatchSubscriber( @@ -190,9 +193,15 @@ def _validate_input_for_misconfigure( is_manual: bool, group_id: Optional[str], ) -> None: - if ack_policy is not EMPTY and not is_manual: + if not is_manual and ack_policy is not EMPTY and ack_policy is not AckPolicy.ACK_FIRST: warnings.warn( - "You can't use acknowledgement policy with `is_manual=False` subscriber", + "You can't use ack_policy other then AckPolicy.ACK_FIRST with `auto_commit=True`", + RuntimeWarning, + stacklevel=4, + ) + elif is_manual and ack_policy is not EMPTY and ack_policy is AckPolicy.ACK_FIRST: + warnings.warn( + "You can't use AckPolicy.ACK_FIRST with `auto_commit=False`", RuntimeWarning, stacklevel=4, ) From f22c2d53df66148bc231efd36b3ef0d58beaae3b Mon Sep 17 00:00:00 2001 From: Pastukhov Nikita Date: Wed, 20 Nov 2024 21:10:42 +0300 Subject: [PATCH 198/245] refactor: new Specification Schema (#1843) * refactor: new Specification Schema * fix: add missing pre-commit changes * refactor: delete defaults * refactor: polish AsyncAPI all brokers * fix: add missing pre-commit changes --------- Co-authored-by: Lancetnik --- .../asyncapi_customization/custom_info.py | 3 +- faststream/_internal/_compat.py | 5 +- faststream/_internal/basic_types.py | 2 +- faststream/_internal/broker/broker.py | 6 +- faststream/_internal/cli/docs/app.py | 8 +- faststream/_internal/cli/utils/imports.py | 4 +- faststream/_internal/fastapi/router.py | 4 +- faststream/_internal/publisher/specified.py | 36 ++-- faststream/_internal/publisher/usecase.py | 17 +- faststream/_internal/subscriber/proto.py | 7 +- faststream/_internal/subscriber/specified.py | 34 ++-- faststream/_internal/subscriber/usecase.py | 14 +- faststream/_internal/utils/data.py | 19 +- faststream/confluent/broker/broker.py | 9 +- faststream/confluent/fastapi/fastapi.py | 6 +- faststream/confluent/publisher/specified.py | 49 ++--- faststream/confluent/publisher/usecase.py | 21 --- faststream/confluent/subscriber/specified.py | 48 ++--- faststream/confluent/subscriber/usecase.py | 24 --- faststream/exceptions.py | 2 +- faststream/kafka/broker/broker.py | 12 +- faststream/kafka/fastapi/fastapi.py | 6 +- faststream/kafka/publisher/specified.py | 47 ++--- faststream/kafka/publisher/usecase.py | 20 --- faststream/kafka/subscriber/specified.py | 49 +++-- faststream/kafka/subscriber/usecase.py | 24 --- faststream/nats/broker/broker.py | 21 ++- faststream/nats/fastapi/fastapi.py | 6 +- faststream/nats/publisher/specified.py | 25 +-- faststream/nats/publisher/usecase.py | 11 -- faststream/nats/subscriber/specified.py | 34 ++-- faststream/nats/subscriber/usecase.py | 3 +- faststream/nats/subscriber/usecases/basic.py | 19 +- .../subscriber/usecases/core_subscriber.py | 16 -- .../usecases/key_value_subscriber.py | 8 - .../usecases/object_storage_subscriber.py | 8 - .../nats/subscriber/usecases/stream_basic.py | 8 - .../usecases/stream_pull_subscriber.py | 24 --- .../usecases/stream_push_subscriber.py | 8 - faststream/rabbit/broker/broker.py | 6 +- faststream/rabbit/fastapi/fastapi.py | 6 +- faststream/rabbit/publisher/specified.py | 134 ++++++++------ faststream/rabbit/publisher/usecase.py | 47 ++--- faststream/rabbit/schemas/proto.py | 39 +++- faststream/rabbit/subscriber/specified.py | 114 ++++++++---- faststream/rabbit/subscriber/usecase.py | 26 +-- faststream/redis/broker/broker.py | 6 +- faststream/redis/fastapi/fastapi.py | 6 +- faststream/redis/publisher/specified.py | 37 ++-- faststream/redis/publisher/usecase.py | 37 ---- faststream/redis/schemas/proto.py | 4 +- faststream/redis/subscriber/specified.py | 38 ++-- faststream/redis/subscriber/usecase.py | 64 ------- faststream/specification/__init__.py | 2 +- faststream/specification/asyncapi/factory.py | 38 +++- faststream/specification/asyncapi/utils.py | 35 +++- .../specification/asyncapi/v2_6_0/facade.py | 22 ++- .../specification/asyncapi/v2_6_0/generate.py | 117 ++++-------- .../asyncapi/v2_6_0/schema/__init__.py | 52 ++---- .../v2_6_0/schema/bindings/__init__.py | 9 +- .../v2_6_0/schema/bindings/amqp/__init__.py | 12 +- .../v2_6_0/schema/bindings/amqp/channel.py | 68 +++++-- .../v2_6_0/schema/bindings/amqp/operation.py | 30 +++- .../v2_6_0/schema/bindings/kafka/__init__.py | 12 +- .../v2_6_0/schema/bindings/kafka/channel.py | 19 +- .../v2_6_0/schema/bindings/kafka/operation.py | 25 ++- .../v2_6_0/schema/bindings/main/__init__.py | 12 +- .../v2_6_0/schema/bindings/main/channel.py | 101 ++++++++--- .../v2_6_0/schema/bindings/main/operation.py | 101 ++++++++--- .../v2_6_0/schema/bindings/nats/__init__.py | 12 +- .../v2_6_0/schema/bindings/nats/channel.py | 20 ++- .../v2_6_0/schema/bindings/nats/operation.py | 19 +- .../v2_6_0/schema/bindings/redis/__init__.py | 12 +- .../v2_6_0/schema/bindings/redis/channel.py | 28 ++- .../v2_6_0/schema/bindings/redis/operation.py | 19 +- .../v2_6_0/schema/bindings/sqs/__init__.py | 17 +- .../v2_6_0/schema/bindings/sqs/channel.py | 6 +- .../v2_6_0/schema/bindings/sqs/operation.py | 6 +- .../asyncapi/v2_6_0/schema/channels.py | 44 ++--- .../asyncapi/v2_6_0/schema/components.py | 1 - .../asyncapi/v2_6_0/schema/contact.py | 60 ++++--- .../asyncapi/v2_6_0/schema/docs.py | 46 +++-- .../asyncapi/v2_6_0/schema/info.py | 16 +- .../asyncapi/v2_6_0/schema/license.py | 62 ++++--- .../asyncapi/v2_6_0/schema/message.py | 47 ++--- .../asyncapi/v2_6_0/schema/operations.py | 58 +++--- .../asyncapi/v2_6_0/schema/schema.py | 12 +- .../asyncapi/v2_6_0/schema/servers.py | 15 +- .../asyncapi/v2_6_0/schema/tag.py | 58 +++--- .../asyncapi/v2_6_0/schema/utils.py | 1 - .../specification/asyncapi/v3_0_0/facade.py | 22 ++- .../specification/asyncapi/v3_0_0/generate.py | 170 +++++++----------- .../asyncapi/v3_0_0/schema/__init__.py | 38 ++-- .../v3_0_0/schema/bindings/__init__.py | 6 +- .../v3_0_0/schema/bindings/amqp/__init__.py | 10 +- .../v3_0_0/schema/bindings/amqp/channel.py | 22 +-- .../v3_0_0/schema/bindings/amqp/operation.py | 51 +++--- .../asyncapi/v3_0_0/schema/bindings/kafka.py | 9 + .../v3_0_0/schema/bindings/main/__init__.py | 10 +- .../v3_0_0/schema/bindings/main/channel.py | 107 +++++++++-- .../v3_0_0/schema/bindings/main/operation.py | 89 ++++++--- .../asyncapi/v3_0_0/schema/bindings/nats.py | 9 + .../asyncapi/v3_0_0/schema/bindings/redis.py | 9 + .../asyncapi/v3_0_0/schema/bindings/sqs.py | 9 + .../asyncapi/v3_0_0/schema/channels.py | 61 +++---- .../asyncapi/v3_0_0/schema/contact.py | 3 + .../asyncapi/v3_0_0/schema/docs.py | 3 + .../asyncapi/v3_0_0/schema/info.py | 12 +- .../asyncapi/v3_0_0/schema/license.py | 3 + .../asyncapi/v3_0_0/schema/message.py | 6 + .../asyncapi/v3_0_0/schema/operations.py | 85 +++++---- .../asyncapi/v3_0_0/schema/schema.py | 16 +- .../asyncapi/v3_0_0/schema/tag.py | 3 + .../asyncapi/v3_0_0/schema/utils.py | 6 + faststream/specification/base/info.py | 10 +- faststream/specification/base/proto.py | 47 ----- faststream/specification/base/schema.py | 8 +- .../specification/base/specification.py | 4 +- faststream/specification/proto/__init__.py | 4 + faststream/specification/proto/broker.py | 14 ++ faststream/specification/proto/endpoint.py | 62 +++++++ faststream/specification/schema/__init__.py | 47 +++-- .../specification/schema/bindings/amqp.py | 103 +++++------ .../specification/schema/bindings/kafka.py | 22 +-- .../specification/schema/bindings/nats.py | 10 +- .../specification/schema/bindings/redis.py | 8 +- faststream/specification/schema/channel.py | 24 --- faststream/specification/schema/components.py | 39 ---- faststream/specification/schema/contact.py | 44 ----- faststream/specification/schema/docs.py | 29 --- .../specification/schema/extra/__init__.py | 15 ++ .../specification/schema/extra/contact.py | 20 +++ .../schema/extra/external_docs.py | 15 ++ .../specification/schema/extra/license.py | 16 ++ faststream/specification/schema/extra/tag.py | 19 ++ faststream/specification/schema/info.py | 27 --- faststream/specification/schema/license.py | 45 ----- faststream/specification/schema/message.py | 51 ------ .../specification/schema/message/__init__.py | 3 + .../specification/schema/message/model.py | 11 ++ faststream/specification/schema/operation.py | 33 ---- .../schema/operation/__init__.py | 3 + .../specification/schema/operation/model.py | 11 ++ faststream/specification/schema/publisher.py | 12 ++ faststream/specification/schema/security.py | 105 ----------- faststream/specification/schema/servers.py | 65 ------- faststream/specification/schema/subscriber.py | 12 ++ faststream/specification/schema/tag.py | 37 ---- ruff.toml | 6 + serve.py | 9 + tests/asyncapi/base/v2_6_0/arguments.py | 7 +- tests/asyncapi/base/v2_6_0/fastapi.py | 4 +- .../base/v2_6_0/from_spec/__init__.py | 0 .../base/v2_6_0/from_spec/test_contact.py | 59 ++++++ .../v2_6_0/from_spec/test_external_docs.py | 35 ++++ .../base/v2_6_0/from_spec/test_license.py | 35 ++++ .../base/v2_6_0/from_spec/test_tag.py | 49 +++++ tests/asyncapi/base/v2_6_0/publisher.py | 4 +- tests/asyncapi/base/v3_0_0/fastapi.py | 7 +- .../confluent/v2_6_0/test_connection.py | 2 +- .../confluent/v3_0_0/test_connection.py | 2 +- tests/asyncapi/kafka/v2_6_0/test_app.py | 5 +- .../asyncapi/kafka/v2_6_0/test_connection.py | 2 +- .../asyncapi/kafka/v3_0_0/test_connection.py | 2 +- tests/asyncapi/nats/v2_6_0/test_arguments.py | 2 +- tests/asyncapi/nats/v2_6_0/test_connection.py | 2 +- tests/asyncapi/nats/v3_0_0/test_connection.py | 2 +- .../asyncapi/rabbit/v2_6_0/test_connection.py | 4 +- .../asyncapi/rabbit/v2_6_0/test_publisher.py | 8 + .../asyncapi/rabbit/v3_0_0/test_connection.py | 2 +- .../asyncapi/rabbit/v3_0_0/test_publisher.py | 14 +- tests/asyncapi/redis/v2_6_0/test_arguments.py | 4 +- .../asyncapi/redis/v2_6_0/test_connection.py | 2 +- tests/asyncapi/redis/v3_0_0/test_arguments.py | 4 +- .../asyncapi/redis/v3_0_0/test_connection.py | 2 +- tests/cli/test_asyncapi_docs.py | 5 +- .../cli/{test_run_regular.py => test_run.py} | 0 tests/cli/test_run_asgi.py | 9 +- 178 files changed, 2141 insertions(+), 2326 deletions(-) create mode 100644 faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka.py create mode 100644 faststream/specification/asyncapi/v3_0_0/schema/bindings/nats.py create mode 100644 faststream/specification/asyncapi/v3_0_0/schema/bindings/redis.py create mode 100644 faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs.py create mode 100644 faststream/specification/asyncapi/v3_0_0/schema/contact.py create mode 100644 faststream/specification/asyncapi/v3_0_0/schema/docs.py create mode 100644 faststream/specification/asyncapi/v3_0_0/schema/license.py create mode 100644 faststream/specification/asyncapi/v3_0_0/schema/message.py create mode 100644 faststream/specification/asyncapi/v3_0_0/schema/tag.py create mode 100644 faststream/specification/asyncapi/v3_0_0/schema/utils.py delete mode 100644 faststream/specification/base/proto.py create mode 100644 faststream/specification/proto/__init__.py create mode 100644 faststream/specification/proto/broker.py create mode 100644 faststream/specification/proto/endpoint.py delete mode 100644 faststream/specification/schema/channel.py delete mode 100644 faststream/specification/schema/components.py delete mode 100644 faststream/specification/schema/contact.py delete mode 100644 faststream/specification/schema/docs.py create mode 100644 faststream/specification/schema/extra/__init__.py create mode 100644 faststream/specification/schema/extra/contact.py create mode 100644 faststream/specification/schema/extra/external_docs.py create mode 100644 faststream/specification/schema/extra/license.py create mode 100644 faststream/specification/schema/extra/tag.py delete mode 100644 faststream/specification/schema/info.py delete mode 100644 faststream/specification/schema/license.py delete mode 100644 faststream/specification/schema/message.py create mode 100644 faststream/specification/schema/message/__init__.py create mode 100644 faststream/specification/schema/message/model.py delete mode 100644 faststream/specification/schema/operation.py create mode 100644 faststream/specification/schema/operation/__init__.py create mode 100644 faststream/specification/schema/operation/model.py create mode 100644 faststream/specification/schema/publisher.py delete mode 100644 faststream/specification/schema/security.py delete mode 100644 faststream/specification/schema/servers.py create mode 100644 faststream/specification/schema/subscriber.py delete mode 100644 faststream/specification/schema/tag.py create mode 100644 serve.py create mode 100644 tests/asyncapi/base/v2_6_0/from_spec/__init__.py create mode 100644 tests/asyncapi/base/v2_6_0/from_spec/test_contact.py create mode 100644 tests/asyncapi/base/v2_6_0/from_spec/test_external_docs.py create mode 100644 tests/asyncapi/base/v2_6_0/from_spec/test_license.py create mode 100644 tests/asyncapi/base/v2_6_0/from_spec/test_tag.py rename tests/cli/{test_run_regular.py => test_run.py} (100%) diff --git a/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_info.py b/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_info.py index 4121bebe29..d177e86909 100644 --- a/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_info.py +++ b/docs/docs_src/getting_started/asyncapi/asyncapi_customization/custom_info.py @@ -1,7 +1,6 @@ from faststream import FastStream from faststream.specification.asyncapi import AsyncAPI -from faststream.specification.schema.license import License -from faststream.specification.schema.contact import Contact +from faststream.specification import License, Contact from faststream.kafka import KafkaBroker broker = KafkaBroker("localhost:9092") diff --git a/faststream/_internal/_compat.py b/faststream/_internal/_compat.py index f58233757d..ba38326ac9 100644 --- a/faststream/_internal/_compat.py +++ b/faststream/_internal/_compat.py @@ -110,7 +110,7 @@ def model_to_jsonable( def dump_json(data: Any) -> bytes: return json_dumps(model_to_jsonable(data)) - def get_model_fields(model: type[BaseModel]) -> dict[str, Any]: + def get_model_fields(model: type[BaseModel]) -> AnyDict: return model.model_fields def model_to_json(model: BaseModel, **kwargs: Any) -> str: @@ -140,7 +140,7 @@ def model_schema(model: type[BaseModel], **kwargs: Any) -> AnyDict: def dump_json(data: Any) -> bytes: return json_dumps(data, default=pydantic_encoder) - def get_model_fields(model: type[BaseModel]) -> dict[str, Any]: + def get_model_fields(model: type[BaseModel]) -> AnyDict: return model.__fields__ # type: ignore[return-value] def model_to_json(model: BaseModel, **kwargs: Any) -> str: @@ -187,7 +187,6 @@ def with_info_plain_validator_function( # type: ignore[misc] ExceptionGroup, ) - try: import email_validator diff --git a/faststream/_internal/basic_types.py b/faststream/_internal/basic_types.py index f781df146e..e844171150 100644 --- a/faststream/_internal/basic_types.py +++ b/faststream/_internal/basic_types.py @@ -58,7 +58,7 @@ class StandardDataclass(Protocol): """Protocol to check type is dataclass.""" - __dataclass_fields__: ClassVar[dict[str, Any]] + __dataclass_fields__: ClassVar[AnyDict] BaseSendableMessage: TypeAlias = Union[ diff --git a/faststream/_internal/broker/broker.py b/faststream/_internal/broker/broker.py index b3621d34ee..831295ae76 100644 --- a/faststream/_internal/broker/broker.py +++ b/faststream/_internal/broker/broker.py @@ -35,6 +35,7 @@ MsgType, ) from faststream._internal.utils.functions import to_async +from faststream.specification.proto import ServerSpecification from .abc_broker import ABCBroker from .pub_base import BrokerPublishMixin @@ -51,12 +52,13 @@ PublisherProto, ) from faststream.security import BaseSecurity - from faststream.specification.schema.tag import Tag, TagDict + from faststream.specification.schema.extra import Tag, TagDict class BrokerUsecase( ABCBroker[MsgType], SetupAble, + ServerSpecification, BrokerPublishMixin[MsgType], Generic[MsgType, ConnectionType], ): @@ -121,7 +123,7 @@ def __init__( Doc("AsyncAPI server description."), ], tags: Annotated[ - Optional[Iterable[Union["Tag", "TagDict"]]], + Iterable[Union["Tag", "TagDict"]], Doc("AsyncAPI server tags."), ], specification_url: Annotated[ diff --git a/faststream/_internal/cli/docs/app.py b/faststream/_internal/cli/docs/app.py index d85f53de9c..d7c7b5951d 100644 --- a/faststream/_internal/cli/docs/app.py +++ b/faststream/_internal/cli/docs/app.py @@ -12,8 +12,12 @@ from faststream._internal.cli.utils.imports import import_from_string from faststream.exceptions import INSTALL_WATCHFILES, INSTALL_YAML, SCHEMA_NOT_SUPPORTED from faststream.specification.asyncapi.site import serve_app -from faststream.specification.asyncapi.v2_6_0.schema import Schema as SchemaV2_6 -from faststream.specification.asyncapi.v3_0_0.schema import Schema as SchemaV3 +from faststream.specification.asyncapi.v2_6_0.schema import ( + ApplicationSchema as SchemaV2_6, +) +from faststream.specification.asyncapi.v3_0_0.schema import ( + ApplicationSchema as SchemaV3, +) from faststream.specification.base.specification import Specification if TYPE_CHECKING: diff --git a/faststream/_internal/cli/utils/imports.py b/faststream/_internal/cli/utils/imports.py index 27be43cf05..860b69a42a 100644 --- a/faststream/_internal/cli/utils/imports.py +++ b/faststream/_internal/cli/utils/imports.py @@ -8,7 +8,9 @@ def import_from_string( - import_str: str, *, is_factory: bool = False + import_str: str, + *, + is_factory: bool = False, ) -> tuple[Path, object]: module_path, instance = _import_object_or_factory(import_str) diff --git a/faststream/_internal/fastapi/router.py b/faststream/_internal/fastapi/router.py index 4828893324..29452792b1 100644 --- a/faststream/_internal/fastapi/router.py +++ b/faststream/_internal/fastapi/router.py @@ -55,7 +55,7 @@ from faststream._internal.types import BrokerMiddleware from faststream.message import StreamMessage from faststream.specification.base.specification import Specification - from faststream.specification.schema.tag import Tag, TagDict + from faststream.specification.schema.extra import Tag, TagDict class _BackgroundMiddleware(BaseMiddleware): @@ -121,7 +121,7 @@ def __init__( generate_unique_id, ), # Specification information - specification_tags: Optional[Iterable[Union["Tag", "TagDict"]]] = None, + specification_tags: Iterable[Union["Tag", "TagDict"]] = (), schema_url: Optional[str] = "/asyncapi", **connection_kwars: Any, ) -> None: diff --git a/faststream/_internal/publisher/specified.py b/faststream/_internal/publisher/specified.py index 8ad62a1d00..a6e34a163b 100644 --- a/faststream/_internal/publisher/specified.py +++ b/faststream/_internal/publisher/specified.py @@ -1,11 +1,9 @@ from inspect import Parameter, unwrap -from typing import TYPE_CHECKING, Any, Optional +from typing import TYPE_CHECKING, Any, Callable, Optional, Union from fast_depends.core import build_call_model from fast_depends.pydantic._compat import create_model, get_config_base -from faststream._internal.publisher.proto import PublisherProto -from faststream._internal.subscriber.call_wrapper.call import HandlerCallWrapper from faststream._internal.types import ( MsgType, P_HandlerParams, @@ -13,34 +11,40 @@ ) from faststream.specification.asyncapi.message import get_model_schema from faststream.specification.asyncapi.utils import to_camelcase -from faststream.specification.base.proto import SpecificationEndpoint +from faststream.specification.proto import EndpointSpecification +from faststream.specification.schema import PublisherSpec if TYPE_CHECKING: - from faststream._internal.basic_types import AnyDict + from faststream._internal.basic_types import AnyCallable, AnyDict + from faststream._internal.state import BrokerState, Pointer + from faststream._internal.subscriber.call_wrapper.call import HandlerCallWrapper -class BaseSpicificationPublisher(SpecificationEndpoint, PublisherProto[MsgType]): +class SpecificationPublisher(EndpointSpecification[PublisherSpec]): """A base class for publishers in an asynchronous API.""" + _state: "Pointer[BrokerState]" # should be set in next parent + def __init__( self, - *, + *args: Any, schema_: Optional[Any], - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, + **kwargs: Any, ) -> None: - self.calls = [] + self.calls: list[AnyCallable] = [] - self.title_ = title_ - self.description_ = description_ - self.include_in_schema = include_in_schema self.schema_ = schema_ + super().__init__(*args, **kwargs) + def __call__( self, - func: HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn], - ) -> HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]: + func: Union[ + Callable[P_HandlerParams, T_HandlerReturn], + "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]", + ], + ) -> "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]": + func = super().__call__(func) self.calls.append(func._original_call) return func diff --git a/faststream/_internal/publisher/usecase.py b/faststream/_internal/publisher/usecase.py index c729a5b13d..46ebf0f7da 100644 --- a/faststream/_internal/publisher/usecase.py +++ b/faststream/_internal/publisher/usecase.py @@ -27,8 +27,6 @@ ) from faststream.message.source_type import SourceType -from .specified import BaseSpicificationPublisher - if TYPE_CHECKING: from faststream._internal.publisher.proto import ProducerProto from faststream._internal.types import ( @@ -38,7 +36,7 @@ from faststream.response.response import PublishCommand -class PublisherUsecase(BaseSpicificationPublisher, PublisherProto[MsgType]): +class PublisherUsecase(PublisherProto[MsgType]): """A base class for publishers in an asynchronous API.""" def __init__( @@ -46,11 +44,6 @@ def __init__( *, broker_middlewares: Iterable["BrokerMiddleware[MsgType]"], middlewares: Iterable["PublisherMiddleware"], - # AsyncAPI args - schema_: Optional[Any], - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: self.middlewares = middlewares self._broker_middlewares = broker_middlewares @@ -60,13 +53,6 @@ def __init__( self._fake_handler = False self.mock: Optional[MagicMock] = None - super().__init__( - title_=title_, - description_=description_, - include_in_schema=include_in_schema, - schema_=schema_, - ) - self._state: Pointer[BrokerState] = Pointer( EmptyBrokerState("You should include publisher to any broker.") ) @@ -115,7 +101,6 @@ def __call__( ensure_call_wrapper(func) ) handler._publishers.append(self) - super().__call__(handler) return handler async def _basic_publish( diff --git a/faststream/_internal/subscriber/proto.py b/faststream/_internal/subscriber/proto.py index a402009407..8b6151df30 100644 --- a/faststream/_internal/subscriber/proto.py +++ b/faststream/_internal/subscriber/proto.py @@ -17,7 +17,6 @@ ProducerProto, ) from faststream._internal.state import BrokerState, Pointer - from faststream._internal.subscriber.call_item import HandlerItem from faststream._internal.types import ( BrokerMiddleware, CustomCallable, @@ -27,6 +26,8 @@ from faststream.message import StreamMessage from faststream.response import Response + from .call_item import HandlerItem + class SubscriberProto( Endpoint, @@ -68,10 +69,6 @@ def _make_response_publisher( message: "StreamMessage[MsgType]", ) -> Iterable["BasePublisherProto"]: ... - @property - @abstractmethod - def call_name(self) -> str: ... - @abstractmethod async def start(self) -> None: ... diff --git a/faststream/_internal/subscriber/specified.py b/faststream/_internal/subscriber/specified.py index e6dec70970..3af87b590c 100644 --- a/faststream/_internal/subscriber/specified.py +++ b/faststream/_internal/subscriber/specified.py @@ -1,30 +1,38 @@ from typing import ( TYPE_CHECKING, + Any, Optional, ) -from faststream._internal.subscriber.proto import SubscriberProto -from faststream._internal.types import MsgType from faststream.exceptions import SetupError from faststream.specification.asyncapi.message import parse_handler_params from faststream.specification.asyncapi.utils import to_camelcase -from faststream.specification.base.proto import SpecificationEndpoint +from faststream.specification.proto import EndpointSpecification +from faststream.specification.schema import SubscriberSpec if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict + from faststream._internal.types import ( + MsgType, + ) + from .call_item import HandlerItem + + +class SpecificationSubscriber( + EndpointSpecification[SubscriberSpec], +): + calls: list["HandlerItem[MsgType]"] -class BaseSpicificationSubscriber(SpecificationEndpoint, SubscriberProto[MsgType]): def __init__( self, - *, - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, + *args: Any, + **kwargs: Any, ) -> None: - self.title_ = title_ - self.description_ = description_ - self.include_in_schema = include_in_schema + self.calls = [] + + # Call next base class parent init + super().__init__(*args, **kwargs) @property def call_name(self) -> str: @@ -34,9 +42,9 @@ def call_name(self) -> str: return to_camelcase(self.calls[0].call_name) - def get_description(self) -> Optional[str]: + def get_default_description(self) -> Optional[str]: """Returns the description of the handler.""" - if not self.calls: # pragma: no cover + if not self.calls: return None return self.calls[0].description diff --git a/faststream/_internal/subscriber/usecase.py b/faststream/_internal/subscriber/usecase.py index c8ee25678a..3a8aa1227d 100644 --- a/faststream/_internal/subscriber/usecase.py +++ b/faststream/_internal/subscriber/usecase.py @@ -34,8 +34,6 @@ from faststream.middlewares.logging import CriticalLogMiddleware from faststream.response import ensure_response -from .specified import BaseSpicificationSubscriber - if TYPE_CHECKING: from fast_depends.dependencies import Dependant @@ -79,7 +77,7 @@ def __init__( self.dependencies = dependencies -class SubscriberUsecase(BaseSpicificationSubscriber, SubscriberProto[MsgType]): +class SubscriberUsecase(SubscriberProto[MsgType]): """A class representing an asynchronous handler.""" lock: "AbstractContextManager[Any]" @@ -100,18 +98,8 @@ def __init__( default_parser: "AsyncCallable", default_decoder: "AsyncCallable", ack_policy: AckPolicy, - # AsyncAPI information - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: """Initialize a new instance of the class.""" - super().__init__( - title_=title_, - description_=description_, - include_in_schema=include_in_schema, - ) - self.calls = [] self._parser = default_parser diff --git a/faststream/_internal/utils/data.py b/faststream/_internal/utils/data.py index cc12c4cec2..98e3729fac 100644 --- a/faststream/_internal/utils/data.py +++ b/faststream/_internal/utils/data.py @@ -5,8 +5,19 @@ TypedDictCls = TypeVar("TypedDictCls") -def filter_by_dict(typed_dict: type[TypedDictCls], data: AnyDict) -> TypedDictCls: +def filter_by_dict( + typed_dict: type[TypedDictCls], + data: AnyDict, +) -> tuple[TypedDictCls, AnyDict]: annotations = typed_dict.__annotations__ - return typed_dict( # type: ignore[call-arg] - {k: v for k, v in data.items() if k in annotations}, - ) + + out_data = {} + extra_data = {} + + for k, v in data.items(): + if k in annotations: + out_data[k] = v + else: + extra_data[k] = v + + return typed_dict(out_data), extra_data diff --git a/faststream/confluent/broker/broker.py b/faststream/confluent/broker/broker.py index d8a1cd6671..53b487b031 100644 --- a/faststream/confluent/broker/broker.py +++ b/faststream/confluent/broker/broker.py @@ -53,7 +53,7 @@ from faststream.confluent.config import ConfluentConfig from faststream.confluent.message import KafkaMessage from faststream.security import BaseSecurity - from faststream.specification.schema.tag import Tag, TagDict + from faststream.specification.schema.extra import Tag, TagDict Partition = TypeVar("Partition") @@ -304,9 +304,9 @@ def __init__( Doc("AsyncAPI server description."), ] = None, tags: Annotated[ - Optional[Iterable[Union["Tag", "TagDict"]]], + Iterable[Union["Tag", "TagDict"]], Doc("AsyncAPI server tags."), - ] = None, + ] = (), # logging args logger: Annotated[ Optional["LoggerProto"], @@ -452,9 +452,10 @@ async def _connect( # type: ignore[override] self._producer.connect(native_producer) + connection_kwargs, _ = filter_by_dict(ConsumerConnectionParams, kwargs) return partial( AsyncConfluentConsumer, - **filter_by_dict(ConsumerConnectionParams, kwargs), + **connection_kwargs, logger=self._state.get().logger_state, config=self.config, ) diff --git a/faststream/confluent/fastapi/fastapi.py b/faststream/confluent/fastapi/fastapi.py index 5bdc96cf6c..197aa380af 100644 --- a/faststream/confluent/fastapi/fastapi.py +++ b/faststream/confluent/fastapi/fastapi.py @@ -53,7 +53,7 @@ SpecificationDefaultSubscriber, ) from faststream.security import BaseSecurity - from faststream.specification.schema.tag import Tag, TagDict + from faststream.specification.schema.extra import Tag, TagDict Partition = TypeVar("Partition") @@ -296,9 +296,9 @@ def __init__( Doc("Specification server description."), ] = None, specification_tags: Annotated[ - Optional[Iterable[Union["Tag", "TagDict"]]], + Iterable[Union["Tag", "TagDict"]], Doc("Specification server tags."), - ] = None, + ] = (), # logging args logger: Annotated[ Optional["LoggerProto"], diff --git a/faststream/confluent/publisher/specified.py b/faststream/confluent/publisher/specified.py index fec0faf183..69b4ca499b 100644 --- a/faststream/confluent/publisher/specified.py +++ b/faststream/confluent/publisher/specified.py @@ -1,58 +1,43 @@ -from typing import ( - TYPE_CHECKING, -) - -from faststream._internal.types import MsgType -from faststream.confluent.publisher.usecase import ( - BatchPublisher, - DefaultPublisher, - LogicPublisher, +from faststream._internal.publisher.specified import ( + SpecificationPublisher as SpecificationPublisherMixin, ) +from faststream.confluent.publisher.usecase import BatchPublisher, DefaultPublisher from faststream.specification.asyncapi.utils import resolve_payloads +from faststream.specification.schema import Message, Operation, PublisherSpec from faststream.specification.schema.bindings import ChannelBinding, kafka -from faststream.specification.schema.channel import Channel -from faststream.specification.schema.message import CorrelationId, Message -from faststream.specification.schema.operation import Operation -if TYPE_CHECKING: - from confluent_kafka import Message as ConfluentMsg - -class SpecificationPublisher(LogicPublisher[MsgType]): +class SpecificationPublisher(SpecificationPublisherMixin): """A class representing a publisher.""" - def get_name(self) -> str: + def get_default_name(self) -> str: return f"{self.topic}:Publisher" - def get_schema(self) -> dict[str, Channel]: + def get_schema(self) -> dict[str, PublisherSpec]: payloads = self.get_payloads() return { - self.name: Channel( + self.name: PublisherSpec( description=self.description, - publish=Operation( + operation=Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads, "Publisher"), - correlationId=CorrelationId( - location="$message.header#/correlation_id", - ), ), + bindings=None, + ), + bindings=ChannelBinding( + kafka=kafka.ChannelBinding( + topic=self.topic, partitions=None, replicas=None + ) ), - bindings=ChannelBinding(kafka=kafka.ChannelBinding(topic=self.topic)), ), } -class SpecificationBatchPublisher( - BatchPublisher, - SpecificationPublisher[tuple["ConfluentMsg", ...]], -): +class SpecificationBatchPublisher(SpecificationPublisher, BatchPublisher): pass -class SpecificationDefaultPublisher( - DefaultPublisher, - SpecificationPublisher["ConfluentMsg"], -): +class SpecificationDefaultPublisher(SpecificationPublisher, DefaultPublisher): pass diff --git a/faststream/confluent/publisher/usecase.py b/faststream/confluent/publisher/usecase.py index d6b7132155..e7cd4a1fb4 100644 --- a/faststream/confluent/publisher/usecase.py +++ b/faststream/confluent/publisher/usecase.py @@ -1,7 +1,6 @@ from collections.abc import Iterable from typing import ( TYPE_CHECKING, - Any, Optional, Union, ) @@ -40,20 +39,10 @@ def __init__( # Publisher args broker_middlewares: Iterable["BrokerMiddleware[MsgType]"], middlewares: Iterable["PublisherMiddleware"], - # AsyncAPI args - schema_: Optional[Any], - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: super().__init__( broker_middlewares=broker_middlewares, middlewares=middlewares, - # AsyncAPI args - schema_=schema_, - title_=title_, - description_=description_, - include_in_schema=include_in_schema, ) self.topic = topic @@ -105,11 +94,6 @@ def __init__( # Publisher args broker_middlewares: Iterable["BrokerMiddleware[Message]"], middlewares: Iterable["PublisherMiddleware"], - # AsyncAPI args - schema_: Optional[Any], - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: super().__init__( topic=topic, @@ -119,11 +103,6 @@ def __init__( # publisher args broker_middlewares=broker_middlewares, middlewares=middlewares, - # AsyncAPI args - schema_=schema_, - title_=title_, - description_=description_, - include_in_schema=include_in_schema, ) self.key = key diff --git a/faststream/confluent/subscriber/specified.py b/faststream/confluent/subscriber/specified.py index ece2b78457..dbb20b4f7a 100644 --- a/faststream/confluent/subscriber/specified.py +++ b/faststream/confluent/subscriber/specified.py @@ -1,64 +1,54 @@ -from typing import ( - TYPE_CHECKING, -) +from collections.abc import Iterable +from typing import TYPE_CHECKING -from faststream._internal.types import MsgType -from faststream.confluent.subscriber.usecase import ( - BatchSubscriber, - DefaultSubscriber, - LogicSubscriber, +from faststream._internal.subscriber.specified import ( + SpecificationSubscriber as SpecificationSubscriberMixin, ) +from faststream.confluent.subscriber.usecase import BatchSubscriber, DefaultSubscriber from faststream.specification.asyncapi.utils import resolve_payloads +from faststream.specification.schema import Message, Operation, SubscriberSpec from faststream.specification.schema.bindings import ChannelBinding, kafka -from faststream.specification.schema.channel import Channel -from faststream.specification.schema.message import CorrelationId, Message -from faststream.specification.schema.operation import Operation if TYPE_CHECKING: - from confluent_kafka import Message as ConfluentMsg + from faststream.confluent.schemas import TopicPartition -class SpecificationSubscriber(LogicSubscriber[MsgType]): +class SpecificationSubscriber(SpecificationSubscriberMixin): """A class to handle logic and async API operations.""" - def get_name(self) -> str: + topics: Iterable[str] + partitions: Iterable["TopicPartition"] # TODO: support partitions + + def get_default_name(self) -> str: return f"{','.join(self.topics)}:{self.call_name}" - def get_schema(self) -> dict[str, Channel]: + def get_schema(self) -> dict[str, SubscriberSpec]: channels = {} payloads = self.get_payloads() for t in self.topics: handler_name = self.title_ or f"{t}:{self.call_name}" - channels[handler_name] = Channel( + channels[handler_name] = SubscriberSpec( description=self.description, - subscribe=Operation( + operation=Operation( message=Message( title=f"{handler_name}:Message", payload=resolve_payloads(payloads), - correlationId=CorrelationId( - location="$message.header#/correlation_id", - ), ), + bindings=None, ), bindings=ChannelBinding( - kafka=kafka.ChannelBinding(topic=t), + kafka=kafka.ChannelBinding(topic=t, partitions=None, replicas=None), ), ) return channels -class SpecificationDefaultSubscriber( - DefaultSubscriber, - SpecificationSubscriber["ConfluentMsg"], -): +class SpecificationDefaultSubscriber(SpecificationSubscriber, DefaultSubscriber): pass -class SpecificationBatchSubscriber( - BatchSubscriber, - SpecificationSubscriber[tuple["ConfluentMsg", ...]], -): +class SpecificationBatchSubscriber(SpecificationSubscriber, BatchSubscriber): pass diff --git a/faststream/confluent/subscriber/usecase.py b/faststream/confluent/subscriber/usecase.py index adb321dd4a..d1963d7ab4 100644 --- a/faststream/confluent/subscriber/usecase.py +++ b/faststream/confluent/subscriber/usecase.py @@ -63,10 +63,6 @@ def __init__( no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[MsgType]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: super().__init__( default_parser=default_parser, @@ -76,10 +72,6 @@ def __init__( no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, - # AsyncAPI args - title_=title_, - description_=description_, - include_in_schema=include_in_schema, ) self.__connection_data = connection_data @@ -258,10 +250,6 @@ def __init__( no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[Message]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: self.parser = AsyncConfluentParser(is_manual=is_manual) @@ -279,10 +267,6 @@ def __init__( no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, - # AsyncAPI args - title_=title_, - description_=description_, - include_in_schema=include_in_schema, ) async def get_msg(self) -> Optional["Message"]: @@ -321,10 +305,6 @@ def __init__( no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[tuple[Message, ...]]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: self.max_records = max_records @@ -344,10 +324,6 @@ def __init__( no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, - # AsyncAPI args - title_=title_, - description_=description_, - include_in_schema=include_in_schema, ) async def get_msg(self) -> Optional[tuple["Message", ...]]: diff --git a/faststream/exceptions.py b/faststream/exceptions.py index 6d51e76cb3..32557dd42c 100644 --- a/faststream/exceptions.py +++ b/faststream/exceptions.py @@ -162,4 +162,4 @@ def __str__(self) -> str: pip install watchfiles """ -SCHEMA_NOT_SUPPORTED = "{schema_filename} not supported. Make sure that your schema is valid and schema version supported by FastStream" +SCHEMA_NOT_SUPPORTED = "`{schema_filename}` not supported. Make sure that your schema is valid and schema version supported by FastStream" diff --git a/faststream/kafka/broker/broker.py b/faststream/kafka/broker/broker.py index 0f962f0d3b..bec2ed99c9 100644 --- a/faststream/kafka/broker/broker.py +++ b/faststream/kafka/broker/broker.py @@ -57,7 +57,7 @@ ) from faststream.kafka.message import KafkaMessage from faststream.security import BaseSecurity - from faststream.specification.schema.tag import Tag, TagDict + from faststream.specification.schema.extra import Tag, TagDict class KafkaInitKwargs(TypedDict, total=False): request_timeout_ms: Annotated[ @@ -477,9 +477,9 @@ def __init__( Doc("AsyncAPI server description."), ] = None, tags: Annotated[ - Optional[Iterable[Union["Tag", "TagDict"]]], + Iterable[Union["Tag", "TagDict"]], Doc("AsyncAPI server tags."), - ] = None, + ] = (), # logging args logger: Annotated[ Optional["LoggerProto"], @@ -640,10 +640,8 @@ async def _connect( # type: ignore[override] await self._producer.connect(producer) - return partial( - aiokafka.AIOKafkaConsumer, - **filter_by_dict(ConsumerConnectionParams, kwargs), - ) + connection_kwargs, _ = filter_by_dict(ConsumerConnectionParams, kwargs) + return partial(aiokafka.AIOKafkaConsumer, **connection_kwargs) async def start(self) -> None: """Connect broker to Kafka and startup all subscribers.""" diff --git a/faststream/kafka/fastapi/fastapi.py b/faststream/kafka/fastapi/fastapi.py index 5601c05f6c..46a07fb7a7 100644 --- a/faststream/kafka/fastapi/fastapi.py +++ b/faststream/kafka/fastapi/fastapi.py @@ -58,7 +58,7 @@ SpecificationDefaultSubscriber, ) from faststream.security import BaseSecurity - from faststream.specification.schema.tag import Tag, TagDict + from faststream.specification.schema.extra import Tag, TagDict Partition = TypeVar("Partition") @@ -304,9 +304,9 @@ def __init__( Doc("Specification server description."), ] = None, specification_tags: Annotated[ - Optional[Iterable[Union["Tag", "TagDict"]]], + Iterable[Union["Tag", "TagDict"]], Doc("Specification server tags."), - ] = None, + ] = (), # logging args logger: Annotated[ Optional["LoggerProto"], diff --git a/faststream/kafka/publisher/specified.py b/faststream/kafka/publisher/specified.py index d765cc8f8b..b23eef8d92 100644 --- a/faststream/kafka/publisher/specified.py +++ b/faststream/kafka/publisher/specified.py @@ -1,56 +1,43 @@ -from typing import TYPE_CHECKING - -from faststream._internal.types import MsgType -from faststream.kafka.publisher.usecase import ( - BatchPublisher, - DefaultPublisher, - LogicPublisher, +from faststream._internal.publisher.specified import ( + SpecificationPublisher as SpecificationPublisherMixin, ) +from faststream.kafka.publisher.usecase import BatchPublisher, DefaultPublisher from faststream.specification.asyncapi.utils import resolve_payloads +from faststream.specification.schema import Message, Operation, PublisherSpec from faststream.specification.schema.bindings import ChannelBinding, kafka -from faststream.specification.schema.channel import Channel -from faststream.specification.schema.message import CorrelationId, Message -from faststream.specification.schema.operation import Operation - -if TYPE_CHECKING: - from aiokafka import ConsumerRecord -class SpecificationPublisher(LogicPublisher[MsgType]): +class SpecificationPublisher(SpecificationPublisherMixin): """A class representing a publisher.""" - def get_name(self) -> str: + def get_default_name(self) -> str: return f"{self.topic}:Publisher" - def get_schema(self) -> dict[str, Channel]: + def get_schema(self) -> dict[str, PublisherSpec]: payloads = self.get_payloads() return { - self.name: Channel( + self.name: PublisherSpec( description=self.description, - publish=Operation( + operation=Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads, "Publisher"), - correlationId=CorrelationId( - location="$message.header#/correlation_id", - ), ), + bindings=None, + ), + bindings=ChannelBinding( + kafka=kafka.ChannelBinding( + topic=self.topic, partitions=None, replicas=None + ) ), - bindings=ChannelBinding(kafka=kafka.ChannelBinding(topic=self.topic)), ), } -class SpecificationBatchPublisher( - BatchPublisher, - SpecificationPublisher[tuple["ConsumerRecord", ...]], -): +class SpecificationBatchPublisher(SpecificationPublisher, BatchPublisher): pass -class SpecificationDefaultPublisher( - DefaultPublisher, - SpecificationPublisher["ConsumerRecord"], -): +class SpecificationDefaultPublisher(SpecificationPublisher, DefaultPublisher): pass diff --git a/faststream/kafka/publisher/usecase.py b/faststream/kafka/publisher/usecase.py index 0f005770de..895abe044c 100644 --- a/faststream/kafka/publisher/usecase.py +++ b/faststream/kafka/publisher/usecase.py @@ -42,20 +42,10 @@ def __init__( # Publisher args broker_middlewares: Iterable["BrokerMiddleware[MsgType]"], middlewares: Iterable["PublisherMiddleware"], - # AsyncAPI args - schema_: Optional[Any], - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: super().__init__( broker_middlewares=broker_middlewares, middlewares=middlewares, - # AsyncAPI args - schema_=schema_, - title_=title_, - description_=description_, - include_in_schema=include_in_schema, ) self.topic = topic @@ -154,11 +144,6 @@ def __init__( # Publisher args broker_middlewares: Iterable["BrokerMiddleware[ConsumerRecord]"], middlewares: Iterable["PublisherMiddleware"], - # AsyncAPI args - schema_: Optional[Any], - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: super().__init__( topic=topic, @@ -168,11 +153,6 @@ def __init__( # publisher args broker_middlewares=broker_middlewares, middlewares=middlewares, - # AsyncAPI args - schema_=schema_, - title_=title_, - description_=description_, - include_in_schema=include_in_schema, ) self.key = key diff --git a/faststream/kafka/subscriber/specified.py b/faststream/kafka/subscriber/specified.py index c06856f518..a536e54143 100644 --- a/faststream/kafka/subscriber/specified.py +++ b/faststream/kafka/subscriber/specified.py @@ -1,30 +1,29 @@ -from typing import ( - TYPE_CHECKING, -) +from collections.abc import Iterable +from typing import TYPE_CHECKING, Optional -from faststream._internal.types import MsgType -from faststream.kafka.subscriber.usecase import ( - BatchSubscriber, - DefaultSubscriber, - LogicSubscriber, +from faststream._internal.subscriber.specified import ( + SpecificationSubscriber as SpecificationSubscriberMixin, ) +from faststream.kafka.subscriber.usecase import BatchSubscriber, DefaultSubscriber from faststream.specification.asyncapi.utils import resolve_payloads +from faststream.specification.schema import Message, Operation, SubscriberSpec from faststream.specification.schema.bindings import ChannelBinding, kafka -from faststream.specification.schema.channel import Channel -from faststream.specification.schema.message import CorrelationId, Message -from faststream.specification.schema.operation import Operation if TYPE_CHECKING: - from aiokafka import ConsumerRecord + from aiokafka import TopicPartition -class SpecificationSubscriber(LogicSubscriber[MsgType]): +class SpecificationSubscriber(SpecificationSubscriberMixin): """A class to handle logic and async API operations.""" - def get_name(self) -> str: + topics: Iterable[str] + partitions: Iterable["TopicPartition"] # TODO: support partitions + _pattern: Optional[str] # TODO: support pattern schema + + def get_default_name(self) -> str: return f"{','.join(self.topics)}:{self.call_name}" - def get_schema(self) -> dict[str, Channel]: + def get_schema(self) -> dict[str, SubscriberSpec]: channels = {} payloads = self.get_payloads() @@ -32,34 +31,26 @@ def get_schema(self) -> dict[str, Channel]: for t in self.topics: handler_name = self.title_ or f"{t}:{self.call_name}" - channels[handler_name] = Channel( + channels[handler_name] = SubscriberSpec( description=self.description, - subscribe=Operation( + operation=Operation( message=Message( title=f"{handler_name}:Message", payload=resolve_payloads(payloads), - correlationId=CorrelationId( - location="$message.header#/correlation_id", - ), ), + bindings=None, ), bindings=ChannelBinding( - kafka=kafka.ChannelBinding(topic=t), + kafka=kafka.ChannelBinding(topic=t, partitions=None, replicas=None), ), ) return channels -class SpecificationDefaultSubscriber( - DefaultSubscriber, - SpecificationSubscriber["ConsumerRecord"], -): +class SpecificationDefaultSubscriber(SpecificationSubscriber, DefaultSubscriber): pass -class SpecificationBatchSubscriber( - BatchSubscriber, - SpecificationSubscriber[tuple["ConsumerRecord", ...]], -): +class SpecificationBatchSubscriber(SpecificationSubscriber, BatchSubscriber): pass diff --git a/faststream/kafka/subscriber/usecase.py b/faststream/kafka/subscriber/usecase.py index fab52a66f2..3fc89600e2 100644 --- a/faststream/kafka/subscriber/usecase.py +++ b/faststream/kafka/subscriber/usecase.py @@ -69,10 +69,6 @@ def __init__( no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[MsgType]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: super().__init__( default_parser=default_parser, @@ -82,10 +78,6 @@ def __init__( no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, - # AsyncAPI args - title_=title_, - description_=description_, - include_in_schema=include_in_schema, ) self.topics = topics @@ -287,10 +279,6 @@ def __init__( no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[ConsumerRecord]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: if pattern: reg, pattern = compile_path( @@ -322,10 +310,6 @@ def __init__( no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, - # AsyncAPI args - title_=title_, - description_=description_, - include_in_schema=include_in_schema, ) async def get_msg(self) -> "ConsumerRecord": @@ -368,10 +352,6 @@ def __init__( broker_middlewares: Iterable[ "BrokerMiddleware[Sequence[tuple[ConsumerRecord, ...]]]" ], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: self.batch_timeout_ms = batch_timeout_ms self.max_records = max_records @@ -406,10 +386,6 @@ def __init__( no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, - # AsyncAPI args - title_=title_, - description_=description_, - include_in_schema=include_in_schema, ) async def get_msg(self) -> tuple["ConsumerRecord", ...]: diff --git a/faststream/nats/broker/broker.py b/faststream/nats/broker/broker.py index b5996e29e8..8cfa07a9bd 100644 --- a/faststream/nats/broker/broker.py +++ b/faststream/nats/broker/broker.py @@ -36,7 +36,7 @@ from faststream.nats.publisher.producer import NatsFastProducer, NatsJSFastProducer from faststream.nats.response import NatsPublishCommand from faststream.nats.security import parse_security -from faststream.nats.subscriber.specified import SpecificationSubscriber +from faststream.nats.subscriber.usecases.basic import LogicSubscriber from faststream.response.publish_type import PublishType from .logging import make_nats_logger_state @@ -71,9 +71,9 @@ CustomCallable, ) from faststream.nats.message import NatsMessage - from faststream.nats.publisher.specified import SpecificationPublisher + from faststream.nats.publisher.usecase import LogicPublisher from faststream.security import BaseSecurity - from faststream.specification.schema.tag import Tag, TagDict + from faststream.specification.schema.extra import Tag, TagDict class NatsInitKwargs(TypedDict, total=False): """NatsBroker.connect() method type hints.""" @@ -399,9 +399,9 @@ def __init__( Doc("AsyncAPI server description."), ] = None, tags: Annotated[ - Optional[Iterable[Union["Tag", "TagDict"]]], + Iterable[Union["Tag", "TagDict"]], Doc("AsyncAPI server tags."), - ] = None, + ] = (), # logging args logger: Annotated[ Optional["LoggerProto"], @@ -560,7 +560,6 @@ async def _connect(self, **kwargs: Any) -> "Client": self._os_declarer.connect(stream) self._connection_state = ConnectedState(connection, stream) - return connection async def close( @@ -600,7 +599,7 @@ async def start(self) -> None: ) except BadRequestError as e: # noqa: PERF203 - log_context = SpecificationSubscriber.build_log_context( + log_context = LogicSubscriber.build_log_context( message=None, subject="", queue="", @@ -773,7 +772,7 @@ async def request( # type: ignore[override] @override def setup_subscriber( # type: ignore[override] self, - subscriber: "SpecificationSubscriber", + subscriber: "LogicSubscriber", ) -> None: return super().setup_subscriber( subscriber, @@ -785,7 +784,7 @@ def setup_subscriber( # type: ignore[override] @override def setup_publisher( # type: ignore[override] self, - publisher: "SpecificationPublisher", + publisher: "LogicPublisher", ) -> None: producer = self._js_producer if publisher.stream is not None else self._producer @@ -851,7 +850,7 @@ def _log_connection_broken( self, error_cb: Optional["ErrorCallback"] = None, ) -> "ErrorCallback": - c = SpecificationSubscriber.build_log_context(None, "") + c = LogicSubscriber.build_log_context(None, "") async def wrapper(err: Exception) -> None: if error_cb is not None: @@ -872,7 +871,7 @@ def _log_reconnected( self, cb: Optional["Callback"] = None, ) -> "Callback": - c = SpecificationSubscriber.build_log_context(None, "") + c = LogicSubscriber.build_log_context(None, "") async def wrapper() -> None: if cb is not None: diff --git a/faststream/nats/fastapi/fastapi.py b/faststream/nats/fastapi/fastapi.py index a62318c82b..3c465c783c 100644 --- a/faststream/nats/fastapi/fastapi.py +++ b/faststream/nats/fastapi/fastapi.py @@ -63,7 +63,7 @@ from faststream.nats.publisher.specified import SpecificationPublisher from faststream.nats.schemas import JStream, KvWatch, ObjWatch, PullSub from faststream.security import BaseSecurity - from faststream.specification.schema.tag import Tag, TagDict + from faststream.specification.schema.extra import Tag, TagDict class NatsRouter(StreamRouter["Msg"]): @@ -245,9 +245,9 @@ def __init__( Doc("AsyncAPI server description."), ] = None, specification_tags: Annotated[ - Optional[Iterable[Union["Tag", "TagDict"]]], + Iterable[Union["Tag", "TagDict"]], Doc("AsyncAPI server tags."), - ] = None, + ] = (), # logging args logger: Annotated[ Optional["LoggerProto"], diff --git a/faststream/nats/publisher/specified.py b/faststream/nats/publisher/specified.py index 41cfdc27b9..029c62b344 100644 --- a/faststream/nats/publisher/specified.py +++ b/faststream/nats/publisher/specified.py @@ -1,35 +1,38 @@ +from faststream._internal.publisher.specified import ( + SpecificationPublisher as SpecificationPublisherMixin, +) from faststream.nats.publisher.usecase import LogicPublisher from faststream.specification.asyncapi.utils import resolve_payloads +from faststream.specification.schema import Message, Operation, PublisherSpec from faststream.specification.schema.bindings import ChannelBinding, nats -from faststream.specification.schema.channel import Channel -from faststream.specification.schema.message import CorrelationId, Message -from faststream.specification.schema.operation import Operation -class SpecificationPublisher(LogicPublisher): +class SpecificationPublisher( + SpecificationPublisherMixin, + LogicPublisher, +): """A class to represent a NATS publisher.""" - def get_name(self) -> str: + def get_default_name(self) -> str: return f"{self.subject}:Publisher" - def get_schema(self) -> dict[str, Channel]: + def get_schema(self) -> dict[str, PublisherSpec]: payloads = self.get_payloads() return { - self.name: Channel( + self.name: PublisherSpec( description=self.description, - publish=Operation( + operation=Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads, "Publisher"), - correlationId=CorrelationId( - location="$message.header#/correlation_id", - ), ), + bindings=None, ), bindings=ChannelBinding( nats=nats.ChannelBinding( subject=self.subject, + queue=None, ), ), ), diff --git a/faststream/nats/publisher/usecase.py b/faststream/nats/publisher/usecase.py index 9d3ccd92dc..2b16854d73 100644 --- a/faststream/nats/publisher/usecase.py +++ b/faststream/nats/publisher/usecase.py @@ -1,7 +1,6 @@ from collections.abc import Iterable from typing import ( TYPE_CHECKING, - Any, Optional, Union, ) @@ -41,21 +40,11 @@ def __init__( # Publisher args broker_middlewares: Iterable["BrokerMiddleware[Msg]"], middlewares: Iterable["PublisherMiddleware"], - # AsyncAPI args - schema_: Optional[Any], - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: """Initialize NATS publisher object.""" super().__init__( broker_middlewares=broker_middlewares, middlewares=middlewares, - # AsyncAPI args - schema_=schema_, - title_=title_, - description_=description_, - include_in_schema=include_in_schema, ) self.subject = subject diff --git a/faststream/nats/subscriber/specified.py b/faststream/nats/subscriber/specified.py index 2c3387ded3..dc8c6720ef 100644 --- a/faststream/nats/subscriber/specified.py +++ b/faststream/nats/subscriber/specified.py @@ -1,7 +1,8 @@ -from typing import Any - from typing_extensions import override +from faststream._internal.subscriber.specified import ( + SpecificationSubscriber as SpecificationSubscriberMixin, +) from faststream.nats.subscriber.usecases import ( BatchPullStreamSubscriber, ConcurrentCoreSubscriber, @@ -9,38 +10,35 @@ ConcurrentPushStreamSubscriber, CoreSubscriber, KeyValueWatchSubscriber, - LogicSubscriber, ObjStoreWatchSubscriber, PullStreamSubscriber, PushStreamSubscription, ) from faststream.specification.asyncapi.utils import resolve_payloads +from faststream.specification.schema import Message, Operation, SubscriberSpec from faststream.specification.schema.bindings import ChannelBinding, nats -from faststream.specification.schema.channel import Channel -from faststream.specification.schema.message import CorrelationId, Message -from faststream.specification.schema.operation import Operation -class SpecificationSubscriber(LogicSubscriber[Any]): +class SpecificationSubscriber(SpecificationSubscriberMixin): """A class to represent a NATS handler.""" - def get_name(self) -> str: + subject: str + + def get_default_name(self) -> str: return f"{self.subject}:{self.call_name}" - def get_schema(self) -> dict[str, Channel]: + def get_schema(self) -> dict[str, SubscriberSpec]: payloads = self.get_payloads() return { - self.name: Channel( + self.name: SubscriberSpec( description=self.description, - subscribe=Operation( + operation=Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads), - correlationId=CorrelationId( - location="$message.header#/correlation_id", - ), ), + bindings=None, ), bindings=ChannelBinding( nats=nats.ChannelBinding( @@ -108,11 +106,11 @@ class SpecificationKeyValueWatchSubscriber( """KeyValueWatch consumer with Specification methods.""" @override - def get_name(self) -> str: + def get_default_name(self) -> str: return "" @override - def get_schema(self) -> dict[str, Channel]: + def get_schema(self) -> dict[str, SubscriberSpec]: return {} @@ -123,9 +121,9 @@ class SpecificationObjStoreWatchSubscriber( """ObjStoreWatch consumer with Specification methods.""" @override - def get_name(self) -> str: + def get_default_name(self) -> str: return "" @override - def get_schema(self) -> dict[str, Channel]: + def get_schema(self) -> dict[str, SubscriberSpec]: return {} diff --git a/faststream/nats/subscriber/usecase.py b/faststream/nats/subscriber/usecase.py index e2c6b207e1..8c85b8569a 100644 --- a/faststream/nats/subscriber/usecase.py +++ b/faststream/nats/subscriber/usecase.py @@ -6,7 +6,6 @@ Annotated, Any, Callable, - Generic, Optional, cast, ) @@ -68,7 +67,7 @@ from faststream.nats.schemas import JStream, KvWatch, ObjWatch, PullSub -class LogicSubscriber(SubscriberUsecase[MsgType], Generic[MsgType]): +class LogicSubscriber(SubscriberUsecase[MsgType]): """A class to represent a NATS handler.""" subscription: Optional[Unsubscriptable] diff --git a/faststream/nats/subscriber/usecases/basic.py b/faststream/nats/subscriber/usecases/basic.py index 3b5f30e1fc..bee03746b3 100644 --- a/faststream/nats/subscriber/usecases/basic.py +++ b/faststream/nats/subscriber/usecases/basic.py @@ -3,7 +3,6 @@ from typing import ( TYPE_CHECKING, Any, - Generic, Optional, ) @@ -46,7 +45,7 @@ from faststream.nats.helpers import KVBucketDeclarer, OSBucketDeclarer -class LogicSubscriber(SubscriberUsecase[MsgType], Generic[MsgType]): +class LogicSubscriber(SubscriberUsecase[MsgType]): """Basic class for all NATS Subscriber types (KeyValue, ObjectStorage, Core & JetStream).""" subscription: Optional[Unsubscriptable] @@ -66,10 +65,6 @@ def __init__( no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[MsgType]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: self.subject = subject self.config = config @@ -84,10 +79,6 @@ def __init__( no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, - # AsyncAPI args - title_=title_, - description_=description_, - include_in_schema=include_in_schema, ) self._fetch_sub = None @@ -201,10 +192,6 @@ def __init__( no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[MsgType]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: super().__init__( subject=subject, @@ -218,10 +205,6 @@ def __init__( no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, ) def _make_response_publisher( diff --git a/faststream/nats/subscriber/usecases/core_subscriber.py b/faststream/nats/subscriber/usecases/core_subscriber.py index 3cff6547d2..e8d2b6a045 100644 --- a/faststream/nats/subscriber/usecases/core_subscriber.py +++ b/faststream/nats/subscriber/usecases/core_subscriber.py @@ -43,10 +43,6 @@ def __init__( no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[Msg]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: parser_ = NatsParser(pattern=subject) @@ -64,10 +60,6 @@ def __init__( no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, ) @override @@ -148,10 +140,6 @@ def __init__( no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[Msg]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: super().__init__( max_workers=max_workers, @@ -164,10 +152,6 @@ def __init__( no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, ) @override diff --git a/faststream/nats/subscriber/usecases/key_value_subscriber.py b/faststream/nats/subscriber/usecases/key_value_subscriber.py index cf4a2a3f4e..9b3f27c494 100644 --- a/faststream/nats/subscriber/usecases/key_value_subscriber.py +++ b/faststream/nats/subscriber/usecases/key_value_subscriber.py @@ -52,10 +52,6 @@ def __init__( kv_watch: "KvWatch", broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[KeyValue.Entry]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: parser = KvParser(pattern=subject) self.kv_watch = kv_watch @@ -70,10 +66,6 @@ def __init__( default_decoder=parser.decode_message, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, ) @override diff --git a/faststream/nats/subscriber/usecases/object_storage_subscriber.py b/faststream/nats/subscriber/usecases/object_storage_subscriber.py index a1d5bace48..0e6332ce3e 100644 --- a/faststream/nats/subscriber/usecases/object_storage_subscriber.py +++ b/faststream/nats/subscriber/usecases/object_storage_subscriber.py @@ -56,10 +56,6 @@ def __init__( obj_watch: "ObjWatch", broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[list[Msg]]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: parser = ObjParser(pattern="") @@ -76,10 +72,6 @@ def __init__( default_decoder=parser.decode_message, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, ) @override diff --git a/faststream/nats/subscriber/usecases/stream_basic.py b/faststream/nats/subscriber/usecases/stream_basic.py index c053f2ce5e..80de14d278 100644 --- a/faststream/nats/subscriber/usecases/stream_basic.py +++ b/faststream/nats/subscriber/usecases/stream_basic.py @@ -50,10 +50,6 @@ def __init__( no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[Msg]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: parser_ = JsParser(pattern=subject) @@ -72,10 +68,6 @@ def __init__( no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, ) def get_log_context( diff --git a/faststream/nats/subscriber/usecases/stream_pull_subscriber.py b/faststream/nats/subscriber/usecases/stream_pull_subscriber.py index 44d82e89dd..7fa638eb11 100644 --- a/faststream/nats/subscriber/usecases/stream_pull_subscriber.py +++ b/faststream/nats/subscriber/usecases/stream_pull_subscriber.py @@ -58,10 +58,6 @@ def __init__( no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[Msg]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: self.pull_sub = pull_sub @@ -77,10 +73,6 @@ def __init__( no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, ) @override @@ -136,10 +128,6 @@ def __init__( no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[Msg]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: super().__init__( max_workers=max_workers, @@ -154,10 +142,6 @@ def __init__( no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, ) @override @@ -199,10 +183,6 @@ def __init__( no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[list[Msg]]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: parser = BatchParser(pattern=subject) @@ -221,10 +201,6 @@ def __init__( no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, ) @override diff --git a/faststream/nats/subscriber/usecases/stream_push_subscriber.py b/faststream/nats/subscriber/usecases/stream_push_subscriber.py index ac14ae3509..66ea31c68d 100644 --- a/faststream/nats/subscriber/usecases/stream_push_subscriber.py +++ b/faststream/nats/subscriber/usecases/stream_push_subscriber.py @@ -65,10 +65,6 @@ def __init__( no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[Msg]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: super().__init__( max_workers=max_workers, @@ -83,10 +79,6 @@ def __init__( no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, ) @override diff --git a/faststream/rabbit/broker/broker.py b/faststream/rabbit/broker/broker.py index b0e60e62cf..7b7e585829 100644 --- a/faststream/rabbit/broker/broker.py +++ b/faststream/rabbit/broker/broker.py @@ -59,7 +59,7 @@ from faststream.rabbit.message import RabbitMessage from faststream.rabbit.types import AioPikaSendableMessage from faststream.security import BaseSecurity - from faststream.specification.schema.tag import Tag, TagDict + from faststream.specification.schema.extra import Tag, TagDict class RabbitBroker( @@ -196,9 +196,9 @@ def __init__( Doc("AsyncAPI server description."), ] = None, tags: Annotated[ - Optional[Iterable[Union["Tag", "TagDict"]]], + Iterable[Union["Tag", "TagDict"]], Doc("AsyncAPI server tags."), - ] = None, + ] = (), # logging args logger: Annotated[ Optional["LoggerProto"], diff --git a/faststream/rabbit/fastapi/fastapi.py b/faststream/rabbit/fastapi/fastapi.py index 6e32718447..02d2d4b2e9 100644 --- a/faststream/rabbit/fastapi/fastapi.py +++ b/faststream/rabbit/fastapi/fastapi.py @@ -50,7 +50,7 @@ from faststream.rabbit.message import RabbitMessage from faststream.rabbit.publisher.specified import SpecificationPublisher from faststream.security import BaseSecurity - from faststream.specification.schema.tag import Tag, TagDict + from faststream.specification.schema.extra import Tag, TagDict class RabbitRouter(StreamRouter["IncomingMessage"]): @@ -176,9 +176,9 @@ def __init__( Doc("AsyncAPI server description."), ] = None, specification_tags: Annotated[ - Optional[Iterable[Union["Tag", "TagDict"]]], + Iterable[Union["Tag", "TagDict"]], Doc("AsyncAPI server tags."), - ] = None, + ] = (), # logging args logger: Annotated[ Optional["LoggerProto"], diff --git a/faststream/rabbit/publisher/specified.py b/faststream/rabbit/publisher/specified.py index 6d16769926..e8da19b3fd 100644 --- a/faststream/rabbit/publisher/specified.py +++ b/faststream/rabbit/publisher/specified.py @@ -1,34 +1,77 @@ +from collections.abc import Iterable +from typing import ( + TYPE_CHECKING, + Any, + Optional, +) + +from faststream._internal.publisher.specified import ( + SpecificationPublisher as SpecificationPublisherMixin, +) +from faststream.rabbit.schemas.proto import BaseRMQInformation as RMQSpecificationMixin from faststream.rabbit.utils import is_routing_exchange from faststream.specification.asyncapi.utils import resolve_payloads +from faststream.specification.schema import Message, Operation, PublisherSpec from faststream.specification.schema.bindings import ( ChannelBinding, OperationBinding, amqp, ) -from faststream.specification.schema.channel import Channel -from faststream.specification.schema.message import CorrelationId, Message -from faststream.specification.schema.operation import Operation -from .usecase import LogicPublisher +from .usecase import LogicPublisher, PublishKwargs +if TYPE_CHECKING: + from aio_pika import IncomingMessage -class SpecificationPublisher(LogicPublisher): - """AsyncAPI-compatible Rabbit Publisher class. + from faststream._internal.types import BrokerMiddleware, PublisherMiddleware + from faststream.rabbit.schemas import RabbitExchange, RabbitQueue - Creating by - ```python - publisher: SpecificationPublisher = ( - broker.publisher(...) - ) - # or - publisher: SpecificationPublisher = ( - router.publisher(...) - ) - ``` - """ +class SpecificationPublisher( + SpecificationPublisherMixin, + RMQSpecificationMixin, + LogicPublisher, +): + """AsyncAPI-compatible Rabbit Publisher class.""" - def get_name(self) -> str: + def __init__( + self, + *, + routing_key: str, + queue: "RabbitQueue", + exchange: "RabbitExchange", + # PublishCommand options + message_kwargs: "PublishKwargs", + # Publisher args + broker_middlewares: Iterable["BrokerMiddleware[IncomingMessage]"], + middlewares: Iterable["PublisherMiddleware"], + # AsyncAPI args + schema_: Optional[Any], + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, + ) -> None: + super().__init__( + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + schema_=schema_, + # propagate to RMQSpecificationMixin + queue=queue, + exchange=exchange, + ) + + LogicPublisher.__init__( + self, + queue=queue, + exchange=exchange, + routing_key=routing_key, + message_kwargs=message_kwargs, + middlewares=middlewares, + broker_middlewares=broker_middlewares, + ) + + def get_default_name(self) -> str: routing = ( self.routing_key or (self.queue.routing if is_routing_exchange(self.exchange) else None) @@ -37,26 +80,28 @@ def get_name(self) -> str: return f"{routing}:{getattr(self.exchange, 'name', None) or '_'}:Publisher" - def get_schema(self) -> dict[str, Channel]: + def get_schema(self) -> dict[str, PublisherSpec]: payloads = self.get_payloads() + exchange_binding = amqp.Exchange.from_exchange(self.exchange) + queue_binding = amqp.Queue.from_queue(self.queue) + return { - self.name: Channel( + self.name: PublisherSpec( description=self.description, - publish=Operation( + operation=Operation( bindings=OperationBinding( amqp=amqp.OperationBinding( - cc=self.routing or None, - deliveryMode=2 - if self.message_options.get("persist") - else 1, - replyTo=self.message_options.get("reply_to"), # type: ignore[arg-type] - mandatory=self.publish_options.get("mandatory"), # type: ignore[arg-type] - priority=self.message_options.get("priority"), # type: ignore[arg-type] + routing_key=self.routing or None, + queue=queue_binding, + exchange=exchange_binding, + ack=True, + persist=self.message_options.get("persist"), + priority=self.message_options.get("priority"), + reply_to=self.message_options.get("reply_to"), + mandatory=self.publish_options.get("mandatory"), ), - ) - if is_routing_exchange(self.exchange) - else None, + ), message=Message( title=f"{self.name}:Message", payload=resolve_payloads( @@ -64,34 +109,13 @@ def get_schema(self) -> dict[str, Channel]: "Publisher", served_words=2 if self.title_ is None else 1, ), - correlationId=CorrelationId( - location="$message.header#/correlation_id", - ), ), ), bindings=ChannelBinding( amqp=amqp.ChannelBinding( - is_="routingKey", - queue=amqp.Queue( - name=self.queue.name, - durable=self.queue.durable, - exclusive=self.queue.exclusive, - autoDelete=self.queue.auto_delete, - vhost=self.virtual_host, - ) - if is_routing_exchange(self.exchange) and self.queue.name - else None, - exchange=( - amqp.Exchange(type="default", vhost=self.virtual_host) - if not self.exchange.name - else amqp.Exchange( - type=self.exchange.type.value, - name=self.exchange.name, - durable=self.exchange.durable, - autoDelete=self.exchange.auto_delete, - vhost=self.virtual_host, - ) - ), + virtual_host=self.virtual_host, + queue=queue_binding, + exchange=exchange_binding, ), ), ), diff --git a/faststream/rabbit/publisher/usecase.py b/faststream/rabbit/publisher/usecase.py index f34cf06b3c..0ae13cf319 100644 --- a/faststream/rabbit/publisher/usecase.py +++ b/faststream/rabbit/publisher/usecase.py @@ -3,7 +3,6 @@ from typing import ( TYPE_CHECKING, Annotated, - Any, Optional, Union, ) @@ -15,7 +14,7 @@ from faststream._internal.utils.data import filter_by_dict from faststream.message import gen_cor_id from faststream.rabbit.response import RabbitPublishCommand -from faststream.rabbit.schemas import BaseRMQInformation, RabbitExchange, RabbitQueue +from faststream.rabbit.schemas import RabbitExchange, RabbitQueue from faststream.response.publish_type import PublishType from .options import MessageOptions, PublishOptions @@ -47,10 +46,7 @@ class PublishKwargs(MessageOptions, PublishOptions, total=False): ] -class LogicPublisher( - PublisherUsecase[IncomingMessage], - BaseRMQInformation, -): +class LogicPublisher(PublisherUsecase[IncomingMessage]): """A class to represent a RabbitMQ publisher.""" app_id: Optional[str] @@ -68,53 +64,38 @@ def __init__( # Publisher args broker_middlewares: Iterable["BrokerMiddleware[IncomingMessage]"], middlewares: Iterable["PublisherMiddleware"], - # AsyncAPI args - schema_: Optional[Any], - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: + self.queue = queue + self.routing_key = routing_key + + self.exchange = exchange + super().__init__( broker_middlewares=broker_middlewares, middlewares=middlewares, - # AsyncAPI args - schema_=schema_, - title_=title_, - description_=description_, - include_in_schema=include_in_schema, ) - self.routing_key = routing_key - request_options = dict(message_kwargs) self.headers = request_options.pop("headers") or {} self.reply_to = request_options.pop("reply_to", "") self.timeout = request_options.pop("timeout", None) - self.message_options = filter_by_dict(MessageOptions, request_options) - self.publish_options = filter_by_dict(PublishOptions, request_options) - # BaseRMQInformation - self.queue = queue - self.exchange = exchange + message_options, _ = filter_by_dict(MessageOptions, request_options) + self.message_options = message_options + + publish_options, _ = filter_by_dict(PublishOptions, request_options) + self.publish_options = publish_options - # Setup it later self.app_id = None - self.virtual_host = "" @override def _setup( # type: ignore[override] self, *, - app_id: Optional[str], - virtual_host: str, state: "BrokerState", ) -> None: - if app_id: - self.message_options["app_id"] = app_id - self.app_id = app_id - - self.virtual_host = virtual_host - + # AppId was set in `faststream.rabbit.schemas.proto.BaseRMQInformation` + self.message_options["app_id"] = self.app_id super()._setup(state=state) @property diff --git a/faststream/rabbit/schemas/proto.py b/faststream/rabbit/schemas/proto.py index 41045b94fa..2109772124 100644 --- a/faststream/rabbit/schemas/proto.py +++ b/faststream/rabbit/schemas/proto.py @@ -1,13 +1,40 @@ -from typing import Optional, Protocol +from typing import TYPE_CHECKING, Any, Optional -from faststream.rabbit.schemas.exchange import RabbitExchange -from faststream.rabbit.schemas.queue import RabbitQueue +if TYPE_CHECKING: + from faststream.rabbit.schemas.exchange import RabbitExchange + from faststream.rabbit.schemas.queue import RabbitQueue -class BaseRMQInformation(Protocol): +class BaseRMQInformation: """Base class to store Specification RMQ bindings.""" virtual_host: str - queue: RabbitQueue - exchange: RabbitExchange + queue: "RabbitQueue" + exchange: "RabbitExchange" app_id: Optional[str] + + def __init__( + self, + *, + queue: "RabbitQueue", + exchange: "RabbitExchange", + ) -> None: + self.queue = queue + self.exchange = exchange + + # Setup it later + self.app_id = None + self.virtual_host = "" + + def _setup( + self, + *, + app_id: Optional[str], + virtual_host: str, + **kwargs: Any, + ) -> None: + self.app_id = app_id + self.virtual_host = virtual_host + + # Setup next parent class + super()._setup(**kwargs) diff --git a/faststream/rabbit/subscriber/specified.py b/faststream/rabbit/subscriber/specified.py index 275f509d2b..b071ea2828 100644 --- a/faststream/rabbit/subscriber/specified.py +++ b/faststream/rabbit/subscriber/specified.py @@ -1,67 +1,107 @@ +from collections.abc import Iterable +from typing import TYPE_CHECKING, Optional + +from faststream._internal.subscriber.specified import ( + SpecificationSubscriber as SpecificationSubscriberMixin, +) +from faststream.rabbit.schemas.proto import BaseRMQInformation as RMQSpecificationMixin from faststream.rabbit.subscriber.usecase import LogicSubscriber -from faststream.rabbit.utils import is_routing_exchange from faststream.specification.asyncapi.utils import resolve_payloads +from faststream.specification.schema import Message, Operation, SubscriberSpec from faststream.specification.schema.bindings import ( ChannelBinding, OperationBinding, amqp, ) -from faststream.specification.schema.channel import Channel -from faststream.specification.schema.message import CorrelationId, Message -from faststream.specification.schema.operation import Operation +if TYPE_CHECKING: + from aio_pika import IncomingMessage + from fast_depends.dependencies import Dependant + + from faststream._internal.basic_types import AnyDict + from faststream._internal.types import BrokerMiddleware + from faststream.middlewares import AckPolicy + from faststream.rabbit.schemas.exchange import RabbitExchange + from faststream.rabbit.schemas.queue import RabbitQueue -class SpecificationSubscriber(LogicSubscriber): + +class SpecificationSubscriber( + SpecificationSubscriberMixin, + RMQSpecificationMixin, + LogicSubscriber, +): """AsyncAPI-compatible Rabbit Subscriber class.""" - def get_name(self) -> str: + def __init__( + self, + *, + queue: "RabbitQueue", + exchange: "RabbitExchange", + consume_args: Optional["AnyDict"], + # Subscriber args + ack_policy: "AckPolicy", + no_reply: bool, + broker_dependencies: Iterable["Dependant"], + broker_middlewares: Iterable["BrokerMiddleware[IncomingMessage]"], + # AsyncAPI args + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, + ) -> None: + super().__init__( + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + # propagate to RMQSpecificationMixin + queue=queue, + exchange=exchange, + ) + + LogicSubscriber.__init__( + self, + queue=queue, + consume_args=consume_args, + ack_policy=ack_policy, + no_reply=no_reply, + broker_dependencies=broker_dependencies, + broker_middlewares=broker_middlewares, + ) + + def get_default_name(self) -> str: return f"{self.queue.name}:{getattr(self.exchange, 'name', None) or '_'}:{self.call_name}" - def get_schema(self) -> dict[str, Channel]: + def get_schema(self) -> dict[str, SubscriberSpec]: payloads = self.get_payloads() + exchange_binding = amqp.Exchange.from_exchange(self.exchange) + queue_binding = amqp.Queue.from_queue(self.queue) + return { - self.name: Channel( + self.name: SubscriberSpec( description=self.description, - subscribe=Operation( + operation=Operation( bindings=OperationBinding( amqp=amqp.OperationBinding( - cc=self.queue.routing, + routing_key=self.queue.routing, + queue=queue_binding, + exchange=exchange_binding, + ack=True, + reply_to=None, + persist=None, + mandatory=None, + priority=None, ), - ) - if is_routing_exchange(self.exchange) - else None, + ), message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads), - correlationId=CorrelationId( - location="$message.header#/correlation_id", - ), ), ), bindings=ChannelBinding( amqp=amqp.ChannelBinding( - is_="routingKey", - queue=amqp.Queue( - name=self.queue.name, - durable=self.queue.durable, - exclusive=self.queue.exclusive, - autoDelete=self.queue.auto_delete, - vhost=self.virtual_host, - ) - if is_routing_exchange(self.exchange) and self.queue.name - else None, - exchange=( - amqp.Exchange(type="default", vhost=self.virtual_host) - if not self.exchange.name - else amqp.Exchange( - type=self.exchange.type.value, - name=self.exchange.name, - durable=self.exchange.durable, - autoDelete=self.exchange.auto_delete, - vhost=self.virtual_host, - ) - ), + virtual_host=self.virtual_host, + queue=queue_binding, + exchange=exchange_binding, ), ), ), diff --git a/faststream/rabbit/subscriber/usecase.py b/faststream/rabbit/subscriber/usecase.py index e91333ed25..df229a5cc4 100644 --- a/faststream/rabbit/subscriber/usecase.py +++ b/faststream/rabbit/subscriber/usecase.py @@ -15,7 +15,6 @@ from faststream.exceptions import SetupError from faststream.rabbit.parser import AioPikaParser from faststream.rabbit.publisher.fake import RabbitFakePublisher -from faststream.rabbit.schemas import BaseRMQInformation if TYPE_CHECKING: from aio_pika import IncomingMessage, RobustQueue @@ -36,10 +35,7 @@ ) -class LogicSubscriber( - SubscriberUsecase["IncomingMessage"], - BaseRMQInformation, -): +class LogicSubscriber(SubscriberUsecase["IncomingMessage"]): """A class to handle logic for RabbitMQ message consumption.""" app_id: Optional[str] @@ -53,18 +49,15 @@ def __init__( self, *, queue: "RabbitQueue", - exchange: "RabbitExchange", consume_args: Optional["AnyDict"], # Subscriber args ack_policy: "AckPolicy", no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[IncomingMessage]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: + self.queue = queue + parser = AioPikaParser(pattern=queue.path_regex) super().__init__( @@ -75,10 +68,6 @@ def __init__( no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, - # AsyncAPI - title_=title_, - description_=description_, - include_in_schema=include_in_schema, ) self.consume_args = consume_args or {} @@ -86,20 +75,13 @@ def __init__( self._consumer_tag = None self._queue_obj = None - # BaseRMQInformation - self.queue = queue - self.exchange = exchange # Setup it later - self.app_id = None - self.virtual_host = "" self.declarer = None @override def _setup( # type: ignore[override] self, *, - app_id: Optional[str], - virtual_host: str, declarer: "RabbitDeclarer", # basic args extra_context: "AnyDict", @@ -109,8 +91,6 @@ def _setup( # type: ignore[override] # dependant args state: "BrokerState", ) -> None: - self.app_id = app_id - self.virtual_host = virtual_host self.declarer = declarer super()._setup( diff --git a/faststream/redis/broker/broker.py b/faststream/redis/broker/broker.py index 8b5a0a0017..bae4bd9de3 100644 --- a/faststream/redis/broker/broker.py +++ b/faststream/redis/broker/broker.py @@ -56,7 +56,7 @@ ) from faststream.redis.message import BaseMessage, RedisMessage from faststream.security import BaseSecurity - from faststream.specification.schema.tag import Tag, TagDict + from faststream.specification.schema.extra import Tag, TagDict class RedisInitKwargs(TypedDict, total=False): host: Optional[str] @@ -162,9 +162,9 @@ def __init__( Doc("AsyncAPI server description."), ] = None, tags: Annotated[ - Optional[Iterable[Union["Tag", "TagDict"]]], + Iterable[Union["Tag", "TagDict"]], Doc("AsyncAPI server tags."), - ] = None, + ] = (), # logging args logger: Annotated[ Optional["LoggerProto"], diff --git a/faststream/redis/fastapi/fastapi.py b/faststream/redis/fastapi/fastapi.py index 032b04d994..3afad46036 100644 --- a/faststream/redis/fastapi/fastapi.py +++ b/faststream/redis/fastapi/fastapi.py @@ -50,7 +50,7 @@ from faststream.redis.message import UnifyRedisMessage from faststream.redis.publisher.specified import SpecificationPublisher from faststream.security import BaseSecurity - from faststream.specification.schema.tag import Tag, TagDict + from faststream.specification.schema.extra import Tag, TagDict class RedisRouter(StreamRouter[UnifyRedisDict]): @@ -125,9 +125,9 @@ def __init__( Doc("AsyncAPI server description."), ] = None, specification_tags: Annotated[ - Optional[Iterable[Union["Tag", "TagDict"]]], + Iterable[Union["Tag", "TagDict"]], Doc("AsyncAPI server tags."), - ] = None, + ] = (), # logging args logger: Annotated[ Optional["LoggerProto"], diff --git a/faststream/redis/publisher/specified.py b/faststream/redis/publisher/specified.py index f0598834c6..3ccd57c931 100644 --- a/faststream/redis/publisher/specified.py +++ b/faststream/redis/publisher/specified.py @@ -1,40 +1,41 @@ from typing import TYPE_CHECKING +from faststream._internal.publisher.specified import ( + SpecificationPublisher as SpecificationPublisherMixin, +) from faststream.redis.publisher.usecase import ( ChannelPublisher, ListBatchPublisher, ListPublisher, - LogicPublisher, StreamPublisher, ) from faststream.redis.schemas.proto import RedisSpecificationProtocol from faststream.specification.asyncapi.utils import resolve_payloads +from faststream.specification.schema import Message, Operation, PublisherSpec from faststream.specification.schema.bindings import ChannelBinding, redis -from faststream.specification.schema.channel import Channel -from faststream.specification.schema.message import CorrelationId, Message -from faststream.specification.schema.operation import Operation if TYPE_CHECKING: from faststream.redis.schemas import ListSub -class SpecificationPublisher(LogicPublisher, RedisSpecificationProtocol): +class SpecificationPublisher( + SpecificationPublisherMixin, + RedisSpecificationProtocol[PublisherSpec], +): """A class to represent a Redis publisher.""" - def get_schema(self) -> dict[str, Channel]: + def get_schema(self) -> dict[str, PublisherSpec]: payloads = self.get_payloads() return { - self.name: Channel( + self.name: PublisherSpec( description=self.description, - publish=Operation( + operation=Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads, "Publisher"), - correlationId=CorrelationId( - location="$message.header#/correlation_id", - ), ), + bindings=None, ), bindings=ChannelBinding( redis=self.channel_binding, @@ -43,8 +44,8 @@ def get_schema(self) -> dict[str, Channel]: } -class SpecificationChannelPublisher(ChannelPublisher, SpecificationPublisher): - def get_name(self) -> str: +class SpecificationChannelPublisher(SpecificationPublisher, ChannelPublisher): + def get_default_name(self) -> str: return f"{self.channel.name}:Publisher" @property @@ -58,7 +59,7 @@ def channel_binding(self) -> "redis.ChannelBinding": class _ListPublisherMixin(SpecificationPublisher): list: "ListSub" - def get_name(self) -> str: + def get_default_name(self) -> str: return f"{self.list.name}:Publisher" @property @@ -69,16 +70,16 @@ def channel_binding(self) -> "redis.ChannelBinding": ) -class SpecificationListPublisher(ListPublisher, _ListPublisherMixin): +class SpecificationListPublisher(_ListPublisherMixin, ListPublisher): pass -class SpecificationListBatchPublisher(ListBatchPublisher, _ListPublisherMixin): +class SpecificationListBatchPublisher(_ListPublisherMixin, ListBatchPublisher): pass -class SpecificationStreamPublisher(StreamPublisher, SpecificationPublisher): - def get_name(self) -> str: +class SpecificationStreamPublisher(SpecificationPublisher, StreamPublisher): + def get_default_name(self) -> str: return f"{self.stream.name}:Publisher" @property diff --git a/faststream/redis/publisher/usecase.py b/faststream/redis/publisher/usecase.py index 479b9ccf66..601d18130c 100644 --- a/faststream/redis/publisher/usecase.py +++ b/faststream/redis/publisher/usecase.py @@ -33,20 +33,10 @@ def __init__( # Publisher args broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], middlewares: Iterable["PublisherMiddleware"], - # AsyncAPI args - schema_: Optional[Any], - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: super().__init__( broker_middlewares=broker_middlewares, middlewares=middlewares, - # AsyncAPI args - schema_=schema_, - title_=title_, - description_=description_, - include_in_schema=include_in_schema, ) self.reply_to = reply_to @@ -67,21 +57,12 @@ def __init__( # Regular publisher options broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], middlewares: Iterable["PublisherMiddleware"], - # AsyncAPI options - schema_: Optional[Any], - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: super().__init__( reply_to=reply_to, headers=headers, broker_middlewares=broker_middlewares, middlewares=middlewares, - schema_=schema_, - title_=title_, - description_=description_, - include_in_schema=include_in_schema, ) self.channel = channel @@ -204,21 +185,12 @@ def __init__( # Regular publisher options broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], middlewares: Iterable["PublisherMiddleware"], - # AsyncAPI options - schema_: Optional[Any], - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: super().__init__( reply_to=reply_to, headers=headers, broker_middlewares=broker_middlewares, middlewares=middlewares, - schema_=schema_, - title_=title_, - description_=description_, - include_in_schema=include_in_schema, ) self.list = list @@ -399,21 +371,12 @@ def __init__( # Regular publisher options broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], middlewares: Iterable["PublisherMiddleware"], - # AsyncAPI options - schema_: Optional[Any], - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: super().__init__( reply_to=reply_to, headers=headers, broker_middlewares=broker_middlewares, middlewares=middlewares, - schema_=schema_, - title_=title_, - description_=description_, - include_in_schema=include_in_schema, ) self.stream = stream diff --git a/faststream/redis/schemas/proto.py b/faststream/redis/schemas/proto.py index 685d4aa679..1f4191df73 100644 --- a/faststream/redis/schemas/proto.py +++ b/faststream/redis/schemas/proto.py @@ -2,14 +2,14 @@ from typing import TYPE_CHECKING, Any, Union from faststream.exceptions import SetupError -from faststream.specification.base.proto import SpecificationEndpoint +from faststream.specification.proto.endpoint import EndpointSpecification, T if TYPE_CHECKING: from faststream.redis.schemas import ListSub, PubSub, StreamSub from faststream.specification.schema.bindings import redis -class RedisSpecificationProtocol(SpecificationEndpoint): +class RedisSpecificationProtocol(EndpointSpecification[T]): @property @abstractmethod def channel_binding(self) -> "redis.ChannelBinding": ... diff --git a/faststream/redis/subscriber/specified.py b/faststream/redis/subscriber/specified.py index 800e5b1f02..e943a80aeb 100644 --- a/faststream/redis/subscriber/specified.py +++ b/faststream/redis/subscriber/specified.py @@ -1,37 +1,37 @@ +from faststream._internal.subscriber.specified import ( + SpecificationSubscriber as SpecificationSubscriberMixin, +) from faststream.redis.schemas import ListSub, StreamSub from faststream.redis.schemas.proto import RedisSpecificationProtocol from faststream.redis.subscriber.usecase import ( BatchListSubscriber, ChannelSubscriber, ListSubscriber, - LogicSubscriber, StreamBatchSubscriber, StreamSubscriber, ) from faststream.specification.asyncapi.utils import resolve_payloads +from faststream.specification.schema import Message, Operation, SubscriberSpec from faststream.specification.schema.bindings import ChannelBinding, redis -from faststream.specification.schema.channel import Channel -from faststream.specification.schema.message import CorrelationId, Message -from faststream.specification.schema.operation import Operation -class SpecificationSubscriber(LogicSubscriber, RedisSpecificationProtocol): +class SpecificationSubscriber( + SpecificationSubscriberMixin, RedisSpecificationProtocol[SubscriberSpec] +): """A class to represent a Redis handler.""" - def get_schema(self) -> dict[str, Channel]: + def get_schema(self) -> dict[str, SubscriberSpec]: payloads = self.get_payloads() return { - self.name: Channel( + self.name: SubscriberSpec( description=self.description, - subscribe=Operation( + operation=Operation( message=Message( title=f"{self.name}:Message", payload=resolve_payloads(payloads), - correlationId=CorrelationId( - location="$message.header#/correlation_id", - ), ), + bindings=None, ), bindings=ChannelBinding( redis=self.channel_binding, @@ -40,8 +40,8 @@ def get_schema(self) -> dict[str, Channel]: } -class SpecificationChannelSubscriber(ChannelSubscriber, SpecificationSubscriber): - def get_name(self) -> str: +class SpecificationChannelSubscriber(SpecificationSubscriber, ChannelSubscriber): + def get_default_name(self) -> str: return f"{self.channel.name}:{self.call_name}" @property @@ -55,7 +55,7 @@ def channel_binding(self) -> "redis.ChannelBinding": class _StreamSubscriberMixin(SpecificationSubscriber): stream_sub: StreamSub - def get_name(self) -> str: + def get_default_name(self) -> str: return f"{self.stream_sub.name}:{self.call_name}" @property @@ -68,18 +68,18 @@ def channel_binding(self) -> "redis.ChannelBinding": ) -class SpecificationStreamSubscriber(StreamSubscriber, _StreamSubscriberMixin): +class SpecificationStreamSubscriber(_StreamSubscriberMixin, StreamSubscriber): pass -class SpecificationStreamBatchSubscriber(StreamBatchSubscriber, _StreamSubscriberMixin): +class SpecificationStreamBatchSubscriber(_StreamSubscriberMixin, StreamBatchSubscriber): pass class _ListSubscriberMixin(SpecificationSubscriber): list_sub: ListSub - def get_name(self) -> str: + def get_default_name(self) -> str: return f"{self.list_sub.name}:{self.call_name}" @property @@ -90,9 +90,9 @@ def channel_binding(self) -> "redis.ChannelBinding": ) -class SpecificationListSubscriber(ListSubscriber, _ListSubscriberMixin): +class SpecificationListSubscriber(_ListSubscriberMixin, ListSubscriber): pass -class SpecificationListBatchSubscriber(BatchListSubscriber, _ListSubscriberMixin): +class SpecificationListBatchSubscriber(_ListSubscriberMixin, BatchListSubscriber): pass diff --git a/faststream/redis/subscriber/usecase.py b/faststream/redis/subscriber/usecase.py index 1f89ca54b4..4d689a9193 100644 --- a/faststream/redis/subscriber/usecase.py +++ b/faststream/redis/subscriber/usecase.py @@ -76,10 +76,6 @@ def __init__( no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: super().__init__( default_parser=default_parser, @@ -89,10 +85,6 @@ def __init__( no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, - # AsyncAPI - title_=title_, - description_=description_, - include_in_schema=include_in_schema, ) self._client = None @@ -208,10 +200,6 @@ def __init__( no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: parser = RedisPubSubParser(pattern=channel.path_regex) super().__init__( @@ -222,10 +210,6 @@ def __init__( no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, - # AsyncAPI - title_=title_, - description_=description_, - include_in_schema=include_in_schema, ) self.channel = channel @@ -333,10 +317,6 @@ def __init__( no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: super().__init__( default_parser=default_parser, @@ -346,10 +326,6 @@ def __init__( no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, - # AsyncAPI - title_=title_, - description_=description_, - include_in_schema=include_in_schema, ) self.list_sub = list @@ -438,10 +414,6 @@ def __init__( no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: parser = RedisListParser() super().__init__( @@ -453,10 +425,6 @@ def __init__( no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, - # AsyncAPI - title_=title_, - description_=description_, - include_in_schema=include_in_schema, ) async def _get_msgs(self, client: "Redis[bytes]") -> None: @@ -486,10 +454,6 @@ def __init__( no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: parser = RedisBatchListParser() super().__init__( @@ -501,10 +465,6 @@ def __init__( no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, - # AsyncAPI - title_=title_, - description_=description_, - include_in_schema=include_in_schema, ) async def _get_msgs(self, client: "Redis[bytes]") -> None: @@ -538,10 +498,6 @@ def __init__( no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: super().__init__( default_parser=default_parser, @@ -551,10 +507,6 @@ def __init__( no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, - # AsyncAPI - title_=title_, - description_=description_, - include_in_schema=include_in_schema, ) self.stream_sub = stream @@ -728,10 +680,6 @@ def __init__( no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: parser = RedisStreamParser() super().__init__( @@ -743,10 +691,6 @@ def __init__( no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, - # AsyncAPI - title_=title_, - description_=description_, - include_in_schema=include_in_schema, ) async def _get_msgs( @@ -795,10 +739,6 @@ def __init__( no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, ) -> None: parser = RedisBatchStreamParser() super().__init__( @@ -810,10 +750,6 @@ def __init__( no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, - # AsyncAPI - title_=title_, - description_=description_, - include_in_schema=include_in_schema, ) async def _get_msgs( diff --git a/faststream/specification/__init__.py b/faststream/specification/__init__.py index 502bf43de6..7738408d36 100644 --- a/faststream/specification/__init__.py +++ b/faststream/specification/__init__.py @@ -1,5 +1,5 @@ from .asyncapi.factory import AsyncAPI -from .schema import Contact, ExternalDocs, License, Tag +from .schema.extra import Contact, ExternalDocs, License, Tag __all__ = ( "AsyncAPI", diff --git a/faststream/specification/asyncapi/factory.py b/faststream/specification/asyncapi/factory.py index 7b537be3c8..5137f6cfa1 100644 --- a/faststream/specification/asyncapi/factory.py +++ b/faststream/specification/asyncapi/factory.py @@ -1,4 +1,4 @@ -from collections.abc import Sequence +from collections.abc import Iterable from typing import TYPE_CHECKING, Any, Literal, Optional, Union from faststream.specification.base.specification import Specification @@ -6,13 +6,39 @@ if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict, AnyHttpUrl from faststream._internal.broker.broker import BrokerUsecase - from faststream.specification.schema.contact import Contact, ContactDict - from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict - from faststream.specification.schema.license import License, LicenseDict - from faststream.specification.schema.tag import Tag, TagDict + from faststream.specification.schema import ( + Contact, + ContactDict, + ExternalDocs, + ExternalDocsDict, + License, + LicenseDict, + Tag, + TagDict, + ) class AsyncAPI(Specification): + # Empty init for correct typehints + def __init__( + self, + broker: "BrokerUsecase[Any, Any]", + /, + title: str = "FastStream", + app_version: str = "0.1.0", + schema_version: Union[Literal["3.0.0", "2.6.0"], str] = "3.0.0", + description: str = "", + terms_of_service: Optional["AnyHttpUrl"] = None, + license: Optional[Union["License", "LicenseDict", "AnyDict"]] = None, + contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] = None, + tags: Iterable[Union["Tag", "TagDict", "AnyDict"]] = (), + external_docs: Optional[ + Union["ExternalDocs", "ExternalDocsDict", "AnyDict"] + ] = None, + identifier: Optional[str] = None, + ) -> Specification: + pass + def __new__( # type: ignore[misc] cls, broker: "BrokerUsecase[Any, Any]", @@ -24,7 +50,7 @@ def __new__( # type: ignore[misc] terms_of_service: Optional["AnyHttpUrl"] = None, license: Optional[Union["License", "LicenseDict", "AnyDict"]] = None, contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] = None, - tags: Optional[Sequence[Union["Tag", "TagDict", "AnyDict"]]] = None, + tags: Iterable[Union["Tag", "TagDict", "AnyDict"]] = (), external_docs: Optional[ Union["ExternalDocs", "ExternalDocsDict", "AnyDict"] ] = None, diff --git a/faststream/specification/asyncapi/utils.py b/faststream/specification/asyncapi/utils.py index 2e6ffadfe2..7f16a215dc 100644 --- a/faststream/specification/asyncapi/utils.py +++ b/faststream/specification/asyncapi/utils.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Any if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict @@ -49,3 +49,36 @@ def resolve_payloads( def clear_key(key: str) -> str: return key.replace("/", ".") + + +def move_pydantic_refs( + original: Any, + key: str, +) -> Any: + """Remove pydantic references and replacem them by real schemas.""" + if not isinstance(original, dict): + return original + + data = original.copy() + + for k in data: + item = data[k] + + if isinstance(item, str): + if key in item: + data[k] = data[k].replace(key, "components/schemas") + + elif isinstance(item, dict): + data[k] = move_pydantic_refs(data[k], key) + + elif isinstance(item, list): + for i in range(len(data[k])): + data[k][i] = move_pydantic_refs(item[i], key) + + if ( + isinstance(desciminator := data.get("discriminator"), dict) + and "propertyName" in desciminator + ): + data["discriminator"] = desciminator["propertyName"] + + return data diff --git a/faststream/specification/asyncapi/v2_6_0/facade.py b/faststream/specification/asyncapi/v2_6_0/facade.py index 80c7cedd38..d8c4b5618b 100644 --- a/faststream/specification/asyncapi/v2_6_0/facade.py +++ b/faststream/specification/asyncapi/v2_6_0/facade.py @@ -1,18 +1,24 @@ -from collections.abc import Sequence +from collections.abc import Iterable from typing import TYPE_CHECKING, Any, Optional, Union from faststream.specification.base.specification import Specification from .generate import get_app_schema -from .schema import Schema +from .schema import ApplicationSchema if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict, AnyHttpUrl from faststream._internal.broker.broker import BrokerUsecase - from faststream.specification.schema.contact import Contact, ContactDict - from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict - from faststream.specification.schema.license import License, LicenseDict - from faststream.specification.schema.tag import Tag, TagDict + from faststream.specification.schema import ( + Contact, + ContactDict, + ExternalDocs, + ExternalDocsDict, + License, + LicenseDict, + Tag, + TagDict, + ) class AsyncAPI2(Specification): @@ -28,7 +34,7 @@ def __init__( contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] = None, license: Optional[Union["License", "LicenseDict", "AnyDict"]] = None, identifier: Optional[str] = None, - tags: Optional[Sequence[Union["Tag", "TagDict", "AnyDict"]]] = None, + tags: Iterable[Union["Tag", "TagDict", "AnyDict"]] = (), external_docs: Optional[ Union["ExternalDocs", "ExternalDocsDict", "AnyDict"] ] = None, @@ -55,7 +61,7 @@ def to_yaml(self) -> str: return self.schema.to_yaml() @property - def schema(self) -> Schema: # type: ignore[override] + def schema(self) -> ApplicationSchema: # type: ignore[override] return get_app_schema( self.broker, title=self.title, diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index 2c6a3b3900..4c81514da7 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -4,32 +4,33 @@ from faststream._internal._compat import DEF_KEY from faststream._internal.basic_types import AnyDict, AnyHttpUrl from faststream._internal.constants import ContentTypes -from faststream.specification.asyncapi.utils import clear_key +from faststream.specification.asyncapi.utils import clear_key, move_pydantic_refs from faststream.specification.asyncapi.v2_6_0.schema import ( + ApplicationInfo, + ApplicationSchema, Channel, Components, - Info, + Contact, + ExternalDocs, + License, + Message, Reference, - Schema, Server, Tag, - channel_from_spec, - contact_from_spec, - docs_from_spec, - license_from_spec, - tag_from_spec, ) -from faststream.specification.asyncapi.v2_6_0.schema.message import Message if TYPE_CHECKING: from faststream._internal.broker.broker import BrokerUsecase from faststream._internal.types import ConnectionType, MsgType - from faststream.specification.schema.contact import Contact, ContactDict - from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict - from faststream.specification.schema.license import License, LicenseDict - from faststream.specification.schema.tag import ( - Tag as SpecsTag, - TagDict as SpecsTagDict, + from faststream.specification.schema.extra import ( + Contact as SpecContact, + ContactDict, + ExternalDocs as SpecDocs, + ExternalDocsDict, + License as SpecLicense, + LicenseDict, + Tag as SpecTag, + TagDict, ) @@ -41,12 +42,12 @@ def get_app_schema( schema_version: str, description: str, terms_of_service: Optional["AnyHttpUrl"], - contact: Optional[Union["Contact", "ContactDict", "AnyDict"]], - license: Optional[Union["License", "LicenseDict", "AnyDict"]], + contact: Optional[Union["SpecContact", "ContactDict", "AnyDict"]], + license: Optional[Union["SpecLicense", "LicenseDict", "AnyDict"]], identifier: Optional[str], - tags: Optional[Sequence[Union["SpecsTag", "SpecsTagDict", "AnyDict"]]], - external_docs: Optional[Union["ExternalDocs", "ExternalDocsDict", "AnyDict"]], -) -> Schema: + tags: Sequence[Union["SpecTag", "TagDict", "AnyDict"]], + external_docs: Optional[Union["SpecDocs", "ExternalDocsDict", "AnyDict"]], +) -> ApplicationSchema: """Get the application schema.""" broker._setup() @@ -62,20 +63,20 @@ def get_app_schema( for channel_name, ch in channels.items(): resolve_channel_messages(ch, channel_name, payloads, messages) - return Schema( - info=Info( + return ApplicationSchema( + info=ApplicationInfo( title=title, version=app_version, description=description, termsOfService=terms_of_service, - contact=contact_from_spec(contact) if contact else None, - license=license_from_spec(license) if license else None, + contact=Contact.from_spec(contact), + license=License.from_spec(license), ), + tags=[Tag.from_spec(tag) for tag in tags] or None, + externalDocs=ExternalDocs.from_spec(external_docs), asyncapi=schema_version, defaultContentType=ContentTypes.JSON.value, id=identifier, - tags=[tag_from_spec(tag) for tag in tags] if tags else None, - externalDocs=docs_from_spec(external_docs) if external_docs else None, servers=servers, channels=channels, components=Components( @@ -121,31 +122,22 @@ def get_broker_server( """Get the broker server for an application.""" servers = {} - tags: Optional[list[Union[Tag, AnyDict]]] = None - if broker.tags: - tags = [tag_from_spec(tag) for tag in broker.tags] - broker_meta: AnyDict = { "protocol": broker.protocol, "protocolVersion": broker.protocol_version, "description": broker.description, - "tags": tags or None, + "tags": [Tag.from_spec(tag) for tag in broker.tags] or None, + "security": broker.security.get_requirement() if broker.security else None, # TODO # "variables": "", # "bindings": "", } - if broker.security is not None: - broker_meta["security"] = broker.security.get_requirement() - urls = broker.url if isinstance(broker.url, list) else [broker.url] for i, url in enumerate(urls, 1): server_name = "development" if len(urls) == 1 else f"Server{i}" - servers[server_name] = Server( - url=url, - **broker_meta, - ) + servers[server_name] = Server(url=url, **broker_meta) return servers @@ -157,16 +149,16 @@ def get_broker_channels( channels = {} for h in broker._subscribers: - schema = h.schema() - channels.update( - {key: channel_from_spec(channel) for key, channel in schema.items()}, - ) + # TODO: add duplication key warning + channels.update({ + key: Channel.from_sub(channel) for key, channel in h.schema().items() + }) for p in broker._publishers: - schema = p.schema() - channels.update( - {key: channel_from_spec(channel) for key, channel in schema.items()}, - ) + # TODO: add duplication key warning + channels.update({ + key: Channel.from_pub(channel) for key, channel in p.schema().items() + }) return channels @@ -223,36 +215,3 @@ def _resolve_msg_payloads( message_title = clear_key(m.title) messages[message_title] = m return Reference(**{"$ref": f"#/components/messages/{message_title}"}) - - -def move_pydantic_refs( - original: Any, - key: str, -) -> Any: - """Remove pydantic references and replacem them by real schemas.""" - if not isinstance(original, dict): - return original - - data = original.copy() - - for k in data: - item = data[k] - - if isinstance(item, str): - if key in item: - data[k] = data[k].replace(key, "components/schemas") - - elif isinstance(item, dict): - data[k] = move_pydantic_refs(data[k], key) - - elif isinstance(item, list): - for i in range(len(data[k])): - data[k][i] = move_pydantic_refs(item[i], key) - - if ( - isinstance(desciminator := data.get("discriminator"), dict) - and "propertyName" in desciminator - ): - data["discriminator"] = desciminator["propertyName"] - - return data diff --git a/faststream/specification/asyncapi/v2_6_0/schema/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/__init__.py index 1e29c5b8cd..e0cbcbd7b2 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/__init__.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/__init__.py @@ -1,61 +1,31 @@ -from .channels import ( - Channel, - from_spec as channel_from_spec, -) +from .channels import Channel from .components import Components -from .contact import ( - Contact, - from_spec as contact_from_spec, -) -from .docs import ( - ExternalDocs, - from_spec as docs_from_spec, -) -from .info import Info -from .license import ( - License, - from_spec as license_from_spec, -) -from .message import ( - CorrelationId, - Message, - from_spec as message_from_spec, -) -from .operations import ( - Operation, - from_spec as operation_from_spec, -) -from .schema import Schema +from .contact import Contact +from .docs import ExternalDocs +from .info import ApplicationInfo +from .license import License +from .message import CorrelationId, Message +from .operations import Operation +from .schema import ApplicationSchema from .servers import Server, ServerVariable -from .tag import ( - Tag, - from_spec as tag_from_spec, -) +from .tag import Tag from .utils import Parameter, Reference __all__ = ( + "ApplicationInfo", + "ApplicationSchema", "Channel", "Channel", "Components", "Contact", "CorrelationId", "ExternalDocs", - "Info", "License", "Message", "Operation", "Parameter", "Reference", - "Schema", "Server", "ServerVariable", "Tag", - "channel_from_spec", - "channel_from_spec", - "contact_from_spec", - "docs_from_spec", - "license_from_spec", - "message_from_spec", - "operation_from_spec", - "tag_from_spec", ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/__init__.py index a0e9cb8389..84b0fa22e8 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/__init__.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/__init__.py @@ -1,13 +1,6 @@ -from .main import ( - ChannelBinding, - OperationBinding, - channel_binding_from_spec, - operation_binding_from_spec, -) +from .main import ChannelBinding, OperationBinding __all__ = ( "ChannelBinding", "OperationBinding", - "channel_binding_from_spec", - "operation_binding_from_spec", ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/__init__.py index 7ead3ce532..8555fd981a 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/__init__.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/__init__.py @@ -1,15 +1,7 @@ -from .channel import ( - ChannelBinding, - from_spec as channel_binding_from_spec, -) -from .operation import ( - OperationBinding, - from_spec as operation_binding_from_spec, -) +from .channel import ChannelBinding +from .operation import OperationBinding __all__ = ( "ChannelBinding", "OperationBinding", - "channel_binding_from_spec", - "operation_binding_from_spec", ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py index 1317967a1d..aa729dce29 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel.py @@ -3,12 +3,12 @@ References: https://github.com/asyncapi/bindings/tree/master/amqp """ -from typing import Literal, Optional +from typing import Literal, Optional, overload from pydantic import BaseModel, Field from typing_extensions import Self -from faststream.specification import schema as spec +from faststream.specification.schema.bindings import amqp class Queue(BaseModel): @@ -28,14 +28,25 @@ class Queue(BaseModel): autoDelete: bool vhost: str = "/" + @overload @classmethod - def from_spec(cls, binding: spec.bindings.amqp.Queue) -> Self: + def from_spec(cls, binding: None, vhost: str) -> None: ... + + @overload + @classmethod + def from_spec(cls, binding: amqp.Queue, vhost: str) -> Self: ... + + @classmethod + def from_spec(cls, binding: Optional[amqp.Queue], vhost: str) -> Optional[Self]: + if binding is None: + return None + return cls( name=binding.name, durable=binding.durable, exclusive=binding.exclusive, - autoDelete=binding.autoDelete, - vhost=binding.vhost, + autoDelete=binding.auto_delete, + vhost=vhost, ) @@ -65,14 +76,25 @@ class Exchange(BaseModel): autoDelete: Optional[bool] = None vhost: str = "/" + @overload + @classmethod + def from_spec(cls, binding: None, vhost: str) -> None: ... + + @overload + @classmethod + def from_spec(cls, binding: amqp.Exchange, vhost: str) -> Self: ... + @classmethod - def from_spec(cls, binding: spec.bindings.amqp.Exchange) -> Self: + def from_spec(cls, binding: Optional[amqp.Exchange], vhost: str) -> Optional[Self]: + if binding is None: + return None + return cls( name=binding.name, type=binding.type, durable=binding.durable, - autoDelete=binding.autoDelete, - vhost=binding.vhost, + autoDelete=binding.auto_delete, + vhost=vhost, ) @@ -92,19 +114,31 @@ class ChannelBinding(BaseModel): exchange: Optional[Exchange] = None @classmethod - def from_spec(cls, binding: spec.bindings.amqp.ChannelBinding) -> Self: + def from_sub(cls, binding: Optional[amqp.ChannelBinding]) -> Optional[Self]: + if binding is None: + return None + return cls( **{ - "is": binding.is_, - "queue": Queue.from_spec(binding.queue) - if binding.queue is not None - else None, - "exchange": Exchange.from_spec(binding.exchange) - if binding.exchange is not None + "is": "routingKey", + "queue": Queue.from_spec(binding.queue, binding.virtual_host) + if binding.exchange.is_respect_routing_key else None, + "exchange": Exchange.from_spec(binding.exchange, binding.virtual_host), }, ) + @classmethod + def from_pub(cls, binding: Optional[amqp.ChannelBinding]) -> Optional[Self]: + if binding is None: + return None -def from_spec(binding: spec.bindings.amqp.ChannelBinding) -> ChannelBinding: - return ChannelBinding.from_spec(binding) + return cls( + **{ + "is": "routingKey", + "queue": Queue.from_spec(binding.queue, binding.virtual_host) + if binding.exchange.is_respect_routing_key and binding.queue.name + else None, + "exchange": Exchange.from_spec(binding.exchange, binding.virtual_host), + }, + ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation.py index cd90dde96d..47ed19af93 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation.py @@ -8,7 +8,7 @@ from pydantic import BaseModel, PositiveInt from typing_extensions import Self -from faststream.specification import schema as spec +from faststream.specification.schema.bindings import amqp class OperationBinding(BaseModel): @@ -22,24 +22,38 @@ class OperationBinding(BaseModel): """ cc: Optional[str] = None - ack: bool = True + ack: bool replyTo: Optional[str] = None deliveryMode: Optional[int] = None mandatory: Optional[bool] = None priority: Optional[PositiveInt] = None + bindingVersion: str = "0.2.0" @classmethod - def from_spec(cls, binding: spec.bindings.amqp.OperationBinding) -> Self: + def from_sub(cls, binding: Optional[amqp.OperationBinding]) -> Optional[Self]: + if not binding: + return None + return cls( - cc=binding.cc, + cc=binding.routing_key if binding.exchange.is_respect_routing_key else None, ack=binding.ack, - replyTo=binding.replyTo, - deliveryMode=binding.deliveryMode, + replyTo=binding.reply_to, + deliveryMode=None if binding.persist is None else int(binding.persist) + 1, mandatory=binding.mandatory, priority=binding.priority, ) + @classmethod + def from_pub(cls, binding: Optional[amqp.OperationBinding]) -> Optional[Self]: + if not binding: + return None -def from_spec(binding: spec.bindings.amqp.OperationBinding) -> OperationBinding: - return OperationBinding.from_spec(binding) + return cls( + cc=binding.routing_key if binding.exchange.is_respect_routing_key else None, + ack=binding.ack, + replyTo=binding.reply_to, + deliveryMode=None if binding.persist is None else int(binding.persist) + 1, + mandatory=binding.mandatory, + priority=binding.priority, + ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/__init__.py index 7ead3ce532..8555fd981a 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/__init__.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/__init__.py @@ -1,15 +1,7 @@ -from .channel import ( - ChannelBinding, - from_spec as channel_binding_from_spec, -) -from .operation import ( - OperationBinding, - from_spec as operation_binding_from_spec, -) +from .channel import ChannelBinding +from .operation import OperationBinding __all__ = ( "ChannelBinding", "OperationBinding", - "channel_binding_from_spec", - "operation_binding_from_spec", ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel.py index d6eda36274..1f304410ba 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel.py @@ -8,7 +8,7 @@ from pydantic import BaseModel, PositiveInt from typing_extensions import Self -from faststream.specification import schema as spec +from faststream.specification.schema.bindings import kafka class ChannelBinding(BaseModel): @@ -30,14 +30,23 @@ class ChannelBinding(BaseModel): # topicConfiguration @classmethod - def from_spec(cls, binding: spec.bindings.kafka.ChannelBinding) -> Self: + def from_sub(cls, binding: Optional[kafka.ChannelBinding]) -> Optional[Self]: + if binding is None: + return None + return cls( topic=binding.topic, partitions=binding.partitions, replicas=binding.replicas, - bindingVersion=binding.bindingVersion, ) + @classmethod + def from_pub(cls, binding: Optional[kafka.ChannelBinding]) -> Optional[Self]: + if binding is None: + return None -def from_spec(binding: spec.bindings.kafka.ChannelBinding) -> ChannelBinding: - return ChannelBinding.from_spec(binding) + return cls( + topic=binding.topic, + partitions=binding.partitions, + replicas=binding.replicas, + ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation.py index 005cc92cf7..4155ce220e 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation.py @@ -9,7 +9,7 @@ from typing_extensions import Self from faststream._internal.basic_types import AnyDict -from faststream.specification import schema as spec +from faststream.specification.schema.bindings import kafka class OperationBinding(BaseModel): @@ -28,14 +28,23 @@ class OperationBinding(BaseModel): bindingVersion: str = "0.4.0" @classmethod - def from_spec(cls, binding: spec.bindings.kafka.OperationBinding) -> Self: + def from_sub(cls, binding: Optional[kafka.OperationBinding]) -> Optional[Self]: + if not binding: + return None + return cls( - groupId=binding.groupId, - clientId=binding.clientId, - replyTo=binding.replyTo, - bindingVersion=binding.bindingVersion, + groupId=binding.group_id, + clientId=binding.client_id, + replyTo=binding.reply_to, ) + @classmethod + def from_pub(cls, binding: Optional[kafka.OperationBinding]) -> Optional[Self]: + if not binding: + return None -def from_spec(binding: spec.bindings.kafka.OperationBinding) -> OperationBinding: - return OperationBinding.from_spec(binding) + return cls( + groupId=binding.group_id, + clientId=binding.client_id, + replyTo=binding.reply_to, + ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/__init__.py index 7ead3ce532..8555fd981a 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/__init__.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/__init__.py @@ -1,15 +1,7 @@ -from .channel import ( - ChannelBinding, - from_spec as channel_binding_from_spec, -) -from .operation import ( - OperationBinding, - from_spec as operation_binding_from_spec, -) +from .channel import ChannelBinding +from .operation import OperationBinding __all__ = ( "ChannelBinding", "OperationBinding", - "channel_binding_from_spec", - "operation_binding_from_spec", ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel.py index 258e08ea3a..bf4b7dbd98 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel.py @@ -1,10 +1,9 @@ -from typing import Optional +from typing import Optional, overload from pydantic import BaseModel from typing_extensions import Self from faststream._internal._compat import PYDANTIC_V2 -from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( amqp as amqp_bindings, kafka as kafka_bindings, @@ -12,6 +11,7 @@ redis as redis_bindings, sqs as sqs_bindings, ) +from faststream.specification.schema.bindings import ChannelBinding as SpecBinding class ChannelBinding(BaseModel): @@ -23,7 +23,6 @@ class ChannelBinding(BaseModel): sqs : SQS channel binding (optional) nats : NATS channel binding (optional) redis : Redis channel binding (optional) - """ amqp: Optional[amqp_bindings.ChannelBinding] = None @@ -40,26 +39,78 @@ class ChannelBinding(BaseModel): class Config: extra = "allow" + @overload + @classmethod + def from_sub(cls, binding: None) -> None: ... + + @overload @classmethod - def from_spec(cls, binding: spec.bindings.ChannelBinding) -> Self: - return cls( - amqp=amqp_bindings.channel_binding_from_spec(binding.amqp) - if binding.amqp is not None - else None, - kafka=kafka_bindings.channel_binding_from_spec(binding.kafka) - if binding.kafka is not None - else None, - sqs=sqs_bindings.channel_binding_from_spec(binding.sqs) - if binding.sqs is not None - else None, - nats=nats_bindings.channel_binding_from_spec(binding.nats) - if binding.nats is not None - else None, - redis=redis_bindings.channel_binding_from_spec(binding.redis) - if binding.redis is not None - else None, - ) - - -def from_spec(binding: spec.bindings.ChannelBinding) -> ChannelBinding: - return ChannelBinding.from_spec(binding) + def from_sub(cls, binding: SpecBinding) -> Self: ... + + @classmethod + def from_sub(cls, binding: Optional[SpecBinding]) -> Optional[Self]: + if binding is None: + return None + + if binding.amqp and ( + amqp := amqp_bindings.ChannelBinding.from_sub(binding.amqp) + ): + return cls(amqp=amqp) + + if binding.kafka and ( + kafka := kafka_bindings.ChannelBinding.from_sub(binding.kafka) + ): + return cls(kafka=kafka) + + if binding.nats and ( + nats := nats_bindings.ChannelBinding.from_sub(binding.nats) + ): + return cls(nats=nats) + + if binding.redis and ( + redis := redis_bindings.ChannelBinding.from_sub(binding.redis) + ): + return cls(redis=redis) + + if binding.sqs and (sqs := sqs_bindings.ChannelBinding.from_sub(binding.sqs)): + return cls(sqs=sqs) + + return None + + @overload + @classmethod + def from_pub(cls, binding: None) -> None: ... + + @overload + @classmethod + def from_pub(cls, binding: SpecBinding) -> Self: ... + + @classmethod + def from_pub(cls, binding: Optional[SpecBinding]) -> Optional[Self]: + if binding is None: + return None + + if binding.amqp and ( + amqp := amqp_bindings.ChannelBinding.from_pub(binding.amqp) + ): + return cls(amqp=amqp) + + if binding.kafka and ( + kafka := kafka_bindings.ChannelBinding.from_pub(binding.kafka) + ): + return cls(kafka=kafka) + + if binding.nats and ( + nats := nats_bindings.ChannelBinding.from_pub(binding.nats) + ): + return cls(nats=nats) + + if binding.redis and ( + redis := redis_bindings.ChannelBinding.from_pub(binding.redis) + ): + return cls(redis=redis) + + if binding.sqs and (sqs := sqs_bindings.ChannelBinding.from_pub(binding.sqs)): + return cls(sqs=sqs) + + return None diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation.py index 61d614dd4d..7367b7921f 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation.py @@ -1,10 +1,9 @@ -from typing import Optional +from typing import Optional, overload from pydantic import BaseModel from typing_extensions import Self from faststream._internal._compat import PYDANTIC_V2 -from faststream.specification import schema as spec from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( amqp as amqp_bindings, kafka as kafka_bindings, @@ -12,6 +11,7 @@ redis as redis_bindings, sqs as sqs_bindings, ) +from faststream.specification.schema.bindings import OperationBinding as SpecBinding class OperationBinding(BaseModel): @@ -23,7 +23,6 @@ class OperationBinding(BaseModel): sqs : SQS operation binding (optional) nats : NATS operation binding (optional) redis : Redis operation binding (optional) - """ amqp: Optional[amqp_bindings.OperationBinding] = None @@ -40,26 +39,78 @@ class OperationBinding(BaseModel): class Config: extra = "allow" + @overload + @classmethod + def from_sub(cls, binding: None) -> None: ... + + @overload @classmethod - def from_spec(cls, binding: spec.bindings.OperationBinding) -> Self: - return cls( - amqp=amqp_bindings.operation_binding_from_spec(binding.amqp) - if binding.amqp is not None - else None, - kafka=kafka_bindings.operation_binding_from_spec(binding.kafka) - if binding.kafka is not None - else None, - sqs=sqs_bindings.operation_binding_from_spec(binding.sqs) - if binding.sqs is not None - else None, - nats=nats_bindings.operation_binding_from_spec(binding.nats) - if binding.nats is not None - else None, - redis=redis_bindings.operation_binding_from_spec(binding.redis) - if binding.redis is not None - else None, - ) - - -def from_spec(binding: spec.bindings.OperationBinding) -> OperationBinding: - return OperationBinding.from_spec(binding) + def from_sub(cls, binding: SpecBinding) -> Self: ... + + @classmethod + def from_sub(cls, binding: Optional[SpecBinding]) -> Optional[Self]: + if binding is None: + return None + + if binding.amqp and ( + amqp := amqp_bindings.OperationBinding.from_sub(binding.amqp) + ): + return cls(amqp=amqp) + + if binding.kafka and ( + kafka := kafka_bindings.OperationBinding.from_sub(binding.kafka) + ): + return cls(kafka=kafka) + + if binding.nats and ( + nats := nats_bindings.OperationBinding.from_sub(binding.nats) + ): + return cls(nats=nats) + + if binding.redis and ( + redis := redis_bindings.OperationBinding.from_sub(binding.redis) + ): + return cls(redis=redis) + + if binding.sqs and (sqs := sqs_bindings.OperationBinding.from_sub(binding.sqs)): + return cls(sqs=sqs) + + return None + + @overload + @classmethod + def from_pub(cls, binding: None) -> None: ... + + @overload + @classmethod + def from_pub(cls, binding: SpecBinding) -> Self: ... + + @classmethod + def from_pub(cls, binding: Optional[SpecBinding]) -> Optional[Self]: + if binding is None: + return None + + if binding.amqp and ( + amqp := amqp_bindings.OperationBinding.from_pub(binding.amqp) + ): + return cls(amqp=amqp) + + if binding.kafka and ( + kafka := kafka_bindings.OperationBinding.from_pub(binding.kafka) + ): + return cls(kafka=kafka) + + if binding.nats and ( + nats := nats_bindings.OperationBinding.from_pub(binding.nats) + ): + return cls(nats=nats) + + if binding.redis and ( + redis := redis_bindings.OperationBinding.from_pub(binding.redis) + ): + return cls(redis=redis) + + if binding.sqs and (sqs := sqs_bindings.OperationBinding.from_pub(binding.sqs)): + return cls(sqs=sqs) + + return None diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/__init__.py index 7ead3ce532..8555fd981a 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/__init__.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/__init__.py @@ -1,15 +1,7 @@ -from .channel import ( - ChannelBinding, - from_spec as channel_binding_from_spec, -) -from .operation import ( - OperationBinding, - from_spec as operation_binding_from_spec, -) +from .channel import ChannelBinding +from .operation import OperationBinding __all__ = ( "ChannelBinding", "OperationBinding", - "channel_binding_from_spec", - "operation_binding_from_spec", ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel.py index ba39c7569b..4cc83faddb 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel.py @@ -8,7 +8,7 @@ from pydantic import BaseModel from typing_extensions import Self -from faststream.specification import schema as spec +from faststream.specification.schema.bindings import nats class ChannelBinding(BaseModel): @@ -25,13 +25,23 @@ class ChannelBinding(BaseModel): bindingVersion: str = "custom" @classmethod - def from_spec(cls, binding: spec.bindings.nats.ChannelBinding) -> Self: + def from_sub(cls, binding: Optional[nats.ChannelBinding]) -> Optional[Self]: + if binding is None: + return None + return cls( subject=binding.subject, queue=binding.queue, - bindingVersion=binding.bindingVersion, + bindingVersion="custom", ) + @classmethod + def from_pub(cls, binding: Optional[nats.ChannelBinding]) -> Optional[Self]: + if binding is None: + return None -def from_spec(binding: spec.bindings.nats.ChannelBinding) -> ChannelBinding: - return ChannelBinding.from_spec(binding) + return cls( + subject=binding.subject, + queue=binding.queue, + bindingVersion="custom", + ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation.py index b38a2f89dd..5e1514fcba 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation.py @@ -9,7 +9,7 @@ from typing_extensions import Self from faststream._internal.basic_types import AnyDict -from faststream.specification import schema as spec +from faststream.specification.schema.bindings import nats class OperationBinding(BaseModel): @@ -24,12 +24,19 @@ class OperationBinding(BaseModel): bindingVersion: str = "custom" @classmethod - def from_spec(cls, binding: spec.bindings.nats.OperationBinding) -> Self: + def from_sub(cls, binding: Optional[nats.OperationBinding]) -> Optional[Self]: + if not binding: + return None + return cls( - replyTo=binding.replyTo, - bindingVersion=binding.bindingVersion, + replyTo=binding.reply_to, ) + @classmethod + def from_pub(cls, binding: Optional[nats.OperationBinding]) -> Optional[Self]: + if not binding: + return None -def from_spec(binding: spec.bindings.nats.OperationBinding) -> OperationBinding: - return OperationBinding.from_spec(binding) + return cls( + replyTo=binding.reply_to, + ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/__init__.py index 7ead3ce532..8555fd981a 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/__init__.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/__init__.py @@ -1,15 +1,7 @@ -from .channel import ( - ChannelBinding, - from_spec as channel_binding_from_spec, -) -from .operation import ( - OperationBinding, - from_spec as operation_binding_from_spec, -) +from .channel import ChannelBinding +from .operation import OperationBinding __all__ = ( "ChannelBinding", "OperationBinding", - "channel_binding_from_spec", - "operation_binding_from_spec", ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel.py index 579f9170ea..abc5bf96d6 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel.py @@ -8,7 +8,7 @@ from pydantic import BaseModel from typing_extensions import Self -from faststream.specification import schema as spec +from faststream.specification.schema.bindings import redis class ChannelBinding(BaseModel): @@ -22,20 +22,30 @@ class ChannelBinding(BaseModel): channel: str method: Optional[str] = None - group_name: Optional[str] = None - consumer_name: Optional[str] = None + groupName: Optional[str] = None + consumerName: Optional[str] = None bindingVersion: str = "custom" @classmethod - def from_spec(cls, binding: spec.bindings.redis.ChannelBinding) -> Self: + def from_sub(cls, binding: Optional[redis.ChannelBinding]) -> Optional[Self]: + if binding is None: + return None + return cls( channel=binding.channel, method=binding.method, - group_name=binding.group_name, - consumer_name=binding.consumer_name, - bindingVersion=binding.bindingVersion, + groupName=binding.group_name, + consumerName=binding.consumer_name, ) + @classmethod + def from_pub(cls, binding: Optional[redis.ChannelBinding]) -> Optional[Self]: + if binding is None: + return None -def from_spec(binding: spec.bindings.redis.ChannelBinding) -> ChannelBinding: - return ChannelBinding.from_spec(binding) + return cls( + channel=binding.channel, + method=binding.method, + groupName=binding.group_name, + consumerName=binding.consumer_name, + ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation.py index 39a4c94b99..cce0316160 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation.py @@ -9,7 +9,7 @@ from typing_extensions import Self from faststream._internal.basic_types import AnyDict -from faststream.specification import schema as spec +from faststream.specification.schema.bindings import redis class OperationBinding(BaseModel): @@ -24,12 +24,19 @@ class OperationBinding(BaseModel): bindingVersion: str = "custom" @classmethod - def from_spec(cls, binding: spec.bindings.redis.OperationBinding) -> Self: + def from_sub(cls, binding: Optional[redis.OperationBinding]) -> Optional[Self]: + if not binding: + return None + return cls( - replyTo=binding.replyTo, - bindingVersion=binding.bindingVersion, + replyTo=binding.reply_to, ) + @classmethod + def from_pub(cls, binding: Optional[redis.OperationBinding]) -> Optional[Self]: + if not binding: + return None -def from_spec(binding: spec.bindings.redis.OperationBinding) -> OperationBinding: - return OperationBinding.from_spec(binding) + return cls( + replyTo=binding.reply_to, + ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/__init__.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/__init__.py index 7ead3ce532..33cdca3a8b 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/__init__.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/__init__.py @@ -1,15 +1,4 @@ -from .channel import ( - ChannelBinding, - from_spec as channel_binding_from_spec, -) -from .operation import ( - OperationBinding, - from_spec as operation_binding_from_spec, -) +from .channel import ChannelBinding +from .operation import OperationBinding -__all__ = ( - "ChannelBinding", - "OperationBinding", - "channel_binding_from_spec", - "operation_binding_from_spec", -) +__all__ = ("ChannelBinding", "OperationBinding") diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel.py index 631e9c7bb4..93a1c5ac80 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel.py @@ -7,7 +7,7 @@ from typing_extensions import Self from faststream._internal.basic_types import AnyDict -from faststream.specification import schema as spec +from faststream.specification.schema.bindings import sqs class ChannelBinding(BaseModel): @@ -22,12 +22,12 @@ class ChannelBinding(BaseModel): bindingVersion: str = "custom" @classmethod - def from_spec(cls, binding: spec.bindings.sqs.ChannelBinding) -> Self: + def from_spec(cls, binding: sqs.ChannelBinding) -> Self: return cls( queue=binding.queue, bindingVersion=binding.bindingVersion, ) -def from_spec(binding: spec.bindings.sqs.ChannelBinding) -> ChannelBinding: +def from_spec(binding: sqs.ChannelBinding) -> ChannelBinding: return ChannelBinding.from_spec(binding) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation.py index 4ea0ece20a..35aa598d20 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation.py @@ -9,7 +9,7 @@ from typing_extensions import Self from faststream._internal.basic_types import AnyDict -from faststream.specification import schema as spec +from faststream.specification.schema.bindings import sqs class OperationBinding(BaseModel): @@ -24,12 +24,12 @@ class OperationBinding(BaseModel): bindingVersion: str = "custom" @classmethod - def from_spec(cls, binding: spec.bindings.sqs.OperationBinding) -> Self: + def from_spec(cls, binding: sqs.OperationBinding) -> Self: return cls( replyTo=binding.replyTo, bindingVersion=binding.bindingVersion, ) -def from_spec(binding: spec.bindings.sqs.OperationBinding) -> OperationBinding: +def from_spec(binding: sqs.OperationBinding) -> OperationBinding: return OperationBinding.from_spec(binding) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/channels.py b/faststream/specification/asyncapi/v2_6_0/schema/channels.py index 99ac5585bc..936248dfd5 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/channels.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/channels.py @@ -4,15 +4,10 @@ from typing_extensions import Self from faststream._internal._compat import PYDANTIC_V2 -from faststream.specification import schema as spec -from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( - ChannelBinding, - channel_binding_from_spec, -) -from faststream.specification.asyncapi.v2_6_0.schema.operations import ( - Operation, - from_spec as operation_from_spec, -) +from faststream.specification.schema import PublisherSpec, SubscriberSpec + +from .bindings import ChannelBinding +from .operations import Operation class Channel(BaseModel): @@ -28,7 +23,6 @@ class Channel(BaseModel): Configurations: model_config : configuration for the model (only applicable for Pydantic version 2) Config : configuration for the class (only applicable for Pydantic version 1) - """ description: Optional[str] = None @@ -49,21 +43,21 @@ class Config: extra = "allow" @classmethod - def from_spec(cls, channel: spec.channel.Channel) -> Self: + def from_sub(cls, subscriber: SubscriberSpec) -> Self: return cls( - description=channel.description, - servers=channel.servers, - bindings=channel_binding_from_spec(channel.bindings) - if channel.bindings is not None - else None, - subscribe=operation_from_spec(channel.subscribe) - if channel.subscribe is not None - else None, - publish=operation_from_spec(channel.publish) - if channel.publish is not None - else None, + description=subscriber.description, + servers=None, + bindings=ChannelBinding.from_sub(subscriber.bindings), + subscribe=Operation.from_sub(subscriber.operation), + publish=None, ) - -def from_spec(channel: spec.channel.Channel) -> Channel: - return Channel.from_spec(channel) + @classmethod + def from_pub(cls, publisher: PublisherSpec) -> Self: + return cls( + description=publisher.description, + servers=None, + bindings=ChannelBinding.from_pub(publisher.bindings), + subscribe=None, + publish=Operation.from_pub(publisher.operation), + ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/components.py b/faststream/specification/asyncapi/v2_6_0/schema/components.py index 764d639a24..a80c3420d0 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/components.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/components.py @@ -36,7 +36,6 @@ class Components(BaseModel): - channelBindings - operationBindings - messageBindings - """ messages: Optional[dict[str, Message]] = None diff --git a/faststream/specification/asyncapi/v2_6_0/schema/contact.py b/faststream/specification/asyncapi/v2_6_0/schema/contact.py index 809b5190c4..9456d7dd61 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/contact.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/contact.py @@ -1,15 +1,15 @@ -from typing import ( - Optional, - Union, - overload, -) +from typing import Optional, Union, overload from pydantic import AnyHttpUrl, BaseModel from typing_extensions import Self from faststream._internal._compat import PYDANTIC_V2, EmailStr from faststream._internal.basic_types import AnyDict -from faststream.specification import schema as spec +from faststream._internal.utils.data import filter_by_dict +from faststream.specification.schema.extra import ( + Contact as SpecContact, + ContactDict, +) class Contact(BaseModel): @@ -19,10 +19,10 @@ class Contact(BaseModel): name : name of the contact (str) url : URL of the contact (Optional[AnyHttpUrl]) email : email of the contact (Optional[EmailStr]) - """ name: str + # Use default values to be able build from dict url: Optional[AnyHttpUrl] = None email: Optional[EmailStr] = None @@ -34,31 +34,39 @@ class Contact(BaseModel): class Config: extra = "allow" + @overload @classmethod - def from_spec(cls, contact: spec.contact.Contact) -> Self: - return cls( - name=contact.name, - url=contact.url, - email=contact.email, - ) - + def from_spec(cls, contact: None) -> None: ... -@overload -def from_spec(contact: spec.contact.Contact) -> Contact: ... + @overload + @classmethod + def from_spec(cls, contact: SpecContact) -> Self: ... + @overload + @classmethod + def from_spec(cls, contact: ContactDict) -> Self: ... -@overload -def from_spec(contact: spec.contact.ContactDict) -> AnyDict: ... + @overload + @classmethod + def from_spec(cls, contact: AnyDict) -> AnyDict: ... + @classmethod + def from_spec( + cls, contact: Union[SpecContact, ContactDict, AnyDict, None] + ) -> Union[Self, AnyDict, None]: + if contact is None: + return None -@overload -def from_spec(contact: AnyDict) -> AnyDict: ... + if isinstance(contact, SpecContact): + return cls( + name=contact.name, + url=contact.url, + email=contact.email, + ) + contact_data, custom_data = filter_by_dict(ContactDict, contact) -def from_spec( - contact: Union[spec.contact.Contact, spec.contact.ContactDict, AnyDict], -) -> Union[Contact, AnyDict]: - if isinstance(contact, spec.contact.Contact): - return Contact.from_spec(contact) + if custom_data: + return contact - return dict(contact) + return cls(**contact_data) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/docs.py b/faststream/specification/asyncapi/v2_6_0/schema/docs.py index 34b2e3ed8d..6ad8d6a252 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/docs.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/docs.py @@ -5,7 +5,11 @@ from faststream._internal._compat import PYDANTIC_V2 from faststream._internal.basic_types import AnyDict -from faststream.specification import schema as spec +from faststream._internal.utils.data import filter_by_dict +from faststream.specification.schema.extra import ( + ExternalDocs as SpecDocs, + ExternalDocsDict, +) class ExternalDocs(BaseModel): @@ -14,10 +18,10 @@ class ExternalDocs(BaseModel): Attributes: url : URL of the external documentation description : optional description of the external documentation - """ url: AnyHttpUrl + # Use default values to be able build from dict description: Optional[str] = None if PYDANTIC_V2: @@ -28,27 +32,35 @@ class ExternalDocs(BaseModel): class Config: extra = "allow" + @overload @classmethod - def from_spec(cls, docs: spec.docs.ExternalDocs) -> Self: - return cls(url=docs.url, description=docs.description) - + def from_spec(cls, docs: None) -> None: ... -@overload -def from_spec(docs: spec.docs.ExternalDocs) -> ExternalDocs: ... + @overload + @classmethod + def from_spec(cls, docs: SpecDocs) -> Self: ... + @overload + @classmethod + def from_spec(cls, docs: ExternalDocsDict) -> Self: ... -@overload -def from_spec(docs: spec.docs.ExternalDocsDict) -> AnyDict: ... + @overload + @classmethod + def from_spec(cls, docs: AnyDict) -> AnyDict: ... + @classmethod + def from_spec( + cls, docs: Union[SpecDocs, ExternalDocsDict, AnyDict, None] + ) -> Union[Self, AnyDict, None]: + if docs is None: + return None -@overload -def from_spec(docs: AnyDict) -> AnyDict: ... + if isinstance(docs, SpecDocs): + return cls(url=docs.url, description=docs.description) + docs_data, custom_data = filter_by_dict(ExternalDocsDict, docs) -def from_spec( - docs: Union[spec.docs.ExternalDocs, spec.docs.ExternalDocsDict, AnyDict], -) -> Union[ExternalDocs, AnyDict]: - if isinstance(docs, spec.docs.ExternalDocs): - return ExternalDocs.from_spec(docs) + if custom_data: + return docs - return dict(docs) + return cls(**docs_data) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/info.py b/faststream/specification/asyncapi/v2_6_0/schema/info.py index b4cf3bceec..50f79fa026 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/info.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/info.py @@ -8,19 +8,19 @@ from faststream._internal.basic_types import AnyDict from faststream.specification.asyncapi.v2_6_0.schema.contact import Contact from faststream.specification.asyncapi.v2_6_0.schema.license import License -from faststream.specification.base.info import BaseInfo +from faststream.specification.base.info import BaseApplicationInfo -class Info(BaseInfo): - """A class to represent information. +class ApplicationInfo(BaseApplicationInfo): + """A class to represent application information. Attributes: title : title of the information - version : version of the information (default: "1.0.0") - description : description of the information (default: "") - termsOfService : terms of service for the information (default: None) - contact : contact information for the information (default: None) - license : license information for the information (default: None) + version : version of the information + description : description of the information + termsOfService : terms of service for the information + contact : contact information for the information + license : license information for the information """ termsOfService: Optional[AnyHttpUrl] = None diff --git a/faststream/specification/asyncapi/v2_6_0/schema/license.py b/faststream/specification/asyncapi/v2_6_0/schema/license.py index 761511789a..1d3b778d8e 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/license.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/license.py @@ -1,17 +1,15 @@ -from typing import ( - Optional, - Union, - overload, -) +from typing import Optional, Union, overload from pydantic import AnyHttpUrl, BaseModel from typing_extensions import Self -from faststream._internal._compat import ( - PYDANTIC_V2, -) +from faststream._internal._compat import PYDANTIC_V2 from faststream._internal.basic_types import AnyDict -from faststream.specification import schema as spec +from faststream._internal.utils.data import filter_by_dict +from faststream.specification.schema.extra import ( + License as SpecLicense, + LicenseDict, +) class License(BaseModel): @@ -23,10 +21,10 @@ class License(BaseModel): Config: extra : allow additional attributes in the model (PYDANTIC_V2) - """ name: str + # Use default values to be able build from dict url: Optional[AnyHttpUrl] = None if PYDANTIC_V2: @@ -37,30 +35,38 @@ class License(BaseModel): class Config: extra = "allow" + @overload @classmethod - def from_spec(cls, license: spec.license.License) -> Self: - return cls( - name=license.name, - url=license.url, - ) - + def from_spec(cls, license: None) -> None: ... -@overload -def from_spec(license: spec.license.License) -> License: ... + @overload + @classmethod + def from_spec(cls, license: SpecLicense) -> Self: ... + @overload + @classmethod + def from_spec(cls, license: LicenseDict) -> Self: ... -@overload -def from_spec(license: spec.license.LicenseDict) -> AnyDict: ... + @overload + @classmethod + def from_spec(cls, license: AnyDict) -> AnyDict: ... + @classmethod + def from_spec( + cls, license: Union[SpecLicense, LicenseDict, AnyDict, None] + ) -> Union[Self, AnyDict, None]: + if license is None: + return None -@overload -def from_spec(license: AnyDict) -> AnyDict: ... + if isinstance(license, SpecLicense): + return cls( + name=license.name, + url=license.url, + ) + license_data, custom_data = filter_by_dict(LicenseDict, license) -def from_spec( - license: Union[spec.license.License, spec.license.LicenseDict, AnyDict], -) -> Union[License, AnyDict]: - if isinstance(license, spec.license.License): - return License.from_spec(license) + if custom_data: + return license - return dict(license) + return cls(**license_data) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/message.py b/faststream/specification/asyncapi/v2_6_0/schema/message.py index d9cde0e403..5f56df156c 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/message.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/message.py @@ -1,15 +1,12 @@ from typing import Optional, Union -import typing_extensions from pydantic import BaseModel +from typing_extensions import Self from faststream._internal._compat import PYDANTIC_V2 from faststream._internal.basic_types import AnyDict -from faststream.specification import schema as spec -from faststream.specification.asyncapi.v2_6_0.schema.tag import ( - Tag, - from_spec as tag_from_spec, -) +from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag +from faststream.specification.schema.message import Message as SpecMessage class CorrelationId(BaseModel): @@ -21,11 +18,10 @@ class CorrelationId(BaseModel): Configurations: extra : allows extra fields in the correlation ID model - """ - description: Optional[str] = None location: str + description: Optional[str] = None if PYDANTIC_V2: model_config = {"extra": "allow"} @@ -35,13 +31,6 @@ class CorrelationId(BaseModel): class Config: extra = "allow" - @classmethod - def from_spec(cls, cor_id: spec.message.CorrelationId) -> typing_extensions.Self: - return cls( - description=cor_id.description, - location=cor_id.location, - ) - class Message(BaseModel): """A class to represent a message. @@ -56,7 +45,6 @@ class Message(BaseModel): contentType : content type of the message payload : dictionary representing the payload of the message tags : list of tags associated with the message - """ title: Optional[str] = None @@ -86,23 +74,18 @@ class Config: extra = "allow" @classmethod - def from_spec(cls, message: spec.message.Message) -> typing_extensions.Self: + def from_spec(cls, message: SpecMessage) -> Self: return cls( title=message.title, - name=message.name, - summary=message.summary, - description=message.description, - messageId=message.messageId, - correlationId=CorrelationId.from_spec(message.correlationId) - if message.correlationId is not None - else None, - contentType=message.contentType, payload=message.payload, - tags=[tag_from_spec(tag) for tag in message.tags] - if message.tags is not None - else None, + correlationId=CorrelationId( + description=None, + location="$message.header#/correlation_id", + ), + name=None, + summary=None, + description=None, + messageId=None, + contentType=None, + tags=None, ) - - -def from_spec(message: spec.message.Message) -> Message: - return Message.from_spec(message) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/operations.py b/faststream/specification/asyncapi/v2_6_0/schema/operations.py index 9d6c6d61fa..c837c844d7 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/operations.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/operations.py @@ -5,22 +5,12 @@ from faststream._internal._compat import PYDANTIC_V2 from faststream._internal.basic_types import AnyDict -from faststream.specification import schema as spec -from faststream.specification.asyncapi.v2_6_0.schema.bindings import OperationBinding -from faststream.specification.asyncapi.v2_6_0.schema.bindings.main import ( - operation_binding_from_spec, -) -from faststream.specification.asyncapi.v2_6_0.schema.message import ( - Message, - from_spec as message_from_spec, -) -from faststream.specification.asyncapi.v2_6_0.schema.tag import ( - Tag, - from_spec as tag_from_spec, -) -from faststream.specification.asyncapi.v2_6_0.schema.utils import ( - Reference, -) +from faststream.specification.schema.operation import Operation as OperationSpec + +from .bindings import OperationBinding +from .message import Message +from .tag import Tag +from .utils import Reference class Operation(BaseModel): @@ -34,7 +24,6 @@ class Operation(BaseModel): message : message of the operation security : security details of the operation tags : tags associated with the operation - """ operationId: Optional[str] = None @@ -61,22 +50,25 @@ class Config: extra = "allow" @classmethod - def from_spec(cls, operation: spec.operation.Operation) -> Self: + def from_sub(cls, operation: OperationSpec) -> Self: return cls( - operationId=operation.operationId, - summary=operation.summary, - description=operation.description, - bindings=operation_binding_from_spec(operation.bindings) - if operation.bindings is not None - else None, - message=message_from_spec(operation.message) - if operation.message is not None - else None, - tags=[tag_from_spec(tag) for tag in operation.tags] - if operation.tags is not None - else None, + message=Message.from_spec(operation.message), + bindings=OperationBinding.from_sub(operation.bindings), + operationId=None, + summary=None, + description=None, + tags=None, + security=None, ) - -def from_spec(operation: spec.operation.Operation) -> Operation: - return Operation.from_spec(operation) + @classmethod + def from_pub(cls, operation: OperationSpec) -> Self: + return cls( + message=Message.from_spec(operation.message), + bindings=OperationBinding.from_pub(operation.bindings), + operationId=None, + summary=None, + description=None, + tags=None, + security=None, + ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/schema.py b/faststream/specification/asyncapi/v2_6_0/schema/schema.py index 9c19130cc2..8f4a70a701 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/schema.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/schema.py @@ -4,14 +4,14 @@ from faststream.specification.asyncapi.v2_6_0.schema.channels import Channel from faststream.specification.asyncapi.v2_6_0.schema.components import Components from faststream.specification.asyncapi.v2_6_0.schema.docs import ExternalDocs -from faststream.specification.asyncapi.v2_6_0.schema.info import Info +from faststream.specification.asyncapi.v2_6_0.schema.info import ApplicationInfo from faststream.specification.asyncapi.v2_6_0.schema.servers import Server from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag -from faststream.specification.base.schema import BaseSchema +from faststream.specification.base.schema import BaseApplicationSchema -class Schema(BaseSchema): - """A class to represent a schema. +class ApplicationSchema(BaseApplicationSchema): + """A class to represent an application schema. Attributes: asyncapi : version of the async API @@ -25,9 +25,9 @@ class Schema(BaseSchema): externalDocs : optional external documentation """ - info: Info + info: ApplicationInfo - asyncapi: Union[Literal["2.6.0"], str] = "2.6.0" + asyncapi: Union[Literal["2.6.0"], str] id: Optional[str] = None defaultContentType: Optional[str] = None servers: Optional[dict[str, Server]] = None diff --git a/faststream/specification/asyncapi/v2_6_0/schema/servers.py b/faststream/specification/asyncapi/v2_6_0/schema/servers.py index a50be2669e..cae721cfd1 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/servers.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/servers.py @@ -18,7 +18,6 @@ class ServerVariable(BaseModel): default : default value for the server variable (optional) description : description of the server variable (optional) examples : list of example values for the server variable (optional) - """ enum: Optional[list[str]] = None @@ -50,19 +49,15 @@ class Server(BaseModel): Note: The attributes `description`, `protocolVersion`, `tags`, `security`, `variables`, and `bindings` are all optional. - - Configurations: - If `PYDANTIC_V2` is True, the model configuration is set to allow extra attributes. - Otherwise, the `Config` class is defined with the `extra` attribute set to "allow". - """ url: str protocol: str - description: Optional[str] = None - protocolVersion: Optional[str] = None - tags: Optional[list[Union[Tag, AnyDict]]] = None - security: Optional[SecurityRequirement] = None + protocolVersion: Optional[str] + description: Optional[str] + tags: Optional[list[Union[Tag, AnyDict]]] + security: Optional[SecurityRequirement] + variables: Optional[dict[str, Union[ServerVariable, Reference]]] = None if PYDANTIC_V2: diff --git a/faststream/specification/asyncapi/v2_6_0/schema/tag.py b/faststream/specification/asyncapi/v2_6_0/schema/tag.py index 182c4effd9..a4fdae8d8d 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/tag.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/tag.py @@ -1,14 +1,15 @@ from typing import Optional, Union, overload -import typing_extensions from pydantic import BaseModel +from typing_extensions import Self from faststream._internal._compat import PYDANTIC_V2 from faststream._internal.basic_types import AnyDict -from faststream.specification import schema as spec -from faststream.specification.asyncapi.v2_6_0.schema.docs import ( - ExternalDocs, - from_spec as docs_from_spec, +from faststream._internal.utils.data import filter_by_dict +from faststream.specification.asyncapi.v2_6_0.schema.docs import ExternalDocs +from faststream.specification.schema.extra import ( + Tag as SpecTag, + TagDict, ) @@ -19,10 +20,10 @@ class Tag(BaseModel): name : name of the tag description : description of the tag (optional) externalDocs : external documentation for the tag (optional) - """ name: str + # Use default values to be able build from dict description: Optional[str] = None externalDocs: Optional[ExternalDocs] = None @@ -34,31 +35,34 @@ class Tag(BaseModel): class Config: extra = "allow" + @overload @classmethod - def from_spec(cls, tag: spec.tag.Tag) -> typing_extensions.Self: - return cls( - name=tag.name, - description=tag.description, - externalDocs=docs_from_spec(tag.externalDocs) if tag.externalDocs else None, - ) - - -@overload -def from_spec(tag: spec.tag.Tag) -> Tag: ... - + def from_spec(cls, tag: SpecTag) -> Self: ... -@overload -def from_spec(tag: spec.tag.TagDict) -> AnyDict: ... + @overload + @classmethod + def from_spec(cls, tag: TagDict) -> Self: ... + @overload + @classmethod + def from_spec(cls, tag: AnyDict) -> AnyDict: ... -@overload -def from_spec(tag: AnyDict) -> AnyDict: ... + @classmethod + def from_spec(cls, tag: Union[SpecTag, TagDict, AnyDict]) -> Union[Self, AnyDict]: + if isinstance(tag, SpecTag): + return cls( + name=tag.name, + description=tag.description, + externalDocs=ExternalDocs.from_spec(tag.external_docs), + ) + tag_data, custom_data = filter_by_dict(TagDict, tag) -def from_spec( - tag: Union[spec.tag.Tag, spec.tag.TagDict, AnyDict], -) -> Union[Tag, AnyDict]: - if isinstance(tag, spec.tag.Tag): - return Tag.from_spec(tag) + if custom_data: + return tag - return dict(tag) + return cls( + name=tag_data.get("name"), + description=tag_data.get("description"), + externalDocs=tag_data.get("external_docs"), + ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/utils.py b/faststream/specification/asyncapi/v2_6_0/schema/utils.py index d145abe37d..6d492ffeb5 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/utils.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/utils.py @@ -6,7 +6,6 @@ class Reference(BaseModel): Attributes: ref : the reference string - """ ref: str = Field(..., alias="$ref") diff --git a/faststream/specification/asyncapi/v3_0_0/facade.py b/faststream/specification/asyncapi/v3_0_0/facade.py index 26e668bd8f..4ce47b6f90 100644 --- a/faststream/specification/asyncapi/v3_0_0/facade.py +++ b/faststream/specification/asyncapi/v3_0_0/facade.py @@ -1,18 +1,24 @@ -from collections.abc import Sequence +from collections.abc import Iterable from typing import TYPE_CHECKING, Any, Optional, Union from faststream.specification.base.specification import Specification from .generate import get_app_schema -from .schema import Schema +from .schema import ApplicationSchema if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict, AnyHttpUrl from faststream._internal.broker.broker import BrokerUsecase - from faststream.specification.schema.contact import Contact, ContactDict - from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict - from faststream.specification.schema.license import License, LicenseDict - from faststream.specification.schema.tag import Tag, TagDict + from faststream.specification.schema.extra import ( + Contact, + ContactDict, + ExternalDocs, + ExternalDocsDict, + License, + LicenseDict, + Tag, + TagDict, + ) class AsyncAPI3(Specification): @@ -28,7 +34,7 @@ def __init__( contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] = None, license: Optional[Union["License", "LicenseDict", "AnyDict"]] = None, identifier: Optional[str] = None, - tags: Optional[Sequence[Union["Tag", "TagDict", "AnyDict"]]] = None, + tags: Iterable[Union["Tag", "TagDict", "AnyDict"]] = (), external_docs: Optional[ Union["ExternalDocs", "ExternalDocsDict", "AnyDict"] ] = None, @@ -55,7 +61,7 @@ def to_yaml(self) -> str: return self.schema.to_yaml() @property - def schema(self) -> Schema: # type: ignore[override] + def schema(self) -> ApplicationSchema: # type: ignore[override] return get_app_schema( self.broker, title=self.title, diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index b14dca2772..1efc8c4fdc 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -5,40 +5,34 @@ from faststream._internal._compat import DEF_KEY from faststream._internal.basic_types import AnyDict, AnyHttpUrl from faststream._internal.constants import ContentTypes -from faststream.specification.asyncapi.utils import clear_key -from faststream.specification.asyncapi.v2_6_0.generate import move_pydantic_refs -from faststream.specification.asyncapi.v2_6_0.schema import ( - Reference, - Tag, - contact_from_spec, - docs_from_spec, - license_from_spec, - tag_from_spec, -) -from faststream.specification.asyncapi.v2_6_0.schema.message import Message +from faststream.specification.asyncapi.utils import clear_key, move_pydantic_refs from faststream.specification.asyncapi.v3_0_0.schema import ( + ApplicationInfo, + ApplicationSchema, Channel, Components, - Info, + Contact, + ExternalDocs, + License, + Message, Operation, - Schema, + Reference, Server, - channel_from_spec, - operation_from_spec, -) -from faststream.specification.asyncapi.v3_0_0.schema.operations import ( - Action, + Tag, ) if TYPE_CHECKING: from faststream._internal.broker.broker import BrokerUsecase from faststream._internal.types import ConnectionType, MsgType - from faststream.specification.schema.contact import Contact, ContactDict - from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict - from faststream.specification.schema.license import License, LicenseDict - from faststream.specification.schema.tag import ( - Tag as SpecsTag, - TagDict as SpecsTagDict, + from faststream.specification.schema.extra import ( + Contact as SpecContact, + ContactDict, + ExternalDocs as SpecDocs, + ExternalDocsDict, + License as SpecLicense, + LicenseDict, + Tag as SpecTag, + TagDict, ) @@ -50,18 +44,17 @@ def get_app_schema( schema_version: str, description: str, terms_of_service: Optional["AnyHttpUrl"], - contact: Optional[Union["Contact", "ContactDict", "AnyDict"]], - license: Optional[Union["License", "LicenseDict", "AnyDict"]], + contact: Optional[Union["SpecContact", "ContactDict", "AnyDict"]], + license: Optional[Union["SpecLicense", "LicenseDict", "AnyDict"]], identifier: Optional[str], - tags: Optional[Sequence[Union["SpecsTag", "SpecsTagDict", "AnyDict"]]], - external_docs: Optional[Union["ExternalDocs", "ExternalDocsDict", "AnyDict"]], -) -> Schema: + tags: Optional[Sequence[Union["SpecTag", "TagDict", "AnyDict"]]], + external_docs: Optional[Union["SpecDocs", "ExternalDocsDict", "AnyDict"]], +) -> ApplicationSchema: """Get the application schema.""" broker._setup() servers = get_broker_server(broker) - channels = get_broker_channels(broker) - operations = get_broker_operations(broker) + channels, operations = get_broker_channels(broker) messages: dict[str, Message] = {} payloads: dict[str, AnyDict] = {} @@ -86,16 +79,16 @@ def get_app_schema( channel.messages = msgs - return Schema( - info=Info( + return ApplicationSchema( + info=ApplicationInfo( title=title, version=app_version, description=description, termsOfService=terms_of_service, - contact=contact_from_spec(contact) if contact else None, - license=license_from_spec(license) if license else None, - tags=[tag_from_spec(tag) for tag in tags] if tags else None, - externalDocs=docs_from_spec(external_docs) if external_docs else None, + contact=Contact.from_spec(contact), + license=License.from_spec(license), + tags=[Tag.from_spec(tag) for tag in tags] or None, + externalDocs=ExternalDocs.from_spec(external_docs), ), asyncapi=schema_version, defaultContentType=ContentTypes.JSON.value, @@ -121,7 +114,7 @@ def get_broker_server( tags: Optional[list[Union[Tag, AnyDict]]] = None if broker.tags: - tags = [tag_from_spec(tag) for tag in broker.tags] + tags = [Tag.from_spec(tag) for tag in broker.tags] broker_meta: AnyDict = { "protocol": broker.protocol, @@ -152,77 +145,52 @@ def get_broker_server( return servers -def get_broker_operations( - broker: "BrokerUsecase[MsgType, ConnectionType]", -) -> dict[str, Operation]: - """Get the broker operations for an application.""" - operations = {} - - for h in broker._subscribers: - for channel, specs_channel in h.schema().items(): - channel_name = clear_key(channel) - - if specs_channel.subscribe is not None: - operations[f"{channel_name}Subscribe"] = operation_from_spec( - specs_channel.subscribe, - Action.RECEIVE, - channel_name, - ) - - for p in broker._publishers: - for channel, specs_channel in p.schema().items(): - channel_name = clear_key(channel) - - if specs_channel.publish is not None: - operations[f"{channel_name}"] = operation_from_spec( - specs_channel.publish, - Action.SEND, - channel_name, - ) - - return operations - - def get_broker_channels( broker: "BrokerUsecase[MsgType, ConnectionType]", -) -> dict[str, Channel]: +) -> tuple[dict[str, Channel], dict[str, Operation]]: """Get the broker channels for an application.""" channels = {} + operations = {} for sub in broker._subscribers: - channels_schema_v3_0 = {} - for channel_name, specs_channel in sub.schema().items(): - if specs_channel.subscribe: - message = specs_channel.subscribe.message - assert message.title - - *left, right = message.title.split(":") - message.title = ":".join(left) + f":Subscribe{right}" - - # TODO: why we are format just a key? - channels_schema_v3_0[clear_key(channel_name)] = channel_from_spec( - specs_channel, - message, - channel_name, - "SubscribeMessage", - ) - - channels.update(channels_schema_v3_0) + for key, channel in sub.schema().items(): + channel_obj = Channel.from_sub(key, channel) + + channel_key = clear_key(key) + # TODO: add duplication key warning + channels[channel_key] = channel_obj + + operations[f"{channel_key}Subscribe"] = Operation.from_sub( + messages=[ + Reference(**{ + "$ref": f"#/channels/{channel_key}/messages/{msg_name}" + }) + for msg_name in channel_obj.messages + ], + channel=Reference(**{"$ref": f"#/channels/{channel_key}"}), + operation=channel.operation, + ) for pub in broker._publishers: - channels_schema_v3_0 = {} - for channel_name, specs_channel in pub.schema().items(): - if specs_channel.publish: - channels_schema_v3_0[clear_key(channel_name)] = channel_from_spec( - specs_channel, - specs_channel.publish.message, - channel_name, - "Message", - ) - - channels.update(channels_schema_v3_0) - - return channels + for key, channel in pub.schema().items(): + channel_obj = Channel.from_pub(key, channel) + + channel_key = clear_key(key) + # TODO: add duplication key warning + channels[channel_key] = channel_obj + + operations[channel_key] = Operation.from_pub( + messages=[ + Reference(**{ + "$ref": f"#/channels/{channel_key}/messages/{msg_name}" + }) + for msg_name in channel_obj.messages + ], + channel=Reference(**{"$ref": f"#/channels/{channel_key}"}), + operation=channel.operation, + ) + + return channels, operations def _resolve_msg_payloads( diff --git a/faststream/specification/asyncapi/v3_0_0/schema/__init__.py b/faststream/specification/asyncapi/v3_0_0/schema/__init__.py index ef2cfe21b7..e0cbcbd7b2 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/__init__.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/__init__.py @@ -1,23 +1,31 @@ -from .channels import ( - Channel, - from_spec as channel_from_spec, -) +from .channels import Channel from .components import Components -from .info import Info -from .operations import ( - Operation, - from_spec as operation_from_spec, -) -from .schema import Schema -from .servers import Server +from .contact import Contact +from .docs import ExternalDocs +from .info import ApplicationInfo +from .license import License +from .message import CorrelationId, Message +from .operations import Operation +from .schema import ApplicationSchema +from .servers import Server, ServerVariable +from .tag import Tag +from .utils import Parameter, Reference __all__ = ( + "ApplicationInfo", + "ApplicationSchema", + "Channel", "Channel", "Components", - "Info", + "Contact", + "CorrelationId", + "ExternalDocs", + "License", + "Message", "Operation", - "Schema", + "Parameter", + "Reference", "Server", - "channel_from_spec", - "operation_from_spec", + "ServerVariable", + "Tag", ) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/__init__.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/__init__.py index d477f704cd..c304608c5b 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/bindings/__init__.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/__init__.py @@ -1,11 +1,9 @@ from .main import ( + ChannelBinding, OperationBinding, - channel_binding_from_spec, - operation_binding_from_spec, ) __all__ = ( + "ChannelBinding", "OperationBinding", - "channel_binding_from_spec", - "operation_binding_from_spec", ) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/__init__.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/__init__.py index 96c7406698..8555fd981a 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/__init__.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/__init__.py @@ -1,11 +1,7 @@ -from .channel import from_spec as channel_binding_from_spec -from .operation import ( - OperationBinding, - from_spec as operation_binding_from_spec, -) +from .channel import ChannelBinding +from .operation import OperationBinding __all__ = ( + "ChannelBinding", "OperationBinding", - "channel_binding_from_spec", - "operation_binding_from_spec", ) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel.py index a31498ee5f..ecab8e4a17 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel.py @@ -1,21 +1,7 @@ -from faststream.specification import schema as spec -from faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp import ChannelBinding -from faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.channel import ( - Exchange, - Queue, +from faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp import ( + ChannelBinding as V2Binding, ) -def from_spec(binding: spec.bindings.amqp.ChannelBinding) -> ChannelBinding: - return ChannelBinding( - **{ - "is": binding.is_, - "bindingVersion": "0.3.0", - "queue": Queue.from_spec(binding.queue) - if binding.queue is not None - else None, - "exchange": Exchange.from_spec(binding.exchange) - if binding.exchange is not None - else None, - }, - ) +class ChannelBinding(V2Binding): + bindingVersion: str = "0.3.0" diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation.py index 1357dd325f..77ba8356a0 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation.py @@ -5,41 +5,46 @@ from typing import Optional -from pydantic import BaseModel, PositiveInt from typing_extensions import Self -from faststream.specification import schema as spec +from faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp import ( + OperationBinding as V2Binding, +) +from faststream.specification.schema.bindings import amqp -class OperationBinding(BaseModel): - """A class to represent an operation binding. - - Attributes: - cc : optional string representing the cc - ack : boolean indicating if the operation is acknowledged - replyTo : optional dictionary representing the replyTo - bindingVersion : string representing the binding version - """ - +class OperationBinding(V2Binding): cc: Optional[list[str]] = None - ack: bool = True - replyTo: Optional[str] = None - deliveryMode: Optional[int] = None - mandatory: Optional[bool] = None - priority: Optional[PositiveInt] = None bindingVersion: str = "0.3.0" @classmethod - def from_spec(cls, binding: spec.bindings.amqp.OperationBinding) -> Self: + def from_sub(cls, binding: Optional[amqp.OperationBinding]) -> Optional[Self]: + if not binding: + return None + return cls( - cc=[binding.cc] if binding.cc is not None else None, + cc=[binding.routing_key] + if (binding.routing_key and binding.exchange.is_respect_routing_key) + else None, ack=binding.ack, - replyTo=binding.replyTo, - deliveryMode=binding.deliveryMode, + replyTo=binding.reply_to, + deliveryMode=None if binding.persist is None else int(binding.persist) + 1, mandatory=binding.mandatory, priority=binding.priority, ) + @classmethod + def from_pub(cls, binding: Optional[amqp.OperationBinding]) -> Optional[Self]: + if not binding: + return None -def from_spec(binding: spec.bindings.amqp.OperationBinding) -> OperationBinding: - return OperationBinding.from_spec(binding) + return cls( + cc=None + if (not binding.routing_key or not binding.exchange.is_respect_routing_key) + else [binding.routing_key], + ack=binding.ack, + replyTo=binding.reply_to, + deliveryMode=None if binding.persist is None else int(binding.persist) + 1, + mandatory=binding.mandatory, + priority=binding.priority, + ) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka.py new file mode 100644 index 0000000000..5605abeefa --- /dev/null +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka.py @@ -0,0 +1,9 @@ +from faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka import ( + ChannelBinding, + OperationBinding, +) + +__all__ = ( + "ChannelBinding", + "OperationBinding", +) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/__init__.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/__init__.py index 96c7406698..8555fd981a 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/__init__.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/__init__.py @@ -1,11 +1,7 @@ -from .channel import from_spec as channel_binding_from_spec -from .operation import ( - OperationBinding, - from_spec as operation_binding_from_spec, -) +from .channel import ChannelBinding +from .operation import OperationBinding __all__ = ( + "ChannelBinding", "OperationBinding", - "channel_binding_from_spec", - "operation_binding_from_spec", ) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel.py index 41aef76aaa..c7552a11d1 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel.py @@ -1,17 +1,100 @@ -from faststream.specification import schema as spec -from faststream.specification.asyncapi.v2_6_0.schema.bindings import ChannelBinding -from faststream.specification.asyncapi.v2_6_0.schema.bindings.main import ( - channel_binding_from_spec, -) -from faststream.specification.asyncapi.v3_0_0.schema.bindings.amqp import ( - channel_binding_from_spec as amqp_channel_binding_from_spec, +from typing import Optional + +from pydantic import BaseModel +from typing_extensions import Self + +from faststream._internal._compat import PYDANTIC_V2 +from faststream.specification.asyncapi.v3_0_0.schema.bindings import ( + amqp as amqp_bindings, + kafka as kafka_bindings, + nats as nats_bindings, + redis as redis_bindings, + sqs as sqs_bindings, ) +from faststream.specification.schema.bindings import ChannelBinding as SpecBinding + + +class ChannelBinding(BaseModel): + """A class to represent channel bindings. + + Attributes: + amqp : AMQP channel binding (optional) + kafka : Kafka channel binding (optional) + sqs : SQS channel binding (optional) + nats : NATS channel binding (optional) + redis : Redis channel binding (optional) + """ + + amqp: Optional[amqp_bindings.ChannelBinding] = None + kafka: Optional[kafka_bindings.ChannelBinding] = None + sqs: Optional[sqs_bindings.ChannelBinding] = None + nats: Optional[nats_bindings.ChannelBinding] = None + redis: Optional[redis_bindings.ChannelBinding] = None + + if PYDANTIC_V2: + model_config = {"extra": "allow"} + + else: + + class Config: + extra = "allow" + + @classmethod + def from_sub(cls, binding: Optional[SpecBinding]) -> Optional[Self]: + if binding is None: + return None + + if binding.amqp and ( + amqp := amqp_bindings.ChannelBinding.from_sub(binding.amqp) + ): + return cls(amqp=amqp) + + if binding.kafka and ( + kafka := kafka_bindings.ChannelBinding.from_sub(binding.kafka) + ): + return cls(kafka=kafka) + + if binding.nats and ( + nats := nats_bindings.ChannelBinding.from_sub(binding.nats) + ): + return cls(nats=nats) + + if binding.redis and ( + redis := redis_bindings.ChannelBinding.from_sub(binding.redis) + ): + return cls(redis=redis) + + if binding.sqs and (sqs := sqs_bindings.ChannelBinding.from_sub(binding.sqs)): + return cls(sqs=sqs) + + return None + + @classmethod + def from_pub(cls, binding: Optional[SpecBinding]) -> Optional[Self]: + if binding is None: + return None + + if binding.amqp and ( + amqp := amqp_bindings.ChannelBinding.from_pub(binding.amqp) + ): + return cls(amqp=amqp) + + if binding.kafka and ( + kafka := kafka_bindings.ChannelBinding.from_pub(binding.kafka) + ): + return cls(kafka=kafka) + if binding.nats and ( + nats := nats_bindings.ChannelBinding.from_pub(binding.nats) + ): + return cls(nats=nats) -def from_spec(binding: spec.bindings.ChannelBinding) -> ChannelBinding: - channel_binding = channel_binding_from_spec(binding) + if binding.redis and ( + redis := redis_bindings.ChannelBinding.from_pub(binding.redis) + ): + return cls(redis=redis) - if binding.amqp: - channel_binding.amqp = amqp_channel_binding_from_spec(binding.amqp) + if binding.sqs and (sqs := sqs_bindings.ChannelBinding.from_pub(binding.sqs)): + return cls(sqs=sqs) - return channel_binding + return None diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation.py index 6d0a70069e..fc37c3dc75 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation.py @@ -4,16 +4,14 @@ from typing_extensions import Self from faststream._internal._compat import PYDANTIC_V2 -from faststream.specification import schema as spec -from faststream.specification.asyncapi.v2_6_0.schema.bindings import ( +from faststream.specification.asyncapi.v3_0_0.schema.bindings import ( + amqp as amqp_bindings, kafka as kafka_bindings, nats as nats_bindings, redis as redis_bindings, sqs as sqs_bindings, ) -from faststream.specification.asyncapi.v3_0_0.schema.bindings import ( - amqp as amqp_bindings, -) +from faststream.specification.schema.bindings import OperationBinding as SpecBinding class OperationBinding(BaseModel): @@ -25,7 +23,6 @@ class OperationBinding(BaseModel): sqs : SQS operation binding (optional) nats : NATS operation binding (optional) redis : Redis operation binding (optional) - """ amqp: Optional[amqp_bindings.OperationBinding] = None @@ -43,25 +40,61 @@ class Config: extra = "allow" @classmethod - def from_spec(cls, binding: spec.bindings.OperationBinding) -> Self: - return cls( - amqp=amqp_bindings.operation_binding_from_spec(binding.amqp) - if binding.amqp is not None - else None, - kafka=kafka_bindings.operation_binding_from_spec(binding.kafka) - if binding.kafka is not None - else None, - sqs=sqs_bindings.operation_binding_from_spec(binding.sqs) - if binding.sqs is not None - else None, - nats=nats_bindings.operation_binding_from_spec(binding.nats) - if binding.nats is not None - else None, - redis=redis_bindings.operation_binding_from_spec(binding.redis) - if binding.redis is not None - else None, - ) - - -def from_spec(binding: spec.bindings.OperationBinding) -> OperationBinding: - return OperationBinding.from_spec(binding) + def from_sub(cls, binding: Optional[SpecBinding]) -> Optional[Self]: + if binding is None: + return None + + if binding.amqp and ( + amqp := amqp_bindings.OperationBinding.from_sub(binding.amqp) + ): + return cls(amqp=amqp) + + if binding.kafka and ( + kafka := kafka_bindings.OperationBinding.from_sub(binding.kafka) + ): + return cls(kafka=kafka) + + if binding.nats and ( + nats := nats_bindings.OperationBinding.from_sub(binding.nats) + ): + return cls(nats=nats) + + if binding.redis and ( + redis := redis_bindings.OperationBinding.from_sub(binding.redis) + ): + return cls(redis=redis) + + if binding.sqs and (sqs := sqs_bindings.OperationBinding.from_sub(binding.sqs)): + return cls(sqs=sqs) + + return None + + @classmethod + def from_pub(cls, binding: Optional[SpecBinding]) -> Optional[Self]: + if binding is None: + return None + + if binding.amqp and ( + amqp := amqp_bindings.OperationBinding.from_pub(binding.amqp) + ): + return cls(amqp=amqp) + + if binding.kafka and ( + kafka := kafka_bindings.OperationBinding.from_pub(binding.kafka) + ): + return cls(kafka=kafka) + + if binding.nats and ( + nats := nats_bindings.OperationBinding.from_pub(binding.nats) + ): + return cls(nats=nats) + + if binding.redis and ( + redis := redis_bindings.OperationBinding.from_pub(binding.redis) + ): + return cls(redis=redis) + + if binding.sqs and (sqs := sqs_bindings.OperationBinding.from_pub(binding.sqs)): + return cls(sqs=sqs) + + return None diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats.py new file mode 100644 index 0000000000..21d5c46926 --- /dev/null +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats.py @@ -0,0 +1,9 @@ +from faststream.specification.asyncapi.v2_6_0.schema.bindings.nats import ( + ChannelBinding, + OperationBinding, +) + +__all__ = ( + "ChannelBinding", + "OperationBinding", +) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis.py new file mode 100644 index 0000000000..26d44644f7 --- /dev/null +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis.py @@ -0,0 +1,9 @@ +from faststream.specification.asyncapi.v2_6_0.schema.bindings.redis import ( + ChannelBinding, + OperationBinding, +) + +__all__ = ( + "ChannelBinding", + "OperationBinding", +) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs.py new file mode 100644 index 0000000000..e437a1cc58 --- /dev/null +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs.py @@ -0,0 +1,9 @@ +from faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs import ( + ChannelBinding, + OperationBinding, +) + +__all__ = ( + "ChannelBinding", + "OperationBinding", +) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/channels.py b/faststream/specification/asyncapi/v3_0_0/schema/channels.py index 3a5ccd40bb..c0a2dbe553 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/channels.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/channels.py @@ -4,16 +4,11 @@ from typing_extensions import Self from faststream._internal._compat import PYDANTIC_V2 -from faststream.specification import schema as spec -from faststream.specification.asyncapi.v2_6_0.schema.bindings import ChannelBinding -from faststream.specification.asyncapi.v2_6_0.schema.message import ( - Message, - from_spec as message_from_spec, -) -from faststream.specification.asyncapi.v2_6_0.schema.utils import Reference -from faststream.specification.asyncapi.v3_0_0.schema.bindings.main import ( - channel_binding_from_spec, -) +from faststream.specification.asyncapi.v3_0_0.schema.bindings import ChannelBinding +from faststream.specification.asyncapi.v3_0_0.schema.message import Message +from faststream.specification.schema import PublisherSpec, SubscriberSpec + +from .utils import Reference class Channel(BaseModel): @@ -29,7 +24,6 @@ class Channel(BaseModel): Configurations: model_config : configuration for the model (only applicable for Pydantic version 2) Config : configuration for the class (only applicable for Pydantic version 1) - """ address: str @@ -50,30 +44,31 @@ class Config: extra = "allow" @classmethod - def from_spec( - cls, - channel: spec.channel.Channel, - message: spec.message.Message, - channel_name: str, - message_name: str, - ) -> Self: + def from_sub(cls, address: str, subscriber: SubscriberSpec) -> Self: + message = subscriber.operation.message + assert message.title + + *left, right = message.title.split(":") + message.title = ":".join((*left, f"Subscribe{right}")) + return cls( - address=channel_name, + description=subscriber.description, + address=address, messages={ - message_name: message_from_spec(message), + "SubscribeMessage": Message.from_spec(message), }, - description=channel.description, - servers=channel.servers, - bindings=channel_binding_from_spec(channel.bindings) - if channel.bindings - else None, + bindings=ChannelBinding.from_sub(subscriber.bindings), + servers=None, ) - -def from_spec( - channel: spec.channel.Channel, - message: spec.message.Message, - channel_name: str, - message_name: str, -) -> Channel: - return Channel.from_spec(channel, message, channel_name, message_name) + @classmethod + def from_pub(cls, address: str, publisher: PublisherSpec) -> Self: + return cls( + description=publisher.description, + address=address, + messages={ + "Message": Message.from_spec(publisher.operation.message), + }, + bindings=ChannelBinding.from_pub(publisher.bindings), + servers=None, + ) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/contact.py b/faststream/specification/asyncapi/v3_0_0/schema/contact.py new file mode 100644 index 0000000000..c42e750b28 --- /dev/null +++ b/faststream/specification/asyncapi/v3_0_0/schema/contact.py @@ -0,0 +1,3 @@ +from faststream.specification.asyncapi.v2_6_0.schema import Contact + +__all__ = ("Contact",) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/docs.py b/faststream/specification/asyncapi/v3_0_0/schema/docs.py new file mode 100644 index 0000000000..0a71688697 --- /dev/null +++ b/faststream/specification/asyncapi/v3_0_0/schema/docs.py @@ -0,0 +1,3 @@ +from faststream.specification.asyncapi.v2_6_0.schema import ExternalDocs + +__all__ = ("ExternalDocs",) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/info.py b/faststream/specification/asyncapi/v3_0_0/schema/info.py index 6d15c9e4dc..c9303e690c 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/info.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/info.py @@ -14,16 +14,16 @@ License, Tag, ) -from faststream.specification.base.info import BaseInfo +from faststream.specification.base.info import BaseApplicationInfo -class Info(BaseInfo): - """A class to represent information. +class ApplicationInfo(BaseApplicationInfo): + """A class to represent application information. Attributes: - termsOfService : terms of service for the information (default: None) - contact : contact information for the information (default: None) - license : license information for the information (default: None) + termsOfService : terms of service for the information + contact : contact information for the information + license : license information for the information tags : optional list of tags externalDocs : optional external documentation """ diff --git a/faststream/specification/asyncapi/v3_0_0/schema/license.py b/faststream/specification/asyncapi/v3_0_0/schema/license.py new file mode 100644 index 0000000000..44ee4b2813 --- /dev/null +++ b/faststream/specification/asyncapi/v3_0_0/schema/license.py @@ -0,0 +1,3 @@ +from faststream.specification.asyncapi.v2_6_0.schema import License + +__all__ = ("License",) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/message.py b/faststream/specification/asyncapi/v3_0_0/schema/message.py new file mode 100644 index 0000000000..fa665082e9 --- /dev/null +++ b/faststream/specification/asyncapi/v3_0_0/schema/message.py @@ -0,0 +1,6 @@ +from faststream.specification.asyncapi.v2_6_0.schema.message import ( + CorrelationId, + Message, +) + +__all__ = ("CorrelationId", "Message") diff --git a/faststream/specification/asyncapi/v3_0_0/schema/operations.py b/faststream/specification/asyncapi/v3_0_0/schema/operations.py index ffc647674a..8afff3c5c6 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/operations.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/operations.py @@ -1,21 +1,17 @@ from enum import Enum from typing import Optional, Union -from pydantic import BaseModel +from pydantic import BaseModel, Field from typing_extensions import Self from faststream._internal._compat import PYDANTIC_V2 from faststream._internal.basic_types import AnyDict -from faststream.specification import schema as spec -from faststream.specification.asyncapi.v2_6_0.schema.tag import Tag -from faststream.specification.asyncapi.v2_6_0.schema.utils import ( - Reference, -) -from faststream.specification.asyncapi.v3_0_0.schema.bindings import OperationBinding -from faststream.specification.asyncapi.v3_0_0.schema.bindings.main import ( - operation_binding_from_spec, -) -from faststream.specification.asyncapi.v3_0_0.schema.channels import Channel +from faststream.specification.schema.operation import Operation as OperationSpec + +from .bindings import OperationBinding +from .channels import Channel +from .tag import Tag +from .utils import Reference class Action(str, Enum): @@ -27,24 +23,24 @@ class Operation(BaseModel): """A class to represent an operation. Attributes: - operationId : ID of the operation + operation_id : ID of the operation summary : summary of the operation description : description of the operation bindings : bindings of the operation message : message of the operation security : security details of the operation tags : tags associated with the operation - """ action: Action + channel: Union[Channel, Reference] + summary: Optional[str] = None description: Optional[str] = None bindings: Optional[OperationBinding] = None - messages: list[Reference] - channel: Union[Channel, Reference] + messages: list[Reference] = Field(default_factory=list) security: Optional[dict[str, list[str]]] = None @@ -62,38 +58,37 @@ class Config: extra = "allow" @classmethod - def from_spec( + def from_sub( cls, - operation: spec.operation.Operation, - action: Action, - channel_name: str, + messages: list[Reference], + channel: Reference, + operation: OperationSpec, ) -> Self: return cls( - action=action, - summary=operation.summary, - description=operation.description, - bindings=operation_binding_from_spec(operation.bindings) - if operation.bindings - else None, - messages=[ - Reference( - **{ - "$ref": f"#/channels/{channel_name}/messages/SubscribeMessage" - if action is Action.RECEIVE - else f"#/channels/{channel_name}/messages/Message", - }, - ), - ], - channel=Reference( - **{"$ref": f"#/channels/{channel_name}"}, - ), - security=operation.security, + action=Action.RECEIVE, + messages=messages, + channel=channel, + bindings=OperationBinding.from_sub(operation.bindings), + summary=None, + description=None, + security=None, + tags=None, ) - -def from_spec( - operation: spec.operation.Operation, - action: Action, - channel_name: str, -) -> Operation: - return Operation.from_spec(operation, action, channel_name) + @classmethod + def from_pub( + cls, + messages: list[Reference], + channel: Reference, + operation: OperationSpec, + ) -> Self: + return cls( + action=Action.SEND, + messages=messages, + channel=channel, + bindings=OperationBinding.from_pub(operation.bindings), + summary=None, + description=None, + security=None, + tags=None, + ) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/schema.py b/faststream/specification/asyncapi/v3_0_0/schema/schema.py index ad60b8bfae..dc894ecb4e 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/schema.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/schema.py @@ -1,15 +1,17 @@ from typing import Literal, Optional, Union +from pydantic import Field + from faststream.specification.asyncapi.v3_0_0.schema.channels import Channel from faststream.specification.asyncapi.v3_0_0.schema.components import Components -from faststream.specification.asyncapi.v3_0_0.schema.info import Info +from faststream.specification.asyncapi.v3_0_0.schema.info import ApplicationInfo from faststream.specification.asyncapi.v3_0_0.schema.operations import Operation from faststream.specification.asyncapi.v3_0_0.schema.servers import Server -from faststream.specification.base.schema import BaseSchema +from faststream.specification.base.schema import BaseApplicationSchema -class Schema(BaseSchema): - """A class to represent a schema. +class ApplicationSchema(BaseApplicationSchema): + """A class to represent an application schema. Attributes: asyncapi : version of the async API @@ -21,12 +23,12 @@ class Schema(BaseSchema): components : optional components of the schema """ - info: Info + info: ApplicationInfo asyncapi: Union[Literal["3.0.0"], str] = "3.0.0" id: Optional[str] = None defaultContentType: Optional[str] = None servers: Optional[dict[str, Server]] = None - channels: dict[str, Channel] - operations: dict[str, Operation] + channels: dict[str, Channel] = Field(default_factory=dict) + operations: dict[str, Operation] = Field(default_factory=dict) components: Optional[Components] = None diff --git a/faststream/specification/asyncapi/v3_0_0/schema/tag.py b/faststream/specification/asyncapi/v3_0_0/schema/tag.py new file mode 100644 index 0000000000..e16c4f61cd --- /dev/null +++ b/faststream/specification/asyncapi/v3_0_0/schema/tag.py @@ -0,0 +1,3 @@ +from faststream.specification.asyncapi.v2_6_0.schema import Tag + +__all__ = ("Tag",) diff --git a/faststream/specification/asyncapi/v3_0_0/schema/utils.py b/faststream/specification/asyncapi/v3_0_0/schema/utils.py new file mode 100644 index 0000000000..c53f3ce1a0 --- /dev/null +++ b/faststream/specification/asyncapi/v3_0_0/schema/utils.py @@ -0,0 +1,6 @@ +from faststream.specification.asyncapi.v2_6_0.schema import Parameter, Reference + +__all__ = ( + "Parameter", + "Reference", +) diff --git a/faststream/specification/base/info.py b/faststream/specification/base/info.py index 79e5164de7..6e282dc19e 100644 --- a/faststream/specification/base/info.py +++ b/faststream/specification/base/info.py @@ -3,18 +3,18 @@ from faststream._internal._compat import PYDANTIC_V2 -class BaseInfo(BaseModel): +class BaseApplicationInfo(BaseModel): """A class to represent basic application information. Attributes: title : application title - version : application version (default: "1.0.0") - description : application description (default: "") + version : application version + description : application description """ title: str - version: str = "1.0.0" - description: str = "" + version: str + description: str if PYDANTIC_V2: model_config = {"extra": "allow"} diff --git a/faststream/specification/base/proto.py b/faststream/specification/base/proto.py deleted file mode 100644 index 42d118c46c..0000000000 --- a/faststream/specification/base/proto.py +++ /dev/null @@ -1,47 +0,0 @@ -from abc import abstractmethod -from typing import Any, Optional, Protocol - -from faststream.specification.schema.channel import Channel - - -class SpecificationEndpoint(Protocol): - """A class representing an asynchronous API operation.""" - - title_: Optional[str] - description_: Optional[str] - include_in_schema: bool - - @property - def name(self) -> str: - """Returns the name of the API operation.""" - return self.title_ or self.get_name() - - @abstractmethod - def get_name(self) -> str: - """Name property fallback.""" - raise NotImplementedError - - @property - def description(self) -> Optional[str]: - """Returns the description of the API operation.""" - return self.description_ or self.get_description() - - def get_description(self) -> Optional[str]: - """Description property fallback.""" - return None - - def schema(self) -> dict[str, Channel]: - """Returns the schema of the API operation as a dictionary of channel names and channel objects.""" - if self.include_in_schema: - return self.get_schema() - return {} - - @abstractmethod - def get_schema(self) -> dict[str, Channel]: - """Generate AsyncAPI schema.""" - raise NotImplementedError - - @abstractmethod - def get_payloads(self) -> Any: - """Generate AsyncAPI payloads.""" - raise NotImplementedError diff --git a/faststream/specification/base/schema.py b/faststream/specification/base/schema.py index 914b389bc2..828e1699b7 100644 --- a/faststream/specification/base/schema.py +++ b/faststream/specification/base/schema.py @@ -4,11 +4,11 @@ from faststream._internal._compat import model_to_json, model_to_jsonable -from .info import BaseInfo +from .info import BaseApplicationInfo -class BaseSchema(BaseModel): - """A class to represent a Pydantic-serializable schema. +class BaseApplicationSchema(BaseModel): + """A class to represent a Pydantic-serializable application schema. Attributes: info : information about the schema @@ -19,7 +19,7 @@ class BaseSchema(BaseModel): to_yaml() -> str: Convert the schema to a YAML string. """ - info: BaseInfo + info: BaseApplicationInfo def to_jsonable(self) -> Any: """Convert the schema to a JSON-serializable object.""" diff --git a/faststream/specification/base/specification.py b/faststream/specification/base/specification.py index d9dc0fcf14..0c3946e76f 100644 --- a/faststream/specification/base/specification.py +++ b/faststream/specification/base/specification.py @@ -1,11 +1,11 @@ from typing import Any, Protocol, runtime_checkable -from .schema import BaseSchema +from .schema import BaseApplicationSchema @runtime_checkable class Specification(Protocol): - schema: BaseSchema + schema: BaseApplicationSchema def to_json(self) -> str: return self.schema.to_json() diff --git a/faststream/specification/proto/__init__.py b/faststream/specification/proto/__init__.py new file mode 100644 index 0000000000..3189e7cc8f --- /dev/null +++ b/faststream/specification/proto/__init__.py @@ -0,0 +1,4 @@ +from .broker import ServerSpecification +from .endpoint import EndpointSpecification + +__all__ = ("EndpointSpecification", "ServerSpecification") diff --git a/faststream/specification/proto/broker.py b/faststream/specification/proto/broker.py new file mode 100644 index 0000000000..225393b24e --- /dev/null +++ b/faststream/specification/proto/broker.py @@ -0,0 +1,14 @@ +from collections.abc import Iterable +from typing import Optional, Protocol, Union + +from faststream.security import BaseSecurity +from faststream.specification.schema.extra import Tag, TagDict + + +class ServerSpecification(Protocol): + url: Union[str, list[str]] + protocol: Optional[str] + protocol_version: Optional[str] + description: Optional[str] + tags: Iterable[Union[Tag, TagDict]] + security: Optional[BaseSecurity] diff --git a/faststream/specification/proto/endpoint.py b/faststream/specification/proto/endpoint.py new file mode 100644 index 0000000000..380acb1071 --- /dev/null +++ b/faststream/specification/proto/endpoint.py @@ -0,0 +1,62 @@ +from abc import ABC, abstractmethod +from typing import Any, Generic, Optional, TypeVar + +T = TypeVar("T") + + +class EndpointSpecification(ABC, Generic[T]): + """A class representing an asynchronous API operation: Pub or Sub.""" + + title_: Optional[str] + description_: Optional[str] + include_in_schema: bool + + def __init__( + self, + *args: Any, + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, + **kwargs: Any, + ) -> None: + self.title_ = title_ + self.description_ = description_ + self.include_in_schema = include_in_schema + + # Call next base class parent init + super().__init__(*args, **kwargs) + + @property + def name(self) -> str: + """Returns the name of the API operation.""" + return self.title_ or self.get_default_name() + + @abstractmethod + def get_default_name(self) -> str: + """Name property fallback.""" + raise NotImplementedError + + @property + def description(self) -> Optional[str]: + """Returns the description of the API operation.""" + return self.description_ or self.get_default_description() + + def get_default_description(self) -> Optional[str]: + """Description property fallback.""" + return None + + def schema(self) -> dict[str, T]: + """Returns the schema of the API operation as a dictionary of channel names and channel objects.""" + if self.include_in_schema: + return self.get_schema() + return {} + + @abstractmethod + def get_schema(self) -> dict[str, T]: + """Generate AsyncAPI schema.""" + raise NotImplementedError + + @abstractmethod + def get_payloads(self) -> Any: + """Generate AsyncAPI payloads.""" + raise NotImplementedError diff --git a/faststream/specification/schema/__init__.py b/faststream/specification/schema/__init__.py index a2ec26fa7a..009a6a63d7 100644 --- a/faststream/specification/schema/__init__.py +++ b/faststream/specification/schema/__init__.py @@ -1,34 +1,29 @@ -from . import ( - bindings, - channel, - contact, - docs, - info, - license, - message, - operation, - security, - tag, +from .extra import ( + Contact, + ContactDict, + ExternalDocs, + ExternalDocsDict, + License, + LicenseDict, + Tag, + TagDict, ) -from .contact import Contact -from .docs import ExternalDocs -from .license import License -from .tag import Tag +from .message import Message +from .operation import Operation +from .publisher import PublisherSpec +from .subscriber import SubscriberSpec __all__ = ( "Contact", + "ContactDict", "ExternalDocs", + "ExternalDocsDict", "License", + "LicenseDict", + "Message", + "Operation", + "PublisherSpec", + "SubscriberSpec", "Tag", - # module aliases - "bindings", - "channel", - "contact", - "docs", - "info", - "license", - "message", - "operation", - "security", - "tag", + "TagDict", ) diff --git a/faststream/specification/schema/bindings/amqp.py b/faststream/specification/schema/bindings/amqp.py index 42f29dd1c8..f15201bb8e 100644 --- a/faststream/specification/schema/bindings/amqp.py +++ b/faststream/specification/schema/bindings/amqp.py @@ -1,43 +1,29 @@ -"""AsyncAPI AMQP bindings. - -References: https://github.com/asyncapi/bindings/tree/master/amqp -""" - from dataclasses import dataclass -from typing import Literal, Optional +from typing import TYPE_CHECKING, Literal, Optional + +if TYPE_CHECKING: + from faststream.rabbit.schemas import RabbitExchange, RabbitQueue @dataclass class Queue: - """A class to represent a queue. - - Attributes: - name : name of the queue - durable : indicates if the queue is durable - exclusive : indicates if the queue is exclusive - autoDelete : indicates if the queue should be automatically deleted - vhost : virtual host of the queue (default is "/") - """ - name: str durable: bool exclusive: bool - autoDelete: bool - vhost: str = "/" + auto_delete: bool + + @classmethod + def from_queue(cls, queue: "RabbitQueue") -> "Queue": + return cls( + name=queue.name, + durable=queue.durable, + exclusive=queue.exclusive, + auto_delete=queue.auto_delete, + ) @dataclass class Exchange: - """A class to represent an exchange. - - Attributes: - name : name of the exchange (optional) - type : type of the exchange, can be one of "default", "direct", "topic", "fanout", "headers" - durable : whether the exchange is durable (optional) - autoDelete : whether the exchange is automatically deleted (optional) - vhost : virtual host of the exchange, default is "/" - """ - type: Literal[ "default", "direct", @@ -51,40 +37,43 @@ class Exchange: name: Optional[str] = None durable: Optional[bool] = None - autoDelete: Optional[bool] = None - vhost: str = "/" + auto_delete: Optional[bool] = None + + @classmethod + def from_exchange(cls, exchange: "RabbitExchange") -> "Exchange": + if not exchange.name: + return cls(type="default") + return cls( + type=exchange.type.value, + name=exchange.name, + durable=exchange.durable, + auto_delete=exchange.auto_delete, + ) + + @property + def is_respect_routing_key(self) -> bool: + """Is exchange respects routing key or not.""" + return self.type in { + "default", + "direct", + "topic", + } @dataclass class ChannelBinding: - """A class to represent channel binding. - - Attributes: - is_ : Type of binding, can be "queue" or "routingKey" - bindingVersion : Version of the binding - queue : Optional queue object - exchange : Optional exchange object - """ - - is_: Literal["queue", "routingKey"] - queue: Optional[Queue] = None - exchange: Optional[Exchange] = None + queue: Queue + exchange: Exchange + virtual_host: str @dataclass class OperationBinding: - """A class to represent an operation binding. - - Attributes: - cc : optional string representing the cc - ack : boolean indicating if the operation is acknowledged - replyTo : optional dictionary representing the replyTo - bindingVersion : string representing the binding version - """ - - cc: Optional[str] = None - ack: bool = True - replyTo: Optional[str] = None - deliveryMode: Optional[int] = None - mandatory: Optional[bool] = None - priority: Optional[int] = None + routing_key: Optional[str] + queue: Queue + exchange: Exchange + ack: bool + reply_to: Optional[str] + persist: Optional[bool] + mandatory: Optional[bool] + priority: Optional[int] diff --git a/faststream/specification/schema/bindings/kafka.py b/faststream/specification/schema/bindings/kafka.py index 142a2a5285..fc9d0867c8 100644 --- a/faststream/specification/schema/bindings/kafka.py +++ b/faststream/specification/schema/bindings/kafka.py @@ -15,13 +15,11 @@ class ChannelBinding: topic : optional string representing the topic partitions : optional positive integer representing the number of partitions replicas : optional positive integer representing the number of replicas - bindingVersion : string representing the binding version """ - topic: Optional[str] = None - partitions: Optional[int] = None - replicas: Optional[int] = None - bindingVersion: str = "0.4.0" + topic: Optional[str] + partitions: Optional[int] + replicas: Optional[int] # TODO: # topicConfiguration @@ -32,13 +30,11 @@ class OperationBinding: """A class to represent an operation binding. Attributes: - groupId : optional dictionary representing the group ID - clientId : optional dictionary representing the client ID - replyTo : optional dictionary representing the reply-to - bindingVersion : version of the binding (default: "0.4.0") + group_id : optional dictionary representing the group ID + client_id : optional dictionary representing the client ID + reply_to : optional dictionary representing the reply-to """ - groupId: Optional[dict[str, Any]] = None - clientId: Optional[dict[str, Any]] = None - replyTo: Optional[dict[str, Any]] = None - bindingVersion: str = "0.4.0" + group_id: Optional[dict[str, Any]] + client_id: Optional[dict[str, Any]] + reply_to: Optional[dict[str, Any]] diff --git a/faststream/specification/schema/bindings/nats.py b/faststream/specification/schema/bindings/nats.py index 034efada4e..412f29d557 100644 --- a/faststream/specification/schema/bindings/nats.py +++ b/faststream/specification/schema/bindings/nats.py @@ -14,12 +14,10 @@ class ChannelBinding: Attributes: subject : subject of the channel binding queue : optional queue for the channel binding - bindingVersion : version of the channel binding, default is "custom" """ subject: str - queue: Optional[str] = None - bindingVersion: str = "custom" + queue: Optional[str] @dataclass @@ -27,9 +25,7 @@ class OperationBinding: """A class to represent an operation binding. Attributes: - replyTo : optional dictionary containing reply information - bindingVersion : version of the binding (default is "custom") + reply_to : optional dictionary containing reply information """ - replyTo: Optional[dict[str, Any]] = None - bindingVersion: str = "custom" + reply_to: Optional[dict[str, Any]] diff --git a/faststream/specification/schema/bindings/redis.py b/faststream/specification/schema/bindings/redis.py index c1b3e138a0..17287aa5e4 100644 --- a/faststream/specification/schema/bindings/redis.py +++ b/faststream/specification/schema/bindings/redis.py @@ -14,14 +14,12 @@ class ChannelBinding: Attributes: channel : the channel name method : the method used for binding (ssubscribe, psubscribe, subscribe) - bindingVersion : the version of the binding """ channel: str method: Optional[str] = None group_name: Optional[str] = None consumer_name: Optional[str] = None - bindingVersion: str = "custom" @dataclass @@ -29,9 +27,7 @@ class OperationBinding: """A class to represent an operation binding. Attributes: - replyTo : optional dictionary containing reply information - bindingVersion : version of the binding (default is "custom") + reply_to : optional dictionary containing reply information """ - replyTo: Optional[dict[str, Any]] = None - bindingVersion: str = "custom" + reply_to: Optional[dict[str, Any]] = None diff --git a/faststream/specification/schema/channel.py b/faststream/specification/schema/channel.py deleted file mode 100644 index 89db7d7a6f..0000000000 --- a/faststream/specification/schema/channel.py +++ /dev/null @@ -1,24 +0,0 @@ -from dataclasses import dataclass -from typing import Optional - -from faststream.specification.schema.bindings import ChannelBinding -from faststream.specification.schema.operation import Operation - - -@dataclass -class Channel: - """Channel specification. - - Attributes: - description : optional description of the channel - servers : optional list of servers associated with the channel - bindings : optional channel binding - subscribe : optional operation for subscribing to the channel - publish : optional operation for publishing to the channel - """ - - description: Optional[str] = None - servers: Optional[list[str]] = None - bindings: Optional[ChannelBinding] = None - subscribe: Optional[Operation] = None - publish: Optional[Operation] = None diff --git a/faststream/specification/schema/components.py b/faststream/specification/schema/components.py deleted file mode 100644 index 39e6011591..0000000000 --- a/faststream/specification/schema/components.py +++ /dev/null @@ -1,39 +0,0 @@ -from typing import ( - Any, - Optional, -) - -from pydantic import BaseModel - -from faststream._internal._compat import ( - PYDANTIC_V2, -) -from faststream.specification.schema.message import Message - - -class Components(BaseModel): - """A class to represent components in a system. - - Attributes: - messages : Optional dictionary of messages - schemas : Optional dictionary of schemas - - Note: - The following attributes are not implemented yet: - - servers - - serverVariables - - channels - - securitySchemes - """ - - messages: Optional[dict[str, Message]] = None - schemas: Optional[dict[str, dict[str, Any]]] = None - securitySchemes: Optional[dict[str, dict[str, Any]]] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" diff --git a/faststream/specification/schema/contact.py b/faststream/specification/schema/contact.py deleted file mode 100644 index 2de5d06292..0000000000 --- a/faststream/specification/schema/contact.py +++ /dev/null @@ -1,44 +0,0 @@ -from typing import ( - Optional, -) - -from pydantic import AnyHttpUrl, BaseModel -from typing_extensions import Required, TypedDict - -from faststream._internal._compat import PYDANTIC_V2, EmailStr - - -class ContactDict(TypedDict, total=False): - """A class to represent a dictionary of contact information. - - Attributes: - name : required name of the contact (type: str) - url : URL of the contact (type: AnyHttpUrl) - email : email address of the contact (type: EmailStr) - """ - - name: Required[str] - url: AnyHttpUrl - email: EmailStr - - -class Contact(BaseModel): - """A class to represent a contact. - - Attributes: - name : name of the contact (str) - url : URL of the contact (Optional[AnyHttpUrl]) - email : email of the contact (Optional[EmailStr]) - """ - - name: str - url: Optional[AnyHttpUrl] = None - email: Optional[EmailStr] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" diff --git a/faststream/specification/schema/docs.py b/faststream/specification/schema/docs.py deleted file mode 100644 index d5b69fe7b4..0000000000 --- a/faststream/specification/schema/docs.py +++ /dev/null @@ -1,29 +0,0 @@ -from dataclasses import dataclass -from typing import Optional - -from typing_extensions import Required, TypedDict - - -class ExternalDocsDict(TypedDict, total=False): - """A dictionary type for representing external documentation. - - Attributes: - url : Required URL for the external documentation - description : Description of the external documentation - """ - - url: Required[str] - description: str - - -@dataclass -class ExternalDocs: - """A class to represent external documentation. - - Attributes: - url : URL of the external documentation - description : optional description of the external documentation - """ - - url: str - description: Optional[str] = None diff --git a/faststream/specification/schema/extra/__init__.py b/faststream/specification/schema/extra/__init__.py new file mode 100644 index 0000000000..f2417a905f --- /dev/null +++ b/faststream/specification/schema/extra/__init__.py @@ -0,0 +1,15 @@ +from .contact import Contact, ContactDict +from .external_docs import ExternalDocs, ExternalDocsDict +from .license import License, LicenseDict +from .tag import Tag, TagDict + +__all__ = ( + "Contact", + "ContactDict", + "ExternalDocs", + "ExternalDocsDict", + "License", + "LicenseDict", + "Tag", + "TagDict", +) diff --git a/faststream/specification/schema/extra/contact.py b/faststream/specification/schema/extra/contact.py new file mode 100644 index 0000000000..dfabbbacb3 --- /dev/null +++ b/faststream/specification/schema/extra/contact.py @@ -0,0 +1,20 @@ +from dataclasses import dataclass +from typing import Optional + +from pydantic import AnyHttpUrl +from typing_extensions import Required, TypedDict + +from faststream._internal._compat import EmailStr + + +class ContactDict(TypedDict, total=False): + name: Required[str] + url: AnyHttpUrl + email: EmailStr + + +@dataclass +class Contact: + name: str + url: Optional[AnyHttpUrl] = None + email: Optional[EmailStr] = None diff --git a/faststream/specification/schema/extra/external_docs.py b/faststream/specification/schema/extra/external_docs.py new file mode 100644 index 0000000000..600a6d3a95 --- /dev/null +++ b/faststream/specification/schema/extra/external_docs.py @@ -0,0 +1,15 @@ +from dataclasses import dataclass +from typing import Optional + +from typing_extensions import Required, TypedDict + + +class ExternalDocsDict(TypedDict, total=False): + url: Required[str] + description: str + + +@dataclass +class ExternalDocs: + url: str + description: Optional[str] = None diff --git a/faststream/specification/schema/extra/license.py b/faststream/specification/schema/extra/license.py new file mode 100644 index 0000000000..7bd4039621 --- /dev/null +++ b/faststream/specification/schema/extra/license.py @@ -0,0 +1,16 @@ +from dataclasses import dataclass +from typing import Optional + +from pydantic import AnyHttpUrl +from typing_extensions import Required, TypedDict + + +class LicenseDict(TypedDict, total=False): + name: Required[str] + url: AnyHttpUrl + + +@dataclass +class License: + name: str + url: Optional[AnyHttpUrl] = None diff --git a/faststream/specification/schema/extra/tag.py b/faststream/specification/schema/extra/tag.py new file mode 100644 index 0000000000..1d62ed7491 --- /dev/null +++ b/faststream/specification/schema/extra/tag.py @@ -0,0 +1,19 @@ +from dataclasses import dataclass +from typing import Optional, Union + +from typing_extensions import Required, TypedDict + +from .external_docs import ExternalDocs, ExternalDocsDict + + +class TagDict(TypedDict, total=False): + name: Required[str] + description: str + external_docs: Union[ExternalDocs, ExternalDocsDict] + + +@dataclass +class Tag: + name: str + description: Optional[str] = None + external_docs: Optional[Union[ExternalDocs, ExternalDocsDict]] = None diff --git a/faststream/specification/schema/info.py b/faststream/specification/schema/info.py deleted file mode 100644 index 67f2341e4f..0000000000 --- a/faststream/specification/schema/info.py +++ /dev/null @@ -1,27 +0,0 @@ -from typing import ( - Any, - Optional, - Union, -) - -from pydantic import AnyHttpUrl, BaseModel - -from faststream.specification.schema.contact import Contact, ContactDict -from faststream.specification.schema.license import License, LicenseDict - - -class Info(BaseModel): - """A class to represent information. - - Attributes: - title : title of the information - version : version of the information (default: "1.0.0") - description : description of the information (default: "") - termsOfService : terms of service for the information (default: None) - contact : contact information for the information (default: None) - license : license information for the information (default: None) - """ - - termsOfService: Optional[AnyHttpUrl] = None - contact: Optional[Union[Contact, ContactDict, dict[str, Any]]] = None - license: Optional[Union[License, LicenseDict, dict[str, Any]]] = None diff --git a/faststream/specification/schema/license.py b/faststream/specification/schema/license.py deleted file mode 100644 index f95faf3e10..0000000000 --- a/faststream/specification/schema/license.py +++ /dev/null @@ -1,45 +0,0 @@ -from typing import ( - Optional, -) - -from pydantic import AnyHttpUrl, BaseModel -from typing_extensions import Required, TypedDict - -from faststream._internal._compat import ( - PYDANTIC_V2, -) - - -class LicenseDict(TypedDict, total=False): - """A dictionary-like class to represent a license. - - Attributes: - name : required name of the license (type: str) - url : URL of the license (type: AnyHttpUrl) - """ - - name: Required[str] - url: AnyHttpUrl - - -class License(BaseModel): - """A class to represent a license. - - Attributes: - name : name of the license - url : URL of the license (optional) - - Config: - extra : allow additional attributes in the model (PYDANTIC_V2) - """ - - name: str - url: Optional[AnyHttpUrl] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" diff --git a/faststream/specification/schema/message.py b/faststream/specification/schema/message.py deleted file mode 100644 index 865ec95553..0000000000 --- a/faststream/specification/schema/message.py +++ /dev/null @@ -1,51 +0,0 @@ -from dataclasses import dataclass -from typing import Any, Optional, Union - -from faststream.specification.schema.docs import ExternalDocs -from faststream.specification.schema.tag import Tag - - -@dataclass -class CorrelationId: - """Correlation ID specification. - - Attributes: - description : optional description of the correlation ID - location : location of the correlation ID - - Configurations: - extra : allows extra fields in the correlation ID model - """ - - location: str - description: Optional[str] = None - - -@dataclass -class Message: - """Message specification. - - Attributes: - title : title of the message - name : name of the message - summary : summary of the message - description : description of the message - messageId : ID of the message - correlationId : correlation ID of the message - contentType : content type of the message - payload : dictionary representing the payload of the message - tags : list of tags associated with the message - externalDocs : external documentation associated with the message - """ - - payload: dict[str, Any] - title: Optional[str] = None - name: Optional[str] = None - summary: Optional[str] = None - description: Optional[str] = None - messageId: Optional[str] = None - correlationId: Optional[CorrelationId] = None - contentType: Optional[str] = None - - tags: Optional[list[Union[Tag, dict[str, Any]]]] = None - externalDocs: Optional[Union[ExternalDocs, dict[str, Any]]] = None diff --git a/faststream/specification/schema/message/__init__.py b/faststream/specification/schema/message/__init__.py new file mode 100644 index 0000000000..6221895ab5 --- /dev/null +++ b/faststream/specification/schema/message/__init__.py @@ -0,0 +1,3 @@ +from .model import Message + +__all__ = ("Message",) diff --git a/faststream/specification/schema/message/model.py b/faststream/specification/schema/message/model.py new file mode 100644 index 0000000000..8b8c37f24a --- /dev/null +++ b/faststream/specification/schema/message/model.py @@ -0,0 +1,11 @@ +from dataclasses import dataclass +from typing import Optional + +from faststream._internal.basic_types import AnyDict + + +@dataclass +class Message: + payload: AnyDict # JSON Schema + + title: Optional[str] diff --git a/faststream/specification/schema/operation.py b/faststream/specification/schema/operation.py deleted file mode 100644 index e88d3c39e4..0000000000 --- a/faststream/specification/schema/operation.py +++ /dev/null @@ -1,33 +0,0 @@ -from dataclasses import dataclass -from typing import Any, Optional, Union - -from faststream.specification.schema.bindings import OperationBinding -from faststream.specification.schema.message import Message -from faststream.specification.schema.tag import Tag - - -@dataclass -class Operation: - """A class to represent an operation. - - Attributes: - operationId : ID of the operation - summary : summary of the operation - description : description of the operation - bindings : bindings of the operation - message : message of the operation - security : security details of the operation - tags : tags associated with the operation - """ - - message: Message - - operationId: Optional[str] = None - summary: Optional[str] = None - description: Optional[str] = None - - bindings: Optional[OperationBinding] = None - - security: Optional[dict[str, list[str]]] = None - - tags: Optional[list[Union[Tag, dict[str, Any]]]] = None diff --git a/faststream/specification/schema/operation/__init__.py b/faststream/specification/schema/operation/__init__.py new file mode 100644 index 0000000000..85cbafe10a --- /dev/null +++ b/faststream/specification/schema/operation/__init__.py @@ -0,0 +1,3 @@ +from .model import Operation + +__all__ = ("Operation",) diff --git a/faststream/specification/schema/operation/model.py b/faststream/specification/schema/operation/model.py new file mode 100644 index 0000000000..2e72e523e9 --- /dev/null +++ b/faststream/specification/schema/operation/model.py @@ -0,0 +1,11 @@ +from dataclasses import dataclass +from typing import Optional + +from faststream.specification.schema.bindings import OperationBinding +from faststream.specification.schema.message import Message + + +@dataclass +class Operation: + message: Message + bindings: Optional[OperationBinding] diff --git a/faststream/specification/schema/publisher.py b/faststream/specification/schema/publisher.py new file mode 100644 index 0000000000..f534619d0f --- /dev/null +++ b/faststream/specification/schema/publisher.py @@ -0,0 +1,12 @@ +from dataclasses import dataclass +from typing import Optional + +from .bindings import ChannelBinding +from .operation import Operation + + +@dataclass +class PublisherSpec: + description: str + operation: Operation + bindings: Optional[ChannelBinding] diff --git a/faststream/specification/schema/security.py b/faststream/specification/schema/security.py deleted file mode 100644 index d940cbdc4f..0000000000 --- a/faststream/specification/schema/security.py +++ /dev/null @@ -1,105 +0,0 @@ -from typing import Literal, Optional - -from pydantic import AnyHttpUrl, BaseModel, Field - -from faststream._internal._compat import PYDANTIC_V2 - - -class OauthFlowObj(BaseModel): - """A class to represent an OAuth flow object. - - Attributes: - authorizationUrl : Optional[AnyHttpUrl] : The URL for authorization - tokenUrl : Optional[AnyHttpUrl] : The URL for token - refreshUrl : Optional[AnyHttpUrl] : The URL for refresh - scopes : dict[str, str] : The scopes for the OAuth flow - """ - - authorizationUrl: Optional[AnyHttpUrl] = None - tokenUrl: Optional[AnyHttpUrl] = None - refreshUrl: Optional[AnyHttpUrl] = None - scopes: dict[str, str] - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" - - -class OauthFlows(BaseModel): - """A class to represent OAuth flows. - - Attributes: - implicit : Optional[OauthFlowObj] : Implicit OAuth flow object - password : Optional[OauthFlowObj] : Password OAuth flow object - clientCredentials : Optional[OauthFlowObj] : Client credentials OAuth flow object - authorizationCode : Optional[OauthFlowObj] : Authorization code OAuth flow object - """ - - implicit: Optional[OauthFlowObj] = None - password: Optional[OauthFlowObj] = None - clientCredentials: Optional[OauthFlowObj] = None - authorizationCode: Optional[OauthFlowObj] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" - - -class SecuritySchemaComponent(BaseModel): - """A class to represent a security schema component. - - Attributes: - type : Literal, the type of the security schema component - name : optional name of the security schema component - description : optional description of the security schema component - in_ : optional location of the security schema component - schema_ : optional schema of the security schema component - bearerFormat : optional bearer format of the security schema component - openIdConnectUrl : optional OpenID Connect URL of the security schema component - flows : optional OAuth flows of the security schema component - """ - - type: Literal[ - "userPassword", - "apikey", - "X509", - "symmetricEncryption", - "asymmetricEncryption", - "httpApiKey", - "http", - "oauth2", - "openIdConnect", - "plain", - "scramSha256", - "scramSha512", - "gssapi", - ] - name: Optional[str] = None - description: Optional[str] = None - in_: Optional[str] = Field( - default=None, - alias="in", - ) - schema_: Optional[str] = Field( - default=None, - alias="schema", - ) - bearerFormat: Optional[str] = None - openIdConnectUrl: Optional[str] = None - flows: Optional[OauthFlows] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" diff --git a/faststream/specification/schema/servers.py b/faststream/specification/schema/servers.py deleted file mode 100644 index d296c359a2..0000000000 --- a/faststream/specification/schema/servers.py +++ /dev/null @@ -1,65 +0,0 @@ -from typing import Any, Optional, Union - -from pydantic import BaseModel - -from faststream._internal._compat import PYDANTIC_V2 -from faststream.specification.schema.tag import Tag - -SecurityRequirement = list[dict[str, list[str]]] - - -class ServerVariable(BaseModel): - """A class to represent a server variable. - - Attributes: - enum : list of possible values for the server variable (optional) - default : default value for the server variable (optional) - description : description of the server variable (optional) - examples : list of example values for the server variable (optional) - """ - - enum: Optional[list[str]] = None - default: Optional[str] = None - description: Optional[str] = None - examples: Optional[list[str]] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" - - -class Server(BaseModel): - """A class to represent a server. - - Attributes: - url : URL of the server - protocol : protocol used by the server - description : optional description of the server - protocolVersion : optional version of the protocol used by the server - tags : optional list of tags associated with the server - security : optional security requirement for the server - variables : optional dictionary of server variables - - Note: - The attributes `description`, `protocolVersion`, `tags`, `security`, `variables`, and `bindings` are all optional. - """ - - url: str - protocol: str - description: Optional[str] = None - protocolVersion: Optional[str] = None - tags: Optional[list[Union[Tag, dict[str, Any]]]] = None - security: Optional[SecurityRequirement] = None - variables: Optional[dict[str, ServerVariable]] = None - - if PYDANTIC_V2: - model_config = {"extra": "allow"} - - else: - - class Config: - extra = "allow" diff --git a/faststream/specification/schema/subscriber.py b/faststream/specification/schema/subscriber.py new file mode 100644 index 0000000000..befcaf61e6 --- /dev/null +++ b/faststream/specification/schema/subscriber.py @@ -0,0 +1,12 @@ +from dataclasses import dataclass +from typing import Optional + +from .bindings import ChannelBinding +from .operation import Operation + + +@dataclass +class SubscriberSpec: + description: str + operation: Operation + bindings: Optional[ChannelBinding] diff --git a/faststream/specification/schema/tag.py b/faststream/specification/schema/tag.py deleted file mode 100644 index ff9509d2c8..0000000000 --- a/faststream/specification/schema/tag.py +++ /dev/null @@ -1,37 +0,0 @@ -from dataclasses import dataclass -from typing import Optional, Union - -from typing_extensions import Required, TypedDict - -from faststream.specification.schema.docs import ExternalDocs, ExternalDocsDict - - -class TagDict(TypedDict, total=False): - """A dictionary-like class for storing tags. - - Attributes: - name : required name of the tag - description : description of the tag - externalDocs : external documentation for the tag - - """ - - name: Required[str] - description: str - externalDocs: Union[ExternalDocs, ExternalDocsDict] - - -@dataclass -class Tag: - """A class to represent a tag. - - Attributes: - name : name of the tag - description : description of the tag (optional) - externalDocs : external documentation for the tag (optional) - - """ - - name: str - description: Optional[str] = None - externalDocs: Optional[Union[ExternalDocs, ExternalDocsDict]] = None diff --git a/ruff.toml b/ruff.toml index 5cf4479d4e..f3ad63fd76 100644 --- a/ruff.toml +++ b/ruff.toml @@ -98,6 +98,12 @@ ignore = [ "N815", # Variable `*` in class scope should not be mixedCase ] +# FIXME +# "faststream/specification/asyncapi/**/*.py" = [ +# "ERA001", +# "N815", # Variable `*` in class scope should not be mixedCase +# ] + "**/fastapi/**/*.py" = [ "N803", # Argument name `expandMessageExamples` should be lowercase ] diff --git a/serve.py b/serve.py new file mode 100644 index 0000000000..bc0a693167 --- /dev/null +++ b/serve.py @@ -0,0 +1,9 @@ +from faststream import FastStream +from faststream.rabbit import RabbitBroker + +broker = RabbitBroker() +app = FastStream(broker) + +@app.after_startup +async def _(): + raise ValueError diff --git a/tests/asyncapi/base/v2_6_0/arguments.py b/tests/asyncapi/base/v2_6_0/arguments.py index b2479fc7ab..aaac817e85 100644 --- a/tests/asyncapi/base/v2_6_0/arguments.py +++ b/tests/asyncapi/base/v2_6_0/arguments.py @@ -5,7 +5,6 @@ import pydantic from dirty_equals import IsDict, IsPartialDict, IsStr from fast_depends import Depends -from fastapi import Depends as APIDepends from typing_extensions import Literal from faststream import Context @@ -17,7 +16,7 @@ class FastAPICompatible: broker_class: type[BrokerUsecase] - dependency_builder = staticmethod(APIDepends) + dependency_builder = staticmethod(Depends) def build_app(self, broker: BrokerUsecase[Any, Any]) -> BrokerUsecase[Any, Any]: """Patch it to test FastAPI scheme generation too.""" @@ -67,7 +66,7 @@ async def handle(msg) -> None: assert key == "custom_name" assert schema["channels"][key]["description"] == "Test description.", schema[ "channels" - ][key]["description"] + ][key] def test_empty(self) -> None: broker = self.broker_class() @@ -424,7 +423,7 @@ class TestModel(pydantic.BaseModel): @broker.subscriber("test") async def handle(model: TestModel) -> None: ... - schema = AsyncAPI(self.build_app(broker)).to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] diff --git a/tests/asyncapi/base/v2_6_0/fastapi.py b/tests/asyncapi/base/v2_6_0/fastapi.py index d814b9df4e..c6b1bd6a2d 100644 --- a/tests/asyncapi/base/v2_6_0/fastapi.py +++ b/tests/asyncapi/base/v2_6_0/fastapi.py @@ -2,7 +2,7 @@ import pytest from dirty_equals import IsStr -from fastapi import FastAPI +from fastapi import Depends, FastAPI from fastapi.testclient import TestClient from faststream._internal.broker.broker import BrokerUsecase @@ -15,6 +15,8 @@ class FastAPITestCase: router_class: type[StreamRouter[MsgType]] broker_wrapper: Callable[[BrokerUsecase[MsgType, Any]], BrokerUsecase[MsgType, Any]] + dependency_builder = staticmethod(Depends) + @pytest.mark.skip() @pytest.mark.asyncio() async def test_fastapi_full_information(self) -> None: diff --git a/tests/asyncapi/base/v2_6_0/from_spec/__init__.py b/tests/asyncapi/base/v2_6_0/from_spec/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/asyncapi/base/v2_6_0/from_spec/test_contact.py b/tests/asyncapi/base/v2_6_0/from_spec/test_contact.py new file mode 100644 index 0000000000..ad97d872ce --- /dev/null +++ b/tests/asyncapi/base/v2_6_0/from_spec/test_contact.py @@ -0,0 +1,59 @@ +from typing import Any + +import pytest + +from faststream.specification import Contact +from faststream.specification.asyncapi.v2_6_0.schema import Contact as AsyncAPIContact + + +@pytest.mark.parametrize( + ("arg", "result"), + ( + pytest.param( + None, + None, + id="None", + ), + pytest.param( + Contact( + name="test", + url="http://contact.com", + email="support@gmail.com", + ), + AsyncAPIContact( + name="test", + url="http://contact.com", + email="support@gmail.com", + ), + id="Contact object", + ), + pytest.param( + { + "name": "test", + "url": "http://contact.com", + }, + AsyncAPIContact( + name="test", + url="http://contact.com", + ), + id="Contact dict", + ), + pytest.param( + { + "name": "test", + "url": "http://contact.com", + "email": "support@gmail.com", + "extra": "test", + }, + { + "name": "test", + "url": "http://contact.com", + "email": "support@gmail.com", + "extra": "test", + }, + id="Unknown dict", + ), + ), +) +def test_contact_factory_method(arg: Any, result: Any) -> None: + assert AsyncAPIContact.from_spec(arg) == result diff --git a/tests/asyncapi/base/v2_6_0/from_spec/test_external_docs.py b/tests/asyncapi/base/v2_6_0/from_spec/test_external_docs.py new file mode 100644 index 0000000000..7b2ede38c8 --- /dev/null +++ b/tests/asyncapi/base/v2_6_0/from_spec/test_external_docs.py @@ -0,0 +1,35 @@ +from typing import Any + +import pytest + +from faststream.specification import ExternalDocs +from faststream.specification.asyncapi.v2_6_0.schema import ExternalDocs as AsyncAPIDocs + + +@pytest.mark.parametrize( + ("arg", "result"), + ( + pytest.param( + None, + None, + id="None", + ), + pytest.param( + ExternalDocs(description="test", url="http://docs.com"), + AsyncAPIDocs(description="test", url="http://docs.com"), + id="ExternalDocs object", + ), + pytest.param( + {"description": "test", "url": "http://docs.com"}, + AsyncAPIDocs(description="test", url="http://docs.com"), + id="ExternalDocs dict", + ), + pytest.param( + {"description": "test", "url": "http://docs.com", "extra": "test"}, + {"description": "test", "url": "http://docs.com", "extra": "test"}, + id="Unknown dict", + ), + ), +) +def test_external_docs_factory_method(arg: Any, result: Any) -> None: + assert AsyncAPIDocs.from_spec(arg) == result diff --git a/tests/asyncapi/base/v2_6_0/from_spec/test_license.py b/tests/asyncapi/base/v2_6_0/from_spec/test_license.py new file mode 100644 index 0000000000..c6e2e9421b --- /dev/null +++ b/tests/asyncapi/base/v2_6_0/from_spec/test_license.py @@ -0,0 +1,35 @@ +from typing import Any + +import pytest + +from faststream.specification import License +from faststream.specification.asyncapi.v2_6_0.schema import License as AsyncAPICLicense + + +@pytest.mark.parametrize( + ("arg", "result"), + ( + pytest.param( + None, + None, + id="None", + ), + pytest.param( + License(name="test", url="http://license.com"), + AsyncAPICLicense(name="test", url="http://license.com"), + id="License object", + ), + pytest.param( + {"name": "test", "url": "http://license.com"}, + AsyncAPICLicense(name="test", url="http://license.com"), + id="License dict", + ), + pytest.param( + {"name": "test", "url": "http://license.com", "extra": "test"}, + {"name": "test", "url": "http://license.com", "extra": "test"}, + id="Unknown dict", + ), + ), +) +def test_license_factory_method(arg: Any, result: Any) -> None: + assert AsyncAPICLicense.from_spec(arg) == result diff --git a/tests/asyncapi/base/v2_6_0/from_spec/test_tag.py b/tests/asyncapi/base/v2_6_0/from_spec/test_tag.py new file mode 100644 index 0000000000..66eedcd811 --- /dev/null +++ b/tests/asyncapi/base/v2_6_0/from_spec/test_tag.py @@ -0,0 +1,49 @@ +from typing import Any + +import pytest + +from faststream.specification import ExternalDocs, Tag +from faststream.specification.asyncapi.v2_6_0.schema import ( + ExternalDocs as AsyncAPIDocs, + Tag as AsyncAPITag, +) + + +@pytest.mark.parametrize( + ("arg", "result"), + ( + pytest.param( + Tag( + name="test", + description="test", + external_docs=ExternalDocs(url="http://docs.com"), + ), + AsyncAPITag( + name="test", + description="test", + externalDocs=AsyncAPIDocs(url="http://docs.com"), + ), + id="Tag object", + ), + pytest.param( + { + "name": "test", + "description": "test", + "external_docs": {"url": "http://docs.com"}, + }, + AsyncAPITag( + name="test", + description="test", + externalDocs=AsyncAPIDocs(url="http://docs.com"), + ), + id="Tag dict", + ), + pytest.param( + {"name": "test", "description": "test", "extra": "test"}, + {"name": "test", "description": "test", "extra": "test"}, + id="Unknown dict", + ), + ), +) +def test_tag_factory_method(arg: Any, result: Any) -> None: + assert AsyncAPITag.from_spec(arg) == result diff --git a/tests/asyncapi/base/v2_6_0/publisher.py b/tests/asyncapi/base/v2_6_0/publisher.py index 6705975a72..c36cb16ecc 100644 --- a/tests/asyncapi/base/v2_6_0/publisher.py +++ b/tests/asyncapi/base/v2_6_0/publisher.py @@ -120,7 +120,7 @@ def test_not_include(self) -> None: async def handler(msg: str) -> None: pass - schema = AsyncAPI(self.build_app(broker)) + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0") assert schema.to_jsonable()["channels"] == {}, schema.to_jsonable()["channels"] @@ -133,7 +133,7 @@ class TestModel(pydantic.BaseModel): @broker.publisher("test") async def handle(msg) -> TestModel: ... - schema = AsyncAPI(self.build_app(broker)).to_jsonable() + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() payload = schema["components"]["schemas"] diff --git a/tests/asyncapi/base/v3_0_0/fastapi.py b/tests/asyncapi/base/v3_0_0/fastapi.py index fcbae28d1c..9920514b86 100644 --- a/tests/asyncapi/base/v3_0_0/fastapi.py +++ b/tests/asyncapi/base/v3_0_0/fastapi.py @@ -26,7 +26,6 @@ async def test_fastapi_full_information(self) -> None: ) app = FastAPI( - lifespan=broker.lifespan_context, title="CustomApp", version="1.1.1", description="Test description", @@ -77,7 +76,7 @@ async def test_fastapi_asyncapi_routes(self) -> None: @router.subscriber("test") async def handler() -> None: ... - app = FastAPI(lifespan=router.lifespan_context) + app = FastAPI() app.include_router(router) async with self.broker_wrapper(router.broker): @@ -107,7 +106,7 @@ async def handler() -> None: ... async def test_fastapi_asyncapi_not_fount(self) -> None: broker = self.router_factory(include_in_schema=False) - app = FastAPI(lifespan=broker.lifespan_context) + app = FastAPI() app.include_router(broker) async with self.broker_wrapper(broker.broker): @@ -125,7 +124,7 @@ async def test_fastapi_asyncapi_not_fount(self) -> None: async def test_fastapi_asyncapi_not_fount_by_url(self) -> None: broker = self.router_factory(schema_url=None) - app = FastAPI(lifespan=broker.lifespan_context) + app = FastAPI() app.include_router(broker) async with self.broker_wrapper(broker.broker): diff --git a/tests/asyncapi/confluent/v2_6_0/test_connection.py b/tests/asyncapi/confluent/v2_6_0/test_connection.py index 56ad2af682..368bbc00dd 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_connection.py +++ b/tests/asyncapi/confluent/v2_6_0/test_connection.py @@ -1,6 +1,6 @@ from faststream.confluent import KafkaBroker +from faststream.specification import Tag from faststream.specification.asyncapi import AsyncAPI -from faststream.specification.schema.tag import Tag def test_base() -> None: diff --git a/tests/asyncapi/confluent/v3_0_0/test_connection.py b/tests/asyncapi/confluent/v3_0_0/test_connection.py index d49503ef9a..63b9c51da3 100644 --- a/tests/asyncapi/confluent/v3_0_0/test_connection.py +++ b/tests/asyncapi/confluent/v3_0_0/test_connection.py @@ -1,6 +1,6 @@ from faststream.confluent import KafkaBroker +from faststream.specification import Tag from faststream.specification.asyncapi import AsyncAPI -from faststream.specification.schema.tag import Tag def test_base() -> None: diff --git a/tests/asyncapi/kafka/v2_6_0/test_app.py b/tests/asyncapi/kafka/v2_6_0/test_app.py index 77470ef1cd..2bd9b5a916 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_app.py +++ b/tests/asyncapi/kafka/v2_6_0/test_app.py @@ -1,9 +1,6 @@ from faststream.kafka import KafkaBroker +from faststream.specification import Contact, ExternalDocs, License, Tag from faststream.specification.asyncapi import AsyncAPI -from faststream.specification.schema.contact import Contact -from faststream.specification.schema.docs import ExternalDocs -from faststream.specification.schema.license import License -from faststream.specification.schema.tag import Tag def test_base() -> None: diff --git a/tests/asyncapi/kafka/v2_6_0/test_connection.py b/tests/asyncapi/kafka/v2_6_0/test_connection.py index cc7b61114b..2107e3882b 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_connection.py +++ b/tests/asyncapi/kafka/v2_6_0/test_connection.py @@ -1,6 +1,6 @@ from faststream.kafka import KafkaBroker +from faststream.specification import Tag from faststream.specification.asyncapi import AsyncAPI -from faststream.specification.schema.tag import Tag def test_base() -> None: diff --git a/tests/asyncapi/kafka/v3_0_0/test_connection.py b/tests/asyncapi/kafka/v3_0_0/test_connection.py index 280cb798d1..e1fb6cfaab 100644 --- a/tests/asyncapi/kafka/v3_0_0/test_connection.py +++ b/tests/asyncapi/kafka/v3_0_0/test_connection.py @@ -1,6 +1,6 @@ from faststream.kafka import KafkaBroker +from faststream.specification import Tag from faststream.specification.asyncapi import AsyncAPI -from faststream.specification.schema.tag import Tag def test_base() -> None: diff --git a/tests/asyncapi/nats/v2_6_0/test_arguments.py b/tests/asyncapi/nats/v2_6_0/test_arguments.py index d3b9b53a34..5ad34a0001 100644 --- a/tests/asyncapi/nats/v2_6_0/test_arguments.py +++ b/tests/asyncapi/nats/v2_6_0/test_arguments.py @@ -17,4 +17,4 @@ async def handle(msg) -> None: ... assert schema["channels"][key]["bindings"] == { "nats": {"bindingVersion": "custom", "subject": "test"}, - } + }, schema["channels"][key]["bindings"] diff --git a/tests/asyncapi/nats/v2_6_0/test_connection.py b/tests/asyncapi/nats/v2_6_0/test_connection.py index 8cb4110d78..486bbb8033 100644 --- a/tests/asyncapi/nats/v2_6_0/test_connection.py +++ b/tests/asyncapi/nats/v2_6_0/test_connection.py @@ -1,6 +1,6 @@ from faststream.nats import NatsBroker +from faststream.specification import Tag from faststream.specification.asyncapi import AsyncAPI -from faststream.specification.schema.tag import Tag def test_base() -> None: diff --git a/tests/asyncapi/nats/v3_0_0/test_connection.py b/tests/asyncapi/nats/v3_0_0/test_connection.py index f4913252ef..f88fc0fb83 100644 --- a/tests/asyncapi/nats/v3_0_0/test_connection.py +++ b/tests/asyncapi/nats/v3_0_0/test_connection.py @@ -1,6 +1,6 @@ from faststream.nats import NatsBroker +from faststream.specification import Tag from faststream.specification.asyncapi import AsyncAPI -from faststream.specification.schema.tag import Tag def test_base() -> None: diff --git a/tests/asyncapi/rabbit/v2_6_0/test_connection.py b/tests/asyncapi/rabbit/v2_6_0/test_connection.py index 6fae2ac389..be4d7a7edc 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_connection.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_connection.py @@ -1,6 +1,6 @@ from faststream.rabbit import RabbitBroker +from faststream.specification import Tag from faststream.specification.asyncapi import AsyncAPI -from faststream.specification.schema.tag import Tag def test_base() -> None: @@ -115,4 +115,4 @@ def test_custom() -> None: }, }, } - ) + ), schema diff --git a/tests/asyncapi/rabbit/v2_6_0/test_publisher.py b/tests/asyncapi/rabbit/v2_6_0/test_publisher.py index b9c17a9d00..abe3255a3d 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_publisher.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_publisher.py @@ -106,6 +106,14 @@ async def handle(msg) -> None: ... }, }, "publish": { + "bindings": { + "amqp": { + "ack": True, + "bindingVersion": "0.2.0", + "deliveryMode": 1, + "mandatory": True, + }, + }, "message": { "$ref": "#/components/messages/_:test-ex:Publisher:Message", }, diff --git a/tests/asyncapi/rabbit/v3_0_0/test_connection.py b/tests/asyncapi/rabbit/v3_0_0/test_connection.py index 0403cef9c5..971a89afec 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_connection.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_connection.py @@ -1,6 +1,6 @@ from faststream.rabbit import RabbitBroker +from faststream.specification import Tag from faststream.specification.asyncapi import AsyncAPI -from faststream.specification.schema.tag import Tag def test_base() -> None: diff --git a/tests/asyncapi/rabbit/v3_0_0/test_publisher.py b/tests/asyncapi/rabbit/v3_0_0/test_publisher.py index 1456b5b86d..a108270da5 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_publisher.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_publisher.py @@ -141,13 +141,19 @@ async def handle(msg) -> None: ... assert schema["operations"] == { "_:test-ex:Publisher": { "action": "send", - "channel": { - "$ref": "#/channels/_:test-ex:Publisher", + "bindings": { + "amqp": { + "ack": True, + "bindingVersion": "0.3.0", + "deliveryMode": 1, + "mandatory": True, + } }, + "channel": {"$ref": "#/channels/_:test-ex:Publisher"}, "messages": [ - {"$ref": "#/channels/_:test-ex:Publisher/messages/Message"}, + {"$ref": "#/channels/_:test-ex:Publisher/messages/Message"} ], - }, + } } def test_reusable_exchange(self) -> None: diff --git a/tests/asyncapi/redis/v2_6_0/test_arguments.py b/tests/asyncapi/redis/v2_6_0/test_arguments.py index b65598f6f5..403cccad84 100644 --- a/tests/asyncapi/redis/v2_6_0/test_arguments.py +++ b/tests/asyncapi/redis/v2_6_0/test_arguments.py @@ -79,8 +79,8 @@ async def handle(msg) -> None: ... "redis": { "bindingVersion": "custom", "channel": "test", - "consumer_name": "consumer", - "group_name": "group", + "consumerName": "consumer", + "groupName": "group", "method": "xreadgroup", }, } diff --git a/tests/asyncapi/redis/v2_6_0/test_connection.py b/tests/asyncapi/redis/v2_6_0/test_connection.py index 221e4cd430..194371e767 100644 --- a/tests/asyncapi/redis/v2_6_0/test_connection.py +++ b/tests/asyncapi/redis/v2_6_0/test_connection.py @@ -1,6 +1,6 @@ from faststream.redis import RedisBroker +from faststream.specification import Tag from faststream.specification.asyncapi import AsyncAPI -from faststream.specification.schema.tag import Tag def test_base() -> None: diff --git a/tests/asyncapi/redis/v3_0_0/test_arguments.py b/tests/asyncapi/redis/v3_0_0/test_arguments.py index b9a3136274..0def5e4f41 100644 --- a/tests/asyncapi/redis/v3_0_0/test_arguments.py +++ b/tests/asyncapi/redis/v3_0_0/test_arguments.py @@ -79,8 +79,8 @@ async def handle(msg) -> None: ... "redis": { "bindingVersion": "custom", "channel": "test", - "consumer_name": "consumer", - "group_name": "group", + "consumerName": "consumer", + "groupName": "group", "method": "xreadgroup", }, } diff --git a/tests/asyncapi/redis/v3_0_0/test_connection.py b/tests/asyncapi/redis/v3_0_0/test_connection.py index 51d7224c50..968e67b464 100644 --- a/tests/asyncapi/redis/v3_0_0/test_connection.py +++ b/tests/asyncapi/redis/v3_0_0/test_connection.py @@ -1,6 +1,6 @@ from faststream.redis import RedisBroker +from faststream.specification import Tag from faststream.specification.asyncapi import AsyncAPI -from faststream.specification.schema.tag import Tag def test_base() -> None: diff --git a/tests/cli/test_asyncapi_docs.py b/tests/cli/test_asyncapi_docs.py index 9deb1877b9..344ba54013 100644 --- a/tests/cli/test_asyncapi_docs.py +++ b/tests/cli/test_asyncapi_docs.py @@ -1,5 +1,6 @@ import json import sys +import traceback from http.server import HTTPServer from pathlib import Path from unittest.mock import Mock @@ -94,7 +95,7 @@ def test_serve_asyncapi_json_schema( m.setattr(HTTPServer, "serve_forever", mock) r = runner.invoke(cli, SERVE_CMD + [str(schema_path)]) # noqa: RUF005 - assert r.exit_code == 0, r.exc_info + assert r.exit_code == 0, traceback.format_tb(r.exc_info[2]) mock.assert_called_once() schema_path.unlink() @@ -115,7 +116,7 @@ def test_serve_asyncapi_yaml_schema( m.setattr(HTTPServer, "serve_forever", mock) r = runner.invoke(cli, SERVE_CMD + [str(schema_path)]) # noqa: RUF005 - assert r.exit_code == 0, r.exc_info + assert r.exit_code == 0, traceback.format_tb(r.exc_info[2]) mock.assert_called_once() schema_path.unlink() diff --git a/tests/cli/test_run_regular.py b/tests/cli/test_run.py similarity index 100% rename from tests/cli/test_run_regular.py rename to tests/cli/test_run.py diff --git a/tests/cli/test_run_asgi.py b/tests/cli/test_run_asgi.py index c644c04bb2..49825f932b 100644 --- a/tests/cli/test_run_asgi.py +++ b/tests/cli/test_run_asgi.py @@ -34,14 +34,7 @@ def test_run_as_asgi(runner: CliRunner) -> None: assert result.exit_code == 0 -@pytest.mark.parametrize( - "workers", - ( - pytest.param(1), - pytest.param(2), - pytest.param(5), - ), -) +@pytest.mark.parametrize("workers", (pytest.param(1), pytest.param(2), pytest.param(5))) def test_run_as_asgi_with_workers(runner: CliRunner, workers: int) -> None: app = AsgiFastStream(AsyncMock()) app.run = AsyncMock() From 921ead86e4535be8bf70e0c211bc0246fdfb8f44 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Wed, 20 Nov 2024 21:42:39 +0300 Subject: [PATCH 199/245] fix: correct AsyncAPI 2.6 operations --- .../specification/asyncapi/v2_6_0/schema/channels.py | 8 ++++---- serve.py | 9 --------- 2 files changed, 4 insertions(+), 13 deletions(-) delete mode 100644 serve.py diff --git a/faststream/specification/asyncapi/v2_6_0/schema/channels.py b/faststream/specification/asyncapi/v2_6_0/schema/channels.py index 936248dfd5..5310578554 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/channels.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/channels.py @@ -48,8 +48,8 @@ def from_sub(cls, subscriber: SubscriberSpec) -> Self: description=subscriber.description, servers=None, bindings=ChannelBinding.from_sub(subscriber.bindings), - subscribe=Operation.from_sub(subscriber.operation), - publish=None, + subscribe=None, + publish=Operation.from_sub(subscriber.operation), ) @classmethod @@ -58,6 +58,6 @@ def from_pub(cls, publisher: PublisherSpec) -> Self: description=publisher.description, servers=None, bindings=ChannelBinding.from_pub(publisher.bindings), - subscribe=None, - publish=Operation.from_pub(publisher.operation), + subscribe=Operation.from_pub(publisher.operation), + publish=None, ) diff --git a/serve.py b/serve.py deleted file mode 100644 index bc0a693167..0000000000 --- a/serve.py +++ /dev/null @@ -1,9 +0,0 @@ -from faststream import FastStream -from faststream.rabbit import RabbitBroker - -broker = RabbitBroker() -app = FastStream(broker) - -@app.after_startup -async def _(): - raise ValueError From 181e8627d1a0bd846e28e97b925889df01326e78 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Wed, 20 Nov 2024 22:27:21 +0300 Subject: [PATCH 200/245] tests: add Nats concurrent test --- faststream/specification/asyncapi/factory.py | 125 +++++++----------- faststream/specification/schema/subscriber.py | 2 +- tests/brokers/nats/test_consume.py | 59 +++++++-- 3 files changed, 100 insertions(+), 86 deletions(-) diff --git a/faststream/specification/asyncapi/factory.py b/faststream/specification/asyncapi/factory.py index 5137f6cfa1..dc263a6b52 100644 --- a/faststream/specification/asyncapi/factory.py +++ b/faststream/specification/asyncapi/factory.py @@ -18,84 +18,55 @@ ) -class AsyncAPI(Specification): - # Empty init for correct typehints - def __init__( - self, - broker: "BrokerUsecase[Any, Any]", - /, - title: str = "FastStream", - app_version: str = "0.1.0", - schema_version: Union[Literal["3.0.0", "2.6.0"], str] = "3.0.0", - description: str = "", - terms_of_service: Optional["AnyHttpUrl"] = None, - license: Optional[Union["License", "LicenseDict", "AnyDict"]] = None, - contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] = None, - tags: Iterable[Union["Tag", "TagDict", "AnyDict"]] = (), - external_docs: Optional[ - Union["ExternalDocs", "ExternalDocsDict", "AnyDict"] - ] = None, - identifier: Optional[str] = None, - ) -> Specification: - pass +def AsyncAPI( # noqa: N802 + broker: "BrokerUsecase[Any, Any]", + /, + title: str = "FastStream", + app_version: str = "0.1.0", + schema_version: Union[Literal["3.0.0", "2.6.0"], str] = "3.0.0", + description: str = "", + terms_of_service: Optional["AnyHttpUrl"] = None, + license: Optional[Union["License", "LicenseDict", "AnyDict"]] = None, + contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] = None, + tags: Iterable[Union["Tag", "TagDict", "AnyDict"]] = (), + external_docs: Optional[ + Union["ExternalDocs", "ExternalDocsDict", "AnyDict"] + ] = None, + identifier: Optional[str] = None, +) -> Specification: + if schema_version.startswith("3.0."): + from .v3_0_0.facade import AsyncAPI3 - def __new__( # type: ignore[misc] - cls, - broker: "BrokerUsecase[Any, Any]", - /, - title: str = "FastStream", - app_version: str = "0.1.0", - schema_version: Union[Literal["3.0.0", "2.6.0"], str] = "3.0.0", - description: str = "", - terms_of_service: Optional["AnyHttpUrl"] = None, - license: Optional[Union["License", "LicenseDict", "AnyDict"]] = None, - contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] = None, - tags: Iterable[Union["Tag", "TagDict", "AnyDict"]] = (), - external_docs: Optional[ - Union["ExternalDocs", "ExternalDocsDict", "AnyDict"] - ] = None, - identifier: Optional[str] = None, - ) -> Specification: - if schema_version.startswith("3.0."): - from .v3_0_0.facade import AsyncAPI3 + return AsyncAPI3( + broker, + title=title, + app_version=app_version, + schema_version=schema_version, + description=description, + terms_of_service=terms_of_service, + contact=contact, + license=license, + identifier=identifier, + tags=tags, + external_docs=external_docs, + ) - return AsyncAPI3( - broker, - title=title, - app_version=app_version, - schema_version=schema_version, - description=description, - terms_of_service=terms_of_service, - contact=contact, - license=license, - identifier=identifier, - tags=tags, - external_docs=external_docs, - ) - if schema_version.startswith("2.6."): - from .v2_6_0.facade import AsyncAPI2 + if schema_version.startswith("2.6."): + from .v2_6_0.facade import AsyncAPI2 - return AsyncAPI2( - broker, - title=title, - app_version=app_version, - schema_version=schema_version, - description=description, - terms_of_service=terms_of_service, - contact=contact, - license=license, - identifier=identifier, - tags=tags, - external_docs=external_docs, - ) - msg = f"Unsupported schema version: {schema_version}" - raise NotImplementedError(msg) + return AsyncAPI2( + broker, + title=title, + app_version=app_version, + schema_version=schema_version, + description=description, + terms_of_service=terms_of_service, + contact=contact, + license=license, + identifier=identifier, + tags=tags, + external_docs=external_docs, + ) - def to_json(self) -> str: - raise NotImplementedError - - def to_jsonable(self) -> Any: - raise NotImplementedError - - def to_yaml(self) -> str: - raise NotImplementedError + msg = f"Unsupported schema version: {schema_version}" + raise NotImplementedError(msg) diff --git a/faststream/specification/schema/subscriber.py b/faststream/specification/schema/subscriber.py index befcaf61e6..9d41177b4f 100644 --- a/faststream/specification/schema/subscriber.py +++ b/faststream/specification/schema/subscriber.py @@ -7,6 +7,6 @@ @dataclass class SubscriberSpec: - description: str + description: Optional[str] operation: Operation bindings: Optional[ChannelBinding] diff --git a/tests/brokers/nats/test_consume.py b/tests/brokers/nats/test_consume.py index 30dba8ee99..b31f927d27 100644 --- a/tests/brokers/nats/test_consume.py +++ b/tests/brokers/nats/test_consume.py @@ -1,6 +1,6 @@ import asyncio from typing import Any -from unittest.mock import Mock, patch +from unittest.mock import MagicMock, patch import pytest from nats.aio.msg import Msg @@ -19,6 +19,47 @@ class TestConsume(BrokerRealConsumeTestcase): def get_broker(self, apply_types: bool = False, **kwargs: Any) -> NatsBroker: return NatsBroker(apply_types=apply_types, **kwargs) + async def test_concurrent_subscriber( + self, + queue: str, + mock: MagicMock, + ) -> None: + event = asyncio.Event() + event2 = asyncio.Event() + + broker = self.get_broker() + + args, kwargs = self.get_subscriber_params(queue, max_workers=2) + + @broker.subscriber(*args, **kwargs) + async def handler(msg): + mock() + + if event.is_set(): + event2.set() + else: + event.set() + + await asyncio.sleep(1.0) + + async with self.patch_broker(broker) as br: + await br.start() + + for i in range(5): + await br.publish(i, queue) + + await asyncio.wait( + ( + asyncio.create_task(event.wait()), + asyncio.create_task(event2.wait()), + ), + timeout=3, + ) + + assert event.is_set() + assert event2.is_set() + assert mock.call_count == 2, mock.call_count + async def test_consume_js( self, queue: str, @@ -28,7 +69,9 @@ async def test_consume_js( consume_broker = self.get_broker() - @consume_broker.subscriber(queue, stream=stream) + args, kwargs = self.get_subscriber_params(queue, stream=stream) + + @consume_broker.subscriber(*args, **kwargs) def subscriber(m) -> None: event.set() @@ -53,8 +96,8 @@ def subscriber(m) -> None: async def test_consume_with_filter( self, - queue, - mock: Mock, + queue: str, + mock: MagicMock, ) -> None: event = asyncio.Event() @@ -541,7 +584,7 @@ async def test_get_one_pull_timeout( self, queue: str, stream: JStream, - mock: Mock, + mock: MagicMock, ) -> None: broker = self.get_broker(apply_types=True) subscriber = broker.subscriber( @@ -595,7 +638,7 @@ async def test_get_one_batch_timeout( self, queue: str, stream: JStream, - mock: Mock, + mock: MagicMock, ) -> None: broker = self.get_broker(apply_types=True) subscriber = broker.subscriber( @@ -680,7 +723,7 @@ async def test_get_one_kv_timeout( self, queue: str, stream: JStream, - mock: Mock, + mock: MagicMock, ) -> None: broker = self.get_broker(apply_types=True) subscriber = broker.subscriber(queue, kv_watch=queue + "1") @@ -728,7 +771,7 @@ async def test_get_one_os_timeout( self, queue: str, stream: JStream, - mock: Mock, + mock: MagicMock, ) -> None: broker = self.get_broker(apply_types=True) subscriber = broker.subscriber(queue, obj_watch=True) From 51f16eb2be743a0d2a1f63d706adedf3f80fbcc7 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Wed, 20 Nov 2024 23:05:47 +0300 Subject: [PATCH 201/245] tests: actualize AsyncAPI 2.6.0 tests --- tests/asyncapi/base/v2_6_0/publisher.py | 2 +- tests/asyncapi/confluent/v2_6_0/test_naming.py | 2 +- tests/asyncapi/confluent/v2_6_0/test_router.py | 2 +- tests/asyncapi/confluent/v2_6_0/test_security.py | 4 ++-- tests/asyncapi/kafka/v2_6_0/test_naming.py | 2 +- tests/asyncapi/kafka/v2_6_0/test_router.py | 2 +- tests/asyncapi/kafka/v2_6_0/test_security.py | 4 ++-- tests/asyncapi/nats/v2_6_0/test_naming.py | 2 +- tests/asyncapi/nats/v2_6_0/test_router.py | 2 +- tests/asyncapi/rabbit/v2_6_0/test_connection.py | 2 +- tests/asyncapi/rabbit/v2_6_0/test_naming.py | 2 +- tests/asyncapi/rabbit/v2_6_0/test_publisher.py | 8 ++++---- tests/asyncapi/rabbit/v2_6_0/test_router.py | 2 +- tests/asyncapi/redis/v2_6_0/test_naming.py | 2 +- tests/asyncapi/redis/v2_6_0/test_router.py | 2 +- 15 files changed, 20 insertions(+), 20 deletions(-) diff --git a/tests/asyncapi/base/v2_6_0/publisher.py b/tests/asyncapi/base/v2_6_0/publisher.py index c36cb16ecc..d61baa2d19 100644 --- a/tests/asyncapi/base/v2_6_0/publisher.py +++ b/tests/asyncapi/base/v2_6_0/publisher.py @@ -32,7 +32,7 @@ async def handle(msg) -> None: ... key = tuple(schema["channels"].keys())[0] # noqa: RUF015 assert schema["channels"][key].get("description") is None - assert schema["channels"][key].get("publish") is not None + assert schema["channels"][key].get("subscribe") is not None payload = schema["components"]["schemas"] for v in payload.values(): diff --git a/tests/asyncapi/confluent/v2_6_0/test_naming.py b/tests/asyncapi/confluent/v2_6_0/test_naming.py index 85bd4cdc06..2fdbd64687 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_naming.py +++ b/tests/asyncapi/confluent/v2_6_0/test_naming.py @@ -29,7 +29,7 @@ async def handle() -> None: ... "test:Handle": { "servers": ["development"], "bindings": {"kafka": {"topic": "test", "bindingVersion": "0.4.0"}}, - "subscribe": { + "publish": { "message": { "$ref": "#/components/messages/test:Handle:Message" }, diff --git a/tests/asyncapi/confluent/v2_6_0/test_router.py b/tests/asyncapi/confluent/v2_6_0/test_router.py index b3cd359b4c..c73885cddb 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_router.py +++ b/tests/asyncapi/confluent/v2_6_0/test_router.py @@ -40,7 +40,7 @@ async def handle(msg) -> None: ... "bindings": { "kafka": {"topic": "test_test", "bindingVersion": "0.4.0"}, }, - "subscribe": { + "publish": { "message": { "$ref": "#/components/messages/test_test:Handle:Message", }, diff --git a/tests/asyncapi/confluent/v2_6_0/test_security.py b/tests/asyncapi/confluent/v2_6_0/test_security.py index f8b90168b7..e20aa94456 100644 --- a/tests/asyncapi/confluent/v2_6_0/test_security.py +++ b/tests/asyncapi/confluent/v2_6_0/test_security.py @@ -18,13 +18,13 @@ "test_1:TestTopic": { "bindings": {"kafka": {"bindingVersion": "0.4.0", "topic": "test_1"}}, "servers": ["development"], - "subscribe": { + "publish": { "message": {"$ref": "#/components/messages/test_1:TestTopic:Message"}, }, }, "test_2:Publisher": { "bindings": {"kafka": {"bindingVersion": "0.4.0", "topic": "test_2"}}, - "publish": { + "subscribe": { "message": {"$ref": "#/components/messages/test_2:Publisher:Message"}, }, "servers": ["development"], diff --git a/tests/asyncapi/kafka/v2_6_0/test_naming.py b/tests/asyncapi/kafka/v2_6_0/test_naming.py index 44297b5ef2..bba38e11b7 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_naming.py +++ b/tests/asyncapi/kafka/v2_6_0/test_naming.py @@ -29,7 +29,7 @@ async def handle() -> None: ... "test:Handle": { "servers": ["development"], "bindings": {"kafka": {"topic": "test", "bindingVersion": "0.4.0"}}, - "subscribe": { + "publish": { "message": { "$ref": "#/components/messages/test:Handle:Message" }, diff --git a/tests/asyncapi/kafka/v2_6_0/test_router.py b/tests/asyncapi/kafka/v2_6_0/test_router.py index 043ebfa453..2fd0342eb0 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_router.py +++ b/tests/asyncapi/kafka/v2_6_0/test_router.py @@ -40,7 +40,7 @@ async def handle(msg) -> None: ... "bindings": { "kafka": {"topic": "test_test", "bindingVersion": "0.4.0"}, }, - "subscribe": { + "publish": { "message": { "$ref": "#/components/messages/test_test:Handle:Message", }, diff --git a/tests/asyncapi/kafka/v2_6_0/test_security.py b/tests/asyncapi/kafka/v2_6_0/test_security.py index 88661995bf..23eb080af5 100644 --- a/tests/asyncapi/kafka/v2_6_0/test_security.py +++ b/tests/asyncapi/kafka/v2_6_0/test_security.py @@ -18,13 +18,13 @@ "test_1:TestTopic": { "bindings": {"kafka": {"bindingVersion": "0.4.0", "topic": "test_1"}}, "servers": ["development"], - "subscribe": { + "publish": { "message": {"$ref": "#/components/messages/test_1:TestTopic:Message"}, }, }, "test_2:Publisher": { "bindings": {"kafka": {"bindingVersion": "0.4.0", "topic": "test_2"}}, - "publish": { + "subscribe": { "message": {"$ref": "#/components/messages/test_2:Publisher:Message"}, }, "servers": ["development"], diff --git a/tests/asyncapi/nats/v2_6_0/test_naming.py b/tests/asyncapi/nats/v2_6_0/test_naming.py index 676be562f9..9c0738f9de 100644 --- a/tests/asyncapi/nats/v2_6_0/test_naming.py +++ b/tests/asyncapi/nats/v2_6_0/test_naming.py @@ -31,7 +31,7 @@ async def handle() -> None: ... "bindings": { "nats": {"subject": "test", "bindingVersion": "custom"}, }, - "subscribe": { + "publish": { "message": { "$ref": "#/components/messages/test:Handle:Message" }, diff --git a/tests/asyncapi/nats/v2_6_0/test_router.py b/tests/asyncapi/nats/v2_6_0/test_router.py index b830dc69fe..7986cba82e 100644 --- a/tests/asyncapi/nats/v2_6_0/test_router.py +++ b/tests/asyncapi/nats/v2_6_0/test_router.py @@ -40,7 +40,7 @@ async def handle(msg) -> None: ... "bindings": { "nats": {"subject": "test_test", "bindingVersion": "custom"}, }, - "subscribe": { + "publish": { "message": { "$ref": "#/components/messages/test_test:Handle:Message", }, diff --git a/tests/asyncapi/rabbit/v2_6_0/test_connection.py b/tests/asyncapi/rabbit/v2_6_0/test_connection.py index be4d7a7edc..15781dcf0e 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_connection.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_connection.py @@ -74,7 +74,7 @@ def test_custom() -> None: }, }, }, - "publish": { + "subscribe": { "bindings": { "amqp": { "ack": True, diff --git a/tests/asyncapi/rabbit/v2_6_0/test_naming.py b/tests/asyncapi/rabbit/v2_6_0/test_naming.py index b63ab03fcb..2ee937f21e 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_naming.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_naming.py @@ -72,7 +72,7 @@ async def handle() -> None: ... "exchange": {"type": "default", "vhost": "/"}, }, }, - "subscribe": { + "publish": { "bindings": { "amqp": { "cc": "test", diff --git a/tests/asyncapi/rabbit/v2_6_0/test_publisher.py b/tests/asyncapi/rabbit/v2_6_0/test_publisher.py index abe3255a3d..e24edd3fed 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_publisher.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_publisher.py @@ -29,7 +29,7 @@ async def handle(msg) -> None: ... "is": "routingKey", }, }, - "publish": { + "subscribe": { "bindings": { "amqp": { "ack": True, @@ -105,7 +105,7 @@ async def handle(msg) -> None: ... "is": "routingKey", }, }, - "publish": { + "subscribe": { "bindings": { "amqp": { "ack": True, @@ -146,7 +146,7 @@ async def handle(msg) -> None: ... "is": "routingKey", }, }, - "publish": { + "subscribe": { "bindings": { "amqp": { "ack": True, @@ -176,7 +176,7 @@ async def handle(msg) -> None: ... "is": "routingKey", }, }, - "publish": { + "subscribe": { "bindings": { "amqp": { "ack": True, diff --git a/tests/asyncapi/rabbit/v2_6_0/test_router.py b/tests/asyncapi/rabbit/v2_6_0/test_router.py index 8dca0c9b1b..8e042da398 100644 --- a/tests/asyncapi/rabbit/v2_6_0/test_router.py +++ b/tests/asyncapi/rabbit/v2_6_0/test_router.py @@ -59,7 +59,7 @@ async def handle(msg) -> None: ... "exchange": {"type": "default", "vhost": "/"}, }, }, - "subscribe": { + "publish": { "bindings": { "amqp": { "cc": "test_key", diff --git a/tests/asyncapi/redis/v2_6_0/test_naming.py b/tests/asyncapi/redis/v2_6_0/test_naming.py index 5afbf50267..e2558bb9a6 100644 --- a/tests/asyncapi/redis/v2_6_0/test_naming.py +++ b/tests/asyncapi/redis/v2_6_0/test_naming.py @@ -28,7 +28,7 @@ async def handle() -> None: ... }, }, "servers": ["development"], - "subscribe": { + "publish": { "message": { "$ref": "#/components/messages/test:Handle:Message" }, diff --git a/tests/asyncapi/redis/v2_6_0/test_router.py b/tests/asyncapi/redis/v2_6_0/test_router.py index 6b785d61bf..7d37538dbc 100644 --- a/tests/asyncapi/redis/v2_6_0/test_router.py +++ b/tests/asyncapi/redis/v2_6_0/test_router.py @@ -35,7 +35,7 @@ async def handle(msg) -> None: ... }, }, "servers": ["development"], - "subscribe": { + "publish": { "message": { "$ref": "#/components/messages/test_test:Handle:Message", }, From 7bd03afa5d07cf15b4489fa369198a981f06b81b Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Thu, 21 Nov 2024 23:53:46 +0300 Subject: [PATCH 202/245] fix: do not ack Nats Core message: --- faststream/_internal/broker/pub_base.py | 6 +- faststream/_internal/publisher/usecase.py | 18 +- faststream/_internal/subscriber/call_item.py | 2 +- faststream/_internal/subscriber/usecase.py | 8 +- faststream/confluent/broker/registrator.py | 39 +- faststream/confluent/fastapi/fastapi.py | 28 +- faststream/confluent/router.py | 13 +- faststream/confluent/subscriber/factory.py | 23 +- faststream/kafka/broker/registrator.py | 39 +- faststream/kafka/fastapi/fastapi.py | 37 +- faststream/kafka/router.py | 15 +- faststream/kafka/subscriber/factory.py | 19 +- faststream/nats/__init__.py | 3 +- faststream/nats/broker/broker.py | 8 +- faststream/nats/broker/registrator.py | 12 +- faststream/nats/fastapi/fastapi.py | 10 +- faststream/nats/message.py | 32 +- faststream/nats/parser.py | 5 - faststream/nats/publisher/producer.py | 5 +- faststream/nats/publisher/usecase.py | 10 +- faststream/nats/router.py | 12 +- faststream/nats/schemas/__init__.py | 3 + faststream/nats/schemas/js_stream.py | 13 +- faststream/nats/subscriber/factory.py | 16 +- faststream/nats/subscriber/usecase.py | 1197 ----------------- faststream/rabbit/broker/registrator.py | 12 +- faststream/rabbit/fastapi/fastapi.py | 10 +- faststream/rabbit/router.py | 12 +- faststream/rabbit/subscriber/factory.py | 24 +- faststream/redis/broker/registrator.py | 12 +- faststream/redis/fastapi/fastapi.py | 10 +- faststream/redis/router.py | 12 +- faststream/redis/schemas/stream_sub.py | 5 +- faststream/redis/subscriber/factory.py | 16 +- .../asyncapi_customization/test_basic.py | 4 +- .../asyncapi_customization/test_handler.py | 4 +- tests/brokers/base/basic.py | 5 + tests/brokers/base/middlewares.py | 247 +++- tests/brokers/confluent/basic.py | 29 +- tests/brokers/confluent/test_consume.py | 5 - tests/brokers/confluent/test_fastapi.py | 11 +- tests/brokers/confluent/test_logger.py | 4 +- tests/brokers/confluent/test_middlewares.py | 16 +- tests/brokers/confluent/test_parser.py | 6 +- tests/brokers/confluent/test_publish.py | 6 +- tests/brokers/confluent/test_requests.py | 14 +- tests/brokers/confluent/test_router.py | 20 +- tests/brokers/confluent/test_test_client.py | 12 +- tests/brokers/kafka/basic.py | 24 + tests/brokers/kafka/test_consume.py | 10 +- tests/brokers/kafka/test_fastapi.py | 10 +- tests/brokers/kafka/test_middlewares.py | 20 +- tests/brokers/kafka/test_parser.py | 10 +- tests/brokers/kafka/test_publish.py | 10 +- tests/brokers/kafka/test_requests.py | 14 +- tests/brokers/kafka/test_router.py | 22 +- tests/brokers/kafka/test_test_client.py | 13 +- tests/brokers/nats/basic.py | 24 + tests/brokers/nats/test_consume.py | 36 +- tests/brokers/nats/test_fastapi.py | 12 +- tests/brokers/nats/test_middlewares.py | 20 +- tests/brokers/nats/test_parser.py | 10 +- tests/brokers/nats/test_publish.py | 9 +- tests/brokers/nats/test_requests.py | 18 +- tests/brokers/nats/test_router.py | 19 +- tests/brokers/nats/test_test_client.py | 13 +- tests/brokers/rabbit/basic.py | 24 + tests/brokers/rabbit/test_consume.py | 14 +- tests/brokers/rabbit/test_fastapi.py | 8 +- tests/brokers/rabbit/test_middlewares.py | 20 +- tests/brokers/rabbit/test_parser.py | 10 +- tests/brokers/rabbit/test_publish.py | 11 +- tests/brokers/rabbit/test_requests.py | 18 +- tests/brokers/rabbit/test_router.py | 20 +- tests/brokers/rabbit/test_schemas.py | 20 +- tests/brokers/rabbit/test_test_client.py | 15 +- tests/brokers/redis/basic.py | 24 + tests/brokers/redis/test_consume.py | 26 +- tests/brokers/redis/test_fastapi.py | 11 +- tests/brokers/redis/test_middlewares.py | 20 +- tests/brokers/redis/test_parser.py | 10 +- tests/brokers/redis/test_publish.py | 10 +- tests/brokers/redis/test_requests.py | 16 +- tests/brokers/redis/test_router.py | 20 +- tests/brokers/redis/test_test_client.py | 24 +- tests/prometheus/basic.py | 12 +- 86 files changed, 944 insertions(+), 1752 deletions(-) delete mode 100644 faststream/nats/subscriber/usecase.py create mode 100644 tests/brokers/kafka/basic.py create mode 100644 tests/brokers/nats/basic.py create mode 100644 tests/brokers/rabbit/basic.py create mode 100644 tests/brokers/redis/basic.py diff --git a/faststream/_internal/broker/pub_base.py b/faststream/_internal/broker/pub_base.py index 31cfb476fd..c45c36cced 100644 --- a/faststream/_internal/broker/pub_base.py +++ b/faststream/_internal/broker/pub_base.py @@ -37,7 +37,7 @@ async def _basic_publish( publish = producer.publish context = self.context # caches property - for m in self.middlewares: + for m in self.middlewares[::-1]: publish = partial(m(None, context=context).publish_scope, publish) return await publish(cmd) @@ -58,7 +58,7 @@ async def _basic_publish_batch( publish = producer.publish_batch context = self.context # caches property - for m in self.middlewares: + for m in self.middlewares[::-1]: publish = partial(m(None, context=context).publish_scope, publish) return await publish(cmd) @@ -82,7 +82,7 @@ async def _basic_request( request = producer.request context = self.context # caches property - for m in self.middlewares: + for m in self.middlewares[::-1]: request = partial(m(None, context=context).publish_scope, request) published_msg = await request(cmd) diff --git a/faststream/_internal/publisher/usecase.py b/faststream/_internal/publisher/usecase.py index 46ebf0f7da..08094ca56f 100644 --- a/faststream/_internal/publisher/usecase.py +++ b/faststream/_internal/publisher/usecase.py @@ -114,14 +114,14 @@ async def _basic_publish( context = self._state.get().di_state.context for pub_m in chain( + self.middlewares[::-1], ( _extra_middlewares or ( m(None, context=context).publish_scope - for m in self._broker_middlewares + for m in self._broker_middlewares[::-1] ) ), - self.middlewares, ): pub = partial(pub_m, pub) @@ -136,8 +136,11 @@ async def _basic_request( context = self._state.get().di_state.context for pub_m in chain( - (m(None, context=context).publish_scope for m in self._broker_middlewares), - self.middlewares, + self.middlewares[::-1], + ( + m(None, context=context).publish_scope + for m in self._broker_middlewares[::-1] + ), ): request = partial(pub_m, request) @@ -146,7 +149,8 @@ async def _basic_request( response_msg: Any = await process_msg( msg=published_msg, middlewares=( - m(published_msg, context=context) for m in self._broker_middlewares + m(published_msg, context=context) + for m in self._broker_middlewares[::-1] ), parser=self._producer._parser, decoder=self._producer._decoder, @@ -165,14 +169,14 @@ async def _basic_publish_batch( context = self._state.get().di_state.context for pub_m in chain( + self.middlewares[::-1], ( _extra_middlewares or ( m(None, context=context).publish_scope - for m in self._broker_middlewares + for m in self._broker_middlewares[::-1] ) ), - self.middlewares, ): pub = partial(pub_m, pub) diff --git a/faststream/_internal/subscriber/call_item.py b/faststream/_internal/subscriber/call_item.py index 48814e9ea0..550da4badb 100644 --- a/faststream/_internal/subscriber/call_item.py +++ b/faststream/_internal/subscriber/call_item.py @@ -153,7 +153,7 @@ async def call( """Execute wrapped handler with consume middlewares.""" call: AsyncFuncAny = self.handler.call_wrapped - for middleware in chain(self.item_middlewares, _extra_middlewares): + for middleware in chain(self.item_middlewares[::-1], _extra_middlewares): call = partial(middleware, call) try: diff --git a/faststream/_internal/subscriber/usecase.py b/faststream/_internal/subscriber/usecase.py index 3a8aa1227d..069185c612 100644 --- a/faststream/_internal/subscriber/usecase.py +++ b/faststream/_internal/subscriber/usecase.py @@ -337,7 +337,9 @@ async def process_message(self, msg: MsgType) -> "Response": await h.call( message=message, # consumer middlewares - _extra_middlewares=(m.consume_scope for m in middlewares), + _extra_middlewares=( + m.consume_scope for m in middlewares[::-1] + ), ), ) @@ -350,7 +352,9 @@ async def process_message(self, msg: MsgType) -> "Response": ): await p._publish( result_msg.as_publish_command(), - _extra_middlewares=(m.publish_scope for m in middlewares), + _extra_middlewares=( + m.publish_scope for m in middlewares[::-1] + ), ) # Return data for tests diff --git a/faststream/confluent/broker/registrator.py b/faststream/confluent/broker/registrator.py index 3bcc604719..39fa3b1cf7 100644 --- a/faststream/confluent/broker/registrator.py +++ b/faststream/confluent/broker/registrator.py @@ -10,7 +10,7 @@ overload, ) -from typing_extensions import Doc, override +from typing_extensions import Doc, deprecated, override from faststream._internal.broker.abc_broker import ABCBroker from faststream._internal.constants import EMPTY @@ -296,10 +296,15 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - ack_policy: Annotated[ - AckPolicy, + no_ack: Annotated[ + bool, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + deprecated( + "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " + "Scheduled to remove in 0.7.0" + ), ] = EMPTY, + ack_policy: AckPolicy = EMPTY, no_reply: Annotated[ bool, Doc( @@ -563,10 +568,15 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - ack_policy: Annotated[ - AckPolicy, + no_ack: Annotated[ + bool, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + deprecated( + "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " + "Scheduled to remove in 0.7.0" + ), ] = EMPTY, + ack_policy: AckPolicy = EMPTY, no_reply: Annotated[ bool, Doc( @@ -830,10 +840,15 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - ack_policy: Annotated[ - AckPolicy, + no_ack: Annotated[ + bool, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + deprecated( + "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " + "Scheduled to remove in 0.7.0" + ), ] = EMPTY, + ack_policy: AckPolicy = EMPTY, no_reply: Annotated[ bool, Doc( @@ -1100,10 +1115,15 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - ack_policy: Annotated[ - AckPolicy, + no_ack: Annotated[ + bool, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + deprecated( + "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " + "Scheduled to remove in 0.7.0" + ), ] = EMPTY, + ack_policy: AckPolicy = EMPTY, no_reply: Annotated[ bool, Doc( @@ -1161,6 +1181,7 @@ def subscriber( is_manual=not auto_commit, # subscriber args ack_policy=ack_policy, + no_ack=no_ack, no_reply=no_reply, broker_middlewares=self.middlewares, broker_dependencies=self._dependencies, diff --git a/faststream/confluent/fastapi/fastapi.py b/faststream/confluent/fastapi/fastapi.py index 197aa380af..3aaf9360a4 100644 --- a/faststream/confluent/fastapi/fastapi.py +++ b/faststream/confluent/fastapi/fastapi.py @@ -834,10 +834,15 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - ack_policy: Annotated[ - AckPolicy, + no_ack: Annotated[ + bool, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + deprecated( + "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " + "Scheduled to remove in 0.7.0" + ), ] = EMPTY, + ack_policy: AckPolicy = EMPTY, no_reply: Annotated[ bool, Doc( @@ -1604,10 +1609,15 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - ack_policy: Annotated[ - AckPolicy, + no_ack: Annotated[ + bool, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + deprecated( + "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " + "Scheduled to remove in 0.7.0" + ), ] = EMPTY, + ack_policy: AckPolicy = EMPTY, no_reply: Annotated[ bool, Doc( @@ -1997,10 +2007,15 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - ack_policy: Annotated[ - AckPolicy, + no_ack: Annotated[ + bool, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + deprecated( + "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " + "Scheduled to remove in 0.7.0" + ), ] = EMPTY, + ack_policy: AckPolicy = EMPTY, no_reply: Annotated[ bool, Doc( @@ -2177,6 +2192,7 @@ def subscriber( decoder=decoder, middlewares=middlewares, ack_policy=ack_policy, + no_ack=no_ack, no_reply=no_reply, title=title, description=description, diff --git a/faststream/confluent/router.py b/faststream/confluent/router.py index a1039fc72f..7b4aa6cb63 100644 --- a/faststream/confluent/router.py +++ b/faststream/confluent/router.py @@ -9,7 +9,7 @@ Union, ) -from typing_extensions import Doc +from typing_extensions import Doc, deprecated from faststream._internal.broker.router import ( ArgsContainer, @@ -382,10 +382,15 @@ def __init__( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - ack_policy: Annotated[ - AckPolicy, + no_ack: Annotated[ + bool, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + deprecated( + "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " + "Scheduled to remove in 0.7.0" + ), ] = EMPTY, + ack_policy: AckPolicy = EMPTY, no_reply: Annotated[ bool, Doc( @@ -442,8 +447,8 @@ def __init__( title=title, description=description, include_in_schema=include_in_schema, - # FastDepends args ack_policy=ack_policy, + no_ack=no_ack, ) diff --git a/faststream/confluent/subscriber/factory.py b/faststream/confluent/subscriber/factory.py index b6edea0456..72bee6b4b7 100644 --- a/faststream/confluent/subscriber/factory.py +++ b/faststream/confluent/subscriber/factory.py @@ -13,6 +13,7 @@ SpecificationBatchSubscriber, SpecificationDefaultSubscriber, ) +from faststream.exceptions import SetupError from faststream.middlewares import AckPolicy if TYPE_CHECKING: @@ -37,6 +38,7 @@ def create_subscriber( is_manual: bool, # Subscriber args ack_policy: "AckPolicy", + no_ack: bool, no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[tuple[ConfluentMsg, ...]]"], @@ -60,6 +62,7 @@ def create_subscriber( is_manual: bool, # Subscriber args ack_policy: "AckPolicy", + no_ack: bool, no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[ConfluentMsg]"], @@ -83,6 +86,7 @@ def create_subscriber( is_manual: bool, # Subscriber args ack_policy: "AckPolicy", + no_ack: bool, no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable[ @@ -110,6 +114,7 @@ def create_subscriber( is_manual: bool, # Subscriber args ack_policy: "AckPolicy", + no_ack: bool, no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable[ @@ -123,10 +128,12 @@ def create_subscriber( "SpecificationDefaultSubscriber", "SpecificationBatchSubscriber", ]: - _validate_input_for_misconfigure(ack_policy=ack_policy, is_manual=is_manual) + _validate_input_for_misconfigure( + ack_policy=ack_policy, is_manual=is_manual, no_ack=no_ack + ) if ack_policy is EMPTY: - ack_policy = AckPolicy.REJECT_ON_ERROR + ack_policy = AckPolicy.DO_NOTHING if no_ack else AckPolicy.REJECT_ON_ERROR if batch: return SpecificationBatchSubscriber( @@ -166,7 +173,19 @@ def _validate_input_for_misconfigure( *, ack_policy: "AckPolicy", is_manual: bool, + no_ack: bool, ) -> None: + if no_ack is not EMPTY: + warnings.warn( + "`no_ack` option was deprecated in prior to `ack_policy=AckPolicy.DO_NOTHING`. Scheduled to remove in 0.7.0", + category=DeprecationWarning, + stacklevel=4, + ) + + if ack_policy is not EMPTY: + msg = "You can't use deprecated `no_ack` and `ack_policy` simultaneously. Please, use `ack_policy` only." + raise SetupError(msg) + if ack_policy is not EMPTY and not is_manual: warnings.warn( "You can't use acknowledgement policy with `is_manual=False` subscriber", diff --git a/faststream/kafka/broker/registrator.py b/faststream/kafka/broker/registrator.py index 3523c2bed7..c4b6539567 100644 --- a/faststream/kafka/broker/registrator.py +++ b/faststream/kafka/broker/registrator.py @@ -13,7 +13,7 @@ from aiokafka import ConsumerRecord from aiokafka.coordinator.assignors.roundrobin import RoundRobinPartitionAssignor -from typing_extensions import Doc, override +from typing_extensions import Doc, deprecated, override from faststream._internal.broker.abc_broker import ABCBroker from faststream._internal.constants import EMPTY @@ -398,10 +398,15 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - ack_policy: Annotated[ - AckPolicy, + no_ack: Annotated[ + bool, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + deprecated( + "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " + "Scheduled to remove in 0.7.0" + ), ] = EMPTY, + ack_policy: AckPolicy = EMPTY, no_reply: Annotated[ bool, Doc( @@ -764,10 +769,15 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - ack_policy: Annotated[ - AckPolicy, + no_ack: Annotated[ + bool, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + deprecated( + "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " + "Scheduled to remove in 0.7.0" + ), ] = EMPTY, + ack_policy: AckPolicy = EMPTY, no_reply: Annotated[ bool, Doc( @@ -1130,10 +1140,15 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - ack_policy: Annotated[ - AckPolicy, + no_ack: Annotated[ + bool, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + deprecated( + "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " + "Scheduled to remove in 0.7.0" + ), ] = EMPTY, + ack_policy: AckPolicy = EMPTY, no_reply: Annotated[ bool, Doc( @@ -1499,10 +1514,15 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - ack_policy: Annotated[ - AckPolicy, + no_ack: Annotated[ + bool, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + deprecated( + "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " + "Scheduled to remove in 0.7.0" + ), ] = EMPTY, + ack_policy: AckPolicy = EMPTY, no_reply: Annotated[ bool, Doc( @@ -1563,6 +1583,7 @@ def subscriber( is_manual=not auto_commit, # subscriber args ack_policy=ack_policy, + no_ack=no_ack, no_reply=no_reply, broker_middlewares=self.middlewares, broker_dependencies=self._dependencies, diff --git a/faststream/kafka/fastapi/fastapi.py b/faststream/kafka/fastapi/fastapi.py index 46a07fb7a7..faef7c01ee 100644 --- a/faststream/kafka/fastapi/fastapi.py +++ b/faststream/kafka/fastapi/fastapi.py @@ -945,10 +945,15 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - ack_policy: Annotated[ - AckPolicy, + no_ack: Annotated[ + bool, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + deprecated( + "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " + "Scheduled to remove in 0.7.0" + ), ] = EMPTY, + ack_policy: AckPolicy = EMPTY, no_reply: Annotated[ bool, Doc( @@ -1431,10 +1436,15 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - ack_policy: Annotated[ - AckPolicy, + no_ack: Annotated[ + bool, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + deprecated( + "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " + "Scheduled to remove in 0.7.0" + ), ] = EMPTY, + ack_policy: AckPolicy = EMPTY, no_reply: Annotated[ bool, Doc( @@ -1917,10 +1927,15 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - ack_policy: Annotated[ - AckPolicy, + no_ack: Annotated[ + bool, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + deprecated( + "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " + "Scheduled to remove in 0.7.0" + ), ] = EMPTY, + ack_policy: AckPolicy = EMPTY, no_reply: Annotated[ bool, Doc( @@ -2406,10 +2421,15 @@ def subscriber( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - ack_policy: Annotated[ - AckPolicy, + no_ack: Annotated[ + bool, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + deprecated( + "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " + "Scheduled to remove in 0.7.0" + ), ] = EMPTY, + ack_policy: AckPolicy = EMPTY, no_reply: Annotated[ bool, Doc( @@ -2593,6 +2613,7 @@ def subscriber( decoder=decoder, middlewares=middlewares, ack_policy=ack_policy, + no_ack=no_ack, no_reply=no_reply, title=title, description=description, diff --git a/faststream/kafka/router.py b/faststream/kafka/router.py index b4fecbe3e0..f98c1c4660 100644 --- a/faststream/kafka/router.py +++ b/faststream/kafka/router.py @@ -10,7 +10,7 @@ ) from aiokafka.coordinator.assignors.roundrobin import RoundRobinPartitionAssignor -from typing_extensions import Doc +from typing_extensions import Doc, deprecated from faststream._internal.broker.router import ( ArgsContainer, @@ -485,10 +485,15 @@ def __init__( Iterable["SubscriberMiddleware[KafkaMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - ack_policy: Annotated[ - AckPolicy, + no_ack: Annotated[ + bool, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + deprecated( + "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " + "Scheduled to remove in 0.7.0" + ), ] = EMPTY, + ack_policy: AckPolicy = EMPTY, no_reply: Annotated[ bool, Doc( @@ -548,12 +553,12 @@ def __init__( decoder=decoder, middlewares=middlewares, no_reply=no_reply, + ack_policy=ack_policy, + no_ack=no_ack, # AsyncAPI args title=title, description=description, include_in_schema=include_in_schema, - # FastDepends args - ack_policy=ack_policy, ) diff --git a/faststream/kafka/subscriber/factory.py b/faststream/kafka/subscriber/factory.py index bb559873cc..0abb87c6ac 100644 --- a/faststream/kafka/subscriber/factory.py +++ b/faststream/kafka/subscriber/factory.py @@ -40,6 +40,7 @@ def create_subscriber( is_manual: bool, # Subscriber args ack_policy: "AckPolicy", + no_ack: bool, no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[tuple[ConsumerRecord, ...]]"], @@ -65,6 +66,7 @@ def create_subscriber( is_manual: bool, # Subscriber args ack_policy: "AckPolicy", + no_ack: bool, no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[ConsumerRecord]"], @@ -90,6 +92,7 @@ def create_subscriber( is_manual: bool, # Subscriber args ack_policy: "AckPolicy", + no_ack: bool, no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable[ @@ -119,6 +122,7 @@ def create_subscriber( is_manual: bool, # Subscriber args ack_policy: "AckPolicy", + no_ack: bool, no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable[ @@ -137,12 +141,13 @@ def create_subscriber( pattern=pattern, partitions=partitions, ack_policy=ack_policy, + no_ack=no_ack, is_manual=is_manual, group_id=group_id, ) if ack_policy is EMPTY: - ack_policy = AckPolicy.REJECT_ON_ERROR + ack_policy = AckPolicy.DO_NOTHING if no_ack else AckPolicy.REJECT_ON_ERROR if batch: return SpecificationBatchSubscriber( @@ -188,8 +193,20 @@ def _validate_input_for_misconfigure( pattern: Optional[str], ack_policy: "AckPolicy", is_manual: bool, + no_ack: bool, group_id: Optional[str], ) -> None: + if no_ack is not EMPTY: + warnings.warn( + "`no_ack` option was deprecated in prior to `ack_policy=AckPolicy.DO_NOTHING`. Scheduled to remove in 0.7.0", + category=DeprecationWarning, + stacklevel=4, + ) + + if ack_policy is not EMPTY: + msg = "You can't use deprecated `no_ack` and `ack_policy` simultaneously. Please, use `ack_policy` only." + raise SetupError(msg) + if ack_policy is not EMPTY and not is_manual: warnings.warn( "You can't use acknowledgement policy with `is_manual=False` subscriber", diff --git a/faststream/nats/__init__.py b/faststream/nats/__init__.py index 42018a3a2a..55ed9abd15 100644 --- a/faststream/nats/__init__.py +++ b/faststream/nats/__init__.py @@ -18,7 +18,7 @@ from faststream.nats.broker.broker import NatsBroker from faststream.nats.response import NatsResponse from faststream.nats.router import NatsPublisher, NatsRoute, NatsRouter -from faststream.nats.schemas import JStream, KvWatch, ObjWatch, PullSub +from faststream.nats.schemas import JStream, KvWatch, ObjWatch, PubAck, PullSub from faststream.nats.testing import TestNatsBroker __all__ = ( @@ -38,6 +38,7 @@ "NatsRouter", "ObjWatch", "Placement", + "PubAck", "PullSub", "RePublish", "ReplayPolicy", diff --git a/faststream/nats/broker/broker.py b/faststream/nats/broker/broker.py index 8cfa07a9bd..ee1005d7d5 100644 --- a/faststream/nats/broker/broker.py +++ b/faststream/nats/broker/broker.py @@ -55,7 +55,7 @@ JWTCallback, SignatureCallback, ) - from nats.js.api import Placement, PubAck, RePublish, StorageType + from nats.js.api import Placement, RePublish, StorageType from nats.js.kv import KeyValue from nats.js.object_store import ObjectStore from typing_extensions import TypedDict, Unpack @@ -72,6 +72,7 @@ ) from faststream.nats.message import NatsMessage from faststream.nats.publisher.usecase import LogicPublisher + from faststream.nats.schemas import PubAck from faststream.security import BaseSecurity from faststream.specification.schema.extra import Tag, TagDict @@ -699,7 +700,7 @@ async def publish( Returns: `None` if you publishes a regular message. - `nats.js.api.PubAck` if you publishes a message to stream. + `faststream.nats.PubAck` if you publishes a message to stream. """ cmd = NatsPublishCommand( message=message, @@ -746,8 +747,7 @@ async def request( # type: ignore[override] Manual message **correlation_id** setter. **correlation_id** is a useful option to trace messages. stream: - This option validates that the target subject is in presented stream. - Can be omitted without any effect if you doesn't want PubAck frame. + JetStream name. This option is required if your target subscriber listens for events using JetStream. timeout: Timeout to send message to NATS. diff --git a/faststream/nats/broker/registrator.py b/faststream/nats/broker/registrator.py index 365c114dcb..4be0981c34 100644 --- a/faststream/nats/broker/registrator.py +++ b/faststream/nats/broker/registrator.py @@ -2,7 +2,7 @@ from typing import TYPE_CHECKING, Annotated, Any, Optional, Union, cast from nats.js import api -from typing_extensions import Doc, override +from typing_extensions import Doc, deprecated, override from faststream._internal.broker.abc_broker import ABCBroker from faststream._internal.constants import EMPTY @@ -162,10 +162,15 @@ def subscriber( # type: ignore[override] int, Doc("Number of workers to process messages concurrently."), ] = 1, - ack_policy: Annotated[ - AckPolicy, + no_ack: Annotated[ + bool, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + deprecated( + "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " + "Scheduled to remove in 0.7.0" + ), ] = EMPTY, + ack_policy: AckPolicy = EMPTY, no_reply: Annotated[ bool, Doc( @@ -221,6 +226,7 @@ def subscriber( # type: ignore[override] ack_first=ack_first, # subscriber args ack_policy=ack_policy, + no_ack=no_ack, no_reply=no_reply, broker_middlewares=self.middlewares, broker_dependencies=self._dependencies, diff --git a/faststream/nats/fastapi/fastapi.py b/faststream/nats/fastapi/fastapi.py index 3c465c783c..da477e051b 100644 --- a/faststream/nats/fastapi/fastapi.py +++ b/faststream/nats/fastapi/fastapi.py @@ -677,10 +677,15 @@ def subscriber( # type: ignore[override] int, Doc("Number of workers to process messages concurrently."), ] = 1, - ack_policy: Annotated[ - AckPolicy, + no_ack: Annotated[ + bool, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + deprecated( + "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " + "Scheduled to remove in 0.7.0" + ), ] = EMPTY, + ack_policy: AckPolicy = EMPTY, no_reply: Annotated[ bool, Doc( @@ -853,6 +858,7 @@ def subscriber( # type: ignore[override] middlewares=middlewares, max_workers=max_workers, ack_policy=ack_policy, + no_ack=no_ack, no_reply=no_reply, title=title, description=description, diff --git a/faststream/nats/message.py b/faststream/nats/message.py index ce7486aceb..eb4a8ab94a 100644 --- a/faststream/nats/message.py +++ b/faststream/nats/message.py @@ -13,27 +13,35 @@ class NatsMessage(StreamMessage[Msg]): async def ack(self) -> None: # Check `self.raw_message._ackd` instead of `self.committed` # to be compatible with `self.raw_message.ack()` - if not self.raw_message._ackd: - await self.raw_message.ack() - await super().ack() + try: + if not self.raw_message._ackd: + await self.raw_message.ack() + finally: + await super().ack() async def ack_sync(self) -> None: - if not self.raw_message._ackd: - await self.raw_message.ack_sync() - await super().ack() + try: + if not self.raw_message._ackd: + await self.raw_message.ack_sync() + finally: + await super().ack() async def nack( self, delay: Optional[float] = None, ) -> None: - if not self.raw_message._ackd: - await self.raw_message.nak(delay=delay) - await super().nack() + try: + if not self.raw_message._ackd: + await self.raw_message.nak(delay=delay) + finally: + await super().nack() async def reject(self) -> None: - if not self.raw_message._ackd: - await self.raw_message.term() - await super().reject() + try: + if not self.raw_message._ackd: + await self.raw_message.term() + finally: + await super().reject() async def in_progress(self) -> None: if not self.raw_message._ackd: diff --git a/faststream/nats/parser.py b/faststream/nats/parser.py index d5ddcfe316..e3343c0af8 100644 --- a/faststream/nats/parser.py +++ b/faststream/nats/parser.py @@ -54,9 +54,6 @@ async def decode_message( class NatsParser(NatsBaseParser): """A class to parse NATS core messages.""" - def __init__(self, *, pattern: str) -> None: - super().__init__(pattern=pattern) - async def parse_message( self, message: "Msg", @@ -68,8 +65,6 @@ async def parse_message( headers = message.header or {} - message._ackd = True # prevent Core message from acknowledgement - return NatsMessage( raw_message=message, body=message.data, diff --git a/faststream/nats/publisher/producer.py b/faststream/nats/publisher/producer.py index aba0f78349..9451092170 100644 --- a/faststream/nats/publisher/producer.py +++ b/faststream/nats/publisher/producer.py @@ -19,13 +19,14 @@ if TYPE_CHECKING: from nats.aio.client import Client from nats.aio.msg import Msg - from nats.js import JetStreamContext, api + from nats.js import JetStreamContext from faststream._internal.types import ( AsyncCallable, CustomCallable, ) from faststream.nats.response import NatsPublishCommand + from faststream.nats.schemas import PubAck class NatsFastProducer(ProducerProto): @@ -126,7 +127,7 @@ def disconnect(self) -> None: async def publish( # type: ignore[override] self, cmd: "NatsPublishCommand", - ) -> "api.PubAck": + ) -> "PubAck": payload, content_type = encode_message(cmd.body) headers_to_send = { diff --git a/faststream/nats/publisher/usecase.py b/faststream/nats/publisher/usecase.py index 2b16854d73..05b98bb20a 100644 --- a/faststream/nats/publisher/usecase.py +++ b/faststream/nats/publisher/usecase.py @@ -14,13 +14,11 @@ from faststream.response.publish_type import PublishType if TYPE_CHECKING: - from nats.js import api - from faststream._internal.basic_types import SendableMessage from faststream._internal.types import BrokerMiddleware, PublisherMiddleware from faststream.nats.message import NatsMessage from faststream.nats.publisher.producer import NatsFastProducer, NatsJSFastProducer - from faststream.nats.schemas import JStream + from faststream.nats.schemas import JStream, PubAck from faststream.response.response import PublishCommand @@ -75,7 +73,7 @@ async def publish( correlation_id: Optional[str] = None, stream: Optional[str] = None, timeout: Optional[float] = None, - ) -> "api.PubAck": ... + ) -> "PubAck": ... @override async def publish( @@ -87,7 +85,7 @@ async def publish( correlation_id: Optional[str] = None, stream: Optional[str] = None, timeout: Optional[float] = None, - ) -> Optional["api.PubAck"]: + ) -> Optional["PubAck"]: """Publish message directly. Args: @@ -112,7 +110,7 @@ async def publish( Returns: `None` if you publishes a regular message. - `nats.js.api.PubAck` if you publishes a message to stream. + `faststream.nats.PubAck` if you publishes a message to stream. """ cmd = NatsPublishCommand( message, diff --git a/faststream/nats/router.py b/faststream/nats/router.py index be895eb8af..baa94fbb44 100644 --- a/faststream/nats/router.py +++ b/faststream/nats/router.py @@ -9,7 +9,7 @@ ) from nats.js import api -from typing_extensions import Doc +from typing_extensions import Doc, deprecated from faststream._internal.broker.router import ( ArgsContainer, @@ -252,10 +252,15 @@ def __init__( int, Doc("Number of workers to process messages concurrently."), ] = 1, - ack_policy: Annotated[ - AckPolicy, + no_ack: Annotated[ + bool, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + deprecated( + "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " + "Scheduled to remove in 0.7.0" + ), ] = EMPTY, + ack_policy: AckPolicy = EMPTY, no_reply: Annotated[ bool, Doc( @@ -306,6 +311,7 @@ def __init__( decoder=decoder, middlewares=middlewares, ack_policy=ack_policy, + no_ack=no_ack, no_reply=no_reply, title=title, description=description, diff --git a/faststream/nats/schemas/__init__.py b/faststream/nats/schemas/__init__.py index 1edd51bcbe..accadfc731 100644 --- a/faststream/nats/schemas/__init__.py +++ b/faststream/nats/schemas/__init__.py @@ -1,3 +1,5 @@ +from nats.js.api import PubAck + from faststream.nats.schemas.js_stream import JStream from faststream.nats.schemas.kv_watch import KvWatch from faststream.nats.schemas.obj_watch import ObjWatch @@ -7,5 +9,6 @@ "JStream", "KvWatch", "ObjWatch", + "PubAck", "PullSub", ) diff --git a/faststream/nats/schemas/js_stream.py b/faststream/nats/schemas/js_stream.py index 3ad4fc2e4f..62e97124f6 100644 --- a/faststream/nats/schemas/js_stream.py +++ b/faststream/nats/schemas/js_stream.py @@ -6,7 +6,6 @@ from faststream._internal.proto import NameRequired from faststream._internal.utils.path import compile_path -from faststream.middlewares import AckPolicy if TYPE_CHECKING: from re import Pattern @@ -121,10 +120,13 @@ def __init__( "cluster may be available but for reads only.", ), ] = None, - ack_policy: Annotated[ - AckPolicy, - Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), - ] = AckPolicy.REJECT_ON_ERROR, + no_ack: Annotated[ + bool, + Doc( + "Should stream acknowledge writes or not. Without acks publisher can't determine, does message " + "received by stream or not." + ), + ] = False, template_owner: Optional[str] = None, duplicate_window: Annotated[ float, @@ -189,7 +191,6 @@ def __init__( super().__init__(name) subjects = subjects or [] - no_ack = ack_policy is AckPolicy.DO_NOTHING self.subjects = subjects self.declare = declare diff --git a/faststream/nats/subscriber/factory.py b/faststream/nats/subscriber/factory.py index c17e6e808d..fa76740e5e 100644 --- a/faststream/nats/subscriber/factory.py +++ b/faststream/nats/subscriber/factory.py @@ -63,6 +63,7 @@ def create_subscriber( stream: Optional["JStream"], # Subscriber args ack_policy: "AckPolicy", + no_ack: bool, no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[Any]"], @@ -96,6 +97,7 @@ def create_subscriber( headers_only=headers_only, pull_sub=pull_sub, ack_policy=ack_policy, + no_ack=no_ack, kv_watch=kv_watch, obj_watch=obj_watch, ack_first=ack_first, @@ -104,7 +106,7 @@ def create_subscriber( ) if ack_policy is EMPTY: - ack_policy = AckPolicy.REJECT_ON_ERROR + ack_policy = AckPolicy.DO_NOTHING if no_ack else AckPolicy.REJECT_ON_ERROR config = config or ConsumerConfig(filter_subjects=[]) if config.durable_name is None: @@ -326,10 +328,22 @@ def _validate_input_for_misconfigure( # noqa: PLR0915 kv_watch: Optional["KvWatch"], obj_watch: Optional["ObjWatch"], ack_policy: "AckPolicy", # default EMPTY + no_ack: bool, # default EMPTY ack_first: bool, # default False max_workers: int, # default 1 stream: Optional["JStream"], ) -> None: + if no_ack is not EMPTY: + warnings.warn( + "`no_ack` option was deprecated in prior to `ack_policy=AckPolicy.DO_NOTHING`. Scheduled to remove in 0.7.0", + category=DeprecationWarning, + stacklevel=4, + ) + + if ack_policy is not EMPTY: + msg = "You can't use deprecated `no_ack` and `ack_policy` simultaneously. Please, use `ack_policy` only." + raise SetupError(msg) + if not subject and not config: msg = "You must provide either the `subject` or `config` option." raise SetupError(msg) diff --git a/faststream/nats/subscriber/usecase.py b/faststream/nats/subscriber/usecase.py deleted file mode 100644 index 8c85b8569a..0000000000 --- a/faststream/nats/subscriber/usecase.py +++ /dev/null @@ -1,1197 +0,0 @@ -from abc import abstractmethod -from collections.abc import Awaitable, Iterable -from contextlib import suppress -from typing import ( - TYPE_CHECKING, - Annotated, - Any, - Callable, - Optional, - cast, -) - -import anyio -from nats.errors import ConnectionClosedError, TimeoutError -from nats.js.api import ConsumerConfig, ObjectInfo -from typing_extensions import Doc, override - -from faststream._internal.subscriber.mixins import ConcurrentMixin, TasksMixin -from faststream._internal.subscriber.usecase import SubscriberUsecase -from faststream._internal.subscriber.utils import process_msg -from faststream._internal.types import MsgType -from faststream.middlewares import AckPolicy -from faststream.nats.helpers import KVBucketDeclarer, OSBucketDeclarer -from faststream.nats.message import NatsMessage -from faststream.nats.parser import ( - BatchParser, - JsParser, - KvParser, - NatsParser, - ObjParser, -) -from faststream.nats.publisher.fake import NatsFakePublisher -from faststream.nats.schemas.js_stream import compile_nats_wildcard -from faststream.nats.subscriber.adapters import ( - UnsubscribeAdapter, - Unsubscriptable, -) - -from .state import ConnectedSubscriberState, EmptySubscriberState, SubscriberState - -if TYPE_CHECKING: - from fast_depends.dependencies import Dependant - from nats.aio.msg import Msg - from nats.aio.subscription import Subscription - from nats.js import JetStreamContext - from nats.js.kv import KeyValue - from nats.js.object_store import ObjectStore - - from faststream._internal.basic_types import ( - AnyDict, - SendableMessage, - ) - from faststream._internal.publisher.proto import BasePublisherProto, ProducerProto - from faststream._internal.state import ( - BrokerState as BasicState, - Pointer, - ) - from faststream._internal.types import ( - AsyncCallable, - BrokerMiddleware, - CustomCallable, - ) - from faststream.message import StreamMessage - from faststream.nats.broker.state import BrokerState - from faststream.nats.helpers import KVBucketDeclarer, OSBucketDeclarer - from faststream.nats.message import NatsKvMessage, NatsObjMessage - from faststream.nats.schemas import JStream, KvWatch, ObjWatch, PullSub - - -class LogicSubscriber(SubscriberUsecase[MsgType]): - """A class to represent a NATS handler.""" - - subscription: Optional[Unsubscriptable] - _fetch_sub: Optional[Unsubscriptable] - producer: Optional["ProducerProto"] - - def __init__( - self, - *, - subject: str, - config: "ConsumerConfig", - extra_options: Optional["AnyDict"], - # Subscriber args - default_parser: "AsyncCallable", - default_decoder: "AsyncCallable", - ack_policy: "AckPolicy", - no_reply: bool, - broker_dependencies: Iterable["Dependant"], - broker_middlewares: Iterable["BrokerMiddleware[MsgType]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> None: - self.subject = subject - self.config = config - - self.extra_options = extra_options or {} - - super().__init__( - default_parser=default_parser, - default_decoder=default_decoder, - # Propagated args - ack_policy=ack_policy, - no_reply=no_reply, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - # AsyncAPI args - title_=title_, - description_=description_, - include_in_schema=include_in_schema, - ) - - self._fetch_sub = None - self.subscription = None - self.producer = None - - self._connection_state: SubscriberState = EmptySubscriberState() - - @override - def _setup( # type: ignore[override] - self, - *, - connection_state: "BrokerState", - os_declarer: "OSBucketDeclarer", - kv_declarer: "KVBucketDeclarer", - # basic args - extra_context: "AnyDict", - # broker options - broker_parser: Optional["CustomCallable"], - broker_decoder: Optional["CustomCallable"], - # dependant args - state: "Pointer[BasicState]", - ) -> None: - self._connection_state = ConnectedSubscriberState( - parent_state=connection_state, - os_declarer=os_declarer, - kv_declarer=kv_declarer, - ) - - super()._setup( - extra_context=extra_context, - broker_parser=broker_parser, - broker_decoder=broker_decoder, - state=state, - ) - - @property - def clear_subject(self) -> str: - """Compile `test.{name}` to `test.*` subject.""" - _, path = compile_nats_wildcard(self.subject) - return path - - async def start(self) -> None: - """Create NATS subscription and start consume tasks.""" - await super().start() - - if self.calls: - await self._create_subscription() - - async def close(self) -> None: - """Clean up handler subscription, cancel consume task in graceful mode.""" - await super().close() - - if self.subscription is not None: - await self.subscription.unsubscribe() - self.subscription = None - - if self._fetch_sub is not None: - await self._fetch_sub.unsubscribe() - self.subscription = None - - @abstractmethod - async def _create_subscription(self) -> None: - """Create NATS subscription object to consume messages.""" - raise NotImplementedError - - @staticmethod - def build_log_context( - message: Annotated[ - Optional["StreamMessage[MsgType]"], - Doc("Message which we are building context for"), - ], - subject: Annotated[ - str, - Doc("NATS subject we are listening"), - ], - *, - queue: Annotated[ - str, - Doc("Using queue group name"), - ] = "", - stream: Annotated[ - str, - Doc("Stream object we are listening"), - ] = "", - ) -> dict[str, str]: - """Static method to build log context out of `self.consume` scope.""" - return { - "subject": subject, - "queue": queue, - "stream": stream, - "message_id": getattr(message, "message_id", ""), - } - - def add_prefix(self, prefix: str) -> None: - """Include Subscriber in router.""" - if self.subject: - self.subject = f"{prefix}{self.subject}" - else: - self.config.filter_subjects = [ - f"{prefix}{subject}" for subject in (self.config.filter_subjects or ()) - ] - - @property - def _resolved_subject_string(self) -> str: - return self.subject or ", ".join(self.config.filter_subjects or ()) - - -class _DefaultSubscriber(LogicSubscriber[MsgType]): - def __init__( - self, - *, - subject: str, - config: "ConsumerConfig", - # default args - extra_options: Optional["AnyDict"], - # Subscriber args - default_parser: "AsyncCallable", - default_decoder: "AsyncCallable", - ack_policy: "AckPolicy", - no_reply: bool, - broker_dependencies: Iterable["Dependant"], - broker_middlewares: Iterable["BrokerMiddleware[MsgType]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> None: - super().__init__( - subject=subject, - config=config, - extra_options=extra_options, - # subscriber args - default_parser=default_parser, - default_decoder=default_decoder, - # Propagated args - ack_policy=ack_policy, - no_reply=no_reply, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, - ) - - def _make_response_publisher( - self, - message: "StreamMessage[Any]", - ) -> Iterable["BasePublisherProto"]: - """Create Publisher objects to use it as one of `publishers` in `self.consume` scope.""" - return ( - NatsFakePublisher( - producer=self._state.get().producer, - subject=message.reply_to, - ), - ) - - def get_log_context( - self, - message: Annotated[ - Optional["StreamMessage[MsgType]"], - Doc("Message which we are building context for"), - ], - ) -> dict[str, str]: - """Log context factory using in `self.consume` scope.""" - return self.build_log_context( - message=message, - subject=self.subject, - ) - - -class CoreSubscriber(_DefaultSubscriber["Msg"]): - subscription: Optional["Subscription"] - _fetch_sub: Optional["Subscription"] - - def __init__( - self, - *, - # default args - subject: str, - config: "ConsumerConfig", - queue: str, - extra_options: Optional["AnyDict"], - # Subscriber args - no_reply: bool, - broker_dependencies: Iterable["Dependant"], - broker_middlewares: Iterable["BrokerMiddleware[Msg]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> None: - parser_ = NatsParser(pattern=subject) - - self.queue = queue - - super().__init__( - subject=subject, - config=config, - extra_options=extra_options, - # subscriber args - default_parser=parser_.parse_message, - default_decoder=parser_.decode_message, - # Propagated args - ack_policy=AckPolicy.DO_NOTHING, - no_reply=no_reply, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, - ) - - @override - async def get_one( - self, - *, - timeout: float = 5.0, - ) -> "Optional[NatsMessage]": - assert ( # nosec B101 - not self.calls - ), "You can't use `get_one` method if subscriber has registered handlers." - - if self._fetch_sub is None: - fetch_sub = self._fetch_sub = await self._connection_state.client.subscribe( - subject=self.clear_subject, - queue=self.queue, - **self.extra_options, - ) - else: - fetch_sub = self._fetch_sub - - try: - raw_message = await fetch_sub.next_msg(timeout=timeout) - except TimeoutError: - return None - - context = self._state.get().di_state.context - - msg: NatsMessage = await process_msg( # type: ignore[assignment] - msg=raw_message, - middlewares=( - m(raw_message, context=context) for m in self._broker_middlewares - ), - parser=self._parser, - decoder=self._decoder, - ) - return msg - - @override - async def _create_subscription(self) -> None: - """Create NATS subscription and start consume task.""" - if self.subscription: - return - - self.subscription = await self._connection_state.client.subscribe( - subject=self.clear_subject, - queue=self.queue, - cb=self.consume, - **self.extra_options, - ) - - def get_log_context( - self, - message: Annotated[ - Optional["StreamMessage[Msg]"], - Doc("Message which we are building context for"), - ], - ) -> dict[str, str]: - """Log context factory using in `self.consume` scope.""" - return self.build_log_context( - message=message, - subject=self.subject, - queue=self.queue, - ) - - -class ConcurrentCoreSubscriber( - ConcurrentMixin, - CoreSubscriber, -): - def __init__( - self, - *, - max_workers: int, - # default args - subject: str, - config: "ConsumerConfig", - queue: str, - extra_options: Optional["AnyDict"], - # Subscriber args - no_reply: bool, - broker_dependencies: Iterable["Dependant"], - broker_middlewares: Iterable["BrokerMiddleware[Msg]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> None: - super().__init__( - max_workers=max_workers, - # basic args - subject=subject, - config=config, - queue=queue, - extra_options=extra_options, - # Propagated args - no_reply=no_reply, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, - ) - - @override - async def _create_subscription(self) -> None: - """Create NATS subscription and start consume task.""" - if self.subscription: - return - - self.start_consume_task() - - self.subscription = await self._connection_state.client.subscribe( - subject=self.clear_subject, - queue=self.queue, - cb=self._put_msg, - **self.extra_options, - ) - - -class _StreamSubscriber(_DefaultSubscriber["Msg"]): - _fetch_sub: Optional["JetStreamContext.PullSubscription"] - - def __init__( - self, - *, - stream: "JStream", - # default args - subject: str, - config: "ConsumerConfig", - queue: str, - extra_options: Optional["AnyDict"], - # Subscriber args - ack_policy: "AckPolicy", - no_reply: bool, - broker_dependencies: Iterable["Dependant"], - broker_middlewares: Iterable["BrokerMiddleware[Msg]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> None: - parser_ = JsParser(pattern=subject) - - self.queue = queue - self.stream = stream - - super().__init__( - subject=subject, - config=config, - extra_options=extra_options, - # subscriber args - default_parser=parser_.parse_message, - default_decoder=parser_.decode_message, - # Propagated args - ack_policy=ack_policy, - no_reply=no_reply, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, - ) - - def get_log_context( - self, - message: Annotated[ - Optional["StreamMessage[Msg]"], - Doc("Message which we are building context for"), - ], - ) -> dict[str, str]: - """Log context factory using in `self.consume` scope.""" - return self.build_log_context( - message=message, - subject=self._resolved_subject_string, - queue=self.queue, - stream=self.stream.name, - ) - - @override - async def get_one( - self, - *, - timeout: float = 5, - ) -> Optional["NatsMessage"]: - assert ( # nosec B101 - not self.calls - ), "You can't use `get_one` method if subscriber has registered handlers." - - if not self._fetch_sub: - extra_options = { - "pending_bytes_limit": self.extra_options["pending_bytes_limit"], - "pending_msgs_limit": self.extra_options["pending_msgs_limit"], - "durable": self.extra_options["durable"], - "stream": self.extra_options["stream"], - } - if inbox_prefix := self.extra_options.get("inbox_prefix"): - extra_options["inbox_prefix"] = inbox_prefix - - self._fetch_sub = await self._connection_state.js.pull_subscribe( - subject=self.clear_subject, - config=self.config, - **extra_options, - ) - - try: - raw_message = ( - await self._fetch_sub.fetch( - batch=1, - timeout=timeout, - ) - )[0] - except (TimeoutError, ConnectionClosedError): - return None - - context = self._state.get().di_state.context - - msg: NatsMessage = await process_msg( # type: ignore[assignment] - msg=raw_message, - middlewares=( - m(raw_message, context=context) for m in self._broker_middlewares - ), - parser=self._parser, - decoder=self._decoder, - ) - return msg - - -class PushStreamSubscription(_StreamSubscriber): - subscription: Optional["JetStreamContext.PushSubscription"] - - @override - async def _create_subscription(self) -> None: - """Create NATS subscription and start consume task.""" - if self.subscription: - return - - self.subscription = await self._connection_state.js.subscribe( - subject=self.clear_subject, - queue=self.queue, - cb=self.consume, - config=self.config, - **self.extra_options, - ) - - -class ConcurrentPushStreamSubscriber( - ConcurrentMixin, - _StreamSubscriber, -): - subscription: Optional["JetStreamContext.PushSubscription"] - - def __init__( - self, - *, - max_workers: int, - stream: "JStream", - # default args - subject: str, - config: "ConsumerConfig", - queue: str, - extra_options: Optional["AnyDict"], - # Subscriber args - ack_policy: "AckPolicy", - no_reply: bool, - broker_dependencies: Iterable["Dependant"], - broker_middlewares: Iterable["BrokerMiddleware[Msg]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> None: - super().__init__( - max_workers=max_workers, - # basic args - stream=stream, - subject=subject, - config=config, - queue=queue, - extra_options=extra_options, - # Propagated args - ack_policy=ack_policy, - no_reply=no_reply, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, - ) - - @override - async def _create_subscription(self) -> None: - """Create NATS subscription and start consume task.""" - if self.subscription: - return - - self.start_consume_task() - - self.subscription = await self._connection_state.js.subscribe( - subject=self.clear_subject, - queue=self.queue, - cb=self._put_msg, - config=self.config, - **self.extra_options, - ) - - -class PullStreamSubscriber( - TasksMixin, - _StreamSubscriber, -): - subscription: Optional["JetStreamContext.PullSubscription"] - - def __init__( - self, - *, - pull_sub: "PullSub", - stream: "JStream", - # default args - subject: str, - config: "ConsumerConfig", - extra_options: Optional["AnyDict"], - # Subscriber args - ack_policy: "AckPolicy", - no_reply: bool, - broker_dependencies: Iterable["Dependant"], - broker_middlewares: Iterable["BrokerMiddleware[Msg]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> None: - self.pull_sub = pull_sub - - super().__init__( - # basic args - stream=stream, - subject=subject, - config=config, - extra_options=extra_options, - queue="", - # Propagated args - ack_policy=ack_policy, - no_reply=no_reply, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, - ) - - @override - async def _create_subscription(self) -> None: - """Create NATS subscription and start consume task.""" - if self.subscription: - return - - self.subscription = await self._connection_state.js.pull_subscribe( - subject=self.clear_subject, - config=self.config, - **self.extra_options, - ) - self.add_task(self._consume_pull(cb=self.consume)) - - async def _consume_pull( - self, - cb: Callable[["Msg"], Awaitable["SendableMessage"]], - ) -> None: - """Endless task consuming messages using NATS Pull subscriber.""" - assert self.subscription # nosec B101 - - while self.running: # pragma: no branch - messages = [] - with suppress(TimeoutError, ConnectionClosedError): - messages = await self.subscription.fetch( - batch=self.pull_sub.batch_size, - timeout=self.pull_sub.timeout, - ) - - if messages: - async with anyio.create_task_group() as tg: - for msg in messages: - tg.start_soon(cb, msg) - - -class ConcurrentPullStreamSubscriber( - ConcurrentMixin, - PullStreamSubscriber, -): - def __init__( - self, - *, - max_workers: int, - # default args - pull_sub: "PullSub", - stream: "JStream", - subject: str, - config: "ConsumerConfig", - extra_options: Optional["AnyDict"], - # Subscriber args - ack_policy: "AckPolicy", - no_reply: bool, - broker_dependencies: Iterable["Dependant"], - broker_middlewares: Iterable["BrokerMiddleware[Msg]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> None: - super().__init__( - max_workers=max_workers, - # basic args - pull_sub=pull_sub, - stream=stream, - subject=subject, - config=config, - extra_options=extra_options, - # Propagated args - ack_policy=ack_policy, - no_reply=no_reply, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, - ) - - @override - async def _create_subscription(self) -> None: - """Create NATS subscription and start consume task.""" - if self.subscription: - return - - self.start_consume_task() - - self.subscription = await self._connection_state.js.pull_subscribe( - subject=self.clear_subject, - config=self.config, - **self.extra_options, - ) - self.add_task(self._consume_pull(cb=self._put_msg)) - - -class BatchPullStreamSubscriber( - TasksMixin, - _DefaultSubscriber[list["Msg"]], -): - """Batch-message consumer class.""" - - subscription: Optional["JetStreamContext.PullSubscription"] - _fetch_sub: Optional["JetStreamContext.PullSubscription"] - - def __init__( - self, - *, - # default args - subject: str, - config: "ConsumerConfig", - stream: "JStream", - pull_sub: "PullSub", - extra_options: Optional["AnyDict"], - # Subscriber args - ack_policy: "AckPolicy", - no_reply: bool, - broker_dependencies: Iterable["Dependant"], - broker_middlewares: Iterable["BrokerMiddleware[list[Msg]]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> None: - parser = BatchParser(pattern=subject) - - self.stream = stream - self.pull_sub = pull_sub - - super().__init__( - subject=subject, - config=config, - extra_options=extra_options, - # subscriber args - default_parser=parser.parse_batch, - default_decoder=parser.decode_batch, - # Propagated args - ack_policy=ack_policy, - no_reply=no_reply, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, - ) - - @override - async def get_one( - self, - *, - timeout: float = 5, - ) -> Optional["NatsMessage"]: - assert ( # nosec B101 - not self.calls - ), "You can't use `get_one` method if subscriber has registered handlers." - - if not self._fetch_sub: - fetch_sub = ( - self._fetch_sub - ) = await self._connection_state.js.pull_subscribe( - subject=self.clear_subject, - config=self.config, - **self.extra_options, - ) - else: - fetch_sub = self._fetch_sub - - try: - raw_message = await fetch_sub.fetch( - batch=1, - timeout=timeout, - ) - except TimeoutError: - return None - - context = self._state.get().di_state.context - - return cast( - NatsMessage, - await process_msg( - msg=raw_message, - middlewares=( - m(raw_message, context=context) for m in self._broker_middlewares - ), - parser=self._parser, - decoder=self._decoder, - ), - ) - - @override - async def _create_subscription(self) -> None: - """Create NATS subscription and start consume task.""" - if self.subscription: - return - - self.subscription = await self._connection_state.js.pull_subscribe( - subject=self.clear_subject, - config=self.config, - **self.extra_options, - ) - self.add_task(self._consume_pull()) - - async def _consume_pull(self) -> None: - """Endless task consuming messages using NATS Pull subscriber.""" - assert self.subscription, "You should call `create_subscription` at first." # nosec B101 - - while self.running: # pragma: no branch - with suppress(TimeoutError, ConnectionClosedError): - messages = await self.subscription.fetch( - batch=self.pull_sub.batch_size, - timeout=self.pull_sub.timeout, - ) - - if messages: - await self.consume(messages) - - -class KeyValueWatchSubscriber( - TasksMixin, - LogicSubscriber["KeyValue.Entry"], -): - subscription: Optional["UnsubscribeAdapter[KeyValue.KeyWatcher]"] - _fetch_sub: Optional[UnsubscribeAdapter["KeyValue.KeyWatcher"]] - - def __init__( - self, - *, - subject: str, - config: "ConsumerConfig", - kv_watch: "KvWatch", - broker_dependencies: Iterable["Dependant"], - broker_middlewares: Iterable["BrokerMiddleware[KeyValue.Entry]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> None: - parser = KvParser(pattern=subject) - self.kv_watch = kv_watch - - super().__init__( - subject=subject, - config=config, - extra_options=None, - ack_policy=AckPolicy.DO_NOTHING, - no_reply=True, - default_parser=parser.parse_message, - default_decoder=parser.decode_message, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, - ) - - @override - async def get_one( - self, - *, - timeout: float = 5, - ) -> Optional["NatsKvMessage"]: - assert ( # nosec B101 - not self.calls - ), "You can't use `get_one` method if subscriber has registered handlers." - - if not self._fetch_sub: - bucket = await self._connection_state.kv_declarer.create_key_value( - bucket=self.kv_watch.name, - declare=self.kv_watch.declare, - ) - - fetch_sub = self._fetch_sub = UnsubscribeAdapter["KeyValue.KeyWatcher"]( - await bucket.watch( - keys=self.clear_subject, - headers_only=self.kv_watch.headers_only, - include_history=self.kv_watch.include_history, - ignore_deletes=self.kv_watch.ignore_deletes, - meta_only=self.kv_watch.meta_only, - ), - ) - else: - fetch_sub = self._fetch_sub - - raw_message = None - sleep_interval = timeout / 10 - with anyio.move_on_after(timeout): - while ( # noqa: ASYNC110 - # type: ignore[no-untyped-call] - raw_message := await fetch_sub.obj.updates(timeout) - ) is None: - await anyio.sleep(sleep_interval) - - context = self._state.get().di_state.context - - msg: NatsKvMessage = await process_msg( - msg=raw_message, - middlewares=( - m(raw_message, context=context) for m in self._broker_middlewares - ), - parser=self._parser, - decoder=self._decoder, - ) - return msg - - @override - async def _create_subscription(self) -> None: - if self.subscription: - return - - bucket = await self._connection_state.kv_declarer.create_key_value( - bucket=self.kv_watch.name, - declare=self.kv_watch.declare, - ) - - self.subscription = UnsubscribeAdapter["KeyValue.KeyWatcher"]( - await bucket.watch( - keys=self.clear_subject, - headers_only=self.kv_watch.headers_only, - include_history=self.kv_watch.include_history, - ignore_deletes=self.kv_watch.ignore_deletes, - meta_only=self.kv_watch.meta_only, - ), - ) - - self.add_task(self.__consume_watch()) - - async def __consume_watch(self) -> None: - assert self.subscription, "You should call `create_subscription` at first." # nosec B101 - - key_watcher = self.subscription.obj - - while self.running: - with suppress(ConnectionClosedError, TimeoutError): - message = cast( - Optional["KeyValue.Entry"], - # type: ignore[no-untyped-call] - await key_watcher.updates(self.kv_watch.timeout), - ) - - if message: - await self.consume(message) - - def _make_response_publisher( - self, - message: Annotated[ - "StreamMessage[KeyValue.Entry]", - Doc("Message requiring reply"), - ], - ) -> Iterable["BasePublisherProto"]: - """Create Publisher objects to use it as one of `publishers` in `self.consume` scope.""" - return () - - def get_log_context( - self, - message: Annotated[ - Optional["StreamMessage[KeyValue.Entry]"], - Doc("Message which we are building context for"), - ], - ) -> dict[str, str]: - """Log context factory using in `self.consume` scope.""" - return self.build_log_context( - message=message, - subject=self.subject, - stream=self.kv_watch.name, - ) - - -OBJECT_STORAGE_CONTEXT_KEY = "__object_storage" - - -class ObjStoreWatchSubscriber( - TasksMixin, - LogicSubscriber[ObjectInfo], -): - subscription: Optional["UnsubscribeAdapter[ObjectStore.ObjectWatcher]"] - _fetch_sub: Optional[UnsubscribeAdapter["ObjectStore.ObjectWatcher"]] - - def __init__( - self, - *, - subject: str, - config: "ConsumerConfig", - obj_watch: "ObjWatch", - broker_dependencies: Iterable["Dependant"], - broker_middlewares: Iterable["BrokerMiddleware[list[Msg]]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> None: - parser = ObjParser(pattern="") - - self.obj_watch = obj_watch - self.obj_watch_conn = None - - super().__init__( - subject=subject, - config=config, - extra_options=None, - ack_policy=AckPolicy.DO_NOTHING, - no_reply=True, - default_parser=parser.parse_message, - default_decoder=parser.decode_message, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, - ) - - @override - async def get_one( - self, - *, - timeout: float = 5, - ) -> Optional["NatsObjMessage"]: - assert ( # nosec B101 - not self.calls - ), "You can't use `get_one` method if subscriber has registered handlers." - - if not self._fetch_sub: - self.bucket = await self._connection_state.os_declarer.create_object_store( - bucket=self.subject, - declare=self.obj_watch.declare, - ) - - obj_watch = await self.bucket.watch( - ignore_deletes=self.obj_watch.ignore_deletes, - include_history=self.obj_watch.include_history, - meta_only=self.obj_watch.meta_only, - ) - fetch_sub = self._fetch_sub = UnsubscribeAdapter[ - "ObjectStore.ObjectWatcher" - ](obj_watch) - else: - fetch_sub = self._fetch_sub - - raw_message = None - sleep_interval = timeout / 10 - with anyio.move_on_after(timeout): - while ( # noqa: ASYNC110 - # type: ignore[no-untyped-call] - raw_message := await fetch_sub.obj.updates(timeout) - ) is None: - await anyio.sleep(sleep_interval) - - context = self._state.get().di_state.context - - msg: NatsObjMessage = await process_msg( - msg=raw_message, - middlewares=( - m(raw_message, context=context) for m in self._broker_middlewares - ), - parser=self._parser, - decoder=self._decoder, - ) - return msg - - @override - async def _create_subscription(self) -> None: - if self.subscription: - return - - self.bucket = await self._connection_state.os_declarer.create_object_store( - bucket=self.subject, - declare=self.obj_watch.declare, - ) - - self.add_task(self.__consume_watch()) - - async def __consume_watch(self) -> None: - assert self.bucket, "You should call `create_subscription` at first." # nosec B101 - - # Should be created inside task to avoid nats-py lock - obj_watch = await self.bucket.watch( - ignore_deletes=self.obj_watch.ignore_deletes, - include_history=self.obj_watch.include_history, - meta_only=self.obj_watch.meta_only, - ) - - self.subscription = UnsubscribeAdapter["ObjectStore.ObjectWatcher"](obj_watch) - - context = self._state.get().di_state.context - - while self.running: - with suppress(TimeoutError): - message = cast( - Optional["ObjectInfo"], - # type: ignore[no-untyped-call] - await obj_watch.updates(self.obj_watch.timeout), - ) - - if message: - with context.scope(OBJECT_STORAGE_CONTEXT_KEY, self.bucket): - await self.consume(message) - - def _make_response_publisher( - self, - message: Annotated[ - "StreamMessage[ObjectInfo]", - Doc("Message requiring reply"), - ], - ) -> Iterable["BasePublisherProto"]: - """Create Publisher objects to use it as one of `publishers` in `self.consume` scope.""" - return () - - def get_log_context( - self, - message: Annotated[ - Optional["StreamMessage[ObjectInfo]"], - Doc("Message which we are building context for"), - ], - ) -> dict[str, str]: - """Log context factory using in `self.consume` scope.""" - return self.build_log_context( - message=message, - subject=self.subject, - ) diff --git a/faststream/rabbit/broker/registrator.py b/faststream/rabbit/broker/registrator.py index 37ca0066f7..0ce98da45e 100644 --- a/faststream/rabbit/broker/registrator.py +++ b/faststream/rabbit/broker/registrator.py @@ -1,7 +1,7 @@ from collections.abc import Iterable from typing import TYPE_CHECKING, Annotated, Any, Optional, Union, cast -from typing_extensions import Doc, override +from typing_extensions import Doc, deprecated, override from faststream._internal.broker.abc_broker import ABCBroker from faststream._internal.constants import EMPTY @@ -59,10 +59,15 @@ def subscriber( # type: ignore[override] Optional["AnyDict"], Doc("Extra consumer arguments to use in `queue.consume(...)` method."), ] = None, - ack_policy: Annotated[ - AckPolicy, + no_ack: Annotated[ + bool, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + deprecated( + "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " + "Scheduled to remove in 0.7.0" + ), ] = EMPTY, + ack_policy: AckPolicy = EMPTY, # broker arguments dependencies: Annotated[ Iterable["Dependant"], @@ -112,6 +117,7 @@ def subscriber( # type: ignore[override] consume_args=consume_args, # subscriber args ack_policy=ack_policy, + no_ack=no_ack, no_reply=no_reply, broker_middlewares=self.middlewares, broker_dependencies=self._dependencies, diff --git a/faststream/rabbit/fastapi/fastapi.py b/faststream/rabbit/fastapi/fastapi.py index 02d2d4b2e9..a53a93e5fa 100644 --- a/faststream/rabbit/fastapi/fastapi.py +++ b/faststream/rabbit/fastapi/fastapi.py @@ -512,10 +512,15 @@ def subscriber( # type: ignore[override] Iterable["SubscriberMiddleware[RabbitMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - ack_policy: Annotated[ - AckPolicy, + no_ack: Annotated[ + bool, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + deprecated( + "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " + "Scheduled to remove in 0.7.0" + ), ] = EMPTY, + ack_policy: AckPolicy = EMPTY, no_reply: Annotated[ bool, Doc( @@ -673,6 +678,7 @@ def subscriber( # type: ignore[override] decoder=decoder, middlewares=middlewares, ack_policy=ack_policy, + no_ack=no_ack, no_reply=no_reply, title=title, description=description, diff --git a/faststream/rabbit/router.py b/faststream/rabbit/router.py index 8eaec725ef..862ea5bcb0 100644 --- a/faststream/rabbit/router.py +++ b/faststream/rabbit/router.py @@ -1,7 +1,7 @@ from collections.abc import Awaitable, Iterable from typing import TYPE_CHECKING, Annotated, Any, Callable, Optional, Union -from typing_extensions import Doc +from typing_extensions import Doc, deprecated from faststream._internal.broker.router import ( ArgsContainer, @@ -231,10 +231,15 @@ def __init__( Iterable["SubscriberMiddleware[RabbitMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - ack_policy: Annotated[ - AckPolicy, + no_ack: Annotated[ + bool, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + deprecated( + "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " + "Scheduled to remove in 0.7.0" + ), ] = EMPTY, + ack_policy: AckPolicy = EMPTY, no_reply: Annotated[ bool, Doc( @@ -269,6 +274,7 @@ def __init__( decoder=decoder, middlewares=middlewares, ack_policy=ack_policy, + no_ack=no_ack, no_reply=no_reply, title=title, description=description, diff --git a/faststream/rabbit/subscriber/factory.py b/faststream/rabbit/subscriber/factory.py index 8a4475ec58..df49821c6c 100644 --- a/faststream/rabbit/subscriber/factory.py +++ b/faststream/rabbit/subscriber/factory.py @@ -1,7 +1,9 @@ +import warnings from collections.abc import Iterable from typing import TYPE_CHECKING, Optional from faststream._internal.constants import EMPTY +from faststream.exceptions import SetupError from faststream.middlewares import AckPolicy from faststream.rabbit.subscriber.specified import SpecificationSubscriber @@ -24,15 +26,16 @@ def create_subscriber( broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[IncomingMessage]"], ack_policy: "AckPolicy", + no_ack: bool, # AsyncAPI args title_: Optional[str], description_: Optional[str], include_in_schema: bool, ) -> SpecificationSubscriber: - _validate_input_for_misconfigure() + _validate_input_for_misconfigure(ack_policy=ack_policy, no_ack=no_ack) if ack_policy is EMPTY: - ack_policy = AckPolicy.REJECT_ON_ERROR + ack_policy = AckPolicy.DO_NOTHING if no_ack else AckPolicy.REJECT_ON_ERROR return SpecificationSubscriber( queue=queue, @@ -48,5 +51,18 @@ def create_subscriber( ) -def _validate_input_for_misconfigure() -> None: - """Nothing to check yet.""" +def _validate_input_for_misconfigure( + *, + ack_policy: "AckPolicy", + no_ack: bool, +) -> None: + if no_ack is not EMPTY: + warnings.warn( + "`no_ack` option was deprecated in prior to `ack_policy=AckPolicy.DO_NOTHING`. Scheduled to remove in 0.7.0", + category=DeprecationWarning, + stacklevel=4, + ) + + if ack_policy is not EMPTY: + msg = "You can't use deprecated `no_ack` and `ack_policy` simultaneously. Please, use `ack_policy` only." + raise SetupError(msg) diff --git a/faststream/redis/broker/registrator.py b/faststream/redis/broker/registrator.py index 10cf4afe98..50885af7fa 100644 --- a/faststream/redis/broker/registrator.py +++ b/faststream/redis/broker/registrator.py @@ -1,7 +1,7 @@ from collections.abc import Iterable from typing import TYPE_CHECKING, Annotated, Any, Optional, Union, cast -from typing_extensions import Doc, override +from typing_extensions import Doc, deprecated, override from faststream._internal.broker.abc_broker import ABCBroker from faststream._internal.constants import EMPTY @@ -67,10 +67,15 @@ def subscriber( # type: ignore[override] Iterable["SubscriberMiddleware[UnifyRedisMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - ack_policy: Annotated[ - AckPolicy, + no_ack: Annotated[ + bool, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + deprecated( + "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " + "Scheduled to remove in 0.7.0" + ), ] = EMPTY, + ack_policy: AckPolicy = EMPTY, no_reply: Annotated[ bool, Doc( @@ -103,6 +108,7 @@ def subscriber( # type: ignore[override] stream=stream, # subscriber args ack_policy=ack_policy, + no_ack=no_ack, no_reply=no_reply, broker_middlewares=self.middlewares, broker_dependencies=self._dependencies, diff --git a/faststream/redis/fastapi/fastapi.py b/faststream/redis/fastapi/fastapi.py index 3afad46036..f71f329276 100644 --- a/faststream/redis/fastapi/fastapi.py +++ b/faststream/redis/fastapi/fastapi.py @@ -462,10 +462,15 @@ def subscriber( # type: ignore[override] Iterable["SubscriberMiddleware[UnifyRedisMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - ack_policy: Annotated[ - AckPolicy, + no_ack: Annotated[ + bool, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + deprecated( + "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " + "Scheduled to remove in 0.7.0" + ), ] = EMPTY, + ack_policy: AckPolicy = EMPTY, no_reply: Annotated[ bool, Doc( @@ -623,6 +628,7 @@ def subscriber( # type: ignore[override] decoder=decoder, middlewares=middlewares, ack_policy=ack_policy, + no_ack=no_ack, no_reply=no_reply, title=title, description=description, diff --git a/faststream/redis/router.py b/faststream/redis/router.py index fb155829a0..a2a3b8ec2a 100644 --- a/faststream/redis/router.py +++ b/faststream/redis/router.py @@ -1,7 +1,7 @@ from collections.abc import Awaitable, Iterable from typing import TYPE_CHECKING, Annotated, Any, Callable, Optional, Union -from typing_extensions import Doc +from typing_extensions import Doc, deprecated from faststream._internal.broker.router import ( ArgsContainer, @@ -149,10 +149,15 @@ def __init__( Iterable["SubscriberMiddleware[UnifyRedisMessage]"], Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), - ack_policy: Annotated[ - AckPolicy, + no_ack: Annotated[ + bool, Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), + deprecated( + "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " + "Scheduled to remove in 0.7.0" + ), ] = EMPTY, + ack_policy: AckPolicy = EMPTY, no_reply: Annotated[ bool, Doc( @@ -187,6 +192,7 @@ def __init__( decoder=decoder, middlewares=middlewares, ack_policy=ack_policy, + no_ack=no_ack, no_reply=no_reply, title=title, description=description, diff --git a/faststream/redis/schemas/stream_sub.py b/faststream/redis/schemas/stream_sub.py index 07488d5f86..50a0b6d606 100644 --- a/faststream/redis/schemas/stream_sub.py +++ b/faststream/redis/schemas/stream_sub.py @@ -3,7 +3,6 @@ from faststream._internal.proto import NameRequired from faststream.exceptions import SetupError -from faststream.middlewares import AckPolicy class StreamSub(NameRequired): @@ -28,13 +27,11 @@ def __init__( group: Optional[str] = None, consumer: Optional[str] = None, batch: bool = False, - ack_policy: AckPolicy = AckPolicy.REJECT_ON_ERROR, + no_ack: bool = False, last_id: Optional[str] = None, maxlen: Optional[int] = None, max_records: Optional[int] = None, ) -> None: - no_ack = ack_policy is AckPolicy.DO_NOTHING - if (group and not consumer) or (not group and consumer): msg = "You should specify `group` and `consumer` both" raise SetupError(msg) diff --git a/faststream/redis/subscriber/factory.py b/faststream/redis/subscriber/factory.py index 378b561348..db42423078 100644 --- a/faststream/redis/subscriber/factory.py +++ b/faststream/redis/subscriber/factory.py @@ -39,6 +39,7 @@ def create_subscriber( stream: Union["StreamSub", str, None], # Subscriber args ack_policy: "AckPolicy", + no_ack: bool, no_reply: bool = False, broker_dependencies: Iterable["Dependant"] = (), broker_middlewares: Iterable["BrokerMiddleware[UnifyRedisDict]"] = (), @@ -52,10 +53,11 @@ def create_subscriber( list=list, stream=stream, ack_policy=ack_policy, + no_ack=no_ack, ) if ack_policy is EMPTY: - ack_policy = AckPolicy.REJECT_ON_ERROR + ack_policy = AckPolicy.DO_NOTHING if no_ack else AckPolicy.REJECT_ON_ERROR if (channel_sub := PubSub.validate(channel)) is not None: return SpecificationChannelSubscriber( @@ -133,9 +135,21 @@ def _validate_input_for_misconfigure( list: Union["ListSub", str, None], stream: Union["StreamSub", str, None], ack_policy: AckPolicy, + no_ack: bool, ) -> None: validate_options(channel=channel, list=list, stream=stream) + if no_ack is not EMPTY: + warnings.warn( + "`no_ack` option was deprecated in prior to `ack_policy=AckPolicy.DO_NOTHING`. Scheduled to remove in 0.7.0", + category=DeprecationWarning, + stacklevel=4, + ) + + if ack_policy is not EMPTY: + msg = "You can't use deprecated `no_ack` and `ack_policy` simultaneously. Please, use `ack_policy` only." + raise SetupError(msg) + if ack_policy is not EMPTY: if channel: warnings.warn( diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py index 463d541d3d..05577fbbb2 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_basic.py @@ -13,7 +13,7 @@ def test_basic_customization() -> None: "kafka": {"bindingVersion": "0.4.0", "topic": "input_data"}, }, "servers": ["development"], - "subscribe": { + "publish": { "message": { "$ref": "#/components/messages/input_data:OnInputData:Message", }, @@ -23,7 +23,7 @@ def test_basic_customization() -> None: "bindings": { "kafka": {"bindingVersion": "0.4.0", "topic": "output_data"}, }, - "publish": { + "subscribe": { "message": { "$ref": "#/components/messages/output_data:Publisher:Message", }, diff --git a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py index 3b852203be..c7499bb15e 100644 --- a/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py +++ b/tests/a_docs/getting_started/asyncapi/asyncapi_customization/test_handler.py @@ -16,7 +16,7 @@ def test_handler_customization() -> None: assert subscriber_value == IsPartialDict({ "servers": ["development"], "bindings": {"kafka": {"topic": "input_data", "bindingVersion": "0.4.0"}}, - "subscribe": { + "publish": { "message": {"$ref": "#/components/messages/input_data:Consume:Message"}, }, }), subscriber_value @@ -32,7 +32,7 @@ def test_handler_customization() -> None: "description": "My publisher description", "servers": ["development"], "bindings": {"kafka": {"topic": "output_data", "bindingVersion": "0.4.0"}}, - "publish": { + "subscribe": { "message": {"$ref": "#/components/messages/output_data:Produce:Message"} }, } diff --git a/tests/brokers/base/basic.py b/tests/brokers/base/basic.py index 23d6e3a1ec..28f9dbfa78 100644 --- a/tests/brokers/base/basic.py +++ b/tests/brokers/base/basic.py @@ -2,6 +2,7 @@ from typing import Any from faststream._internal.broker.broker import BrokerUsecase +from faststream._internal.broker.router import BrokerRouter class BaseTestcaseConfig: @@ -31,3 +32,7 @@ def get_subscriber_params( dict[str, Any], ]: return args, kwargs + + @abstractmethod + def get_router(self, **kwargs: Any) -> BrokerRouter: + raise NotImplementedError diff --git a/tests/brokers/base/middlewares.py b/tests/brokers/base/middlewares.py index 47e07c6398..729a0966c9 100644 --- a/tests/brokers/base/middlewares.py +++ b/tests/brokers/base/middlewares.py @@ -1,5 +1,5 @@ import asyncio -from unittest.mock import Mock, call +from unittest.mock import MagicMock, call import pytest @@ -12,12 +12,227 @@ from .basic import BaseTestcaseConfig +@pytest.mark.asyncio() +class MiddlewaresOrderTestcase(BaseTestcaseConfig): + async def test_broker_middleware_order(self, queue: str, mock: MagicMock): + class InnerMiddleware(BaseMiddleware): + async def consume_scope(self, call_next, msg): + mock.consume_inner() + mock.sub("inner") + return await call_next(msg) + + async def publish_scope(self, call_next, cmd): + mock.publish_inner() + mock.pub("inner") + return await call_next(cmd) + + class OuterMiddleware(BaseMiddleware): + async def consume_scope(self, call_next, msg): + mock.consume_outer() + mock.sub("outer") + return await call_next(msg) + + async def publish_scope(self, call_next, cmd): + mock.publish_outer() + mock.pub("outer") + return await call_next(cmd) + + broker = self.get_broker(middlewares=[OuterMiddleware, InnerMiddleware]) + + args, kwargs = self.get_subscriber_params(queue) + + @broker.subscriber(*args, **kwargs) + async def handler(msg): + pass + + async with self.patch_broker(broker) as br: + await br.publish(None, queue) + + mock.consume_inner.assert_called_once() + mock.consume_outer.assert_called_once() + mock.publish_inner.assert_called_once() + mock.publish_outer.assert_called_once() + + assert [c.args[0] for c in mock.sub.call_args_list] == ["outer", "inner"] + assert [c.args[0] for c in mock.pub.call_args_list] == ["outer", "inner"] + + async def test_publisher_middleware_order(self, queue: str, mock: MagicMock): + class InnerMiddleware(BaseMiddleware): + async def publish_scope(self, call_next, cmd): + mock.publish_inner() + mock("inner") + return await call_next(cmd) + + class MiddleMiddleware(BaseMiddleware): + async def publish_scope(self, call_next, cmd): + mock.publish_middle() + mock("middle") + return await call_next(cmd) + + class OuterMiddleware(BaseMiddleware): + async def publish_scope(self, call_next, cmd): + mock.publish_outer() + mock("outer") + return await call_next(cmd) + + broker = self.get_broker(middlewares=[OuterMiddleware]) + publisher = broker.publisher( + queue, + middlewares=[ + MiddleMiddleware(None, context=None).publish_scope, + InnerMiddleware(None, context=None).publish_scope, + ], + ) + + args, kwargs = self.get_subscriber_params(queue) + + @broker.subscriber(*args, **kwargs) + async def handler(msg): + pass + + async with self.patch_broker(broker): + await publisher.publish(None, queue) + + mock.publish_inner.assert_called_once() + mock.publish_middle.assert_called_once() + mock.publish_outer.assert_called_once() + + assert [c.args[0] for c in mock.call_args_list] == ["outer", "middle", "inner"] + + async def test_publisher_with_router_middleware_order( + self, queue: str, mock: MagicMock + ): + class InnerMiddleware(BaseMiddleware): + async def publish_scope(self, call_next, cmd): + mock.publish_inner() + mock("inner") + return await call_next(cmd) + + class MiddleMiddleware(BaseMiddleware): + async def publish_scope(self, call_next, cmd): + mock.publish_middle() + mock("middle") + return await call_next(cmd) + + class OuterMiddleware(BaseMiddleware): + async def publish_scope(self, call_next, cmd): + mock.publish_outer() + mock("outer") + return await call_next(cmd) + + broker = self.get_broker(middlewares=[OuterMiddleware]) + router = self.get_router(middlewares=[MiddleMiddleware]) + router2 = self.get_router(middlewares=[InnerMiddleware]) + + publisher = router2.publisher(queue) + + args, kwargs = self.get_subscriber_params(queue) + + @router2.subscriber(*args, **kwargs) + async def handler(msg): + pass + + router.include_router(router2) + broker.include_router(router) + + async with self.patch_broker(broker): + await publisher.publish(None, queue) + + mock.publish_inner.assert_called_once() + mock.publish_middle.assert_called_once() + mock.publish_outer.assert_called_once() + + assert [c.args[0] for c in mock.call_args_list] == ["outer", "middle", "inner"] + + async def test_consume_middleware_order(self, queue: str, mock: MagicMock): + class InnerMiddleware(BaseMiddleware): + async def consume_scope(self, call_next, cmd): + mock.consume_inner() + mock("inner") + return await call_next(cmd) + + class MiddleMiddleware(BaseMiddleware): + async def consume_scope(self, call_next, cmd): + mock.consume_middle() + mock("middle") + return await call_next(cmd) + + class OuterMiddleware(BaseMiddleware): + async def consume_scope(self, call_next, cmd): + mock.consume_outer() + mock("outer") + return await call_next(cmd) + + broker = self.get_broker(middlewares=[OuterMiddleware]) + + args, kwargs = self.get_subscriber_params( + queue, + middlewares=[ + MiddleMiddleware(None, context=None).consume_scope, + InnerMiddleware(None, context=None).consume_scope, + ], + ) + + @broker.subscriber(*args, **kwargs) + async def handler(msg): + pass + + async with self.patch_broker(broker) as br: + await br.publish(None, queue) + + mock.consume_inner.assert_called_once() + mock.consume_middle.assert_called_once() + mock.consume_outer.assert_called_once() + + assert [c.args[0] for c in mock.call_args_list] == ["outer", "middle", "inner"] + + async def test_consume_with_middleware_order(self, queue: str, mock: MagicMock): + class InnerMiddleware(BaseMiddleware): + async def consume_scope(self, call_next, cmd): + mock.consume_inner() + mock("inner") + return await call_next(cmd) + + class MiddleMiddleware(BaseMiddleware): + async def consume_scope(self, call_next, cmd): + mock.consume_middle() + mock("middle") + return await call_next(cmd) + + class OuterMiddleware(BaseMiddleware): + async def consume_scope(self, call_next, cmd): + mock.consume_outer() + mock("outer") + return await call_next(cmd) + + broker = self.get_broker(middlewares=[OuterMiddleware]) + router = self.get_router(middlewares=[MiddleMiddleware]) + router2 = self.get_router(middlewares=[InnerMiddleware]) + + args, kwargs = self.get_subscriber_params(queue) + + @router2.subscriber(*args, **kwargs) + async def handler(msg): + pass + + router.include_router(router2) + broker.include_router(router) + async with self.patch_broker(broker) as br: + await br.publish(None, queue) + + mock.consume_inner.assert_called_once() + mock.consume_middle.assert_called_once() + mock.consume_outer.assert_called_once() + + assert [c.args[0] for c in mock.call_args_list] == ["outer", "middle", "inner"] + + @pytest.mark.asyncio() class LocalMiddlewareTestcase(BaseTestcaseConfig): async def test_subscriber_middleware( self, queue: str, - mock: Mock, + mock: MagicMock, ) -> None: event = asyncio.Event() @@ -56,7 +271,7 @@ async def handler(m) -> str: async def test_publisher_middleware( self, queue: str, - mock: Mock, + mock: MagicMock, ) -> None: event = asyncio.Event() @@ -97,7 +312,7 @@ async def handler(m) -> str: async def test_local_middleware_not_shared_between_subscribers( self, queue: str, - mock: Mock, + mock: MagicMock, ) -> None: event1 = asyncio.Event() event2 = asyncio.Event() @@ -147,7 +362,7 @@ async def handler(m) -> str: async def test_local_middleware_consume_not_shared_between_filters( self, queue: str, - mock: Mock, + mock: MagicMock, ) -> None: event1 = asyncio.Event() event2 = asyncio.Event() @@ -196,7 +411,7 @@ async def handler2(m) -> str: mock.end.assert_called_once() assert mock.call_count == 2 - async def test_error_traceback(self, queue: str, mock: Mock) -> None: + async def test_error_traceback(self, queue: str, mock: MagicMock) -> None: event = asyncio.Event() async def mid(call_next, msg): @@ -237,7 +452,7 @@ class MiddlewareTestcase(LocalMiddlewareTestcase): async def test_global_middleware( self, queue: str, - mock: Mock, + mock: MagicMock, ) -> None: event = asyncio.Event() @@ -278,7 +493,7 @@ async def handler(m) -> str: async def test_add_global_middleware( self, queue: str, - mock: Mock, + mock: MagicMock, ) -> None: event = asyncio.Event() @@ -333,7 +548,7 @@ async def handler2(m) -> str: async def test_patch_publish( self, queue: str, - mock: Mock, + mock: MagicMock, ) -> None: event = asyncio.Event() @@ -374,7 +589,7 @@ async def handler_resp(m) -> None: async def test_global_publisher_middleware( self, queue: str, - mock: Mock, + mock: MagicMock, ) -> None: event = asyncio.Event() @@ -422,7 +637,7 @@ class ExceptionMiddlewareTestcase(BaseTestcaseConfig): async def test_exception_middleware_default_msg( self, queue: str, - mock: Mock, + mock: MagicMock, ) -> None: event = asyncio.Event() @@ -465,7 +680,7 @@ async def subscriber2(msg=Context("message")) -> None: async def test_exception_middleware_skip_msg( self, queue: str, - mock: Mock, + mock: MagicMock, ) -> None: event = asyncio.Event() @@ -506,7 +721,7 @@ async def subscriber2(msg=Context("message")) -> None: async def test_exception_middleware_do_not_catch_skip_msg( self, queue: str, - mock: Mock, + mock: MagicMock, ) -> None: event = asyncio.Event() @@ -541,7 +756,7 @@ async def subscriber(m): async def test_exception_middleware_reraise( self, queue: str, - mock: Mock, + mock: MagicMock, ) -> None: event = asyncio.Event() @@ -582,7 +797,7 @@ async def subscriber2(msg=Context("message")) -> None: async def test_exception_middleware_different_handler( self, queue: str, - mock: Mock, + mock: MagicMock, ) -> None: event = asyncio.Event() @@ -663,7 +878,7 @@ async def value_error_handler(exc) -> str: async def test_exception_middleware_decoder_error( self, queue: str, - mock: Mock, + mock: MagicMock, ) -> None: event = asyncio.Event() diff --git a/tests/brokers/confluent/basic.py b/tests/brokers/confluent/basic.py index 2ea7a94c91..4b9e626695 100644 --- a/tests/brokers/confluent/basic.py +++ b/tests/brokers/confluent/basic.py @@ -1,10 +1,15 @@ from typing import Any -from faststream.confluent import TopicPartition -from tests.brokers.base.basic import BaseTestcaseConfig as _Base +from faststream.confluent import ( + KafkaBroker, + KafkaRouter, + TestKafkaBroker, + TopicPartition, +) +from tests.brokers.base.basic import BaseTestcaseConfig -class ConfluentTestcaseConfig(_Base): +class ConfluentTestcaseConfig(BaseTestcaseConfig): timeout: float = 10.0 def get_subscriber_params( @@ -27,3 +32,21 @@ def get_subscriber_params( "partitions": partitions, **kwargs, } + + def get_broker( + self, + apply_types: bool = False, + **kwargs: Any, + ) -> KafkaBroker: + return KafkaBroker(apply_types=apply_types, **kwargs) + + def patch_broker(self, broker: KafkaBroker, **kwargs: Any) -> KafkaBroker: + return broker + + def get_router(self, **kwargs: Any) -> KafkaRouter: + return KafkaRouter(**kwargs) + + +class ConfluentMemoryTestcaseConfig(ConfluentTestcaseConfig): + def patch_broker(self, broker: KafkaBroker, **kwargs: Any) -> KafkaBroker: + return TestKafkaBroker(broker, **kwargs) diff --git a/tests/brokers/confluent/test_consume.py b/tests/brokers/confluent/test_consume.py index 2e886bc1f6..d0d100d6af 100644 --- a/tests/brokers/confluent/test_consume.py +++ b/tests/brokers/confluent/test_consume.py @@ -1,11 +1,9 @@ import asyncio -from typing import Any from unittest.mock import patch import pytest from faststream import AckPolicy -from faststream.confluent import KafkaBroker from faststream.confluent.annotations import KafkaMessage from faststream.confluent.client import AsyncConfluentConsumer from faststream.exceptions import AckMessage @@ -19,9 +17,6 @@ class TestConsume(ConfluentTestcaseConfig, BrokerRealConsumeTestcase): """A class to represent a test Kafka broker.""" - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: - return KafkaBroker(apply_types=apply_types, **kwargs) - @pytest.mark.asyncio() async def test_consume_batch(self, queue: str) -> None: consume_broker = self.get_broker() diff --git a/tests/brokers/confluent/test_fastapi.py b/tests/brokers/confluent/test_fastapi.py index d47612c91e..1059e4d433 100644 --- a/tests/brokers/confluent/test_fastapi.py +++ b/tests/brokers/confluent/test_fastapi.py @@ -1,15 +1,13 @@ import asyncio -from typing import Any from unittest.mock import Mock import pytest -from faststream.confluent import KafkaBroker, KafkaRouter +from faststream.confluent import KafkaRouter from faststream.confluent.fastapi import KafkaRouter as StreamRouter -from faststream.confluent.testing import TestKafkaBroker from tests.brokers.base.fastapi import FastAPILocalTestcase, FastAPITestcase -from .basic import ConfluentTestcaseConfig +from .basic import ConfluentMemoryTestcaseConfig, ConfluentTestcaseConfig @pytest.mark.confluent() @@ -47,13 +45,10 @@ async def hello(msg: list[str]): mock.assert_called_with(["hi"]) -class TestRouterLocal(ConfluentTestcaseConfig, FastAPILocalTestcase): +class TestRouterLocal(ConfluentMemoryTestcaseConfig, FastAPILocalTestcase): router_class = StreamRouter broker_router_class = KafkaRouter - def patch_broker(self, broker: KafkaBroker, **kwargs: Any) -> TestKafkaBroker: - return TestKafkaBroker(broker, **kwargs) - async def test_batch_testclient( self, mock: Mock, diff --git a/tests/brokers/confluent/test_logger.py b/tests/brokers/confluent/test_logger.py index 01b74ef5f9..ce1c8f145f 100644 --- a/tests/brokers/confluent/test_logger.py +++ b/tests/brokers/confluent/test_logger.py @@ -2,8 +2,6 @@ import pytest -from faststream.confluent import KafkaBroker - from .basic import ConfluentTestcaseConfig @@ -14,7 +12,7 @@ class TestLogger(ConfluentTestcaseConfig): @pytest.mark.asyncio() async def test_custom_logger(self, queue: str) -> None: test_logger = logging.getLogger("test_logger") - broker = KafkaBroker(logger=test_logger) + broker = self.get_broker(logger=test_logger) args, kwargs = self.get_subscriber_params(queue) diff --git a/tests/brokers/confluent/test_middlewares.py b/tests/brokers/confluent/test_middlewares.py index 5309d8008e..b81c9a4325 100644 --- a/tests/brokers/confluent/test_middlewares.py +++ b/tests/brokers/confluent/test_middlewares.py @@ -1,23 +1,23 @@ -from typing import Any - import pytest -from faststream.confluent import KafkaBroker from tests.brokers.base.middlewares import ( ExceptionMiddlewareTestcase, MiddlewareTestcase, + MiddlewaresOrderTestcase, ) -from .basic import ConfluentTestcaseConfig +from .basic import ConfluentMemoryTestcaseConfig, ConfluentTestcaseConfig + + +class TestMiddlewaresOrder(ConfluentMemoryTestcaseConfig, MiddlewaresOrderTestcase): + pass @pytest.mark.confluent() class TestMiddlewares(ConfluentTestcaseConfig, MiddlewareTestcase): - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: - return KafkaBroker(apply_types=apply_types, **kwargs) + pass @pytest.mark.confluent() class TestExceptionMiddlewares(ConfluentTestcaseConfig, ExceptionMiddlewareTestcase): - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: - return KafkaBroker(apply_types=apply_types, **kwargs) + pass diff --git a/tests/brokers/confluent/test_parser.py b/tests/brokers/confluent/test_parser.py index deb150cc9a..65aa2bff15 100644 --- a/tests/brokers/confluent/test_parser.py +++ b/tests/brokers/confluent/test_parser.py @@ -1,8 +1,5 @@ -from typing import Any - import pytest -from faststream.confluent import KafkaBroker from tests.brokers.base.parser import CustomParserTestcase from .basic import ConfluentTestcaseConfig @@ -10,5 +7,4 @@ @pytest.mark.confluent() class TestCustomParser(ConfluentTestcaseConfig, CustomParserTestcase): - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: - return KafkaBroker(apply_types=apply_types, **kwargs) + pass diff --git a/tests/brokers/confluent/test_publish.py b/tests/brokers/confluent/test_publish.py index 0d6fc9f4e1..7ed7a76ac8 100644 --- a/tests/brokers/confluent/test_publish.py +++ b/tests/brokers/confluent/test_publish.py @@ -1,11 +1,10 @@ import asyncio -from typing import Any from unittest.mock import Mock import pytest from faststream import Context -from faststream.confluent import KafkaBroker, KafkaResponse +from faststream.confluent import KafkaResponse from tests.brokers.base.publish import BrokerPublishTestcase from .basic import ConfluentTestcaseConfig @@ -13,9 +12,6 @@ @pytest.mark.confluent() class TestPublish(ConfluentTestcaseConfig, BrokerPublishTestcase): - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: - return KafkaBroker(apply_types=apply_types, **kwargs) - @pytest.mark.asyncio() async def test_publish_batch(self, queue: str) -> None: pub_broker = self.get_broker() diff --git a/tests/brokers/confluent/test_requests.py b/tests/brokers/confluent/test_requests.py index a0343ced57..fac1b09331 100644 --- a/tests/brokers/confluent/test_requests.py +++ b/tests/brokers/confluent/test_requests.py @@ -3,10 +3,9 @@ import pytest from faststream import BaseMiddleware -from faststream.confluent import KafkaBroker, KafkaRouter, TestKafkaBroker from tests.brokers.base.requests import RequestsTestcase -from .basic import ConfluentTestcaseConfig +from .basic import ConfluentMemoryTestcaseConfig class Mid(BaseMiddleware): @@ -19,15 +18,6 @@ async def consume_scope(self, call_next, msg): @pytest.mark.asyncio() -class TestRequestTestClient(ConfluentTestcaseConfig, RequestsTestcase): +class TestRequestTestClient(ConfluentMemoryTestcaseConfig, RequestsTestcase): def get_middleware(self, **kwargs: Any): return Mid - - def get_router(self, **kwargs: Any): - return KafkaRouter(**kwargs) - - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: - return KafkaBroker(apply_types=apply_types, **kwargs) - - def patch_broker(self, broker: KafkaBroker, **kwargs: Any) -> TestKafkaBroker: - return TestKafkaBroker(broker, **kwargs) diff --git a/tests/brokers/confluent/test_router.py b/tests/brokers/confluent/test_router.py index 8d134e62c3..c26198d8d4 100644 --- a/tests/brokers/confluent/test_router.py +++ b/tests/brokers/confluent/test_router.py @@ -1,36 +1,20 @@ -from typing import Any - import pytest from faststream.confluent import ( - KafkaBroker, KafkaPublisher, KafkaRoute, - KafkaRouter, - TestKafkaBroker, ) from tests.brokers.base.router import RouterLocalTestcase, RouterTestcase -from .basic import ConfluentTestcaseConfig +from .basic import ConfluentMemoryTestcaseConfig, ConfluentTestcaseConfig @pytest.mark.confluent() class TestRouter(ConfluentTestcaseConfig, RouterTestcase): - broker_class = KafkaRouter route_class = KafkaRoute publisher_class = KafkaPublisher - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: - return KafkaBroker(apply_types=apply_types, **kwargs) - -class TestRouterLocal(ConfluentTestcaseConfig, RouterLocalTestcase): - broker_class = KafkaRouter +class TestRouterLocal(ConfluentMemoryTestcaseConfig, RouterLocalTestcase): route_class = KafkaRoute publisher_class = KafkaPublisher - - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: - return KafkaBroker(apply_types=apply_types, **kwargs) - - def patch_broker(self, broker: KafkaBroker, **kwargs: Any) -> TestKafkaBroker: - return TestKafkaBroker(broker, **kwargs) diff --git a/tests/brokers/confluent/test_test_client.py b/tests/brokers/confluent/test_test_client.py index 73077ec147..490d150ede 100644 --- a/tests/brokers/confluent/test_test_client.py +++ b/tests/brokers/confluent/test_test_client.py @@ -1,28 +1,20 @@ import asyncio -from typing import Any from unittest.mock import patch import pytest from faststream import BaseMiddleware -from faststream.confluent import KafkaBroker, TestKafkaBroker from faststream.confluent.annotations import KafkaMessage from faststream.confluent.message import FAKE_CONSUMER from faststream.confluent.testing import FakeProducer from tests.brokers.base.testclient import BrokerTestclientTestcase from tests.tools import spy_decorator -from .basic import ConfluentTestcaseConfig +from .basic import ConfluentMemoryTestcaseConfig @pytest.mark.asyncio() -class TestTestclient(ConfluentTestcaseConfig, BrokerTestclientTestcase): - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: - return KafkaBroker(apply_types=apply_types, **kwargs) - - def patch_broker(self, broker: KafkaBroker, **kwargs: Any) -> TestKafkaBroker: - return TestKafkaBroker(broker, **kwargs) - +class TestTestclient(ConfluentMemoryTestcaseConfig, BrokerTestclientTestcase): async def test_message_nack_seek( self, queue: str, diff --git a/tests/brokers/kafka/basic.py b/tests/brokers/kafka/basic.py new file mode 100644 index 0000000000..39c095a637 --- /dev/null +++ b/tests/brokers/kafka/basic.py @@ -0,0 +1,24 @@ +from typing import Any + +from faststream.kafka import KafkaBroker, KafkaRouter, TestKafkaBroker +from tests.brokers.base.basic import BaseTestcaseConfig + + +class KafkaTestcaseConfig(BaseTestcaseConfig): + def get_broker( + self, + apply_types: bool = False, + **kwargs: Any, + ) -> KafkaBroker: + return KafkaBroker(apply_types=apply_types, **kwargs) + + def patch_broker(self, broker: KafkaBroker, **kwargs: Any) -> KafkaBroker: + return broker + + def get_router(self, **kwargs: Any) -> KafkaRouter: + return KafkaRouter(**kwargs) + + +class KafkaMemoryTestcaseConfig(KafkaTestcaseConfig): + def patch_broker(self, broker: KafkaBroker, **kwargs: Any) -> KafkaBroker: + return TestKafkaBroker(broker, **kwargs) diff --git a/tests/brokers/kafka/test_consume.py b/tests/brokers/kafka/test_consume.py index f725f90371..29a96e2a36 100644 --- a/tests/brokers/kafka/test_consume.py +++ b/tests/brokers/kafka/test_consume.py @@ -1,5 +1,4 @@ import asyncio -from typing import Any from unittest.mock import patch import pytest @@ -7,17 +6,16 @@ from faststream import AckPolicy from faststream.exceptions import AckMessage -from faststream.kafka import KafkaBroker, TopicPartition +from faststream.kafka import TopicPartition from faststream.kafka.annotations import KafkaMessage from tests.brokers.base.consume import BrokerRealConsumeTestcase from tests.tools import spy_decorator +from .basic import KafkaTestcaseConfig -@pytest.mark.kafka() -class TestConsume(BrokerRealConsumeTestcase): - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: - return KafkaBroker(apply_types=apply_types, **kwargs) +@pytest.mark.kafka() +class TestConsume(KafkaTestcaseConfig, BrokerRealConsumeTestcase): @pytest.mark.asyncio() async def test_consume_by_pattern( self, diff --git a/tests/brokers/kafka/test_fastapi.py b/tests/brokers/kafka/test_fastapi.py index 899deaffce..3da7a8bf51 100644 --- a/tests/brokers/kafka/test_fastapi.py +++ b/tests/brokers/kafka/test_fastapi.py @@ -1,13 +1,14 @@ import asyncio -from typing import Any from unittest.mock import Mock import pytest -from faststream.kafka import KafkaBroker, KafkaRouter, TestKafkaBroker +from faststream.kafka import KafkaRouter from faststream.kafka.fastapi import KafkaRouter as StreamRouter from tests.brokers.base.fastapi import FastAPILocalTestcase, FastAPITestcase +from .basic import KafkaMemoryTestcaseConfig + @pytest.mark.kafka() class TestKafkaRouter(FastAPITestcase): @@ -42,13 +43,10 @@ async def hello(msg: list[str]): mock.assert_called_with(["hi"]) -class TestRouterLocal(FastAPILocalTestcase): +class TestRouterLocal(KafkaMemoryTestcaseConfig, FastAPILocalTestcase): router_class = StreamRouter broker_router_class = KafkaRouter - def patch_broker(self, broker: KafkaBroker, **kwargs: Any) -> TestKafkaBroker: - return TestKafkaBroker(broker, **kwargs) - async def test_batch_testclient( self, mock: Mock, diff --git a/tests/brokers/kafka/test_middlewares.py b/tests/brokers/kafka/test_middlewares.py index 3bde2314f0..58d5bf7d31 100644 --- a/tests/brokers/kafka/test_middlewares.py +++ b/tests/brokers/kafka/test_middlewares.py @@ -1,21 +1,23 @@ -from typing import Any - import pytest -from faststream.kafka import KafkaBroker from tests.brokers.base.middlewares import ( ExceptionMiddlewareTestcase, MiddlewareTestcase, + MiddlewaresOrderTestcase, ) +from .basic import KafkaMemoryTestcaseConfig, KafkaTestcaseConfig + + +class TestMiddlewaresOrder(KafkaMemoryTestcaseConfig, MiddlewaresOrderTestcase): + pass + @pytest.mark.kafka() -class TestMiddlewares(MiddlewareTestcase): - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: - return KafkaBroker(apply_types=apply_types, **kwargs) +class TestMiddlewares(KafkaTestcaseConfig, MiddlewareTestcase): + pass @pytest.mark.kafka() -class TestExceptionMiddlewares(ExceptionMiddlewareTestcase): - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: - return KafkaBroker(apply_types=apply_types, **kwargs) +class TestExceptionMiddlewares(KafkaTestcaseConfig, ExceptionMiddlewareTestcase): + pass diff --git a/tests/brokers/kafka/test_parser.py b/tests/brokers/kafka/test_parser.py index 0b91d82ff5..0e229bbd37 100644 --- a/tests/brokers/kafka/test_parser.py +++ b/tests/brokers/kafka/test_parser.py @@ -1,12 +1,10 @@ -from typing import Any - import pytest -from faststream.kafka import KafkaBroker from tests.brokers.base.parser import CustomParserTestcase +from .basic import KafkaTestcaseConfig + @pytest.mark.kafka() -class TestCustomParser(CustomParserTestcase): - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: - return KafkaBroker(apply_types=apply_types, **kwargs) +class TestCustomParser(KafkaTestcaseConfig, CustomParserTestcase): + pass diff --git a/tests/brokers/kafka/test_publish.py b/tests/brokers/kafka/test_publish.py index 80cb7b017b..bb884c450a 100644 --- a/tests/brokers/kafka/test_publish.py +++ b/tests/brokers/kafka/test_publish.py @@ -1,19 +1,17 @@ import asyncio -from typing import Any from unittest.mock import Mock import pytest from faststream import Context -from faststream.kafka import KafkaBroker, KafkaResponse +from faststream.kafka import KafkaResponse from tests.brokers.base.publish import BrokerPublishTestcase +from .basic import KafkaTestcaseConfig -@pytest.mark.kafka() -class TestPublish(BrokerPublishTestcase): - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: - return KafkaBroker(apply_types=apply_types, **kwargs) +@pytest.mark.kafka() +class TestPublish(KafkaTestcaseConfig, BrokerPublishTestcase): @pytest.mark.asyncio() async def test_publish_batch(self, queue: str) -> None: pub_broker = self.get_broker() diff --git a/tests/brokers/kafka/test_requests.py b/tests/brokers/kafka/test_requests.py index f84ba2a5db..c3d7a4cb4d 100644 --- a/tests/brokers/kafka/test_requests.py +++ b/tests/brokers/kafka/test_requests.py @@ -3,9 +3,10 @@ import pytest from faststream import BaseMiddleware -from faststream.kafka import KafkaBroker, KafkaRouter, TestKafkaBroker from tests.brokers.base.requests import RequestsTestcase +from .basic import KafkaMemoryTestcaseConfig + class Mid(BaseMiddleware): async def on_receive(self) -> None: @@ -17,15 +18,6 @@ async def consume_scope(self, call_next, msg): @pytest.mark.asyncio() -class TestRequestTestClient(RequestsTestcase): +class TestRequestTestClient(KafkaMemoryTestcaseConfig, RequestsTestcase): def get_middleware(self, **kwargs: Any): return Mid - - def get_router(self, **kwargs: Any): - return KafkaRouter(**kwargs) - - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: - return KafkaBroker(apply_types=apply_types, **kwargs) - - def patch_broker(self, broker: KafkaBroker, **kwargs: Any) -> TestKafkaBroker: - return TestKafkaBroker(broker, **kwargs) diff --git a/tests/brokers/kafka/test_router.py b/tests/brokers/kafka/test_router.py index 8460b6cc56..e9b27f5a01 100644 --- a/tests/brokers/kafka/test_router.py +++ b/tests/brokers/kafka/test_router.py @@ -1,34 +1,20 @@ -from typing import Any - import pytest from faststream.kafka import ( - KafkaBroker, KafkaPublisher, KafkaRoute, - KafkaRouter, - TestKafkaBroker, ) from tests.brokers.base.router import RouterLocalTestcase, RouterTestcase +from .basic import KafkaMemoryTestcaseConfig, KafkaTestcaseConfig + @pytest.mark.kafka() -class TestRouter(RouterTestcase): - broker_class = KafkaRouter +class TestRouter(KafkaTestcaseConfig, RouterTestcase): route_class = KafkaRoute publisher_class = KafkaPublisher - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: - return KafkaBroker(apply_types=apply_types, **kwargs) - -class TestRouterLocal(RouterLocalTestcase): - broker_class = KafkaRouter +class TestRouterLocal(KafkaMemoryTestcaseConfig, RouterLocalTestcase): route_class = KafkaRoute publisher_class = KafkaPublisher - - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: - return KafkaBroker(apply_types=apply_types, **kwargs) - - def patch_broker(self, broker: KafkaBroker, **kwargs: Any) -> TestKafkaBroker: - return TestKafkaBroker(broker, **kwargs) diff --git a/tests/brokers/kafka/test_test_client.py b/tests/brokers/kafka/test_test_client.py index b490604453..5abcdbcf3b 100644 --- a/tests/brokers/kafka/test_test_client.py +++ b/tests/brokers/kafka/test_test_client.py @@ -1,26 +1,21 @@ import asyncio -from typing import Any from unittest.mock import patch import pytest from faststream import BaseMiddleware -from faststream.kafka import KafkaBroker, TestKafkaBroker, TopicPartition +from faststream.kafka import TopicPartition from faststream.kafka.annotations import KafkaMessage from faststream.kafka.message import FAKE_CONSUMER from faststream.kafka.testing import FakeProducer from tests.brokers.base.testclient import BrokerTestclientTestcase from tests.tools import spy_decorator +from .basic import KafkaMemoryTestcaseConfig -@pytest.mark.asyncio() -class TestTestclient(BrokerTestclientTestcase): - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> KafkaBroker: - return KafkaBroker(apply_types=apply_types, **kwargs) - - def patch_broker(self, broker: KafkaBroker, **kwargs: Any) -> TestKafkaBroker: - return TestKafkaBroker(broker, **kwargs) +@pytest.mark.asyncio() +class TestTestclient(KafkaMemoryTestcaseConfig, BrokerTestclientTestcase): async def test_partition_match( self, queue: str, diff --git a/tests/brokers/nats/basic.py b/tests/brokers/nats/basic.py new file mode 100644 index 0000000000..bc73b67da6 --- /dev/null +++ b/tests/brokers/nats/basic.py @@ -0,0 +1,24 @@ +from typing import Any + +from faststream.nats import NatsBroker, NatsRouter, TestNatsBroker +from tests.brokers.base.basic import BaseTestcaseConfig + + +class NatsTestcaseConfig(BaseTestcaseConfig): + def get_broker( + self, + apply_types: bool = False, + **kwargs: Any, + ) -> NatsBroker: + return NatsBroker(apply_types=apply_types, **kwargs) + + def patch_broker(self, broker: NatsBroker, **kwargs: Any) -> NatsBroker: + return broker + + def get_router(self, **kwargs: Any) -> NatsRouter: + return NatsRouter(**kwargs) + + +class NatsMemoryTestcaseConfig(NatsTestcaseConfig): + def patch_broker(self, broker: NatsBroker, **kwargs: Any) -> NatsBroker: + return TestNatsBroker(broker, **kwargs) diff --git a/tests/brokers/nats/test_consume.py b/tests/brokers/nats/test_consume.py index b31f927d27..feab15055f 100644 --- a/tests/brokers/nats/test_consume.py +++ b/tests/brokers/nats/test_consume.py @@ -1,24 +1,22 @@ import asyncio -from typing import Any from unittest.mock import MagicMock, patch import pytest from nats.aio.msg import Msg -from nats.js.api import PubAck from faststream import AckPolicy from faststream.exceptions import AckMessage -from faststream.nats import ConsumerConfig, JStream, NatsBroker, PullSub +from faststream.nats import ConsumerConfig, JStream, PubAck, PullSub from faststream.nats.annotations import NatsMessage +from faststream.nats.message import NatsMessage as StreamMessage from tests.brokers.base.consume import BrokerRealConsumeTestcase from tests.tools import spy_decorator +from .basic import NatsTestcaseConfig -@pytest.mark.nats() -class TestConsume(BrokerRealConsumeTestcase): - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> NatsBroker: - return NatsBroker(apply_types=apply_types, **kwargs) +@pytest.mark.nats() +class TestConsume(NatsTestcaseConfig, BrokerRealConsumeTestcase): async def test_concurrent_subscriber( self, queue: str, @@ -190,23 +188,29 @@ def subscriber(m) -> None: assert event.is_set() mock.assert_called_once_with([b"hello"]) - async def test_consume_ack( + async def test_core_consume_no_ack( self, queue: str, - stream: JStream, + mock: MagicMock, ) -> None: event = asyncio.Event() consume_broker = self.get_broker(apply_types=True) - @consume_broker.subscriber(queue, stream=stream) + args, kwargs = self.get_subscriber_params(queue) + + @consume_broker.subscriber(*args, **kwargs) async def handler(msg: NatsMessage) -> None: + mock(msg.raw_message._ackd) event.set() async with self.patch_broker(consume_broker) as br: await br.start() - with patch.object(Msg, "ack", spy_decorator(Msg.ack)) as m: + # Check, that Core Subscriber doesn't call Acknowledgement automatically + with patch.object( + StreamMessage, "ack", spy_decorator(StreamMessage.ack) + ) as m: await asyncio.wait( ( asyncio.create_task(br.publish("hello", queue)), @@ -214,19 +218,21 @@ async def handler(msg: NatsMessage) -> None: ), timeout=3, ) - m.mock.assert_called_once() + assert not m.mock.called assert event.is_set() + mock.assert_called_once_with(False) - async def test_core_consume_no_ack( + async def test_consume_ack( self, queue: str, + stream: JStream, ) -> None: event = asyncio.Event() consume_broker = self.get_broker(apply_types=True) - @consume_broker.subscriber(queue) + @consume_broker.subscriber(queue, stream=stream) async def handler(msg: NatsMessage) -> None: event.set() @@ -241,7 +247,7 @@ async def handler(msg: NatsMessage) -> None: ), timeout=3, ) - assert not m.mock.called + m.mock.assert_called_once() assert event.is_set() diff --git a/tests/brokers/nats/test_fastapi.py b/tests/brokers/nats/test_fastapi.py index bbcdac2113..15fbe319f7 100644 --- a/tests/brokers/nats/test_fastapi.py +++ b/tests/brokers/nats/test_fastapi.py @@ -1,16 +1,17 @@ import asyncio -from typing import Any from unittest.mock import MagicMock import pytest -from faststream.nats import JStream, NatsBroker, NatsRouter, PullSub, TestNatsBroker +from faststream.nats import JStream, NatsRouter, PullSub from faststream.nats.fastapi import NatsRouter as StreamRouter from tests.brokers.base.fastapi import FastAPILocalTestcase, FastAPITestcase +from .basic import NatsMemoryTestcaseConfig, NatsTestcaseConfig + @pytest.mark.nats() -class TestRouter(FastAPITestcase): +class TestRouter(NatsTestcaseConfig, FastAPITestcase): router_class = StreamRouter broker_router_class = NatsRouter @@ -76,13 +77,10 @@ def subscriber(m: list[str]) -> None: mock.assert_called_once_with(["hello"]) -class TestRouterLocal(FastAPILocalTestcase): +class TestRouterLocal(NatsMemoryTestcaseConfig, FastAPILocalTestcase): router_class = StreamRouter broker_router_class = NatsRouter - def patch_broker(self, broker: NatsBroker, **kwargs: Any) -> NatsBroker: - return TestNatsBroker(broker, **kwargs) - async def test_consume_batch( self, queue: str, diff --git a/tests/brokers/nats/test_middlewares.py b/tests/brokers/nats/test_middlewares.py index d646418eba..c726d7e231 100644 --- a/tests/brokers/nats/test_middlewares.py +++ b/tests/brokers/nats/test_middlewares.py @@ -1,21 +1,23 @@ -from typing import Any - import pytest -from faststream.nats import NatsBroker from tests.brokers.base.middlewares import ( ExceptionMiddlewareTestcase, MiddlewareTestcase, + MiddlewaresOrderTestcase, ) +from .basic import NatsMemoryTestcaseConfig, NatsTestcaseConfig + + +class TestMiddlewaresOrder(NatsMemoryTestcaseConfig, MiddlewaresOrderTestcase): + pass + @pytest.mark.nats() -class TestMiddlewares(MiddlewareTestcase): - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> NatsBroker: - return NatsBroker(apply_types=apply_types, **kwargs) +class TestMiddlewares(NatsTestcaseConfig, MiddlewareTestcase): + pass @pytest.mark.nats() -class TestExceptionMiddlewares(ExceptionMiddlewareTestcase): - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> NatsBroker: - return NatsBroker(apply_types=apply_types, **kwargs) +class TestExceptionMiddlewares(NatsTestcaseConfig, ExceptionMiddlewareTestcase): + pass diff --git a/tests/brokers/nats/test_parser.py b/tests/brokers/nats/test_parser.py index 82caa39d3f..635cbccb65 100644 --- a/tests/brokers/nats/test_parser.py +++ b/tests/brokers/nats/test_parser.py @@ -1,12 +1,10 @@ -from typing import Any - import pytest -from faststream.nats import NatsBroker from tests.brokers.base.parser import CustomParserTestcase +from .basic import NatsTestcaseConfig + @pytest.mark.nats() -class TestCustomParser(CustomParserTestcase): - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> NatsBroker: - return NatsBroker(apply_types=apply_types, **kwargs) +class TestCustomParser(NatsTestcaseConfig, CustomParserTestcase): + pass diff --git a/tests/brokers/nats/test_publish.py b/tests/brokers/nats/test_publish.py index c7367ac389..cee41ef6a4 100644 --- a/tests/brokers/nats/test_publish.py +++ b/tests/brokers/nats/test_publish.py @@ -4,17 +4,16 @@ import pytest from faststream import Context -from faststream.nats import NatsBroker, NatsResponse +from faststream.nats import NatsResponse from tests.brokers.base.publish import BrokerPublishTestcase +from .basic import NatsTestcaseConfig + @pytest.mark.nats() -class TestPublish(BrokerPublishTestcase): +class TestPublish(NatsTestcaseConfig, BrokerPublishTestcase): """Test publish method of NATS broker.""" - def get_broker(self, apply_types: bool = False, **kwargs) -> NatsBroker: - return NatsBroker(apply_types=apply_types, **kwargs) - @pytest.mark.asyncio() async def test_response( self, diff --git a/tests/brokers/nats/test_requests.py b/tests/brokers/nats/test_requests.py index 579f13113d..f440a83c6d 100644 --- a/tests/brokers/nats/test_requests.py +++ b/tests/brokers/nats/test_requests.py @@ -1,11 +1,10 @@ -from typing import Any - import pytest from faststream import BaseMiddleware -from faststream.nats import NatsBroker, NatsRouter, TestNatsBroker from tests.brokers.base.requests import RequestsTestcase +from .basic import NatsMemoryTestcaseConfig, NatsTestcaseConfig + class Mid(BaseMiddleware): async def on_receive(self) -> None: @@ -21,12 +20,6 @@ class NatsRequestsTestcase(RequestsTestcase): def get_middleware(self, **kwargs): return Mid - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> NatsBroker: - return NatsBroker(apply_types=apply_types, **kwargs) - - def get_router(self, **kwargs): - return NatsRouter(**kwargs) - async def test_broker_stream_request(self, queue: str) -> None: broker = self.get_broker() @@ -78,10 +71,9 @@ async def handler(msg) -> str: @pytest.mark.nats() -class TestRealRequests(NatsRequestsTestcase): +class TestRealRequests(NatsTestcaseConfig, NatsRequestsTestcase): pass -class TestRequestTestClient(NatsRequestsTestcase): - def patch_broker(self, broker, **kwargs): - return TestNatsBroker(broker, **kwargs) +class TestRequestTestClient(NatsMemoryTestcaseConfig, NatsRequestsTestcase): + pass diff --git a/tests/brokers/nats/test_router.py b/tests/brokers/nats/test_router.py index 8af70bcfa0..4bd846abd0 100644 --- a/tests/brokers/nats/test_router.py +++ b/tests/brokers/nats/test_router.py @@ -1,29 +1,24 @@ import asyncio -from typing import Any import pytest from faststream import Path from faststream.nats import ( JStream, - NatsBroker, NatsPublisher, NatsRoute, NatsRouter, - TestNatsBroker, ) from tests.brokers.base.router import RouterLocalTestcase, RouterTestcase +from .basic import NatsMemoryTestcaseConfig, NatsTestcaseConfig + @pytest.mark.nats() -class TestRouter(RouterTestcase): - broker_class = NatsRouter +class TestRouter(NatsTestcaseConfig, RouterTestcase): route_class = NatsRoute publisher_class = NatsPublisher - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> NatsBroker: - return NatsBroker(apply_types=apply_types, **kwargs) - async def test_router_path( self, event, @@ -158,16 +153,10 @@ def response(m) -> None: assert event.is_set() -class TestRouterLocal(RouterLocalTestcase): +class TestRouterLocal(NatsMemoryTestcaseConfig, RouterLocalTestcase): route_class = NatsRoute publisher_class = NatsPublisher - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> NatsBroker: - return NatsBroker(apply_types=apply_types, **kwargs) - - def patch_broker(self, broker: NatsBroker, **kwargs: Any) -> NatsBroker: - return TestNatsBroker(broker, **kwargs) - async def test_include_stream( self, router: NatsRouter, diff --git a/tests/brokers/nats/test_test_client.py b/tests/brokers/nats/test_test_client.py index 7ca172e6ce..1c008ed9b2 100644 --- a/tests/brokers/nats/test_test_client.py +++ b/tests/brokers/nats/test_test_client.py @@ -1,5 +1,4 @@ import asyncio -from typing import Any import pytest @@ -7,22 +6,16 @@ from faststream.nats import ( ConsumerConfig, JStream, - NatsBroker, PullSub, - TestNatsBroker, ) from faststream.nats.testing import FakeProducer from tests.brokers.base.testclient import BrokerTestclientTestcase +from .basic import NatsMemoryTestcaseConfig -@pytest.mark.asyncio() -class TestTestclient(BrokerTestclientTestcase): - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> NatsBroker: - return NatsBroker(apply_types=apply_types, **kwargs) - - def patch_broker(self, broker: NatsBroker, **kwargs: Any) -> NatsBroker: - return TestNatsBroker(broker, **kwargs) +@pytest.mark.asyncio() +class TestTestclient(NatsMemoryTestcaseConfig, BrokerTestclientTestcase): @pytest.mark.asyncio() async def test_stream_publish( self, diff --git a/tests/brokers/rabbit/basic.py b/tests/brokers/rabbit/basic.py new file mode 100644 index 0000000000..6a451530c5 --- /dev/null +++ b/tests/brokers/rabbit/basic.py @@ -0,0 +1,24 @@ +from typing import Any + +from faststream.rabbit import RabbitBroker, RabbitRouter, TestRabbitBroker +from tests.brokers.base.basic import BaseTestcaseConfig + + +class RabbitTestcaseConfig(BaseTestcaseConfig): + def get_broker( + self, + apply_types: bool = False, + **kwargs: Any, + ) -> RabbitBroker: + return RabbitBroker(apply_types=apply_types, **kwargs) + + def patch_broker(self, broker: RabbitBroker, **kwargs: Any) -> RabbitBroker: + return broker + + def get_router(self, **kwargs: Any) -> RabbitRouter: + return RabbitRouter(**kwargs) + + +class RabbitMemoryTestcaseConfig(RabbitTestcaseConfig): + def patch_broker(self, broker: RabbitBroker, **kwargs: Any) -> RabbitBroker: + return TestRabbitBroker(broker, **kwargs) diff --git a/tests/brokers/rabbit/test_consume.py b/tests/brokers/rabbit/test_consume.py index 19317948fa..45b0ad0026 100644 --- a/tests/brokers/rabbit/test_consume.py +++ b/tests/brokers/rabbit/test_consume.py @@ -1,5 +1,4 @@ import asyncio -from typing import Any from unittest.mock import patch import pytest @@ -7,17 +6,16 @@ from faststream import AckPolicy from faststream.exceptions import AckMessage, NackMessage, RejectMessage, SkipMessage -from faststream.rabbit import RabbitBroker, RabbitExchange, RabbitQueue +from faststream.rabbit import RabbitExchange, RabbitQueue from faststream.rabbit.annotations import RabbitMessage from tests.brokers.base.consume import BrokerRealConsumeTestcase from tests.tools import spy_decorator +from .basic import RabbitTestcaseConfig -@pytest.mark.rabbit() -class TestConsume(BrokerRealConsumeTestcase): - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RabbitBroker: - return RabbitBroker(apply_types=apply_types, **kwargs) +@pytest.mark.rabbit() +class TestConsume(RabbitTestcaseConfig, BrokerRealConsumeTestcase): @pytest.mark.asyncio() async def test_consume_from_exchange( self, @@ -398,7 +396,9 @@ async def test_consume_no_ack( consume_broker = self.get_broker(apply_types=True) @consume_broker.subscriber( - queue, exchange=exchange, ack_policy=AckPolicy.DO_NOTHING + queue, + exchange=exchange, + ack_policy=AckPolicy.DO_NOTHING, ) async def handler(msg: RabbitMessage) -> None: event.set() diff --git a/tests/brokers/rabbit/test_fastapi.py b/tests/brokers/rabbit/test_fastapi.py index 3bd99eae62..6ffa26392a 100644 --- a/tests/brokers/rabbit/test_fastapi.py +++ b/tests/brokers/rabbit/test_fastapi.py @@ -5,9 +5,10 @@ from faststream.rabbit import ExchangeType, RabbitExchange, RabbitQueue, RabbitRouter from faststream.rabbit.fastapi import RabbitRouter as StreamRouter -from faststream.rabbit.testing import TestRabbitBroker from tests.brokers.base.fastapi import FastAPILocalTestcase, FastAPITestcase +from .basic import RabbitMemoryTestcaseConfig + @pytest.mark.rabbit() class TestRouter(FastAPITestcase): @@ -55,13 +56,10 @@ def subscriber(msg: str, name: str) -> None: @pytest.mark.asyncio() -class TestRouterLocal(FastAPILocalTestcase): +class TestRouterLocal(RabbitMemoryTestcaseConfig, FastAPILocalTestcase): router_class = StreamRouter broker_router_class = RabbitRouter - def patch_broker(self, broker, **kwargs): - return TestRabbitBroker(broker, **kwargs) - async def test_path(self) -> None: router = self.router_class() diff --git a/tests/brokers/rabbit/test_middlewares.py b/tests/brokers/rabbit/test_middlewares.py index 9f21be5f8b..f56c836e8d 100644 --- a/tests/brokers/rabbit/test_middlewares.py +++ b/tests/brokers/rabbit/test_middlewares.py @@ -1,21 +1,23 @@ -from typing import Any - import pytest -from faststream.rabbit import RabbitBroker from tests.brokers.base.middlewares import ( ExceptionMiddlewareTestcase, MiddlewareTestcase, + MiddlewaresOrderTestcase, ) +from .basic import RabbitMemoryTestcaseConfig, RabbitTestcaseConfig + + +class TestMiddlewaresOrder(RabbitMemoryTestcaseConfig, MiddlewaresOrderTestcase): + pass + @pytest.mark.rabbit() -class TestMiddlewares(MiddlewareTestcase): - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RabbitBroker: - return RabbitBroker(apply_types=apply_types, **kwargs) +class TestMiddlewares(RabbitTestcaseConfig, MiddlewareTestcase): + pass @pytest.mark.rabbit() -class TestExceptionMiddlewares(ExceptionMiddlewareTestcase): - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RabbitBroker: - return RabbitBroker(apply_types=apply_types, **kwargs) +class TestExceptionMiddlewares(RabbitTestcaseConfig, ExceptionMiddlewareTestcase): + pass diff --git a/tests/brokers/rabbit/test_parser.py b/tests/brokers/rabbit/test_parser.py index db5b52aef1..2ecaf2967c 100644 --- a/tests/brokers/rabbit/test_parser.py +++ b/tests/brokers/rabbit/test_parser.py @@ -1,12 +1,10 @@ -from typing import Any - import pytest -from faststream.rabbit import RabbitBroker from tests.brokers.base.parser import CustomParserTestcase +from .basic import RabbitTestcaseConfig + @pytest.mark.rabbit() -class TestCustomParser(CustomParserTestcase): - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RabbitBroker: - return RabbitBroker(apply_types=apply_types, **kwargs) +class TestCustomParser(RabbitTestcaseConfig, CustomParserTestcase): + pass diff --git a/tests/brokers/rabbit/test_publish.py b/tests/brokers/rabbit/test_publish.py index f5000d9104..a8aa2508f1 100644 --- a/tests/brokers/rabbit/test_publish.py +++ b/tests/brokers/rabbit/test_publish.py @@ -1,24 +1,23 @@ import asyncio -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING from unittest.mock import Mock, patch import pytest from faststream import Context -from faststream.rabbit import RabbitBroker, RabbitResponse +from faststream.rabbit import RabbitResponse from faststream.rabbit.publisher.producer import AioPikaFastProducer from tests.brokers.base.publish import BrokerPublishTestcase from tests.tools import spy_decorator +from .basic import RabbitTestcaseConfig + if TYPE_CHECKING: from faststream.rabbit.response import RabbitPublishCommand @pytest.mark.rabbit() -class TestPublish(BrokerPublishTestcase): - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RabbitBroker: - return RabbitBroker(apply_types=apply_types, **kwargs) - +class TestPublish(RabbitTestcaseConfig, BrokerPublishTestcase): @pytest.mark.asyncio() async def test_reply_config( self, diff --git a/tests/brokers/rabbit/test_requests.py b/tests/brokers/rabbit/test_requests.py index fd5fb93ebf..8eb64a075a 100644 --- a/tests/brokers/rabbit/test_requests.py +++ b/tests/brokers/rabbit/test_requests.py @@ -1,11 +1,10 @@ -from typing import Any - import pytest from faststream import BaseMiddleware -from faststream.rabbit import RabbitBroker, RabbitRouter, TestRabbitBroker from tests.brokers.base.requests import RequestsTestcase +from .basic import RabbitMemoryTestcaseConfig, RabbitTestcaseConfig + class Mid(BaseMiddleware): async def on_receive(self) -> None: @@ -22,19 +21,12 @@ class RabbitRequestsTestcase(RequestsTestcase): def get_middleware(self, **kwargs): return Mid - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RabbitBroker: - return RabbitBroker(apply_types=apply_types, **kwargs) - - def get_router(self, **kwargs): - return RabbitRouter(**kwargs) - @pytest.mark.rabbit() -class TestRealRequests(RabbitRequestsTestcase): +class TestRealRequests(RabbitTestcaseConfig, RabbitRequestsTestcase): pass @pytest.mark.asyncio() -class TestRequestTestClient(RabbitRequestsTestcase): - def patch_broker(self, broker, **kwargs): - return TestRabbitBroker(broker, **kwargs) +class TestRequestTestClient(RabbitMemoryTestcaseConfig, RabbitRequestsTestcase): + pass diff --git a/tests/brokers/rabbit/test_router.py b/tests/brokers/rabbit/test_router.py index 0fb2b8babf..fba7752300 100644 --- a/tests/brokers/rabbit/test_router.py +++ b/tests/brokers/rabbit/test_router.py @@ -1,31 +1,26 @@ import asyncio -from typing import Any import pytest from faststream import Path from faststream.rabbit import ( ExchangeType, - RabbitBroker, RabbitExchange, RabbitPublisher, RabbitQueue, RabbitRoute, RabbitRouter, - TestRabbitBroker, ) from tests.brokers.base.router import RouterLocalTestcase, RouterTestcase +from .basic import RabbitMemoryTestcaseConfig, RabbitTestcaseConfig + @pytest.mark.rabbit() -class TestRouter(RouterTestcase): - broker_class = RabbitRouter +class TestRouter(RabbitTestcaseConfig, RouterTestcase): route_class = RabbitRoute publisher_class = RabbitPublisher - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RabbitBroker: - return RabbitBroker(apply_types=apply_types, **kwargs) - async def test_router_path( self, queue, @@ -213,13 +208,6 @@ def response(m) -> None: assert event.is_set() -class TestRouterLocal(RouterLocalTestcase): - broker_class = RabbitRouter +class TestRouterLocal(RabbitMemoryTestcaseConfig, RouterLocalTestcase): route_class = RabbitRoute publisher_class = RabbitPublisher - - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RabbitBroker: - return RabbitBroker(apply_types=apply_types, **kwargs) - - def patch_broker(self, broker: RabbitBroker, **kwargs: Any) -> RabbitBroker: - return TestRabbitBroker(broker, **kwargs) diff --git a/tests/brokers/rabbit/test_schemas.py b/tests/brokers/rabbit/test_schemas.py index ce686c6d69..2224fb976a 100644 --- a/tests/brokers/rabbit/test_schemas.py +++ b/tests/brokers/rabbit/test_schemas.py @@ -3,23 +3,19 @@ def test_same_queue() -> None: assert ( - len( - { - RabbitQueue("test"): 0, - RabbitQueue("test"): 1, - }, - ) + len({ + RabbitQueue("test"): 0, + RabbitQueue("test"): 1, + }) == 1 ) def test_different_queue_routing_key() -> None: assert ( - len( - { - RabbitQueue("test", routing_key="binding-1"): 0, - RabbitQueue("test", routing_key="binding-2"): 1, - }, - ) + len({ + RabbitQueue("test", routing_key="binding-1"): 0, + RabbitQueue("test", routing_key="binding-2"): 1, + }) == 1 ) diff --git a/tests/brokers/rabbit/test_test_client.py b/tests/brokers/rabbit/test_test_client.py index 0784da9bf3..0ddaf24b58 100644 --- a/tests/brokers/rabbit/test_test_client.py +++ b/tests/brokers/rabbit/test_test_client.py @@ -1,5 +1,4 @@ import asyncio -from typing import Any import pytest @@ -7,26 +6,18 @@ from faststream.exceptions import SubscriberNotFound from faststream.rabbit import ( ExchangeType, - RabbitBroker, RabbitExchange, RabbitQueue, - TestRabbitBroker, ) from faststream.rabbit.annotations import RabbitMessage from faststream.rabbit.testing import FakeProducer, apply_pattern from tests.brokers.base.testclient import BrokerTestclientTestcase +from .basic import RabbitMemoryTestcaseConfig -@pytest.mark.asyncio() -class TestTestclient(BrokerTestclientTestcase): - test_class = TestRabbitBroker - - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RabbitBroker: - return RabbitBroker(apply_types=apply_types, **kwargs) - - def patch_broker(self, broker: RabbitBroker, **kwargs: Any) -> RabbitBroker: - return TestRabbitBroker(broker, **kwargs) +@pytest.mark.asyncio() +class TestTestclient(RabbitMemoryTestcaseConfig, BrokerTestclientTestcase): @pytest.mark.rabbit() async def test_with_real_testclient( self, diff --git a/tests/brokers/redis/basic.py b/tests/brokers/redis/basic.py new file mode 100644 index 0000000000..11f424017c --- /dev/null +++ b/tests/brokers/redis/basic.py @@ -0,0 +1,24 @@ +from typing import Any + +from faststream.redis import RedisBroker, RedisRouter, TestRedisBroker +from tests.brokers.base.basic import BaseTestcaseConfig + + +class RedisTestcaseConfig(BaseTestcaseConfig): + def get_broker( + self, + apply_types: bool = False, + **kwargs: Any, + ) -> RedisBroker: + return RedisBroker(apply_types=apply_types, **kwargs) + + def patch_broker(self, broker: RedisBroker, **kwargs: Any) -> RedisBroker: + return broker + + def get_router(self, **kwargs: Any) -> RedisRouter: + return RedisRouter(**kwargs) + + +class RedisMemoryTestcaseConfig(RedisTestcaseConfig): + def patch_broker(self, broker: RedisBroker, **kwargs: Any) -> RedisBroker: + return TestRedisBroker(broker, **kwargs) diff --git a/tests/brokers/redis/test_consume.py b/tests/brokers/redis/test_consume.py index 7c7a1e4152..9aa3b7590b 100644 --- a/tests/brokers/redis/test_consume.py +++ b/tests/brokers/redis/test_consume.py @@ -1,21 +1,19 @@ import asyncio -from typing import Any from unittest.mock import MagicMock, patch import pytest from redis.asyncio import Redis -from faststream.redis import ListSub, PubSub, RedisBroker, RedisMessage, StreamSub +from faststream.redis import ListSub, PubSub, RedisMessage, StreamSub from tests.brokers.base.consume import BrokerRealConsumeTestcase from tests.tools import spy_decorator +from .basic import RedisTestcaseConfig + @pytest.mark.redis() @pytest.mark.asyncio() -class TestConsume(BrokerRealConsumeTestcase): - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RedisBroker: - return RedisBroker(apply_types=apply_types, **kwargs) - +class TestConsume(RedisTestcaseConfig, BrokerRealConsumeTestcase): async def test_consume_native( self, mock: MagicMock, @@ -98,13 +96,7 @@ async def handler(msg) -> None: @pytest.mark.redis() @pytest.mark.asyncio() -class TestConsumeList: - def get_broker(self, apply_types: bool = False): - return RedisBroker(apply_types=apply_types) - - def patch_broker(self, broker): - return broker - +class TestConsumeList(RedisTestcaseConfig): async def test_consume_list( self, queue: str, @@ -365,13 +357,7 @@ async def test_get_one_timeout( @pytest.mark.redis() @pytest.mark.asyncio() -class TestConsumeStream: - def get_broker(self, apply_types: bool = False): - return RedisBroker(apply_types=apply_types) - - def patch_broker(self, broker): - return broker - +class TestConsumeStream(RedisTestcaseConfig): @pytest.mark.slow() async def test_consume_stream( self, diff --git a/tests/brokers/redis/test_fastapi.py b/tests/brokers/redis/test_fastapi.py index 9c66a73230..31c1ff0f70 100644 --- a/tests/brokers/redis/test_fastapi.py +++ b/tests/brokers/redis/test_fastapi.py @@ -1,14 +1,14 @@ import asyncio -from typing import Any from unittest.mock import Mock import pytest -from faststream.redis import ListSub, RedisBroker, RedisRouter, StreamSub +from faststream.redis import ListSub, RedisRouter, StreamSub from faststream.redis.fastapi import RedisRouter as StreamRouter -from faststream.redis.testing import TestRedisBroker from tests.brokers.base.fastapi import FastAPILocalTestcase, FastAPITestcase +from .basic import RedisMemoryTestcaseConfig + @pytest.mark.redis() class TestRouter(FastAPITestcase): @@ -140,13 +140,10 @@ async def handler(msg: list[str]) -> None: mock.assert_called_once_with(["hello"]) -class TestRouterLocal(FastAPILocalTestcase): +class TestRouterLocal(RedisMemoryTestcaseConfig, FastAPILocalTestcase): router_class = StreamRouter broker_router_class = RedisRouter - def patch_broker(self, broker: RedisBroker, **kwargs: Any) -> RedisBroker: - return TestRedisBroker(broker, **kwargs) - async def test_batch_testclient( self, mock: Mock, diff --git a/tests/brokers/redis/test_middlewares.py b/tests/brokers/redis/test_middlewares.py index 8dd6cdee7e..c75e0914cd 100644 --- a/tests/brokers/redis/test_middlewares.py +++ b/tests/brokers/redis/test_middlewares.py @@ -1,21 +1,23 @@ -from typing import Any - import pytest -from faststream.redis import RedisBroker from tests.brokers.base.middlewares import ( ExceptionMiddlewareTestcase, MiddlewareTestcase, + MiddlewaresOrderTestcase, ) +from .basic import RedisMemoryTestcaseConfig, RedisTestcaseConfig + + +class TestMiddlewaresOrder(RedisMemoryTestcaseConfig, MiddlewaresOrderTestcase): + pass + @pytest.mark.redis() -class TestMiddlewares(MiddlewareTestcase): - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RedisBroker: - return RedisBroker(apply_types=apply_types, **kwargs) +class TestMiddlewares(RedisTestcaseConfig, MiddlewareTestcase): + pass @pytest.mark.redis() -class TestExceptionMiddlewares(ExceptionMiddlewareTestcase): - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RedisBroker: - return RedisBroker(apply_types=apply_types, **kwargs) +class TestExceptionMiddlewares(RedisTestcaseConfig, ExceptionMiddlewareTestcase): + pass diff --git a/tests/brokers/redis/test_parser.py b/tests/brokers/redis/test_parser.py index 8e9093bc04..cf16275b65 100644 --- a/tests/brokers/redis/test_parser.py +++ b/tests/brokers/redis/test_parser.py @@ -1,12 +1,10 @@ -from typing import Any - import pytest -from faststream.redis import RedisBroker from tests.brokers.base.parser import CustomParserTestcase +from .basic import RedisTestcaseConfig + @pytest.mark.redis() -class TestCustomParser(CustomParserTestcase): - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RedisBroker: - return RedisBroker(apply_types=apply_types, **kwargs) +class TestCustomParser(RedisTestcaseConfig, CustomParserTestcase): + pass diff --git a/tests/brokers/redis/test_publish.py b/tests/brokers/redis/test_publish.py index 8967aa0778..ba4d445d78 100644 --- a/tests/brokers/redis/test_publish.py +++ b/tests/brokers/redis/test_publish.py @@ -1,22 +1,20 @@ import asyncio -from typing import Any from unittest.mock import MagicMock, patch import pytest from redis.asyncio import Redis from faststream import Context -from faststream.redis import ListSub, RedisBroker, RedisResponse, StreamSub +from faststream.redis import ListSub, RedisResponse, StreamSub from tests.brokers.base.publish import BrokerPublishTestcase from tests.tools import spy_decorator +from .basic import RedisTestcaseConfig + @pytest.mark.redis() @pytest.mark.asyncio() -class TestPublish(BrokerPublishTestcase): - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RedisBroker: - return RedisBroker(apply_types=apply_types, **kwargs) - +class TestPublish(RedisTestcaseConfig, BrokerPublishTestcase): async def test_list_publisher( self, queue: str, diff --git a/tests/brokers/redis/test_requests.py b/tests/brokers/redis/test_requests.py index f1d4fc3c0f..03c1441fa7 100644 --- a/tests/brokers/redis/test_requests.py +++ b/tests/brokers/redis/test_requests.py @@ -3,9 +3,10 @@ import pytest from faststream import BaseMiddleware -from faststream.redis import RedisBroker, RedisRouter, TestRedisBroker from tests.brokers.base.requests import RequestsTestcase +from .basic import RedisMemoryTestcaseConfig, RedisTestcaseConfig + class Mid(BaseMiddleware): async def on_receive(self) -> None: @@ -23,18 +24,11 @@ class RedisRequestsTestcase(RequestsTestcase): def get_middleware(self, **kwargs): return Mid - def get_broker(self, **kwargs): - return RedisBroker(**kwargs) - - def get_router(self, **kwargs): - return RedisRouter(**kwargs) - @pytest.mark.redis() -class TestRealRequests(RedisRequestsTestcase): +class TestRealRequests(RedisTestcaseConfig, RedisRequestsTestcase): pass -class TestRequestTestClient(RedisRequestsTestcase): - def patch_broker(self, broker, **kwargs): - return TestRedisBroker(broker, **kwargs) +class TestRequestTestClient(RedisMemoryTestcaseConfig, RedisRequestsTestcase): + pass diff --git a/tests/brokers/redis/test_router.py b/tests/brokers/redis/test_router.py index ef53e47a37..7a56d30edf 100644 --- a/tests/brokers/redis/test_router.py +++ b/tests/brokers/redis/test_router.py @@ -1,40 +1,28 @@ import asyncio -from typing import Any import pytest from faststream import Path from faststream.redis import ( - RedisBroker, RedisPublisher, RedisRoute, RedisRouter, - TestRedisBroker, ) from tests.brokers.base.router import RouterLocalTestcase, RouterTestcase +from .basic import RedisMemoryTestcaseConfig, RedisTestcaseConfig + @pytest.mark.redis() -class TestRouter(RouterTestcase): - broker_class = RedisRouter +class TestRouter(RedisTestcaseConfig, RouterTestcase): route_class = RedisRoute publisher_class = RedisPublisher - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RedisBroker: - return RedisBroker(apply_types=apply_types, **kwargs) - -class TestRouterLocal(RouterLocalTestcase): - broker_class = RedisRouter +class TestRouterLocal(RedisMemoryTestcaseConfig, RouterLocalTestcase): route_class = RedisRoute publisher_class = RedisPublisher - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RedisBroker: - return RedisBroker(apply_types=apply_types, **kwargs) - - def patch_broker(self, broker: RedisBroker, **kwargs: Any) -> RedisBroker: - return TestRedisBroker(broker, **kwargs) - async def test_router_path( self, event, diff --git a/tests/brokers/redis/test_test_client.py b/tests/brokers/redis/test_test_client.py index c9bcbe5527..da352a0c7b 100644 --- a/tests/brokers/redis/test_test_client.py +++ b/tests/brokers/redis/test_test_client.py @@ -1,24 +1,17 @@ import asyncio -from typing import Any import pytest from faststream import BaseMiddleware -from faststream.redis import ListSub, RedisBroker, StreamSub, TestRedisBroker +from faststream.redis import ListSub, StreamSub from faststream.redis.testing import FakeProducer from tests.brokers.base.testclient import BrokerTestclientTestcase +from .basic import RedisMemoryTestcaseConfig -@pytest.mark.asyncio() -class TestTestclient(BrokerTestclientTestcase): - test_class = TestRedisBroker - - def get_broker(self, apply_types: bool = False, **kwargs: Any) -> RedisBroker: - return RedisBroker(apply_types=apply_types, **kwargs) - - def patch_broker(self, broker: RedisBroker, **kwargs: Any) -> TestRedisBroker: - return TestRedisBroker(broker, **kwargs) +@pytest.mark.asyncio() +class TestTestclient(RedisMemoryTestcaseConfig, BrokerTestclientTestcase): @pytest.mark.redis() async def test_with_real_testclient( self, @@ -43,7 +36,7 @@ def subscriber(m) -> None: assert event.is_set() - async def test_respect_middleware(self, queue) -> None: + async def test_respect_middleware(self, queue: str) -> None: routes = [] class Middleware(BaseMiddleware): @@ -66,7 +59,7 @@ async def h2(m) -> None: ... assert len(routes) == 2 @pytest.mark.redis() - async def test_real_respect_middleware(self, queue) -> None: + async def test_real_respect_middleware(self, queue: str) -> None: routes = [] class Middleware(BaseMiddleware): @@ -209,10 +202,7 @@ async def m(msg): m.mock.assert_called_once_with("hello") publisher.mock.assert_called_once_with([1, 2, 3]) - async def test_publish_to_none( - self, - queue: str, - ) -> None: + async def test_publish_to_none(self) -> None: broker = self.get_broker() async with self.patch_broker(broker) as br: diff --git a/tests/prometheus/basic.py b/tests/prometheus/basic.py index e856d7b33a..3780651288 100644 --- a/tests/prometheus/basic.py +++ b/tests/prometheus/basic.py @@ -52,8 +52,16 @@ def settings_provider_factory(self): Exception, id="acked status with not handler exception", ), - pytest.param(AckStatus.ACKED, None, id="acked status without exception"), - pytest.param(AckStatus.NACKED, None, id="nacked status without exception"), + pytest.param( + AckStatus.ACKED, + None, + id="acked status without exception", + ), + pytest.param( + AckStatus.NACKED, + None, + id="nacked status without exception", + ), pytest.param( AckStatus.REJECTED, None, From cdeb2e87efb10defc1e34706748bdf293382ab93 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Fri, 22 Nov 2024 17:09:16 +0300 Subject: [PATCH 203/245] chore: fix NATS Core acknowledgement --- faststream/kafka/broker/registrator.py | 4 +-- faststream/kafka/subscriber/usecase.py | 4 +-- faststream/nats/message.py | 32 +++++++------------ faststream/nats/parser.py | 8 +++++ faststream/nats/publisher/producer.py | 6 ++-- faststream/nats/subscriber/factory.py | 9 ++++-- .../subscriber/usecases/core_subscriber.py | 8 ++++- faststream/nats/testing.py | 2 +- tests/brokers/nats/test_consume.py | 4 ++- 9 files changed, 46 insertions(+), 31 deletions(-) diff --git a/faststream/kafka/broker/registrator.py b/faststream/kafka/broker/registrator.py index 7f7b01ebd4..1b20a0c830 100644 --- a/faststream/kafka/broker/registrator.py +++ b/faststream/kafka/broker/registrator.py @@ -54,14 +54,14 @@ class KafkaRegistrator( ): """Includable to KafkaBroker router.""" - subscribers: list[ + _subscribers: list[ Union[ "SpecificationBatchSubscriber", "SpecificationDefaultSubscriber", "SpecificationConcurrentDefaultSubscriber", ] ] - publishers: list[ + _publishers: list[ Union["SpecificationBatchPublisher", "SpecificationDefaultPublisher"], ] diff --git a/faststream/kafka/subscriber/usecase.py b/faststream/kafka/subscriber/usecase.py index dca8bef89e..29c77a5829 100644 --- a/faststream/kafka/subscriber/usecase.py +++ b/faststream/kafka/subscriber/usecase.py @@ -1,4 +1,4 @@ -from abc import ABC, abstractmethod +from abc import abstractmethod from collections.abc import Iterable, Sequence from itertools import chain from typing import TYPE_CHECKING, Any, Callable, Optional @@ -34,7 +34,7 @@ from faststream.middlewares import AckPolicy -class LogicSubscriber(ABC, TasksMixin, SubscriberUsecase[MsgType]): +class LogicSubscriber(TasksMixin, SubscriberUsecase[MsgType]): """A class to handle logic for consuming messages from Kafka.""" topics: Sequence[str] diff --git a/faststream/nats/message.py b/faststream/nats/message.py index eb4a8ab94a..ce7486aceb 100644 --- a/faststream/nats/message.py +++ b/faststream/nats/message.py @@ -13,35 +13,27 @@ class NatsMessage(StreamMessage[Msg]): async def ack(self) -> None: # Check `self.raw_message._ackd` instead of `self.committed` # to be compatible with `self.raw_message.ack()` - try: - if not self.raw_message._ackd: - await self.raw_message.ack() - finally: - await super().ack() + if not self.raw_message._ackd: + await self.raw_message.ack() + await super().ack() async def ack_sync(self) -> None: - try: - if not self.raw_message._ackd: - await self.raw_message.ack_sync() - finally: - await super().ack() + if not self.raw_message._ackd: + await self.raw_message.ack_sync() + await super().ack() async def nack( self, delay: Optional[float] = None, ) -> None: - try: - if not self.raw_message._ackd: - await self.raw_message.nak(delay=delay) - finally: - await super().nack() + if not self.raw_message._ackd: + await self.raw_message.nak(delay=delay) + await super().nack() async def reject(self) -> None: - try: - if not self.raw_message._ackd: - await self.raw_message.term() - finally: - await super().reject() + if not self.raw_message._ackd: + await self.raw_message.term() + await super().reject() async def in_progress(self) -> None: if not self.raw_message._ackd: diff --git a/faststream/nats/parser.py b/faststream/nats/parser.py index e3343c0af8..7553ef7882 100644 --- a/faststream/nats/parser.py +++ b/faststream/nats/parser.py @@ -54,6 +54,11 @@ async def decode_message( class NatsParser(NatsBaseParser): """A class to parse NATS core messages.""" + def __init__(self, *, pattern: str, is_ack_disabled: bool) -> None: + super().__init__(pattern=pattern) + + self.is_ack_disabled = is_ack_disabled + async def parse_message( self, message: "Msg", @@ -65,6 +70,9 @@ async def parse_message( headers = message.header or {} + if self.is_ack_disabled: + message._ackd = True + return NatsMessage( raw_message=message, body=message.data, diff --git a/faststream/nats/publisher/producer.py b/faststream/nats/publisher/producer.py index 9451092170..7feefe3a59 100644 --- a/faststream/nats/publisher/producer.py +++ b/faststream/nats/publisher/producer.py @@ -40,7 +40,7 @@ def __init__( parser: Optional["CustomCallable"], decoder: Optional["CustomCallable"], ) -> None: - default = NatsParser(pattern="") + default = NatsParser(pattern="", is_ack_disabled=True) self._parser = resolve_custom_func(parser, default.parse_message) self._decoder = resolve_custom_func(decoder, default.decode_message) @@ -111,7 +111,9 @@ def __init__( parser: Optional["CustomCallable"], decoder: Optional["CustomCallable"], ) -> None: - default = NatsParser(pattern="") # core parser to serializer responses + default = NatsParser( + pattern="", is_ack_disabled=True + ) # core parser to serializer responses self._parser = resolve_custom_func(parser, default.parse_message) self._decoder = resolve_custom_func(decoder, default.decode_message) diff --git a/faststream/nats/subscriber/factory.py b/faststream/nats/subscriber/factory.py index fa76740e5e..cebd1df871 100644 --- a/faststream/nats/subscriber/factory.py +++ b/faststream/nats/subscriber/factory.py @@ -190,6 +190,7 @@ def create_subscriber( extra_options=extra_options, # Subscriber args no_reply=no_reply, + ack_policy=ack_policy, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, # Specification @@ -206,6 +207,7 @@ def create_subscriber( extra_options=extra_options, # Subscriber args no_reply=no_reply, + ack_policy=ack_policy, broker_dependencies=broker_dependencies, broker_middlewares=broker_middlewares, # Specification @@ -381,9 +383,12 @@ def _validate_input_for_misconfigure( # noqa: PLR0915 stacklevel=4, ) - elif stream is None: + elif stream is None and ack_policy is not AckPolicy.DO_NOTHING: warnings.warn( - "You can't use acknowledgement policy with core subscriber. Use JetStream instead.", + ( + "Core subscriber supports only `ack_policy=AckPolicy.DO_NOTHING` option for very specific cases. " + "If you are using different option, probably, you should use JetStream Subscriber instead." + ), RuntimeWarning, stacklevel=4, ) diff --git a/faststream/nats/subscriber/usecases/core_subscriber.py b/faststream/nats/subscriber/usecases/core_subscriber.py index e8d2b6a045..329eb66a50 100644 --- a/faststream/nats/subscriber/usecases/core_subscriber.py +++ b/faststream/nats/subscriber/usecases/core_subscriber.py @@ -39,12 +39,16 @@ def __init__( config: "ConsumerConfig", queue: str, extra_options: Optional["AnyDict"], + ack_policy: AckPolicy, # Subscriber args no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[Msg]"], ) -> None: - parser_ = NatsParser(pattern=subject) + parser_ = NatsParser( + pattern=subject, + is_ack_disabled=ack_policy is not AckPolicy.DO_NOTHING, + ) self.queue = queue @@ -137,6 +141,7 @@ def __init__( queue: str, extra_options: Optional["AnyDict"], # Subscriber args + ack_policy: AckPolicy, no_reply: bool, broker_dependencies: Iterable["Dependant"], broker_middlewares: Iterable["BrokerMiddleware[Msg]"], @@ -149,6 +154,7 @@ def __init__( queue=queue, extra_options=extra_options, # Propagated args + ack_policy=ack_policy, no_reply=no_reply, broker_middlewares=broker_middlewares, broker_dependencies=broker_dependencies, diff --git a/faststream/nats/testing.py b/faststream/nats/testing.py index 63c9fb9a22..0b0ce88302 100644 --- a/faststream/nats/testing.py +++ b/faststream/nats/testing.py @@ -86,7 +86,7 @@ class FakeProducer(NatsFastProducer): def __init__(self, broker: NatsBroker) -> None: self.broker = broker - default = NatsParser(pattern="") + default = NatsParser(pattern="", is_ack_disabled=True) self._parser = resolve_custom_func(broker._parser, default.parse_message) self._decoder = resolve_custom_func(broker._decoder, default.decode_message) diff --git a/tests/brokers/nats/test_consume.py b/tests/brokers/nats/test_consume.py index feab15055f..18fb87c818 100644 --- a/tests/brokers/nats/test_consume.py +++ b/tests/brokers/nats/test_consume.py @@ -197,7 +197,9 @@ async def test_core_consume_no_ack( consume_broker = self.get_broker(apply_types=True) - args, kwargs = self.get_subscriber_params(queue) + args, kwargs = self.get_subscriber_params( + queue, ack_policy=AckPolicy.DO_NOTHING + ) @consume_broker.subscriber(*args, **kwargs) async def handler(msg: NatsMessage) -> None: From d1820feaab66c5e781906ed35f2a481bb6a3b490 Mon Sep 17 00:00:00 2001 From: sheldy <85823514+sheldygg@users.noreply.github.com> Date: Mon, 25 Nov 2024 20:41:06 +0100 Subject: [PATCH 204/245] Remove `retry` from docs and add acknowledgement to getting start (#1934) * Remove `retry` from block and add acknowledgement to getting start * fix pre-commit --- docs/docs/en/getting-started/acknowlegment.md | 24 ++++++++++++ docs/docs/en/nats/jetstream/ack.md | 23 ----------- docs/docs/en/rabbit/ack.md | 38 ------------------- 3 files changed, 24 insertions(+), 61 deletions(-) create mode 100644 docs/docs/en/getting-started/acknowlegment.md diff --git a/docs/docs/en/getting-started/acknowlegment.md b/docs/docs/en/getting-started/acknowlegment.md new file mode 100644 index 0000000000..e26179e30f --- /dev/null +++ b/docs/docs/en/getting-started/acknowlegment.md @@ -0,0 +1,24 @@ +# Acknowledgment + +Since unexpected errors may occur during message processing, **FastStream** has an `ack_policy` parameter. + +`AckPolicy` have 4 variants: + +- `ACK` means that the message will be acked anyway. + +- `NACK_ON_ERROR` means that the message will be nacked if an error occurs during processing and consumer will receive this message one more time. + +- `REJECT_ON_ERROR` means that the message will be rejected if an error occurs during processing and consumer will not receive this message again. + +- `DO_NOTHING` in this case *FastStream* will do nothing with the message. You must ack/nack/reject the message manually. + + +You must provide this parameter when initializing the subscriber. + +```python linenums="1" hl_lines="5" title="main.py" +from faststream import AckPolicy +from faststream.nats import NatsBroker + +broker = NatsBroker() +@broker.subscriber(ack_policy=AckPolicy.REJECT_ON_ERROR) +``` diff --git a/docs/docs/en/nats/jetstream/ack.md b/docs/docs/en/nats/jetstream/ack.md index f003966493..a1dbc41168 100644 --- a/docs/docs/en/nats/jetstream/ack.md +++ b/docs/docs/en/nats/jetstream/ack.md @@ -16,29 +16,6 @@ In most cases, **FastStream** automatically acknowledges (*acks*) messages on yo However, there are situations where you might want to use different acknowledgement logic. -## Retries - -If you prefer to use a *nack* instead of a *reject* when there's an error in message processing, you can specify the `retry` flag in the `#!python @broker.subscriber(...)` method, which is responsible for error handling logic. - -By default, this flag is set to `False`, indicating that if an error occurs during message processing, the message can still be retrieved from the queue: - -```python -@broker.subscriber("test", retry=False) # don't handle exceptions -async def base_handler(body: str): - ... -``` - -If this flag is set to `True`, the message will be *nack*ed and placed back in the queue each time an error occurs. In this scenario, the message can be processed by another consumer (if there are several of them) or by the same one: - -```python -@broker.subscriber("test", retry=True) # try again indefinitely -async def base_handler(body: str): - ... -``` - -!!! tip - For more complex error handling cases, you can use [tenacity](https://tenacity.readthedocs.io/en/latest/){.external-link target="_blank"} - ## Manual Acknowledgement If you want to acknowledge a message manually, you can get access directly to the message object via the [Context](../../getting-started/context/existed.md){.internal-link} and call the method. diff --git a/docs/docs/en/rabbit/ack.md b/docs/docs/en/rabbit/ack.md index d68b66a0cd..e7632742dc 100644 --- a/docs/docs/en/rabbit/ack.md +++ b/docs/docs/en/rabbit/ack.md @@ -16,44 +16,6 @@ In most cases, **FastStream** automatically acknowledges (*acks*) messages on yo However, there are situations where you might want to use a different acknowledgement logic. -## Retries - -If you prefer to use a *nack* instead of a *reject* when there's an error in message processing, you can specify the `retry` flag in the `#!python @broker.subscriber(...)` method, which is responsible for error handling logic. - -By default, this flag is set to `False`, indicating that if an error occurs during message processing, the message can still be retrieved from the queue: - -```python -@broker.subscriber("test", retry=False) # don't handle exceptions -async def base_handler(body: str): - ... -``` - -If this flag is set to `True`, the message will be *nack*ed and placed back in the queue each time an error occurs. In this scenario, the message can be processed by another consumer (if there are several of them) or by the same one: - -```python -@broker.subscriber("test", retry=True) # try again indefinitely -async def base_handler(body: str): - ... -``` - -If the `retry` flag is set to an `int`, the message will be placed back in the queue, and the number of retries will be limited to this number: - -```python -@broker.subscriber("test", retry=3) # make up to 3 attempts -async def base_handler(body: str): - ... -``` - -!!! tip - **FastStream** identifies the message by its `message_id`. To make this option work, you should manually set this field on the producer side (if your library doesn't set it automatically). - -!!! bug - At the moment, attempts are counted only by the current consumer. If the message goes to another consumer, it will have its own counter. - Subsequently, this logic will be reworked. - -!!! tip - For more complex error handling cases, you can use [tenacity](https://tenacity.readthedocs.io/en/latest/){.external-link target="_blank"} - ## Manual acknowledgement If you want to acknowledge a message manually, you can get access directly to the message object via the [Context](../getting-started/context/existed.md){.internal-link} and call the method. From d81397acad18255e0c926e2435bea8b7e8cee78b Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Mon, 25 Nov 2024 22:45:23 +0300 Subject: [PATCH 205/245] tests: add middlewares enter-exit order test --- tests/brokers/base/middlewares.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/brokers/base/middlewares.py b/tests/brokers/base/middlewares.py index 729a0966c9..9df2f84d19 100644 --- a/tests/brokers/base/middlewares.py +++ b/tests/brokers/base/middlewares.py @@ -16,6 +16,14 @@ class MiddlewaresOrderTestcase(BaseTestcaseConfig): async def test_broker_middleware_order(self, queue: str, mock: MagicMock): class InnerMiddleware(BaseMiddleware): + async def __aenter__(self): + mock.enter_inner() + mock.enter("inner") + + async def __aexit__(self, *args): + mock.exit_inner() + mock.exit("inner") + async def consume_scope(self, call_next, msg): mock.consume_inner() mock.sub("inner") @@ -27,6 +35,14 @@ async def publish_scope(self, call_next, cmd): return await call_next(cmd) class OuterMiddleware(BaseMiddleware): + async def __aenter__(self): + mock.enter_outer() + mock.enter("outer") + + async def __aexit__(self, *args): + mock.exit_outer() + mock.exit("outer") + async def consume_scope(self, call_next, msg): mock.consume_outer() mock.sub("outer") @@ -52,9 +68,15 @@ async def handler(msg): mock.consume_outer.assert_called_once() mock.publish_inner.assert_called_once() mock.publish_outer.assert_called_once() + mock.enter_inner.assert_called_once() + mock.enter_outer.assert_called_once() + mock.exit_inner.assert_called_once() + mock.exit_outer.assert_called_once() assert [c.args[0] for c in mock.sub.call_args_list] == ["outer", "inner"] assert [c.args[0] for c in mock.pub.call_args_list] == ["outer", "inner"] + assert [c.args[0] for c in mock.enter.call_args_list] == ["outer", "inner"] + assert [c.args[0] for c in mock.exit.call_args_list] == ["inner", "outer"] async def test_publisher_middleware_order(self, queue: str, mock: MagicMock): class InnerMiddleware(BaseMiddleware): From d13624c254299f31195d47cd2c97a84ac422ca76 Mon Sep 17 00:00:00 2001 From: Ruslan Alimov Date: Tue, 26 Nov 2024 21:55:36 +0300 Subject: [PATCH 206/245] feat: added ack_first (#1917) * feat: added ack_first * docs: generate API References * feat: ack_first added deprecated and docstrings to Ack_Policy * docs: generate API References * feat: ack_first refactored ack_first check * chore: merge 0.6 * docs: generate API References --------- Co-authored-by: Rusich90 Co-authored-by: Nikita Pastukhov --- docs/docs/SUMMARY.md | 204 +++++++++--------- ...pecificationConcurrentDefaultSubscriber.md | 11 + .../schema/tag/Tag.md => nats/PubAck.md} | 2 +- .../info/Info.md => nats/schemas/PubAck.md} | 2 +- .../middleware/BasePrometheusMiddleware.md} | 2 +- .../asyncapi/utils/move_pydantic_refs.md} | 2 +- .../v2_6_0/generate/move_pydantic_refs.md | 11 - .../v2_6_0/schema/ApplicationInfo.md} | 2 +- .../v2_6_0/schema/ApplicationSchema.md} | 2 +- .../schema/bindings/amqp/channel/from_spec.md | 11 - .../amqp/channel_binding_from_spec.md | 11 - .../bindings/amqp/operation/from_spec.md | 11 - .../amqp/operation_binding_from_spec.md | 11 - .../bindings/channel_binding_from_spec.md | 11 - .../bindings/kafka/operation/from_spec.md | 11 - .../kafka/operation_binding_from_spec.md | 11 - .../schema/bindings/main/channel/from_spec.md | 11 - .../main/channel_binding_from_spec.md | 11 - .../bindings/main/operation/from_spec.md | 11 - .../main/operation_binding_from_spec.md | 11 - .../bindings/nats/operation/from_spec.md | 11 - .../nats/operation_binding_from_spec.md | 11 - .../bindings/operation_binding_from_spec.md | 11 - .../bindings/redis/operation/from_spec.md | 11 - .../redis/operation_binding_from_spec.md | 11 - .../v2_6_0/schema/channel_from_spec.md | 11 - .../v2_6_0/schema/channels/from_spec.md | 11 - .../v2_6_0/schema/contact/from_spec.md | 11 - .../v2_6_0/schema/contact_from_spec.md | 11 - .../asyncapi/v2_6_0/schema/docs/from_spec.md | 11 - .../asyncapi/v2_6_0/schema/docs_from_spec.md | 11 - .../v2_6_0/schema/info/ApplicationInfo.md | 11 + .../asyncapi/v2_6_0/schema/info/Info.md | 11 - .../v2_6_0/schema/license/from_spec.md | 11 - .../v2_6_0/schema/license_from_spec.md | 11 - .../v2_6_0/schema/message/from_spec.md | 11 - .../v2_6_0/schema/message_from_spec.md | 11 - .../v2_6_0/schema/operation_from_spec.md | 11 - .../v2_6_0/schema/operations/from_spec.md | 11 - .../v2_6_0/schema/schema/ApplicationSchema.md | 11 + .../asyncapi/v2_6_0/schema/schema/Schema.md | 11 - .../asyncapi/v2_6_0/schema/tag/from_spec.md | 11 - .../asyncapi/v2_6_0/schema/tag_from_spec.md | 11 - .../v3_0_0/generate/get_broker_operations.md | 11 - .../asyncapi/v3_0_0/schema/ApplicationInfo.md | 11 + .../v3_0_0/schema/ApplicationSchema.md} | 2 +- .../asyncapi/v3_0_0/schema/Contact.md | 11 + .../v3_0_0/schema}/CorrelationId.md | 2 +- .../asyncapi/v3_0_0/schema/ExternalDocs.md | 11 + .../asyncapi/v3_0_0/schema/License.md | 11 + .../asyncapi/v3_0_0/schema/Message.md | 11 + .../asyncapi/v3_0_0/schema/Parameter.md | 11 + .../asyncapi/v3_0_0/schema/Reference.md | 11 + .../asyncapi/v3_0_0/schema/Schema.md | 11 - .../v3_0_0/schema}/ServerVariable.md | 2 +- .../asyncapi/v3_0_0/schema/Tag.md} | 2 +- .../v3_0_0/schema/bindings/ChannelBinding.md | 11 + .../from_spec.md => ChannelBinding.md} | 2 +- .../ChannelBinding.md} | 2 +- .../amqp/channel_binding_from_spec.md | 11 - .../amqp/operation_binding_from_spec.md | 11 - .../bindings/channel_binding_from_spec.md | 11 - .../schema/bindings/kafka/ChannelBinding.md} | 2 +- .../bindings/kafka/OperationBinding.md} | 2 +- .../from_spec.md => ChannelBinding.md} | 2 +- .../ChannelBinding.md} | 2 +- .../main/channel_binding_from_spec.md | 11 - .../main/operation_binding_from_spec.md | 11 - .../schema/bindings/nats/ChannelBinding.md} | 2 +- .../schema/bindings/nats/OperationBinding.md} | 2 +- .../bindings/operation_binding_from_spec.md | 11 - .../schema/bindings/redis/ChannelBinding.md} | 2 +- .../bindings/redis/OperationBinding.md} | 2 +- .../schema/bindings/sqs/ChannelBinding.md} | 2 +- .../schema/bindings/sqs/OperationBinding.md} | 2 +- .../v3_0_0/schema/channel_from_spec.md | 11 - .../v3_0_0/schema/channels/from_spec.md | 11 - .../asyncapi/v3_0_0/schema/contact/Contact.md | 11 + .../v3_0_0/schema/docs/ExternalDocs.md | 11 + .../v3_0_0/schema/info/ApplicationInfo.md | 11 + .../asyncapi/v3_0_0/schema/info/Info.md | 11 - .../asyncapi/v3_0_0/schema/license/License.md | 11 + .../v3_0_0/schema/message/CorrelationId.md | 11 + .../asyncapi/v3_0_0/schema/message/Message.md | 11 + .../v3_0_0/schema/operation_from_spec.md | 11 - .../v3_0_0/schema/operations/from_spec.md | 11 - .../v3_0_0/schema/schema/ApplicationSchema.md | 11 + .../asyncapi/v3_0_0/schema/schema/Schema.md | 11 - .../asyncapi/v3_0_0/schema/tag/Tag.md | 11 + .../asyncapi/v3_0_0/schema/utils/Parameter.md | 11 + .../asyncapi/v3_0_0/schema/utils/Reference.md | 11 + .../info/BaseApplicationInfo.md} | 2 +- .../base/proto/SpecificationEndpoint.md | 11 - .../base/schema/BaseApplicationSchema.md} | 2 +- .../EndpointSpecification.md} | 2 +- .../proto/ServerSpecification.md} | 2 +- .../proto/broker/ServerSpecification.md | 11 + .../proto/endpoint/EndpointSpecification.md} | 2 +- .../BaseInfo.md => schema/ContactDict.md} | 2 +- .../Channel.md => ExternalDocsDict.md} | 2 +- .../specification/schema/LicenseDict.md | 11 + .../specification/schema/Message.md | 11 + .../specification/schema/Operation.md | 11 + .../specification/schema/PublisherSpec.md | 11 + .../{servers/Server.md => SubscriberSpec.md} | 2 +- .../specification/schema/{tag => }/TagDict.md | 2 +- .../schema/components/Components.md | 11 - .../specification/schema/extra/Contact.md | 11 + .../schema/extra/ContactDict.md} | 2 +- .../schema/{docs => extra}/ExternalDocs.md | 2 +- .../{docs => extra}/ExternalDocsDict.md | 2 +- .../specification/schema/extra/License.md | 11 + .../extra/LicenseDict.md} | 2 +- .../specification/schema/extra/Tag.md | 11 + .../specification/schema/extra/TagDict.md | 11 + .../schema/{ => extra}/contact/Contact.md | 2 +- .../schema/{ => extra}/contact/ContactDict.md | 2 +- .../extra/external_docs/ExternalDocs.md | 11 + .../extra/external_docs/ExternalDocsDict.md | 11 + .../schema/{ => extra}/license/License.md | 2 +- .../schema/{ => extra}/license/LicenseDict.md | 2 +- .../specification/schema/extra/tag/Tag.md | 11 + .../specification/schema/extra/tag/TagDict.md | 11 + .../message/model/Message.md} | 2 +- .../schema/operation/model/Operation.md | 11 + .../schema/publisher/PublisherSpec.md | 11 + .../schema/security/OauthFlowObj.md | 11 - .../schema/security/OauthFlows.md | 11 - .../security/SecuritySchemaComponent.md | 11 - .../schema/subscriber/SubscriberSpec.md | 11 + 130 files changed, 548 insertions(+), 715 deletions(-) create mode 100644 docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationConcurrentDefaultSubscriber.md rename docs/docs/en/api/faststream/{specification/schema/tag/Tag.md => nats/PubAck.md} (71%) rename docs/docs/en/api/faststream/{specification/schema/info/Info.md => nats/schemas/PubAck.md} (70%) rename docs/docs/en/api/faststream/{nats/subscriber/usecase/PushStreamSubscription.md => prometheus/middleware/BasePrometheusMiddleware.md} (63%) rename docs/docs/en/api/faststream/{nats/subscriber/usecase/ObjStoreWatchSubscriber.md => specification/asyncapi/utils/move_pydantic_refs.md} (63%) delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/move_pydantic_refs.md rename docs/docs/en/api/faststream/{nats/subscriber/usecase/ConcurrentCoreSubscriber.md => specification/asyncapi/v2_6_0/schema/ApplicationInfo.md} (61%) rename docs/docs/en/api/faststream/{nats/subscriber/usecase/ConcurrentPullStreamSubscriber.md => specification/asyncapi/v2_6_0/schema/ApplicationSchema.md} (61%) delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel_binding_from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation_binding_from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/channel_binding_from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation_binding_from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel_binding_from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation_binding_from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation_binding_from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/operation_binding_from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation_binding_from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channel_from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channels/from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact/from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact_from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs/from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs_from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/info/ApplicationInfo.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/info/Info.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license/from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license_from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message_from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operation_from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operations/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/schema/ApplicationSchema.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/schema/Schema.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag/from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag_from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_operations.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationInfo.md rename docs/docs/en/api/faststream/{nats/subscriber/usecase/ConcurrentPushStreamSubscriber.md => specification/asyncapi/v3_0_0/schema/ApplicationSchema.md} (61%) create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Contact.md rename docs/docs/en/api/faststream/specification/{schema/message => asyncapi/v3_0_0/schema}/CorrelationId.md (59%) create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ExternalDocs.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/License.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Message.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Parameter.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Reference.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Schema.md rename docs/docs/en/api/faststream/specification/{schema/servers => asyncapi/v3_0_0/schema}/ServerVariable.md (59%) rename docs/docs/en/api/faststream/{nats/subscriber/usecase/PullStreamSubscriber.md => specification/asyncapi/v3_0_0/schema/Tag.md} (64%) create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/ChannelBinding.md rename docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/{channel/from_spec.md => ChannelBinding.md} (89%) rename docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/{operation/from_spec.md => channel/ChannelBinding.md} (87%) delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel_binding_from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation_binding_from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/channel_binding_from_spec.md rename docs/docs/en/api/faststream/specification/asyncapi/{v2_6_0/schema/bindings/kafka/channel/from_spec.md => v3_0_0/schema/bindings/kafka/ChannelBinding.md} (87%) rename docs/docs/en/api/faststream/specification/asyncapi/{v2_6_0/schema/bindings/kafka/channel_binding_from_spec.md => v3_0_0/schema/bindings/kafka/OperationBinding.md} (85%) rename docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/{channel/from_spec.md => ChannelBinding.md} (89%) rename docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/{operation/from_spec.md => channel/ChannelBinding.md} (87%) delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel_binding_from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation_binding_from_spec.md rename docs/docs/en/api/faststream/specification/asyncapi/{v2_6_0/schema/bindings/nats/channel/from_spec.md => v3_0_0/schema/bindings/nats/ChannelBinding.md} (87%) rename docs/docs/en/api/faststream/specification/asyncapi/{v2_6_0/schema/bindings/nats/channel_binding_from_spec.md => v3_0_0/schema/bindings/nats/OperationBinding.md} (85%) delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/operation_binding_from_spec.md rename docs/docs/en/api/faststream/specification/asyncapi/{v2_6_0/schema/bindings/redis/channel/from_spec.md => v3_0_0/schema/bindings/redis/ChannelBinding.md} (87%) rename docs/docs/en/api/faststream/specification/asyncapi/{v2_6_0/schema/bindings/redis/channel_binding_from_spec.md => v3_0_0/schema/bindings/redis/OperationBinding.md} (85%) rename docs/docs/en/api/faststream/specification/asyncapi/{v2_6_0/schema/bindings/sqs/channel_binding_from_spec.md => v3_0_0/schema/bindings/sqs/ChannelBinding.md} (86%) rename docs/docs/en/api/faststream/specification/asyncapi/{v2_6_0/schema/bindings/sqs/operation_binding_from_spec.md => v3_0_0/schema/bindings/sqs/OperationBinding.md} (85%) delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channel_from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channels/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/contact/Contact.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/docs/ExternalDocs.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/info/ApplicationInfo.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/info/Info.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/license/License.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/message/CorrelationId.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/message/Message.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operation_from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/schema/ApplicationSchema.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/schema/Schema.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/tag/Tag.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/utils/Parameter.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/utils/Reference.md rename docs/docs/en/api/faststream/specification/{asyncapi/v2_6_0/schema/Schema.md => base/info/BaseApplicationInfo.md} (65%) delete mode 100644 docs/docs/en/api/faststream/specification/base/proto/SpecificationEndpoint.md rename docs/docs/en/api/faststream/{nats/subscriber/usecase/KeyValueWatchSubscriber.md => specification/base/schema/BaseApplicationSchema.md} (63%) rename docs/docs/en/api/faststream/specification/{asyncapi/v3_0_0/schema/Info.md => proto/EndpointSpecification.md} (65%) rename docs/docs/en/api/faststream/{nats/subscriber/usecase/LogicSubscriber.md => specification/proto/ServerSpecification.md} (66%) create mode 100644 docs/docs/en/api/faststream/specification/proto/broker/ServerSpecification.md rename docs/docs/en/api/faststream/{nats/subscriber/usecase/BatchPullStreamSubscriber.md => specification/proto/endpoint/EndpointSpecification.md} (62%) rename docs/docs/en/api/faststream/specification/{base/info/BaseInfo.md => schema/ContactDict.md} (69%) rename docs/docs/en/api/faststream/specification/schema/{channel/Channel.md => ExternalDocsDict.md} (67%) create mode 100644 docs/docs/en/api/faststream/specification/schema/LicenseDict.md create mode 100644 docs/docs/en/api/faststream/specification/schema/Message.md create mode 100644 docs/docs/en/api/faststream/specification/schema/Operation.md create mode 100644 docs/docs/en/api/faststream/specification/schema/PublisherSpec.md rename docs/docs/en/api/faststream/specification/schema/{servers/Server.md => SubscriberSpec.md} (68%) rename docs/docs/en/api/faststream/specification/schema/{tag => }/TagDict.md (69%) delete mode 100644 docs/docs/en/api/faststream/specification/schema/components/Components.md create mode 100644 docs/docs/en/api/faststream/specification/schema/extra/Contact.md rename docs/docs/en/api/faststream/{nats/subscriber/usecase/CoreSubscriber.md => specification/schema/extra/ContactDict.md} (67%) rename docs/docs/en/api/faststream/specification/schema/{docs => extra}/ExternalDocs.md (66%) rename docs/docs/en/api/faststream/specification/schema/{docs => extra}/ExternalDocsDict.md (65%) create mode 100644 docs/docs/en/api/faststream/specification/schema/extra/License.md rename docs/docs/en/api/faststream/specification/{base/schema/BaseSchema.md => schema/extra/LicenseDict.md} (67%) create mode 100644 docs/docs/en/api/faststream/specification/schema/extra/Tag.md create mode 100644 docs/docs/en/api/faststream/specification/schema/extra/TagDict.md rename docs/docs/en/api/faststream/specification/schema/{ => extra}/contact/Contact.md (65%) rename docs/docs/en/api/faststream/specification/schema/{ => extra}/contact/ContactDict.md (63%) create mode 100644 docs/docs/en/api/faststream/specification/schema/extra/external_docs/ExternalDocs.md create mode 100644 docs/docs/en/api/faststream/specification/schema/extra/external_docs/ExternalDocsDict.md rename docs/docs/en/api/faststream/specification/schema/{ => extra}/license/License.md (65%) rename docs/docs/en/api/faststream/specification/schema/{ => extra}/license/LicenseDict.md (63%) create mode 100644 docs/docs/en/api/faststream/specification/schema/extra/tag/Tag.md create mode 100644 docs/docs/en/api/faststream/specification/schema/extra/tag/TagDict.md rename docs/docs/en/api/faststream/specification/{asyncapi/v2_6_0/schema/Info.md => schema/message/model/Message.md} (65%) create mode 100644 docs/docs/en/api/faststream/specification/schema/operation/model/Operation.md create mode 100644 docs/docs/en/api/faststream/specification/schema/publisher/PublisherSpec.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/security/OauthFlowObj.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/security/OauthFlows.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/security/SecuritySchemaComponent.md create mode 100644 docs/docs/en/api/faststream/specification/schema/subscriber/SubscriberSpec.md diff --git a/docs/docs/SUMMARY.md b/docs/docs/SUMMARY.md index cf444fbe1a..8866bf3c04 100644 --- a/docs/docs/SUMMARY.md +++ b/docs/docs/SUMMARY.md @@ -169,6 +169,7 @@ search: - [NatsRouter](public_api/faststream/nats/NatsRouter.md) - [ObjWatch](public_api/faststream/nats/ObjWatch.md) - [Placement](public_api/faststream/nats/Placement.md) + - [PubAck](public_api/faststream/nats/PubAck.md) - [PullSub](public_api/faststream/nats/PullSub.md) - [RePublish](public_api/faststream/nats/RePublish.md) - [ReplayPolicy](public_api/faststream/nats/ReplayPolicy.md) @@ -455,10 +456,12 @@ search: - [create_subscriber](api/faststream/kafka/subscriber/factory/create_subscriber.md) - specified - [SpecificationBatchSubscriber](api/faststream/kafka/subscriber/specified/SpecificationBatchSubscriber.md) + - [SpecificationConcurrentDefaultSubscriber](api/faststream/kafka/subscriber/specified/SpecificationConcurrentDefaultSubscriber.md) - [SpecificationDefaultSubscriber](api/faststream/kafka/subscriber/specified/SpecificationDefaultSubscriber.md) - [SpecificationSubscriber](api/faststream/kafka/subscriber/specified/SpecificationSubscriber.md) - usecase - [BatchSubscriber](api/faststream/kafka/subscriber/usecase/BatchSubscriber.md) + - [ConcurrentDefaultSubscriber](api/faststream/kafka/subscriber/usecase/ConcurrentDefaultSubscriber.md) - [DefaultSubscriber](api/faststream/kafka/subscriber/usecase/DefaultSubscriber.md) - [LogicSubscriber](api/faststream/kafka/subscriber/usecase/LogicSubscriber.md) - testing @@ -513,6 +516,7 @@ search: - [NatsRouter](api/faststream/nats/NatsRouter.md) - [ObjWatch](api/faststream/nats/ObjWatch.md) - [Placement](api/faststream/nats/Placement.md) + - [PubAck](api/faststream/nats/PubAck.md) - [PullSub](api/faststream/nats/PullSub.md) - [RePublish](api/faststream/nats/RePublish.md) - [ReplayPolicy](api/faststream/nats/ReplayPolicy.md) @@ -607,6 +611,7 @@ search: - [JStream](api/faststream/nats/schemas/JStream.md) - [KvWatch](api/faststream/nats/schemas/KvWatch.md) - [ObjWatch](api/faststream/nats/schemas/ObjWatch.md) + - [PubAck](api/faststream/nats/schemas/PubAck.md) - [PullSub](api/faststream/nats/schemas/PullSub.md) - js_stream - [JStream](api/faststream/nats/schemas/js_stream/JStream.md) @@ -642,17 +647,6 @@ search: - [ConnectedSubscriberState](api/faststream/nats/subscriber/state/ConnectedSubscriberState.md) - [EmptySubscriberState](api/faststream/nats/subscriber/state/EmptySubscriberState.md) - [SubscriberState](api/faststream/nats/subscriber/state/SubscriberState.md) - - usecase - - [BatchPullStreamSubscriber](api/faststream/nats/subscriber/usecase/BatchPullStreamSubscriber.md) - - [ConcurrentCoreSubscriber](api/faststream/nats/subscriber/usecase/ConcurrentCoreSubscriber.md) - - [ConcurrentPullStreamSubscriber](api/faststream/nats/subscriber/usecase/ConcurrentPullStreamSubscriber.md) - - [ConcurrentPushStreamSubscriber](api/faststream/nats/subscriber/usecase/ConcurrentPushStreamSubscriber.md) - - [CoreSubscriber](api/faststream/nats/subscriber/usecase/CoreSubscriber.md) - - [KeyValueWatchSubscriber](api/faststream/nats/subscriber/usecase/KeyValueWatchSubscriber.md) - - [LogicSubscriber](api/faststream/nats/subscriber/usecase/LogicSubscriber.md) - - [ObjStoreWatchSubscriber](api/faststream/nats/subscriber/usecase/ObjStoreWatchSubscriber.md) - - [PullStreamSubscriber](api/faststream/nats/subscriber/usecase/PullStreamSubscriber.md) - - [PushStreamSubscription](api/faststream/nats/subscriber/usecase/PushStreamSubscription.md) - usecases - [BatchPullStreamSubscriber](api/faststream/nats/subscriber/usecases/BatchPullStreamSubscriber.md) - [ConcurrentCoreSubscriber](api/faststream/nats/subscriber/usecases/ConcurrentCoreSubscriber.md) @@ -720,6 +714,7 @@ search: - manager - [MetricsManager](api/faststream/prometheus/manager/MetricsManager.md) - middleware + - [BasePrometheusMiddleware](api/faststream/prometheus/middleware/BasePrometheusMiddleware.md) - [PrometheusMiddleware](api/faststream/prometheus/middleware/PrometheusMiddleware.md) - provider - [MetricsSettingsProvider](api/faststream/prometheus/provider/MetricsSettingsProvider.md) @@ -1001,6 +996,7 @@ search: - [serve_app](api/faststream/specification/asyncapi/site/serve_app.md) - utils - [clear_key](api/faststream/specification/asyncapi/utils/clear_key.md) + - [move_pydantic_refs](api/faststream/specification/asyncapi/utils/move_pydantic_refs.md) - [resolve_payloads](api/faststream/specification/asyncapi/utils/resolve_payloads.md) - [to_camelcase](api/faststream/specification/asyncapi/utils/to_camelcase.md) - v2_6_0 @@ -1012,98 +1008,66 @@ search: - [get_app_schema](api/faststream/specification/asyncapi/v2_6_0/generate/get_app_schema.md) - [get_broker_channels](api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_channels.md) - [get_broker_server](api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_server.md) - - [move_pydantic_refs](api/faststream/specification/asyncapi/v2_6_0/generate/move_pydantic_refs.md) - [resolve_channel_messages](api/faststream/specification/asyncapi/v2_6_0/generate/resolve_channel_messages.md) - schema + - [ApplicationInfo](api/faststream/specification/asyncapi/v2_6_0/schema/ApplicationInfo.md) + - [ApplicationSchema](api/faststream/specification/asyncapi/v2_6_0/schema/ApplicationSchema.md) - [Channel](api/faststream/specification/asyncapi/v2_6_0/schema/Channel.md) - [Components](api/faststream/specification/asyncapi/v2_6_0/schema/Components.md) - [Contact](api/faststream/specification/asyncapi/v2_6_0/schema/Contact.md) - [CorrelationId](api/faststream/specification/asyncapi/v2_6_0/schema/CorrelationId.md) - [ExternalDocs](api/faststream/specification/asyncapi/v2_6_0/schema/ExternalDocs.md) - - [Info](api/faststream/specification/asyncapi/v2_6_0/schema/Info.md) - [License](api/faststream/specification/asyncapi/v2_6_0/schema/License.md) - [Message](api/faststream/specification/asyncapi/v2_6_0/schema/Message.md) - [Operation](api/faststream/specification/asyncapi/v2_6_0/schema/Operation.md) - [Parameter](api/faststream/specification/asyncapi/v2_6_0/schema/Parameter.md) - [Reference](api/faststream/specification/asyncapi/v2_6_0/schema/Reference.md) - - [Schema](api/faststream/specification/asyncapi/v2_6_0/schema/Schema.md) - [Server](api/faststream/specification/asyncapi/v2_6_0/schema/Server.md) - [ServerVariable](api/faststream/specification/asyncapi/v2_6_0/schema/ServerVariable.md) - [Tag](api/faststream/specification/asyncapi/v2_6_0/schema/Tag.md) - - [channel_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/channel_from_spec.md) - - [contact_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/contact_from_spec.md) - - [docs_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/docs_from_spec.md) - - [license_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/license_from_spec.md) - - [message_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/message_from_spec.md) - - [operation_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/operation_from_spec.md) - - [tag_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/tag_from_spec.md) - bindings - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/ChannelBinding.md) - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/OperationBinding.md) - - [channel_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/channel_binding_from_spec.md) - - [operation_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/operation_binding_from_spec.md) - amqp - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/ChannelBinding.md) - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/OperationBinding.md) - - [channel_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel_binding_from_spec.md) - - [operation_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation_binding_from_spec.md) - channel - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/ChannelBinding.md) - [Exchange](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Exchange.md) - [Queue](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Queue.md) - - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/from_spec.md) - operation - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/OperationBinding.md) - - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/from_spec.md) - kafka - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/ChannelBinding.md) - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/OperationBinding.md) - - [channel_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel_binding_from_spec.md) - - [operation_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation_binding_from_spec.md) - channel - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel/ChannelBinding.md) - - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel/from_spec.md) - operation - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/OperationBinding.md) - - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/from_spec.md) - main - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/ChannelBinding.md) - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/OperationBinding.md) - - [channel_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel_binding_from_spec.md) - - [operation_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation_binding_from_spec.md) - channel - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/ChannelBinding.md) - - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/from_spec.md) - operation - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/OperationBinding.md) - - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/from_spec.md) - nats - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/ChannelBinding.md) - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/OperationBinding.md) - - [channel_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel_binding_from_spec.md) - - [operation_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation_binding_from_spec.md) - channel - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel/ChannelBinding.md) - - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel/from_spec.md) - operation - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/OperationBinding.md) - - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/from_spec.md) - redis - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/ChannelBinding.md) - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/OperationBinding.md) - - [channel_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel_binding_from_spec.md) - - [operation_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation_binding_from_spec.md) - channel - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel/ChannelBinding.md) - - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel/from_spec.md) - operation - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/OperationBinding.md) - - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/from_spec.md) - sqs - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/ChannelBinding.md) - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/OperationBinding.md) - - [channel_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel_binding_from_spec.md) - - [operation_binding_from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation_binding_from_spec.md) - channel - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/ChannelBinding.md) - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/from_spec.md) @@ -1112,35 +1076,28 @@ search: - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/from_spec.md) - channels - [Channel](api/faststream/specification/asyncapi/v2_6_0/schema/channels/Channel.md) - - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/channels/from_spec.md) - components - [Components](api/faststream/specification/asyncapi/v2_6_0/schema/components/Components.md) - contact - [Contact](api/faststream/specification/asyncapi/v2_6_0/schema/contact/Contact.md) - - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/contact/from_spec.md) - docs - [ExternalDocs](api/faststream/specification/asyncapi/v2_6_0/schema/docs/ExternalDocs.md) - - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/docs/from_spec.md) - info - - [Info](api/faststream/specification/asyncapi/v2_6_0/schema/info/Info.md) + - [ApplicationInfo](api/faststream/specification/asyncapi/v2_6_0/schema/info/ApplicationInfo.md) - license - [License](api/faststream/specification/asyncapi/v2_6_0/schema/license/License.md) - - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/license/from_spec.md) - message - [CorrelationId](api/faststream/specification/asyncapi/v2_6_0/schema/message/CorrelationId.md) - [Message](api/faststream/specification/asyncapi/v2_6_0/schema/message/Message.md) - - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/message/from_spec.md) - operations - [Operation](api/faststream/specification/asyncapi/v2_6_0/schema/operations/Operation.md) - - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/operations/from_spec.md) - schema - - [Schema](api/faststream/specification/asyncapi/v2_6_0/schema/schema/Schema.md) + - [ApplicationSchema](api/faststream/specification/asyncapi/v2_6_0/schema/schema/ApplicationSchema.md) - servers - [Server](api/faststream/specification/asyncapi/v2_6_0/schema/servers/Server.md) - [ServerVariable](api/faststream/specification/asyncapi/v2_6_0/schema/servers/ServerVariable.md) - tag - [Tag](api/faststream/specification/asyncapi/v2_6_0/schema/tag/Tag.md) - - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/tag/from_spec.md) - utils - [Parameter](api/faststream/specification/asyncapi/v2_6_0/schema/utils/Parameter.md) - [Reference](api/faststream/specification/asyncapi/v2_6_0/schema/utils/Reference.md) @@ -1152,68 +1109,106 @@ search: - generate - [get_app_schema](api/faststream/specification/asyncapi/v3_0_0/generate/get_app_schema.md) - [get_broker_channels](api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_channels.md) - - [get_broker_operations](api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_operations.md) - [get_broker_server](api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_server.md) - schema + - [ApplicationInfo](api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationInfo.md) + - [ApplicationSchema](api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationSchema.md) - [Channel](api/faststream/specification/asyncapi/v3_0_0/schema/Channel.md) - [Components](api/faststream/specification/asyncapi/v3_0_0/schema/Components.md) - - [Info](api/faststream/specification/asyncapi/v3_0_0/schema/Info.md) + - [Contact](api/faststream/specification/asyncapi/v3_0_0/schema/Contact.md) + - [CorrelationId](api/faststream/specification/asyncapi/v3_0_0/schema/CorrelationId.md) + - [ExternalDocs](api/faststream/specification/asyncapi/v3_0_0/schema/ExternalDocs.md) + - [License](api/faststream/specification/asyncapi/v3_0_0/schema/License.md) + - [Message](api/faststream/specification/asyncapi/v3_0_0/schema/Message.md) - [Operation](api/faststream/specification/asyncapi/v3_0_0/schema/Operation.md) - - [Schema](api/faststream/specification/asyncapi/v3_0_0/schema/Schema.md) + - [Parameter](api/faststream/specification/asyncapi/v3_0_0/schema/Parameter.md) + - [Reference](api/faststream/specification/asyncapi/v3_0_0/schema/Reference.md) - [Server](api/faststream/specification/asyncapi/v3_0_0/schema/Server.md) - - [channel_from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/channel_from_spec.md) - - [operation_from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/operation_from_spec.md) + - [ServerVariable](api/faststream/specification/asyncapi/v3_0_0/schema/ServerVariable.md) + - [Tag](api/faststream/specification/asyncapi/v3_0_0/schema/Tag.md) - bindings + - [ChannelBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/ChannelBinding.md) - [OperationBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/OperationBinding.md) - - [channel_binding_from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/channel_binding_from_spec.md) - - [operation_binding_from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/operation_binding_from_spec.md) - amqp + - [ChannelBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/ChannelBinding.md) - [OperationBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/OperationBinding.md) - - [channel_binding_from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel_binding_from_spec.md) - - [operation_binding_from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation_binding_from_spec.md) - channel - - [from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel/from_spec.md) + - [ChannelBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel/ChannelBinding.md) - operation - [OperationBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation/OperationBinding.md) - - [from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation/from_spec.md) + - kafka + - [ChannelBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka/OperationBinding.md) - main + - [ChannelBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/ChannelBinding.md) - [OperationBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/OperationBinding.md) - - [channel_binding_from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel_binding_from_spec.md) - - [operation_binding_from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation_binding_from_spec.md) - channel - - [from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel/from_spec.md) + - [ChannelBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel/ChannelBinding.md) - operation - [OperationBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation/OperationBinding.md) - - [from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation/from_spec.md) + - nats + - [ChannelBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats/OperationBinding.md) + - redis + - [ChannelBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis/OperationBinding.md) + - sqs + - [ChannelBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs/OperationBinding.md) - channels - [Channel](api/faststream/specification/asyncapi/v3_0_0/schema/channels/Channel.md) - - [from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/channels/from_spec.md) - components - [Components](api/faststream/specification/asyncapi/v3_0_0/schema/components/Components.md) + - contact + - [Contact](api/faststream/specification/asyncapi/v3_0_0/schema/contact/Contact.md) + - docs + - [ExternalDocs](api/faststream/specification/asyncapi/v3_0_0/schema/docs/ExternalDocs.md) - info - - [Info](api/faststream/specification/asyncapi/v3_0_0/schema/info/Info.md) + - [ApplicationInfo](api/faststream/specification/asyncapi/v3_0_0/schema/info/ApplicationInfo.md) + - license + - [License](api/faststream/specification/asyncapi/v3_0_0/schema/license/License.md) + - message + - [CorrelationId](api/faststream/specification/asyncapi/v3_0_0/schema/message/CorrelationId.md) + - [Message](api/faststream/specification/asyncapi/v3_0_0/schema/message/Message.md) - operations - [Action](api/faststream/specification/asyncapi/v3_0_0/schema/operations/Action.md) - [Operation](api/faststream/specification/asyncapi/v3_0_0/schema/operations/Operation.md) - - [from_spec](api/faststream/specification/asyncapi/v3_0_0/schema/operations/from_spec.md) - schema - - [Schema](api/faststream/specification/asyncapi/v3_0_0/schema/schema/Schema.md) + - [ApplicationSchema](api/faststream/specification/asyncapi/v3_0_0/schema/schema/ApplicationSchema.md) - servers - [Server](api/faststream/specification/asyncapi/v3_0_0/schema/servers/Server.md) + - tag + - [Tag](api/faststream/specification/asyncapi/v3_0_0/schema/tag/Tag.md) + - utils + - [Parameter](api/faststream/specification/asyncapi/v3_0_0/schema/utils/Parameter.md) + - [Reference](api/faststream/specification/asyncapi/v3_0_0/schema/utils/Reference.md) - base - info - - [BaseInfo](api/faststream/specification/base/info/BaseInfo.md) - - proto - - [SpecificationEndpoint](api/faststream/specification/base/proto/SpecificationEndpoint.md) + - [BaseApplicationInfo](api/faststream/specification/base/info/BaseApplicationInfo.md) - schema - - [BaseSchema](api/faststream/specification/base/schema/BaseSchema.md) + - [BaseApplicationSchema](api/faststream/specification/base/schema/BaseApplicationSchema.md) - specification - [Specification](api/faststream/specification/base/specification/Specification.md) + - proto + - [EndpointSpecification](api/faststream/specification/proto/EndpointSpecification.md) + - [ServerSpecification](api/faststream/specification/proto/ServerSpecification.md) + - broker + - [ServerSpecification](api/faststream/specification/proto/broker/ServerSpecification.md) + - endpoint + - [EndpointSpecification](api/faststream/specification/proto/endpoint/EndpointSpecification.md) - schema - [Contact](api/faststream/specification/schema/Contact.md) + - [ContactDict](api/faststream/specification/schema/ContactDict.md) - [ExternalDocs](api/faststream/specification/schema/ExternalDocs.md) + - [ExternalDocsDict](api/faststream/specification/schema/ExternalDocsDict.md) - [License](api/faststream/specification/schema/License.md) + - [LicenseDict](api/faststream/specification/schema/LicenseDict.md) + - [Message](api/faststream/specification/schema/Message.md) + - [Operation](api/faststream/specification/schema/Operation.md) + - [PublisherSpec](api/faststream/specification/schema/PublisherSpec.md) + - [SubscriberSpec](api/faststream/specification/schema/SubscriberSpec.md) - [Tag](api/faststream/specification/schema/Tag.md) + - [TagDict](api/faststream/specification/schema/TagDict.md) - bindings - [ChannelBinding](api/faststream/specification/schema/bindings/ChannelBinding.md) - [OperationBinding](api/faststream/specification/schema/bindings/OperationBinding.md) @@ -1237,36 +1232,39 @@ search: - sqs - [ChannelBinding](api/faststream/specification/schema/bindings/sqs/ChannelBinding.md) - [OperationBinding](api/faststream/specification/schema/bindings/sqs/OperationBinding.md) - - channel - - [Channel](api/faststream/specification/schema/channel/Channel.md) - - components - - [Components](api/faststream/specification/schema/components/Components.md) - - contact - - [Contact](api/faststream/specification/schema/contact/Contact.md) - - [ContactDict](api/faststream/specification/schema/contact/ContactDict.md) - - docs - - [ExternalDocs](api/faststream/specification/schema/docs/ExternalDocs.md) - - [ExternalDocsDict](api/faststream/specification/schema/docs/ExternalDocsDict.md) - - info - - [Info](api/faststream/specification/schema/info/Info.md) - - license - - [License](api/faststream/specification/schema/license/License.md) - - [LicenseDict](api/faststream/specification/schema/license/LicenseDict.md) + - extra + - [Contact](api/faststream/specification/schema/extra/Contact.md) + - [ContactDict](api/faststream/specification/schema/extra/ContactDict.md) + - [ExternalDocs](api/faststream/specification/schema/extra/ExternalDocs.md) + - [ExternalDocsDict](api/faststream/specification/schema/extra/ExternalDocsDict.md) + - [License](api/faststream/specification/schema/extra/License.md) + - [LicenseDict](api/faststream/specification/schema/extra/LicenseDict.md) + - [Tag](api/faststream/specification/schema/extra/Tag.md) + - [TagDict](api/faststream/specification/schema/extra/TagDict.md) + - contact + - [Contact](api/faststream/specification/schema/extra/contact/Contact.md) + - [ContactDict](api/faststream/specification/schema/extra/contact/ContactDict.md) + - external_docs + - [ExternalDocs](api/faststream/specification/schema/extra/external_docs/ExternalDocs.md) + - [ExternalDocsDict](api/faststream/specification/schema/extra/external_docs/ExternalDocsDict.md) + - license + - [License](api/faststream/specification/schema/extra/license/License.md) + - [LicenseDict](api/faststream/specification/schema/extra/license/LicenseDict.md) + - tag + - [Tag](api/faststream/specification/schema/extra/tag/Tag.md) + - [TagDict](api/faststream/specification/schema/extra/tag/TagDict.md) - message - - [CorrelationId](api/faststream/specification/schema/message/CorrelationId.md) - [Message](api/faststream/specification/schema/message/Message.md) + - model + - [Message](api/faststream/specification/schema/message/model/Message.md) - operation - [Operation](api/faststream/specification/schema/operation/Operation.md) - - security - - [OauthFlowObj](api/faststream/specification/schema/security/OauthFlowObj.md) - - [OauthFlows](api/faststream/specification/schema/security/OauthFlows.md) - - [SecuritySchemaComponent](api/faststream/specification/schema/security/SecuritySchemaComponent.md) - - servers - - [Server](api/faststream/specification/schema/servers/Server.md) - - [ServerVariable](api/faststream/specification/schema/servers/ServerVariable.md) - - tag - - [Tag](api/faststream/specification/schema/tag/Tag.md) - - [TagDict](api/faststream/specification/schema/tag/TagDict.md) + - model + - [Operation](api/faststream/specification/schema/operation/model/Operation.md) + - publisher + - [PublisherSpec](api/faststream/specification/schema/publisher/PublisherSpec.md) + - subscriber + - [SubscriberSpec](api/faststream/specification/schema/subscriber/SubscriberSpec.md) - [FastStream People](faststream-people.md) - Contributing - [Development](getting-started/contributing/CONTRIBUTING.md) diff --git a/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationConcurrentDefaultSubscriber.md b/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationConcurrentDefaultSubscriber.md new file mode 100644 index 0000000000..16f0f81d14 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationConcurrentDefaultSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.subscriber.specified.SpecificationConcurrentDefaultSubscriber diff --git a/docs/docs/en/api/faststream/specification/schema/tag/Tag.md b/docs/docs/en/api/faststream/nats/PubAck.md similarity index 71% rename from docs/docs/en/api/faststream/specification/schema/tag/Tag.md rename to docs/docs/en/api/faststream/nats/PubAck.md index 00ead386cb..697f22abe6 100644 --- a/docs/docs/en/api/faststream/specification/schema/tag/Tag.md +++ b/docs/docs/en/api/faststream/nats/PubAck.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.schema.tag.Tag +::: nats.js.api.PubAck diff --git a/docs/docs/en/api/faststream/specification/schema/info/Info.md b/docs/docs/en/api/faststream/nats/schemas/PubAck.md similarity index 70% rename from docs/docs/en/api/faststream/specification/schema/info/Info.md rename to docs/docs/en/api/faststream/nats/schemas/PubAck.md index 23d6ddec87..697f22abe6 100644 --- a/docs/docs/en/api/faststream/specification/schema/info/Info.md +++ b/docs/docs/en/api/faststream/nats/schemas/PubAck.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.schema.info.Info +::: nats.js.api.PubAck diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecase/PushStreamSubscription.md b/docs/docs/en/api/faststream/prometheus/middleware/BasePrometheusMiddleware.md similarity index 63% rename from docs/docs/en/api/faststream/nats/subscriber/usecase/PushStreamSubscription.md rename to docs/docs/en/api/faststream/prometheus/middleware/BasePrometheusMiddleware.md index bb29bbb9c2..62bbd031ac 100644 --- a/docs/docs/en/api/faststream/nats/subscriber/usecase/PushStreamSubscription.md +++ b/docs/docs/en/api/faststream/prometheus/middleware/BasePrometheusMiddleware.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.nats.subscriber.usecase.PushStreamSubscription +::: faststream.prometheus.middleware.BasePrometheusMiddleware diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecase/ObjStoreWatchSubscriber.md b/docs/docs/en/api/faststream/specification/asyncapi/utils/move_pydantic_refs.md similarity index 63% rename from docs/docs/en/api/faststream/nats/subscriber/usecase/ObjStoreWatchSubscriber.md rename to docs/docs/en/api/faststream/specification/asyncapi/utils/move_pydantic_refs.md index ad15f32931..445472f96d 100644 --- a/docs/docs/en/api/faststream/nats/subscriber/usecase/ObjStoreWatchSubscriber.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/utils/move_pydantic_refs.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.nats.subscriber.usecase.ObjStoreWatchSubscriber +::: faststream.specification.asyncapi.utils.move_pydantic_refs diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/move_pydantic_refs.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/move_pydantic_refs.md deleted file mode 100644 index 3494537e25..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/move_pydantic_refs.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.generate.move_pydantic_refs diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecase/ConcurrentCoreSubscriber.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ApplicationInfo.md similarity index 61% rename from docs/docs/en/api/faststream/nats/subscriber/usecase/ConcurrentCoreSubscriber.md rename to docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ApplicationInfo.md index e1f100c043..b7aaf16515 100644 --- a/docs/docs/en/api/faststream/nats/subscriber/usecase/ConcurrentCoreSubscriber.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ApplicationInfo.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.nats.subscriber.usecase.ConcurrentCoreSubscriber +::: faststream.specification.asyncapi.v2_6_0.schema.ApplicationInfo diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecase/ConcurrentPullStreamSubscriber.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ApplicationSchema.md similarity index 61% rename from docs/docs/en/api/faststream/nats/subscriber/usecase/ConcurrentPullStreamSubscriber.md rename to docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ApplicationSchema.md index c1b7207285..614fed94e1 100644 --- a/docs/docs/en/api/faststream/nats/subscriber/usecase/ConcurrentPullStreamSubscriber.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ApplicationSchema.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.nats.subscriber.usecase.ConcurrentPullStreamSubscriber +::: faststream.specification.asyncapi.v2_6_0.schema.ApplicationSchema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/from_spec.md deleted file mode 100644 index a1217d16ed..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.channel.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel_binding_from_spec.md deleted file mode 100644 index b23b92754d..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel_binding_from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.channel_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/from_spec.md deleted file mode 100644 index b9f6bb0bad..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.operation.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation_binding_from_spec.md deleted file mode 100644 index 9d6d922417..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation_binding_from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.operation_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/channel_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/channel_binding_from_spec.md deleted file mode 100644 index b6b5acc218..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/channel_binding_from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.channel_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/from_spec.md deleted file mode 100644 index b272f8b9c8..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka.operation.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation_binding_from_spec.md deleted file mode 100644 index 6f21621ca9..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation_binding_from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka.operation_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/from_spec.md deleted file mode 100644 index a585d16f8f..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.main.channel.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel_binding_from_spec.md deleted file mode 100644 index 8bdcd11238..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel_binding_from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.main.channel_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/from_spec.md deleted file mode 100644 index 5c5fbed4b9..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.main.operation.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation_binding_from_spec.md deleted file mode 100644 index ff97aa268d..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation_binding_from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.main.operation_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/from_spec.md deleted file mode 100644 index 208641ea9b..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.nats.operation.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation_binding_from_spec.md deleted file mode 100644 index a96dc2df87..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation_binding_from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.nats.operation_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/operation_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/operation_binding_from_spec.md deleted file mode 100644 index 3ca4781fb7..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/operation_binding_from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.operation_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/from_spec.md deleted file mode 100644 index f046e5bbe4..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.redis.operation.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation_binding_from_spec.md deleted file mode 100644 index 8bd9df5f63..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation_binding_from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.redis.operation_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channel_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channel_from_spec.md deleted file mode 100644 index 7f5747228e..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channel_from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.channel_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channels/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channels/from_spec.md deleted file mode 100644 index 64b96ac9a6..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channels/from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.channels.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact/from_spec.md deleted file mode 100644 index bb218f2cfb..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact/from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.contact.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact_from_spec.md deleted file mode 100644 index 31b181d86e..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact_from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.contact_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs/from_spec.md deleted file mode 100644 index a604f0734a..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs/from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.docs.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs_from_spec.md deleted file mode 100644 index 343fbfdb3c..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs_from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.docs_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/info/ApplicationInfo.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/info/ApplicationInfo.md new file mode 100644 index 0000000000..db377ddd61 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/info/ApplicationInfo.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.info.ApplicationInfo diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/info/Info.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/info/Info.md deleted file mode 100644 index 9865afcb70..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/info/Info.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.info.Info diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license/from_spec.md deleted file mode 100644 index f3e154561d..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license/from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.license.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license_from_spec.md deleted file mode 100644 index 0281ab3755..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license_from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.license_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/from_spec.md deleted file mode 100644 index 4d3923d382..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.message.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message_from_spec.md deleted file mode 100644 index 25fec8161b..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message_from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.message_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operation_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operation_from_spec.md deleted file mode 100644 index 750a7d5f66..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operation_from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.operation_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operations/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operations/from_spec.md deleted file mode 100644 index 70119aae06..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operations/from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.operations.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/schema/ApplicationSchema.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/schema/ApplicationSchema.md new file mode 100644 index 0000000000..2a380a8e4d --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/schema/ApplicationSchema.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.schema.ApplicationSchema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/schema/Schema.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/schema/Schema.md deleted file mode 100644 index 5f7dc7f43e..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/schema/Schema.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.schema.Schema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag/from_spec.md deleted file mode 100644 index 0269c70d4c..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag/from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.tag.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag_from_spec.md deleted file mode 100644 index 8f349787b1..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag_from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.tag_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_operations.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_operations.md deleted file mode 100644 index eea75e44cb..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_operations.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.generate.get_broker_operations diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationInfo.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationInfo.md new file mode 100644 index 0000000000..be7a85513c --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationInfo.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.ApplicationInfo diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecase/ConcurrentPushStreamSubscriber.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationSchema.md similarity index 61% rename from docs/docs/en/api/faststream/nats/subscriber/usecase/ConcurrentPushStreamSubscriber.md rename to docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationSchema.md index ffa2e0c37b..0f3fa28a38 100644 --- a/docs/docs/en/api/faststream/nats/subscriber/usecase/ConcurrentPushStreamSubscriber.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationSchema.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.nats.subscriber.usecase.ConcurrentPushStreamSubscriber +::: faststream.specification.asyncapi.v3_0_0.schema.ApplicationSchema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Contact.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Contact.md new file mode 100644 index 0000000000..14b7574d92 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Contact.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.contact.Contact diff --git a/docs/docs/en/api/faststream/specification/schema/message/CorrelationId.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/CorrelationId.md similarity index 59% rename from docs/docs/en/api/faststream/specification/schema/message/CorrelationId.md rename to docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/CorrelationId.md index 7f283d5a73..bbfc2f40d8 100644 --- a/docs/docs/en/api/faststream/specification/schema/message/CorrelationId.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/CorrelationId.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.schema.message.CorrelationId +::: faststream.specification.asyncapi.v2_6_0.schema.message.CorrelationId diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ExternalDocs.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ExternalDocs.md new file mode 100644 index 0000000000..8b66a2c5f3 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ExternalDocs.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.docs.ExternalDocs diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/License.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/License.md new file mode 100644 index 0000000000..d9d4102522 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/License.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.license.License diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Message.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Message.md new file mode 100644 index 0000000000..9667e77e8e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Message.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.message.Message diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Parameter.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Parameter.md new file mode 100644 index 0000000000..c2971d5485 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Parameter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.utils.Parameter diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Reference.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Reference.md new file mode 100644 index 0000000000..2737907b0e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Reference.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.utils.Reference diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Schema.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Schema.md deleted file mode 100644 index 680b107ea3..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Schema.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.Schema diff --git a/docs/docs/en/api/faststream/specification/schema/servers/ServerVariable.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ServerVariable.md similarity index 59% rename from docs/docs/en/api/faststream/specification/schema/servers/ServerVariable.md rename to docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ServerVariable.md index 2831c07069..8606288a32 100644 --- a/docs/docs/en/api/faststream/specification/schema/servers/ServerVariable.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ServerVariable.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.schema.servers.ServerVariable +::: faststream.specification.asyncapi.v2_6_0.schema.servers.ServerVariable diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecase/PullStreamSubscriber.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Tag.md similarity index 64% rename from docs/docs/en/api/faststream/nats/subscriber/usecase/PullStreamSubscriber.md rename to docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Tag.md index 30f30a893f..c3d9025966 100644 --- a/docs/docs/en/api/faststream/nats/subscriber/usecase/PullStreamSubscriber.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Tag.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.nats.subscriber.usecase.PullStreamSubscriber +::: faststream.specification.asyncapi.v2_6_0.schema.tag.Tag diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/ChannelBinding.md new file mode 100644 index 0000000000..ca8431218b --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/ChannelBinding.md similarity index 89% rename from docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel/from_spec.md rename to docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/ChannelBinding.md index 543112ccce..2777001c4d 100644 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel/from_spec.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/ChannelBinding.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.asyncapi.v3_0_0.schema.bindings.amqp.channel.from_spec +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.amqp.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel/ChannelBinding.md similarity index 87% rename from docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation/from_spec.md rename to docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel/ChannelBinding.md index be10d174d9..74c10098ac 100644 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation/from_spec.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel/ChannelBinding.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.asyncapi.v3_0_0.schema.bindings.amqp.operation.from_spec +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.amqp.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel_binding_from_spec.md deleted file mode 100644 index 13fc791e80..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel_binding_from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.bindings.amqp.channel_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation_binding_from_spec.md deleted file mode 100644 index 17aecb0abd..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation_binding_from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.bindings.amqp.operation_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/channel_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/channel_binding_from_spec.md deleted file mode 100644 index 71d74cb263..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/channel_binding_from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.bindings.channel_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka/ChannelBinding.md similarity index 87% rename from docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel/from_spec.md rename to docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka/ChannelBinding.md index 5b5f07e785..82b2556711 100644 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel/from_spec.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka/ChannelBinding.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka.channel.from_spec +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka/OperationBinding.md similarity index 85% rename from docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel_binding_from_spec.md rename to docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka/OperationBinding.md index 12cec52d31..49e28f86ef 100644 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel_binding_from_spec.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka/OperationBinding.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka.channel_binding_from_spec +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/ChannelBinding.md similarity index 89% rename from docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel/from_spec.md rename to docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/ChannelBinding.md index 056c911d83..07977ed15f 100644 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel/from_spec.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/ChannelBinding.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.asyncapi.v3_0_0.schema.bindings.main.channel.from_spec +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.main.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel/ChannelBinding.md similarity index 87% rename from docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation/from_spec.md rename to docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel/ChannelBinding.md index 833a6e58c1..409e449a27 100644 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation/from_spec.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel/ChannelBinding.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.asyncapi.v3_0_0.schema.bindings.main.operation.from_spec +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.main.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel_binding_from_spec.md deleted file mode 100644 index c50397eed5..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel_binding_from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.bindings.main.channel_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation_binding_from_spec.md deleted file mode 100644 index a00d249af4..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation_binding_from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.bindings.main.operation_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats/ChannelBinding.md similarity index 87% rename from docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel/from_spec.md rename to docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats/ChannelBinding.md index 942832cb44..ebc06a51b8 100644 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel/from_spec.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats/ChannelBinding.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.nats.channel.from_spec +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.nats.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats/OperationBinding.md similarity index 85% rename from docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel_binding_from_spec.md rename to docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats/OperationBinding.md index 3ad06c3ee2..10ebc684ce 100644 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel_binding_from_spec.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats/OperationBinding.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.nats.channel_binding_from_spec +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.nats.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/operation_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/operation_binding_from_spec.md deleted file mode 100644 index c76d126bf0..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/operation_binding_from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.bindings.operation_binding_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis/ChannelBinding.md similarity index 87% rename from docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel/from_spec.md rename to docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis/ChannelBinding.md index 54540e817f..4c859b133e 100644 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel/from_spec.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis/ChannelBinding.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.redis.channel.from_spec +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.redis.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis/OperationBinding.md similarity index 85% rename from docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel_binding_from_spec.md rename to docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis/OperationBinding.md index 550f068d5c..5e7ef90817 100644 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel_binding_from_spec.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis/OperationBinding.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.redis.channel_binding_from_spec +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.redis.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs/ChannelBinding.md similarity index 86% rename from docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel_binding_from_spec.md rename to docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs/ChannelBinding.md index 82d3c125b1..274f800ea8 100644 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel_binding_from_spec.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs/ChannelBinding.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.channel_binding_from_spec +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation_binding_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs/OperationBinding.md similarity index 85% rename from docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation_binding_from_spec.md rename to docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs/OperationBinding.md index e42a8bdedb..931067bfef 100644 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation_binding_from_spec.md +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs/OperationBinding.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.operation_binding_from_spec +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channel_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channel_from_spec.md deleted file mode 100644 index 109f18f748..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channel_from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.channel_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channels/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channels/from_spec.md deleted file mode 100644 index 949ff18a73..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channels/from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.channels.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/contact/Contact.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/contact/Contact.md new file mode 100644 index 0000000000..14b7574d92 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/contact/Contact.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.contact.Contact diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/docs/ExternalDocs.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/docs/ExternalDocs.md new file mode 100644 index 0000000000..8b66a2c5f3 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/docs/ExternalDocs.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.docs.ExternalDocs diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/info/ApplicationInfo.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/info/ApplicationInfo.md new file mode 100644 index 0000000000..f0c2b0f95d --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/info/ApplicationInfo.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.info.ApplicationInfo diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/info/Info.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/info/Info.md deleted file mode 100644 index b3ddac50c0..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/info/Info.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.info.Info diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/license/License.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/license/License.md new file mode 100644 index 0000000000..d9d4102522 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/license/License.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.license.License diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/message/CorrelationId.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/message/CorrelationId.md new file mode 100644 index 0000000000..bbfc2f40d8 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/message/CorrelationId.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.message.CorrelationId diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/message/Message.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/message/Message.md new file mode 100644 index 0000000000..9667e77e8e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/message/Message.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.message.Message diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operation_from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operation_from_spec.md deleted file mode 100644 index 178bf36c4a..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operation_from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.operation_from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/from_spec.md deleted file mode 100644 index 9b9b197889..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.operations.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/schema/ApplicationSchema.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/schema/ApplicationSchema.md new file mode 100644 index 0000000000..57fc00568a --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/schema/ApplicationSchema.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.schema.ApplicationSchema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/schema/Schema.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/schema/Schema.md deleted file mode 100644 index 16a72b4b01..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/schema/Schema.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.schema.Schema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/tag/Tag.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/tag/Tag.md new file mode 100644 index 0000000000..c3d9025966 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/tag/Tag.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.tag.Tag diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/utils/Parameter.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/utils/Parameter.md new file mode 100644 index 0000000000..c2971d5485 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/utils/Parameter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.utils.Parameter diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/utils/Reference.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/utils/Reference.md new file mode 100644 index 0000000000..2737907b0e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/utils/Reference.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.utils.Reference diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Schema.md b/docs/docs/en/api/faststream/specification/base/info/BaseApplicationInfo.md similarity index 65% rename from docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Schema.md rename to docs/docs/en/api/faststream/specification/base/info/BaseApplicationInfo.md index 929fbef551..324bbbcec9 100644 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Schema.md +++ b/docs/docs/en/api/faststream/specification/base/info/BaseApplicationInfo.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.asyncapi.v2_6_0.schema.Schema +::: faststream.specification.base.info.BaseApplicationInfo diff --git a/docs/docs/en/api/faststream/specification/base/proto/SpecificationEndpoint.md b/docs/docs/en/api/faststream/specification/base/proto/SpecificationEndpoint.md deleted file mode 100644 index a6a2658fc4..0000000000 --- a/docs/docs/en/api/faststream/specification/base/proto/SpecificationEndpoint.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.base.proto.SpecificationEndpoint diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecase/KeyValueWatchSubscriber.md b/docs/docs/en/api/faststream/specification/base/schema/BaseApplicationSchema.md similarity index 63% rename from docs/docs/en/api/faststream/nats/subscriber/usecase/KeyValueWatchSubscriber.md rename to docs/docs/en/api/faststream/specification/base/schema/BaseApplicationSchema.md index 778557ee2b..8d9291322c 100644 --- a/docs/docs/en/api/faststream/nats/subscriber/usecase/KeyValueWatchSubscriber.md +++ b/docs/docs/en/api/faststream/specification/base/schema/BaseApplicationSchema.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.nats.subscriber.usecase.KeyValueWatchSubscriber +::: faststream.specification.base.schema.BaseApplicationSchema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Info.md b/docs/docs/en/api/faststream/specification/proto/EndpointSpecification.md similarity index 65% rename from docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Info.md rename to docs/docs/en/api/faststream/specification/proto/EndpointSpecification.md index 78a6f784de..3d6dcee882 100644 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Info.md +++ b/docs/docs/en/api/faststream/specification/proto/EndpointSpecification.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.asyncapi.v3_0_0.schema.Info +::: faststream.specification.proto.EndpointSpecification diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecase/LogicSubscriber.md b/docs/docs/en/api/faststream/specification/proto/ServerSpecification.md similarity index 66% rename from docs/docs/en/api/faststream/nats/subscriber/usecase/LogicSubscriber.md rename to docs/docs/en/api/faststream/specification/proto/ServerSpecification.md index 100db07bbe..d49b60e512 100644 --- a/docs/docs/en/api/faststream/nats/subscriber/usecase/LogicSubscriber.md +++ b/docs/docs/en/api/faststream/specification/proto/ServerSpecification.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.nats.subscriber.usecase.LogicSubscriber +::: faststream.specification.proto.ServerSpecification diff --git a/docs/docs/en/api/faststream/specification/proto/broker/ServerSpecification.md b/docs/docs/en/api/faststream/specification/proto/broker/ServerSpecification.md new file mode 100644 index 0000000000..6bb667f707 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/proto/broker/ServerSpecification.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.proto.broker.ServerSpecification diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecase/BatchPullStreamSubscriber.md b/docs/docs/en/api/faststream/specification/proto/endpoint/EndpointSpecification.md similarity index 62% rename from docs/docs/en/api/faststream/nats/subscriber/usecase/BatchPullStreamSubscriber.md rename to docs/docs/en/api/faststream/specification/proto/endpoint/EndpointSpecification.md index dfb1c43575..491c5e3e87 100644 --- a/docs/docs/en/api/faststream/nats/subscriber/usecase/BatchPullStreamSubscriber.md +++ b/docs/docs/en/api/faststream/specification/proto/endpoint/EndpointSpecification.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.nats.subscriber.usecase.BatchPullStreamSubscriber +::: faststream.specification.proto.endpoint.EndpointSpecification diff --git a/docs/docs/en/api/faststream/specification/base/info/BaseInfo.md b/docs/docs/en/api/faststream/specification/schema/ContactDict.md similarity index 69% rename from docs/docs/en/api/faststream/specification/base/info/BaseInfo.md rename to docs/docs/en/api/faststream/specification/schema/ContactDict.md index 0925aac556..79d9ca5fb2 100644 --- a/docs/docs/en/api/faststream/specification/base/info/BaseInfo.md +++ b/docs/docs/en/api/faststream/specification/schema/ContactDict.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.base.info.BaseInfo +::: faststream.specification.schema.ContactDict diff --git a/docs/docs/en/api/faststream/specification/schema/channel/Channel.md b/docs/docs/en/api/faststream/specification/schema/ExternalDocsDict.md similarity index 67% rename from docs/docs/en/api/faststream/specification/schema/channel/Channel.md rename to docs/docs/en/api/faststream/specification/schema/ExternalDocsDict.md index 054f3a7524..788848b13a 100644 --- a/docs/docs/en/api/faststream/specification/schema/channel/Channel.md +++ b/docs/docs/en/api/faststream/specification/schema/ExternalDocsDict.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.schema.channel.Channel +::: faststream.specification.schema.ExternalDocsDict diff --git a/docs/docs/en/api/faststream/specification/schema/LicenseDict.md b/docs/docs/en/api/faststream/specification/schema/LicenseDict.md new file mode 100644 index 0000000000..16204a3fc8 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/LicenseDict.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.LicenseDict diff --git a/docs/docs/en/api/faststream/specification/schema/Message.md b/docs/docs/en/api/faststream/specification/schema/Message.md new file mode 100644 index 0000000000..d1baee52f5 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/Message.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.Message diff --git a/docs/docs/en/api/faststream/specification/schema/Operation.md b/docs/docs/en/api/faststream/specification/schema/Operation.md new file mode 100644 index 0000000000..cde09d402f --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/Operation.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.Operation diff --git a/docs/docs/en/api/faststream/specification/schema/PublisherSpec.md b/docs/docs/en/api/faststream/specification/schema/PublisherSpec.md new file mode 100644 index 0000000000..5b3e7f23e5 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/PublisherSpec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.PublisherSpec diff --git a/docs/docs/en/api/faststream/specification/schema/servers/Server.md b/docs/docs/en/api/faststream/specification/schema/SubscriberSpec.md similarity index 68% rename from docs/docs/en/api/faststream/specification/schema/servers/Server.md rename to docs/docs/en/api/faststream/specification/schema/SubscriberSpec.md index 9885a049b8..7ec1f6964b 100644 --- a/docs/docs/en/api/faststream/specification/schema/servers/Server.md +++ b/docs/docs/en/api/faststream/specification/schema/SubscriberSpec.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.schema.servers.Server +::: faststream.specification.schema.SubscriberSpec diff --git a/docs/docs/en/api/faststream/specification/schema/tag/TagDict.md b/docs/docs/en/api/faststream/specification/schema/TagDict.md similarity index 69% rename from docs/docs/en/api/faststream/specification/schema/tag/TagDict.md rename to docs/docs/en/api/faststream/specification/schema/TagDict.md index e76b92e43b..02f4de9c05 100644 --- a/docs/docs/en/api/faststream/specification/schema/tag/TagDict.md +++ b/docs/docs/en/api/faststream/specification/schema/TagDict.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.schema.tag.TagDict +::: faststream.specification.schema.TagDict diff --git a/docs/docs/en/api/faststream/specification/schema/components/Components.md b/docs/docs/en/api/faststream/specification/schema/components/Components.md deleted file mode 100644 index aee53e9aeb..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/components/Components.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.components.Components diff --git a/docs/docs/en/api/faststream/specification/schema/extra/Contact.md b/docs/docs/en/api/faststream/specification/schema/extra/Contact.md new file mode 100644 index 0000000000..f89be2dc65 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/extra/Contact.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.extra.Contact diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecase/CoreSubscriber.md b/docs/docs/en/api/faststream/specification/schema/extra/ContactDict.md similarity index 67% rename from docs/docs/en/api/faststream/nats/subscriber/usecase/CoreSubscriber.md rename to docs/docs/en/api/faststream/specification/schema/extra/ContactDict.md index 8ddb0b8c04..8f20fd396d 100644 --- a/docs/docs/en/api/faststream/nats/subscriber/usecase/CoreSubscriber.md +++ b/docs/docs/en/api/faststream/specification/schema/extra/ContactDict.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.nats.subscriber.usecase.CoreSubscriber +::: faststream.specification.schema.extra.ContactDict diff --git a/docs/docs/en/api/faststream/specification/schema/docs/ExternalDocs.md b/docs/docs/en/api/faststream/specification/schema/extra/ExternalDocs.md similarity index 66% rename from docs/docs/en/api/faststream/specification/schema/docs/ExternalDocs.md rename to docs/docs/en/api/faststream/specification/schema/extra/ExternalDocs.md index 641eab0547..a745e15910 100644 --- a/docs/docs/en/api/faststream/specification/schema/docs/ExternalDocs.md +++ b/docs/docs/en/api/faststream/specification/schema/extra/ExternalDocs.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.schema.docs.ExternalDocs +::: faststream.specification.schema.extra.ExternalDocs diff --git a/docs/docs/en/api/faststream/specification/schema/docs/ExternalDocsDict.md b/docs/docs/en/api/faststream/specification/schema/extra/ExternalDocsDict.md similarity index 65% rename from docs/docs/en/api/faststream/specification/schema/docs/ExternalDocsDict.md rename to docs/docs/en/api/faststream/specification/schema/extra/ExternalDocsDict.md index 7639fe848b..1110d88070 100644 --- a/docs/docs/en/api/faststream/specification/schema/docs/ExternalDocsDict.md +++ b/docs/docs/en/api/faststream/specification/schema/extra/ExternalDocsDict.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.schema.docs.ExternalDocsDict +::: faststream.specification.schema.extra.ExternalDocsDict diff --git a/docs/docs/en/api/faststream/specification/schema/extra/License.md b/docs/docs/en/api/faststream/specification/schema/extra/License.md new file mode 100644 index 0000000000..033374ed25 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/extra/License.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.extra.License diff --git a/docs/docs/en/api/faststream/specification/base/schema/BaseSchema.md b/docs/docs/en/api/faststream/specification/schema/extra/LicenseDict.md similarity index 67% rename from docs/docs/en/api/faststream/specification/base/schema/BaseSchema.md rename to docs/docs/en/api/faststream/specification/schema/extra/LicenseDict.md index 27512fe2b3..e2994e1d88 100644 --- a/docs/docs/en/api/faststream/specification/base/schema/BaseSchema.md +++ b/docs/docs/en/api/faststream/specification/schema/extra/LicenseDict.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.base.schema.BaseSchema +::: faststream.specification.schema.extra.LicenseDict diff --git a/docs/docs/en/api/faststream/specification/schema/extra/Tag.md b/docs/docs/en/api/faststream/specification/schema/extra/Tag.md new file mode 100644 index 0000000000..cc373f1528 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/extra/Tag.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.extra.Tag diff --git a/docs/docs/en/api/faststream/specification/schema/extra/TagDict.md b/docs/docs/en/api/faststream/specification/schema/extra/TagDict.md new file mode 100644 index 0000000000..c2455e5c4f --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/extra/TagDict.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.extra.TagDict diff --git a/docs/docs/en/api/faststream/specification/schema/contact/Contact.md b/docs/docs/en/api/faststream/specification/schema/extra/contact/Contact.md similarity index 65% rename from docs/docs/en/api/faststream/specification/schema/contact/Contact.md rename to docs/docs/en/api/faststream/specification/schema/extra/contact/Contact.md index 5db25a7342..f34ea777d3 100644 --- a/docs/docs/en/api/faststream/specification/schema/contact/Contact.md +++ b/docs/docs/en/api/faststream/specification/schema/extra/contact/Contact.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.schema.contact.Contact +::: faststream.specification.schema.extra.contact.Contact diff --git a/docs/docs/en/api/faststream/specification/schema/contact/ContactDict.md b/docs/docs/en/api/faststream/specification/schema/extra/contact/ContactDict.md similarity index 63% rename from docs/docs/en/api/faststream/specification/schema/contact/ContactDict.md rename to docs/docs/en/api/faststream/specification/schema/extra/contact/ContactDict.md index 6e03ef208b..17d0d774eb 100644 --- a/docs/docs/en/api/faststream/specification/schema/contact/ContactDict.md +++ b/docs/docs/en/api/faststream/specification/schema/extra/contact/ContactDict.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.schema.contact.ContactDict +::: faststream.specification.schema.extra.contact.ContactDict diff --git a/docs/docs/en/api/faststream/specification/schema/extra/external_docs/ExternalDocs.md b/docs/docs/en/api/faststream/specification/schema/extra/external_docs/ExternalDocs.md new file mode 100644 index 0000000000..bf06e4b97c --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/extra/external_docs/ExternalDocs.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.extra.external_docs.ExternalDocs diff --git a/docs/docs/en/api/faststream/specification/schema/extra/external_docs/ExternalDocsDict.md b/docs/docs/en/api/faststream/specification/schema/extra/external_docs/ExternalDocsDict.md new file mode 100644 index 0000000000..cf1c76bc2b --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/extra/external_docs/ExternalDocsDict.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.extra.external_docs.ExternalDocsDict diff --git a/docs/docs/en/api/faststream/specification/schema/license/License.md b/docs/docs/en/api/faststream/specification/schema/extra/license/License.md similarity index 65% rename from docs/docs/en/api/faststream/specification/schema/license/License.md rename to docs/docs/en/api/faststream/specification/schema/extra/license/License.md index bad1afae02..58cb3821e7 100644 --- a/docs/docs/en/api/faststream/specification/schema/license/License.md +++ b/docs/docs/en/api/faststream/specification/schema/extra/license/License.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.schema.license.License +::: faststream.specification.schema.extra.license.License diff --git a/docs/docs/en/api/faststream/specification/schema/license/LicenseDict.md b/docs/docs/en/api/faststream/specification/schema/extra/license/LicenseDict.md similarity index 63% rename from docs/docs/en/api/faststream/specification/schema/license/LicenseDict.md rename to docs/docs/en/api/faststream/specification/schema/extra/license/LicenseDict.md index 2ed6323a54..fb8779aa39 100644 --- a/docs/docs/en/api/faststream/specification/schema/license/LicenseDict.md +++ b/docs/docs/en/api/faststream/specification/schema/extra/license/LicenseDict.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.schema.license.LicenseDict +::: faststream.specification.schema.extra.license.LicenseDict diff --git a/docs/docs/en/api/faststream/specification/schema/extra/tag/Tag.md b/docs/docs/en/api/faststream/specification/schema/extra/tag/Tag.md new file mode 100644 index 0000000000..b25a4d5cb1 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/extra/tag/Tag.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.extra.tag.Tag diff --git a/docs/docs/en/api/faststream/specification/schema/extra/tag/TagDict.md b/docs/docs/en/api/faststream/specification/schema/extra/tag/TagDict.md new file mode 100644 index 0000000000..92500cc5b2 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/extra/tag/TagDict.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.extra.tag.TagDict diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Info.md b/docs/docs/en/api/faststream/specification/schema/message/model/Message.md similarity index 65% rename from docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Info.md rename to docs/docs/en/api/faststream/specification/schema/message/model/Message.md index a721edf50a..f057a4e898 100644 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Info.md +++ b/docs/docs/en/api/faststream/specification/schema/message/model/Message.md @@ -8,4 +8,4 @@ search: boost: 0.5 --- -::: faststream.specification.asyncapi.v2_6_0.schema.Info +::: faststream.specification.schema.message.model.Message diff --git a/docs/docs/en/api/faststream/specification/schema/operation/model/Operation.md b/docs/docs/en/api/faststream/specification/schema/operation/model/Operation.md new file mode 100644 index 0000000000..17c306a8ab --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/operation/model/Operation.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.operation.model.Operation diff --git a/docs/docs/en/api/faststream/specification/schema/publisher/PublisherSpec.md b/docs/docs/en/api/faststream/specification/schema/publisher/PublisherSpec.md new file mode 100644 index 0000000000..002bc1ecb8 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/publisher/PublisherSpec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.publisher.PublisherSpec diff --git a/docs/docs/en/api/faststream/specification/schema/security/OauthFlowObj.md b/docs/docs/en/api/faststream/specification/schema/security/OauthFlowObj.md deleted file mode 100644 index 9fad152d4e..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/security/OauthFlowObj.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.security.OauthFlowObj diff --git a/docs/docs/en/api/faststream/specification/schema/security/OauthFlows.md b/docs/docs/en/api/faststream/specification/schema/security/OauthFlows.md deleted file mode 100644 index 3b4bee7938..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/security/OauthFlows.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.security.OauthFlows diff --git a/docs/docs/en/api/faststream/specification/schema/security/SecuritySchemaComponent.md b/docs/docs/en/api/faststream/specification/schema/security/SecuritySchemaComponent.md deleted file mode 100644 index 78395ed097..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/security/SecuritySchemaComponent.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.security.SecuritySchemaComponent diff --git a/docs/docs/en/api/faststream/specification/schema/subscriber/SubscriberSpec.md b/docs/docs/en/api/faststream/specification/schema/subscriber/SubscriberSpec.md new file mode 100644 index 0000000000..5a4e4515e2 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/subscriber/SubscriberSpec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.subscriber.SubscriberSpec From 9456e7a935219b39702bb92a07a5263e921d378e Mon Sep 17 00:00:00 2001 From: Vladimir Kibisov <88668176+KrySeyt@users.noreply.github.com> Date: Sun, 1 Dec 2024 11:38:18 +0300 Subject: [PATCH 207/245] Fix AsyncAPI 3.0.0 AMQP bindings (#1949) * Fix RabbitMQ AsyncAPI 3.0.0 binding version * Fix tests * docs: generate API References --------- Co-authored-by: KrySeyt --- .../AsyncAPIConcurrentDefaultSubscriber.md | 11 ----- docs/docs/en/release.md | 48 +++++++++++++++++++ .../v3_0_0/schema/bindings/amqp/channel.py | 31 ++++++++++++ .../asyncapi/rabbit/v3_0_0/test_arguments.py | 19 +++----- .../asyncapi/rabbit/v3_0_0/test_connection.py | 7 --- tests/asyncapi/rabbit/v3_0_0/test_naming.py | 3 +- .../asyncapi/rabbit/v3_0_0/test_publisher.py | 7 --- tests/asyncapi/rabbit/v3_0_0/test_router.py | 3 +- 8 files changed, 87 insertions(+), 42 deletions(-) delete mode 100644 docs/docs/en/api/faststream/kafka/subscriber/asyncapi/AsyncAPIConcurrentDefaultSubscriber.md diff --git a/docs/docs/en/api/faststream/kafka/subscriber/asyncapi/AsyncAPIConcurrentDefaultSubscriber.md b/docs/docs/en/api/faststream/kafka/subscriber/asyncapi/AsyncAPIConcurrentDefaultSubscriber.md deleted file mode 100644 index 8ce5838961..0000000000 --- a/docs/docs/en/api/faststream/kafka/subscriber/asyncapi/AsyncAPIConcurrentDefaultSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.subscriber.asyncapi.AsyncAPIConcurrentDefaultSubscriber diff --git a/docs/docs/en/release.md b/docs/docs/en/release.md index efe5d81bf7..58f22673cb 100644 --- a/docs/docs/en/release.md +++ b/docs/docs/en/release.md @@ -12,6 +12,54 @@ hide: --- # Release Notes +## 0.5.31 + +### What's Changed + +Well, you (community) made a new breathtaken release for us! +Thanks to all of this release contributors. + +Special thanks to @Flosckow. He promores a new perfect feature - concurrent Kafka subscriber (with autocommit mode) + +```python +from faststream.kafka import KafkaBroker + +broker = KafkaBroker() + +@broker.subscriber("topic", max_workers=10) +async def handler(): + """Usign `max_workers` option you can process up to 10 messages by one subscriber concurrently""" +``` + +Also, thanks to [@Sehat1137](https://github.com/Sehat1137){.external-link target="_blank"} with his ASGI CLI start fixins - now you can use FastStream CLI to scale your AsgiFastStream application by workers + +```bash +faststream run main:asgi --workers 2 +``` + +There are a lot of other increadible changes you made: + +* feat: add NatsMessage ack_sync method #1906 by [@wpn10](https://github.com/wpn10){.external-link target="_blank"} in [#1909](https://github.com/airtai/faststream/pull/1909){.external-link target="_blank"} +* feat: support running ASGI app with Uvicorn using file descriptor by [@minhyeoky](https://github.com/minhyeoky){.external-link target="_blank"} in [#1923](https://github.com/airtai/faststream/pull/1923){.external-link target="_blank"} +* feat: Add kafka concurrent subscriber by [@Flosckow](https://github.com/Flosckow){.external-link target="_blank"} in [#1912](https://github.com/airtai/faststream/pull/1912){.external-link target="_blank"} +* fix: bug when using one register for several middleware by @roma-frolov in [#1921](https://github.com/airtai/faststream/pull/1921){.external-link target="_blank"} +* fix: change oauth type in asyncapi schema by [@spataphore1337](https://github.com/spataphore1337){.external-link target="_blank"} in [#1926](https://github.com/airtai/faststream/pull/1926){.external-link target="_blank"} +* fix: HandlerException ingored by @roma-frolov in [#1928](https://github.com/airtai/faststream/pull/1928){.external-link target="_blank"} +* fix: Pomo/nats router by [@Drakorgaur](https://github.com/Drakorgaur){.external-link target="_blank"} in [#1932](https://github.com/airtai/faststream/pull/1932){.external-link target="_blank"} +* fix: RabbitBroker's ping is more objective by @roma-frolov in [#1933](https://github.com/airtai/faststream/pull/1933){.external-link target="_blank"} +* fix: AsyncAPI 2.6.0 fix empty channels for KafkaSubscriber and ConfluentSubscriber if partitions provided by [@KrySeyt](https://github.com/KrySeyt){.external-link target="_blank"} in [#1930](https://github.com/airtai/faststream/pull/1930){.external-link target="_blank"} +* fix: #1874 support workers for ASGI FastStream by [@Sehat1137](https://github.com/Sehat1137){.external-link target="_blank"} in [#1936](https://github.com/airtai/faststream/pull/1936){.external-link target="_blank"} +* fix: correct middlewares order by [@sheldygg](https://github.com/sheldygg){.external-link target="_blank"} in [#1935](https://github.com/airtai/faststream/pull/1935){.external-link target="_blank"} +* chore: run PR altering automated check in same CI job by [@kumaranvpl](https://github.com/kumaranvpl){.external-link target="_blank"} in [#1942](https://github.com/airtai/faststream/pull/1942){.external-link target="_blank"} +* chore: pin typer version by [@Lancetnik](https://github.com/Lancetnik){.external-link target="_blank"} in [#1947](https://github.com/airtai/faststream/pull/1947){.external-link target="_blank"} + +### New Contributors + +* [@wpn10](https://github.com/wpn10){.external-link target="_blank"} made their first contribution in [#1909](https://github.com/airtai/faststream/pull/1909){.external-link target="_blank"} +* [@minhyeoky](https://github.com/minhyeoky){.external-link target="_blank"} made their first contribution in [#1923](https://github.com/airtai/faststream/pull/1923){.external-link target="_blank"} + +**Full Changelog**: [#0.5.30...0.5.31](https://github.com/airtai/faststream/compare/0.5.30...0.5.31){.external-link target="_blank"} + ## 0.5.30 ### What's Changed diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel.py index ecab8e4a17..3d2bcc23ad 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel.py @@ -1,7 +1,38 @@ +from typing import Optional, Self + from faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp import ( ChannelBinding as V2Binding, ) +from faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.channel import ( + Exchange, + Queue, +) +from faststream.specification.schema.bindings import amqp class ChannelBinding(V2Binding): bindingVersion: str = "0.3.0" + + @classmethod + def from_sub(cls, binding: Optional[amqp.ChannelBinding]) -> Optional[Self]: + if binding is None: + return None + + return cls( + **{ + "is": "queue", + "queue": Queue.from_spec(binding.queue, binding.virtual_host), + }, + ) + + @classmethod + def from_pub(cls, binding: Optional[amqp.ChannelBinding]) -> Optional[Self]: + if binding is None: + return None + + return cls( + **{ + "is": "routingKey", + "exchange": Exchange.from_spec(binding.exchange, binding.virtual_host), + }, + ) diff --git a/tests/asyncapi/rabbit/v3_0_0/test_arguments.py b/tests/asyncapi/rabbit/v3_0_0/test_arguments.py index af3e0a8789..1b4ef1f730 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_arguments.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_arguments.py @@ -21,14 +21,7 @@ async def handle(msg) -> None: ... assert schema["channels"][key]["bindings"] == { "amqp": { "bindingVersion": "0.3.0", - "exchange": { - "autoDelete": False, - "durable": False, - "name": "test-ex", - "type": "topic", - "vhost": "/", - }, - "is": "routingKey", + "is": "queue", "queue": { "autoDelete": True, "durable": False, @@ -54,13 +47,13 @@ async def handle(msg) -> None: ... assert schema["channels"][key]["bindings"] == { "amqp": { "bindingVersion": "0.3.0", - "exchange": { - "autoDelete": False, + "queue": { + "autoDelete": True, "durable": False, - "name": "test-ex", - "type": "fanout", + "exclusive": False, + "name": "test", "vhost": "/", }, - "is": "routingKey", + "is": "queue", }, } diff --git a/tests/asyncapi/rabbit/v3_0_0/test_connection.py b/tests/asyncapi/rabbit/v3_0_0/test_connection.py index 971a89afec..adf937a705 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_connection.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_connection.py @@ -66,13 +66,6 @@ def test_custom() -> None: "bindingVersion": "0.3.0", "exchange": {"type": "default", "vhost": "/vh"}, "is": "routingKey", - "queue": { - "autoDelete": False, - "durable": False, - "exclusive": False, - "name": "test", - "vhost": "/vh", - }, }, }, "servers": [ diff --git a/tests/asyncapi/rabbit/v3_0_0/test_naming.py b/tests/asyncapi/rabbit/v3_0_0/test_naming.py index e3ba3f04cc..2839a4505a 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_naming.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_naming.py @@ -73,7 +73,7 @@ async def handle() -> None: ... ], "bindings": { "amqp": { - "is": "routingKey", + "is": "queue", "bindingVersion": "0.3.0", "queue": { "name": "test", @@ -82,7 +82,6 @@ async def handle() -> None: ... "autoDelete": False, "vhost": "/", }, - "exchange": {"type": "default", "vhost": "/"}, }, }, "messages": { diff --git a/tests/asyncapi/rabbit/v3_0_0/test_publisher.py b/tests/asyncapi/rabbit/v3_0_0/test_publisher.py index a108270da5..b4826fe7e0 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_publisher.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_publisher.py @@ -88,13 +88,6 @@ async def handle(msg) -> None: ... "vhost": "/", }, "is": "routingKey", - "queue": { - "autoDelete": True, - "durable": False, - "exclusive": False, - "name": "test", - "vhost": "/", - }, }, } diff --git a/tests/asyncapi/rabbit/v3_0_0/test_router.py b/tests/asyncapi/rabbit/v3_0_0/test_router.py index 245988d8df..e1bb277da6 100644 --- a/tests/asyncapi/rabbit/v3_0_0/test_router.py +++ b/tests/asyncapi/rabbit/v3_0_0/test_router.py @@ -55,7 +55,7 @@ async def handle(msg) -> None: ... }, "bindings": { "amqp": { - "is": "routingKey", + "is": "queue", "bindingVersion": "0.3.0", "queue": { "name": "test_test", @@ -64,7 +64,6 @@ async def handle(msg) -> None: ... "autoDelete": False, "vhost": "/", }, - "exchange": {"type": "default", "vhost": "/"}, }, }, }, From f8ab59dc3c3a959158f1ae555c4c10eedcb66948 Mon Sep 17 00:00:00 2001 From: Majajashka <96516033+Majajashka@users.noreply.github.com> Date: Sun, 1 Dec 2024 22:34:43 +0400 Subject: [PATCH 208/245] docs: use DeliverPolicy Enum for deliver_policy in subscriber (#1952) * docs: use DeliverPolicy Enum for deliver_policy in subscriber Updated deliver_policy to use DeliverPolicy enum according to type definition * docs: generate API References --------- Co-authored-by: Majajashka --- .secrets.baseline | 4 ++-- docs/docs_src/nats/js/main.py | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.secrets.baseline b/.secrets.baseline index 047a7df974..f396e694ed 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -153,7 +153,7 @@ "filename": "docs/docs/en/release.md", "hashed_secret": "35675e68f4b5af7b995d9205ad0fc43842f16450", "is_verified": false, - "line_number": 1850, + "line_number": 1898, "is_secret": false } ], @@ -178,5 +178,5 @@ } ] }, - "generated_at": "2024-11-15T07:38:53Z" + "generated_at": "2024-12-01T18:17:03Z" } diff --git a/docs/docs_src/nats/js/main.py b/docs/docs_src/nats/js/main.py index a65749b082..715e04fd4b 100644 --- a/docs/docs_src/nats/js/main.py +++ b/docs/docs_src/nats/js/main.py @@ -1,5 +1,6 @@ from faststream import FastStream, Logger from faststream.nats import JStream, NatsBroker +from nats.js.api import DeliverPolicy broker = NatsBroker() app = FastStream(broker) @@ -9,7 +10,7 @@ @broker.subscriber( "js-subject", stream=stream, - deliver_policy="new", + deliver_policy=DeliverPolicy.NEW, ) async def handler(msg: str, logger: Logger): logger.info(msg) From 1fd1039ffa67d6527bfd8fadcd063e345ed7d18d Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Tue, 3 Dec 2024 17:56:22 +0300 Subject: [PATCH 209/245] chore: remove useless --- faststream/nats/subscriber/usecase.py | 1267 ------------------------- faststream/rabbit/schemas/reply.py | 46 - 2 files changed, 1313 deletions(-) delete mode 100644 faststream/nats/subscriber/usecase.py delete mode 100644 faststream/rabbit/schemas/reply.py diff --git a/faststream/nats/subscriber/usecase.py b/faststream/nats/subscriber/usecase.py deleted file mode 100644 index 75c1b5bd62..0000000000 --- a/faststream/nats/subscriber/usecase.py +++ /dev/null @@ -1,1267 +0,0 @@ -from abc import abstractmethod -from collections.abc import Awaitable, Iterable, Sequence -from contextlib import suppress -from typing import ( - TYPE_CHECKING, - Annotated, - Any, - Callable, - Generic, - Optional, - TypeVar, - Union, - cast, -) - -import anyio -from fast_depends.dependencies import Depends -from nats.errors import ConnectionClosedError, TimeoutError -from nats.js.api import ConsumerConfig, ObjectInfo -from typing_extensions import Doc, override - -from faststream.broker.publisher.fake import FakePublisher -from faststream.broker.subscriber.mixins import ConcurrentMixin, TasksMixin -from faststream.broker.subscriber.usecase import SubscriberUsecase -from faststream.broker.types import MsgType -from faststream.broker.utils import process_msg -from faststream.exceptions import NOT_CONNECTED_YET -from faststream.nats.message import NatsMessage -from faststream.nats.parser import ( - BatchParser, - JsParser, - KvParser, - NatsParser, - ObjParser, -) -from faststream.nats.schemas.js_stream import compile_nats_wildcard -from faststream.nats.subscriber.subscription import ( - UnsubscribeAdapter, - Unsubscriptable, -) -from faststream.utils.context.repository import context - -if TYPE_CHECKING: - from nats.aio.client import Client - from nats.aio.msg import Msg - from nats.aio.subscription import Subscription - from nats.js import JetStreamContext - from nats.js.kv import KeyValue - from nats.js.object_store import ObjectStore - - from faststream.broker.message import StreamMessage - from faststream.broker.publisher.proto import ProducerProto - from faststream.broker.types import ( - AsyncCallable, - BrokerMiddleware, - CustomCallable, - ) - from faststream.nats.helpers import KVBucketDeclarer, OSBucketDeclarer - from faststream.nats.message import NatsKvMessage, NatsObjMessage - from faststream.nats.schemas import JStream, KvWatch, ObjWatch, PullSub - from faststream.types import AnyDict, Decorator, LoggerProto, SendableMessage - - -ConnectionType = TypeVar("ConnectionType") - - -class LogicSubscriber(SubscriberUsecase[MsgType], Generic[ConnectionType, MsgType]): - """A class to represent a NATS handler.""" - - subscription: Optional[Unsubscriptable] - _fetch_sub: Optional[Unsubscriptable] - producer: Optional["ProducerProto"] - _connection: Optional[ConnectionType] - - def __init__( - self, - *, - subject: str, - config: "ConsumerConfig", - extra_options: Optional["AnyDict"], - # Subscriber args - default_parser: "AsyncCallable", - default_decoder: "AsyncCallable", - no_ack: bool, - no_reply: bool, - retry: Union[bool, int], - broker_dependencies: Iterable[Depends], - broker_middlewares: Sequence["BrokerMiddleware[MsgType]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> None: - self.subject = subject - self.config = config - - self.extra_options = extra_options or {} - - super().__init__( - default_parser=default_parser, - default_decoder=default_decoder, - # Propagated args - no_ack=no_ack, - no_reply=no_reply, - retry=retry, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - # AsyncAPI args - title_=title_, - description_=description_, - include_in_schema=include_in_schema, - ) - - self._connection = None - self._fetch_sub = None - self.subscription = None - self.producer = None - - @override - def setup( # type: ignore[override] - self, - *, - connection: ConnectionType, - # basic args - logger: Optional["LoggerProto"], - producer: Optional["ProducerProto"], - graceful_timeout: Optional[float], - extra_context: "AnyDict", - # broker options - broker_parser: Optional["CustomCallable"], - broker_decoder: Optional["CustomCallable"], - # dependant args - apply_types: bool, - is_validate: bool, - _get_dependant: Optional[Callable[..., Any]], - _call_decorators: Iterable["Decorator"], - ) -> None: - self._connection = connection - - super().setup( - logger=logger, - producer=producer, - graceful_timeout=graceful_timeout, - extra_context=extra_context, - broker_parser=broker_parser, - broker_decoder=broker_decoder, - apply_types=apply_types, - is_validate=is_validate, - _get_dependant=_get_dependant, - _call_decorators=_call_decorators, - ) - - @property - def clear_subject(self) -> str: - """Compile `test.{name}` to `test.*` subject.""" - _, path = compile_nats_wildcard(self.subject) - return path - - async def start(self) -> None: - """Create NATS subscription and start consume tasks.""" - assert self._connection, NOT_CONNECTED_YET # nosec B101 - - await super().start() - - if self.calls: - await self._create_subscription(connection=self._connection) - - async def close(self) -> None: - """Clean up handler subscription, cancel consume task in graceful mode.""" - await super().close() - - if self.subscription is not None: - await self.subscription.unsubscribe() - self.subscription = None - - if self._fetch_sub is not None: - await self._fetch_sub.unsubscribe() - self.subscription = None - - @abstractmethod - async def _create_subscription( - self, - *, - connection: ConnectionType, - ) -> None: - """Create NATS subscription object to consume messages.""" - raise NotImplementedError - - @staticmethod - def build_log_context( - message: Annotated[ - Optional["StreamMessage[MsgType]"], - Doc("Message which we are building context for"), - ], - subject: Annotated[ - str, - Doc("NATS subject we are listening"), - ], - *, - queue: Annotated[ - str, - Doc("Using queue group name"), - ] = "", - stream: Annotated[ - str, - Doc("Stream object we are listening"), - ] = "", - ) -> dict[str, str]: - """Static method to build log context out of `self.consume` scope.""" - return { - "subject": subject, - "queue": queue, - "stream": stream, - "message_id": getattr(message, "message_id", ""), - } - - def add_prefix(self, prefix: str) -> None: - """Include Subscriber in router.""" - if self.subject: - self.subject = f"{prefix}{self.subject}" - else: - self.config.filter_subjects = [ - f"{prefix}{subject}" for subject in (self.config.filter_subjects or ()) - ] - - @property - def _resolved_subject_string(self) -> str: - return self.subject or ", ".join(self.config.filter_subjects or ()) - - def __hash__(self) -> int: - return self.get_routing_hash(self._resolved_subject_string) - - @staticmethod - def get_routing_hash( - subject: Annotated[ - str, - Doc("NATS subject to consume messages"), - ], - ) -> int: - """Get handler hash by outer data. - - Using to find handler in `broker.handlers` dictionary. - """ - return hash(subject) - - -class _DefaultSubscriber(LogicSubscriber[ConnectionType, MsgType]): - def __init__( - self, - *, - subject: str, - config: "ConsumerConfig", - # default args - extra_options: Optional["AnyDict"], - # Subscriber args - default_parser: "AsyncCallable", - default_decoder: "AsyncCallable", - no_ack: bool, - no_reply: bool, - retry: Union[bool, int], - broker_dependencies: Iterable[Depends], - broker_middlewares: Sequence["BrokerMiddleware[MsgType]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> None: - super().__init__( - subject=subject, - config=config, - extra_options=extra_options, - # subscriber args - default_parser=default_parser, - default_decoder=default_decoder, - # Propagated args - no_ack=no_ack, - no_reply=no_reply, - retry=retry, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, - ) - - def _make_response_publisher( - self, - message: "StreamMessage[Any]", - ) -> Sequence[FakePublisher]: - """Create FakePublisher object to use it as one of `publishers` in `self.consume` scope.""" - if self._producer is None: - return () - - return ( - FakePublisher( - self._producer.publish, - publish_kwargs={ - "subject": message.reply_to, - }, - ), - ) - - def get_log_context( - self, - message: Annotated[ - Optional["StreamMessage[MsgType]"], - Doc("Message which we are building context for"), - ], - ) -> dict[str, str]: - """Log context factory using in `self.consume` scope.""" - return self.build_log_context( - message=message, - subject=self.subject, - ) - - -class CoreSubscriber(_DefaultSubscriber["Client", "Msg"]): - subscription: Optional["Subscription"] - _fetch_sub: Optional["Subscription"] - - def __init__( - self, - *, - # default args - subject: str, - config: "ConsumerConfig", - queue: str, - extra_options: Optional["AnyDict"], - # Subscriber args - no_ack: bool, - no_reply: bool, - retry: Union[bool, int], - broker_dependencies: Iterable[Depends], - broker_middlewares: Sequence["BrokerMiddleware[Msg]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> None: - parser_ = NatsParser(pattern=subject, no_ack=no_ack) - - self.queue = queue - - super().__init__( - subject=subject, - config=config, - extra_options=extra_options, - # subscriber args - default_parser=parser_.parse_message, - default_decoder=parser_.decode_message, - # Propagated args - no_ack=no_ack, - no_reply=no_reply, - retry=retry, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, - ) - - @override - async def get_one( - self, - *, - timeout: float = 5.0, - ) -> "Optional[NatsMessage]": - assert self._connection, "Please, start() subscriber first" # nosec B101 - assert ( # nosec B101 - not self.calls - ), "You can't use `get_one` method if subscriber has registered handlers." - - if self._fetch_sub is None: - fetch_sub = self._fetch_sub = await self._connection.subscribe( - subject=self.clear_subject, - queue=self.queue, - **self.extra_options, - ) - else: - fetch_sub = self._fetch_sub - - try: - raw_message = await fetch_sub.next_msg(timeout=timeout) - except TimeoutError: - return None - - msg: NatsMessage = await process_msg( # type: ignore[assignment] - msg=raw_message, - middlewares=self._broker_middlewares, - parser=self._parser, - decoder=self._decoder, - ) - return msg - - @override - async def _create_subscription( - self, - *, - connection: "Client", - ) -> None: - """Create NATS subscription and start consume task.""" - if self.subscription: - return - - self.subscription = await connection.subscribe( - subject=self.clear_subject, - queue=self.queue, - cb=self.consume, - **self.extra_options, - ) - - def get_log_context( - self, - message: Annotated[ - Optional["StreamMessage[Msg]"], - Doc("Message which we are building context for"), - ], - ) -> dict[str, str]: - """Log context factory using in `self.consume` scope.""" - return self.build_log_context( - message=message, - subject=self.subject, - queue=self.queue, - ) - - -class ConcurrentCoreSubscriber( - ConcurrentMixin, - CoreSubscriber, -): - def __init__( - self, - *, - max_workers: int, - # default args - subject: str, - config: "ConsumerConfig", - queue: str, - extra_options: Optional["AnyDict"], - # Subscriber args - no_ack: bool, - no_reply: bool, - retry: Union[bool, int], - broker_dependencies: Iterable[Depends], - broker_middlewares: Sequence["BrokerMiddleware[Msg]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> None: - super().__init__( - max_workers=max_workers, - # basic args - subject=subject, - config=config, - queue=queue, - extra_options=extra_options, - # Propagated args - no_ack=no_ack, - no_reply=no_reply, - retry=retry, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, - ) - - @override - async def _create_subscription( - self, - *, - connection: "Client", - ) -> None: - """Create NATS subscription and start consume task.""" - if self.subscription: - return - - self.start_consume_task() - - self.subscription = await connection.subscribe( - subject=self.clear_subject, - queue=self.queue, - cb=self._put_msg, - **self.extra_options, - ) - - -class _StreamSubscriber(_DefaultSubscriber["JetStreamContext", "Msg"]): - _fetch_sub: Optional["JetStreamContext.PullSubscription"] - - def __init__( - self, - *, - stream: "JStream", - # default args - subject: str, - config: "ConsumerConfig", - queue: str, - extra_options: Optional["AnyDict"], - # Subscriber args - no_ack: bool, - no_reply: bool, - retry: Union[bool, int], - broker_dependencies: Iterable[Depends], - broker_middlewares: Sequence["BrokerMiddleware[Msg]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> None: - parser_ = JsParser(pattern=subject) - - self.queue = queue - self.stream = stream - - super().__init__( - subject=subject, - config=config, - extra_options=extra_options, - # subscriber args - default_parser=parser_.parse_message, - default_decoder=parser_.decode_message, - # Propagated args - no_ack=no_ack, - no_reply=no_reply, - retry=retry, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, - ) - - def get_log_context( - self, - message: Annotated[ - Optional["StreamMessage[Msg]"], - Doc("Message which we are building context for"), - ], - ) -> dict[str, str]: - """Log context factory using in `self.consume` scope.""" - return self.build_log_context( - message=message, - subject=self._resolved_subject_string, - queue=self.queue, - stream=self.stream.name, - ) - - @override - async def get_one( - self, - *, - timeout: float = 5, - ) -> Optional["NatsMessage"]: - assert self._connection, "Please, start() subscriber first" # nosec B101 - assert ( # nosec B101 - not self.calls - ), "You can't use `get_one` method if subscriber has registered handlers." - - if not self._fetch_sub: - extra_options = { - "pending_bytes_limit": self.extra_options["pending_bytes_limit"], - "pending_msgs_limit": self.extra_options["pending_msgs_limit"], - "durable": self.extra_options["durable"], - "stream": self.extra_options["stream"], - } - if inbox_prefix := self.extra_options.get("inbox_prefix"): - extra_options["inbox_prefix"] = inbox_prefix - - self._fetch_sub = await self._connection.pull_subscribe( - subject=self.clear_subject, - config=self.config, - **extra_options, - ) - - try: - raw_message = ( - await self._fetch_sub.fetch( - batch=1, - timeout=timeout, - ) - )[0] - except (TimeoutError, ConnectionClosedError): - return None - - msg: NatsMessage = await process_msg( # type: ignore[assignment] - msg=raw_message, - middlewares=self._broker_middlewares, - parser=self._parser, - decoder=self._decoder, - ) - return msg - - -class PushStreamSubscription(_StreamSubscriber): - subscription: Optional["JetStreamContext.PushSubscription"] - - @override - async def _create_subscription( - self, - *, - connection: "JetStreamContext", - ) -> None: - """Create NATS subscription and start consume task.""" - if self.subscription: - return - - self.subscription = await connection.subscribe( - subject=self.clear_subject, - queue=self.queue, - cb=self.consume, - config=self.config, - **self.extra_options, - ) - - -class ConcurrentPushStreamSubscriber( - ConcurrentMixin, - _StreamSubscriber, -): - subscription: Optional["JetStreamContext.PushSubscription"] - - def __init__( - self, - *, - max_workers: int, - stream: "JStream", - # default args - subject: str, - config: "ConsumerConfig", - queue: str, - extra_options: Optional["AnyDict"], - # Subscriber args - no_ack: bool, - no_reply: bool, - retry: Union[bool, int], - broker_dependencies: Iterable[Depends], - broker_middlewares: Sequence["BrokerMiddleware[Msg]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> None: - super().__init__( - max_workers=max_workers, - # basic args - stream=stream, - subject=subject, - config=config, - queue=queue, - extra_options=extra_options, - # Propagated args - no_ack=no_ack, - no_reply=no_reply, - retry=retry, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, - ) - - @override - async def _create_subscription( - self, - *, - connection: "JetStreamContext", - ) -> None: - """Create NATS subscription and start consume task.""" - if self.subscription: - return - - self.start_consume_task() - - self.subscription = await connection.subscribe( - subject=self.clear_subject, - queue=self.queue, - cb=self._put_msg, - config=self.config, - **self.extra_options, - ) - - -class PullStreamSubscriber( - TasksMixin, - _StreamSubscriber, -): - subscription: Optional["JetStreamContext.PullSubscription"] - - def __init__( - self, - *, - pull_sub: "PullSub", - stream: "JStream", - # default args - subject: str, - config: "ConsumerConfig", - extra_options: Optional["AnyDict"], - # Subscriber args - no_ack: bool, - no_reply: bool, - retry: Union[bool, int], - broker_dependencies: Iterable[Depends], - broker_middlewares: Sequence["BrokerMiddleware[Msg]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> None: - self.pull_sub = pull_sub - - super().__init__( - # basic args - stream=stream, - subject=subject, - config=config, - extra_options=extra_options, - queue="", - # Propagated args - no_ack=no_ack, - no_reply=no_reply, - retry=retry, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, - ) - - @override - async def _create_subscription( - self, - *, - connection: "JetStreamContext", - ) -> None: - """Create NATS subscription and start consume task.""" - if self.subscription: - return - - self.subscription = await connection.pull_subscribe( - subject=self.clear_subject, - config=self.config, - **self.extra_options, - ) - self.add_task(self._consume_pull(cb=self.consume)) - - async def _consume_pull( - self, - cb: Callable[["Msg"], Awaitable["SendableMessage"]], - ) -> None: - """Endless task consuming messages using NATS Pull subscriber.""" - assert self.subscription # nosec B101 - - while self.running: # pragma: no branch - messages = [] - with suppress(TimeoutError, ConnectionClosedError): - messages = await self.subscription.fetch( - batch=self.pull_sub.batch_size, - timeout=self.pull_sub.timeout, - ) - - if messages: - async with anyio.create_task_group() as tg: - for msg in messages: - tg.start_soon(cb, msg) - - -class ConcurrentPullStreamSubscriber( - ConcurrentMixin, - PullStreamSubscriber, -): - def __init__( - self, - *, - max_workers: int, - # default args - pull_sub: "PullSub", - stream: "JStream", - subject: str, - config: "ConsumerConfig", - extra_options: Optional["AnyDict"], - # Subscriber args - no_ack: bool, - no_reply: bool, - retry: Union[bool, int], - broker_dependencies: Iterable[Depends], - broker_middlewares: Sequence["BrokerMiddleware[Msg]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> None: - super().__init__( - max_workers=max_workers, - # basic args - pull_sub=pull_sub, - stream=stream, - subject=subject, - config=config, - extra_options=extra_options, - # Propagated args - no_ack=no_ack, - no_reply=no_reply, - retry=retry, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, - ) - - @override - async def _create_subscription( - self, - *, - connection: "JetStreamContext", - ) -> None: - """Create NATS subscription and start consume task.""" - if self.subscription: - return - - self.start_consume_task() - - self.subscription = await connection.pull_subscribe( - subject=self.clear_subject, - config=self.config, - **self.extra_options, - ) - self.add_task(self._consume_pull(cb=self._put_msg)) - - -class BatchPullStreamSubscriber( - TasksMixin, - _DefaultSubscriber["JetStreamContext", list["Msg"]], -): - """Batch-message consumer class.""" - - subscription: Optional["JetStreamContext.PullSubscription"] - _fetch_sub: Optional["JetStreamContext.PullSubscription"] - - def __init__( - self, - *, - # default args - subject: str, - config: "ConsumerConfig", - stream: "JStream", - pull_sub: "PullSub", - extra_options: Optional["AnyDict"], - # Subscriber args - no_ack: bool, - no_reply: bool, - retry: Union[bool, int], - broker_dependencies: Iterable[Depends], - broker_middlewares: Sequence["BrokerMiddleware[list[Msg]]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> None: - parser = BatchParser(pattern=subject) - - self.stream = stream - self.pull_sub = pull_sub - - super().__init__( - subject=subject, - config=config, - extra_options=extra_options, - # subscriber args - default_parser=parser.parse_batch, - default_decoder=parser.decode_batch, - # Propagated args - no_ack=no_ack, - no_reply=no_reply, - retry=retry, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, - ) - - @override - async def get_one( - self, - *, - timeout: float = 5, - ) -> Optional["NatsMessage"]: - assert self._connection, "Please, start() subscriber first" # nosec B101 - assert ( # nosec B101 - not self.calls - ), "You can't use `get_one` method if subscriber has registered handlers." - - if not self._fetch_sub: - fetch_sub = self._fetch_sub = await self._connection.pull_subscribe( - subject=self.clear_subject, - config=self.config, - **self.extra_options, - ) - else: - fetch_sub = self._fetch_sub - - try: - raw_message = await fetch_sub.fetch( - batch=1, - timeout=timeout, - ) - except TimeoutError: - return None - - return cast( - NatsMessage, - await process_msg( - msg=raw_message, - middlewares=self._broker_middlewares, - parser=self._parser, - decoder=self._decoder, - ), - ) - - @override - async def _create_subscription( - self, - *, - connection: "JetStreamContext", - ) -> None: - """Create NATS subscription and start consume task.""" - if self.subscription: - return - - self.subscription = await connection.pull_subscribe( - subject=self.clear_subject, - config=self.config, - **self.extra_options, - ) - self.add_task(self._consume_pull()) - - async def _consume_pull(self) -> None: - """Endless task consuming messages using NATS Pull subscriber.""" - assert self.subscription, "You should call `create_subscription` at first." # nosec B101 - - while self.running: # pragma: no branch - with suppress(TimeoutError, ConnectionClosedError): - messages = await self.subscription.fetch( - batch=self.pull_sub.batch_size, - timeout=self.pull_sub.timeout, - ) - - if messages: - await self.consume(messages) - - -class KeyValueWatchSubscriber( - TasksMixin, - LogicSubscriber["KVBucketDeclarer", "KeyValue.Entry"], -): - subscription: Optional["UnsubscribeAdapter[KeyValue.KeyWatcher]"] - _fetch_sub: Optional[UnsubscribeAdapter["KeyValue.KeyWatcher"]] - - def __init__( - self, - *, - subject: str, - config: "ConsumerConfig", - kv_watch: "KvWatch", - broker_dependencies: Iterable[Depends], - broker_middlewares: Sequence["BrokerMiddleware[KeyValue.Entry]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> None: - parser = KvParser(pattern=subject) - self.kv_watch = kv_watch - - super().__init__( - subject=subject, - config=config, - extra_options=None, - no_ack=True, - no_reply=True, - retry=False, - default_parser=parser.parse_message, - default_decoder=parser.decode_message, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, - ) - - @override - async def get_one( - self, - *, - timeout: float = 5, - ) -> Optional["NatsKvMessage"]: - assert self._connection, "Please, start() subscriber first" # nosec B101 - assert ( # nosec B101 - not self.calls - ), "You can't use `get_one` method if subscriber has registered handlers." - - if not self._fetch_sub: - bucket = await self._connection.create_key_value( - bucket=self.kv_watch.name, - declare=self.kv_watch.declare, - ) - - fetch_sub = self._fetch_sub = UnsubscribeAdapter["KeyValue.KeyWatcher"]( - await bucket.watch( - keys=self.clear_subject, - headers_only=self.kv_watch.headers_only, - include_history=self.kv_watch.include_history, - ignore_deletes=self.kv_watch.ignore_deletes, - meta_only=self.kv_watch.meta_only, - ) - ) - else: - fetch_sub = self._fetch_sub - - raw_message: Optional[KeyValue.Entry] = None - sleep_interval = timeout / 10 - with anyio.move_on_after(timeout): - while ( # noqa: ASYNC110 - raw_message := await fetch_sub.obj.updates(timeout) # type: ignore[no-untyped-call] - ) is None: - await anyio.sleep(sleep_interval) - - return await process_msg( # type: ignore[return-value] - msg=raw_message, - middlewares=self._broker_middlewares, - parser=self._parser, - decoder=self._decoder, - ) - - @override - async def _create_subscription( - self, - *, - connection: "KVBucketDeclarer", - ) -> None: - if self.subscription: - return - - bucket = await connection.create_key_value( - bucket=self.kv_watch.name, - declare=self.kv_watch.declare, - ) - - self.subscription = UnsubscribeAdapter["KeyValue.KeyWatcher"]( - await bucket.watch( - keys=self.clear_subject, - headers_only=self.kv_watch.headers_only, - include_history=self.kv_watch.include_history, - ignore_deletes=self.kv_watch.ignore_deletes, - meta_only=self.kv_watch.meta_only, - ) - ) - - self.add_task(self._consume_watch()) - - async def _consume_watch(self) -> None: - assert self.subscription, "You should call `create_subscription` at first." # nosec B101 - - key_watcher = self.subscription.obj - - while self.running: - with suppress(ConnectionClosedError, TimeoutError): - message = cast( - Optional["KeyValue.Entry"], - await key_watcher.updates(self.kv_watch.timeout), # type: ignore[no-untyped-call] - ) - - if message: - await self.consume(message) - - def _make_response_publisher( - self, - message: Annotated[ - "StreamMessage[KeyValue.Entry]", - Doc("Message requiring reply"), - ], - ) -> Sequence[FakePublisher]: - """Create FakePublisher object to use it as one of `publishers` in `self.consume` scope.""" - return () - - def __hash__(self) -> int: - return hash(self.kv_watch) + hash(self.subject) - - def get_log_context( - self, - message: Annotated[ - Optional["StreamMessage[KeyValue.Entry]"], - Doc("Message which we are building context for"), - ], - ) -> dict[str, str]: - """Log context factory using in `self.consume` scope.""" - return self.build_log_context( - message=message, - subject=self.subject, - stream=self.kv_watch.name, - ) - - -OBJECT_STORAGE_CONTEXT_KEY = "__object_storage" - - -class ObjStoreWatchSubscriber( - TasksMixin, - LogicSubscriber["OSBucketDeclarer", ObjectInfo], -): - subscription: Optional["UnsubscribeAdapter[ObjectStore.ObjectWatcher]"] - _fetch_sub: Optional[UnsubscribeAdapter["ObjectStore.ObjectWatcher"]] - - def __init__( - self, - *, - subject: str, - config: "ConsumerConfig", - obj_watch: "ObjWatch", - broker_dependencies: Iterable[Depends], - broker_middlewares: Sequence["BrokerMiddleware[list[Msg]]"], - # AsyncAPI args - title_: Optional[str], - description_: Optional[str], - include_in_schema: bool, - ) -> None: - parser = ObjParser(pattern="") - - self.obj_watch = obj_watch - self.obj_watch_conn = None - - super().__init__( - subject=subject, - config=config, - extra_options=None, - no_ack=True, - no_reply=True, - retry=False, - default_parser=parser.parse_message, - default_decoder=parser.decode_message, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - # AsyncAPI args - description_=description_, - title_=title_, - include_in_schema=include_in_schema, - ) - - @override - async def get_one( - self, - *, - timeout: float = 5, - ) -> Optional["NatsObjMessage"]: - assert self._connection, "Please, start() subscriber first" # nosec B101 - assert ( # nosec B101 - not self.calls - ), "You can't use `get_one` method if subscriber has registered handlers." - - if not self._fetch_sub: - self.bucket = await self._connection.create_object_store( - bucket=self.subject, - declare=self.obj_watch.declare, - ) - - obj_watch = await self.bucket.watch( - ignore_deletes=self.obj_watch.ignore_deletes, - include_history=self.obj_watch.include_history, - meta_only=self.obj_watch.meta_only, - ) - fetch_sub = self._fetch_sub = UnsubscribeAdapter[ - "ObjectStore.ObjectWatcher" - ](obj_watch) - else: - fetch_sub = self._fetch_sub - - raw_message: Optional[ObjectInfo] = None - sleep_interval = timeout / 10 - with anyio.move_on_after(timeout): - while ( # noqa: ASYNC110 - raw_message := await fetch_sub.obj.updates(timeout) # type: ignore[no-untyped-call] - ) is None: - await anyio.sleep(sleep_interval) - - return await process_msg( # type: ignore[return-value] - msg=raw_message, - middlewares=self._broker_middlewares, - parser=self._parser, - decoder=self._decoder, - ) - - @override - async def _create_subscription( - self, - *, - connection: "OSBucketDeclarer", - ) -> None: - if self.subscription: - return - - self.bucket = await connection.create_object_store( - bucket=self.subject, - declare=self.obj_watch.declare, - ) - - self.add_task(self._consume_watch()) - - async def _consume_watch(self) -> None: - assert self.bucket, "You should call `create_subscription` at first." # nosec B101 - - # Should be created inside task to avoid nats-py lock - obj_watch = await self.bucket.watch( - ignore_deletes=self.obj_watch.ignore_deletes, - include_history=self.obj_watch.include_history, - meta_only=self.obj_watch.meta_only, - ) - - self.subscription = UnsubscribeAdapter["ObjectStore.ObjectWatcher"](obj_watch) - - while self.running: - with suppress(TimeoutError): - message = cast( - Optional["ObjectInfo"], - await obj_watch.updates(self.obj_watch.timeout), # type: ignore[no-untyped-call] - ) - - if message: - with context.scope(OBJECT_STORAGE_CONTEXT_KEY, self.bucket): - await self.consume(message) - - def _make_response_publisher( - self, - message: Annotated[ - "StreamMessage[ObjectInfo]", - Doc("Message requiring reply"), - ], - ) -> Sequence[FakePublisher]: - """Create FakePublisher object to use it as one of `publishers` in `self.consume` scope.""" - return () - - def __hash__(self) -> int: - return hash(self.subject) - - def get_log_context( - self, - message: Annotated[ - Optional["StreamMessage[ObjectInfo]"], - Doc("Message which we are building context for"), - ], - ) -> dict[str, str]: - """Log context factory using in `self.consume` scope.""" - return self.build_log_context( - message=message, - subject=self.subject, - ) diff --git a/faststream/rabbit/schemas/reply.py b/faststream/rabbit/schemas/reply.py deleted file mode 100644 index 6137df7f31..0000000000 --- a/faststream/rabbit/schemas/reply.py +++ /dev/null @@ -1,46 +0,0 @@ -from typing import Annotated - -from typing_extensions import Doc - - -class ReplyConfig: - """Class to store a config for subscribers' replies.""" - - __slots__ = ( - "immediate", - "mandatory", - "persist", - ) - - def __init__( - self, - mandatory: Annotated[ - bool, - Doc( - "Client waits for confirmation that the message is placed to some queue. " - "RabbitMQ returns message to client if there is no suitable queue." - ), - ] = True, - immediate: Annotated[ - bool, - Doc( - "Client expects that there is consumer ready to take the message to work. " - "RabbitMQ returns message to client if there is no suitable consumer." - ), - ] = False, - persist: Annotated[ - bool, - Doc("Restore the message on RabbitMQ reboot."), - ] = False, - ) -> None: - self.mandatory = mandatory - self.immediate = immediate - self.persist = persist - - def to_dict(self) -> dict[str, bool]: - """Convert object to options dict.""" - return { - "mandatory": self.mandatory, - "immediate": self.immediate, - "persist": self.persist, - } From af6f92f60dabe62f980dbb74f192185b0b35a38f Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Wed, 4 Dec 2024 21:36:12 +0300 Subject: [PATCH 210/245] lint: fix mypy a bit --- faststream/_internal/_compat.py | 1 + faststream/_internal/cli/main.py | 28 ++++--- faststream/_internal/fastapi/router.py | 2 +- faststream/_internal/proto.py | 28 ++++++- faststream/_internal/publisher/proto.py | 34 ++++---- faststream/_internal/publisher/specified.py | 10 +-- faststream/_internal/publisher/usecase.py | 21 +++-- .../_internal/state/logger/logger_proxy.py | 4 + faststream/_internal/subscriber/call_item.py | 6 +- .../{call_wrapper/call.py => call_wrapper.py} | 7 +- .../subscriber/call_wrapper/__init__.py | 0 .../subscriber/call_wrapper/proto.py | 79 ------------------- faststream/_internal/subscriber/mixins.py | 2 +- faststream/_internal/subscriber/proto.py | 11 +-- faststream/_internal/subscriber/specified.py | 8 +- faststream/_internal/subscriber/usecase.py | 79 ++++++++++++++----- faststream/_internal/subscriber/utils.py | 10 ++- faststream/_internal/types.py | 9 ++- faststream/_internal/utils/data.py | 5 +- faststream/_internal/utils/functions.py | 20 ++--- faststream/asgi/app.py | 2 + faststream/confluent/client.py | 22 ++++-- faststream/confluent/subscriber/usecase.py | 17 ++-- faststream/confluent/testing.py | 2 +- faststream/kafka/testing.py | 2 +- faststream/redis/subscriber/usecase.py | 22 ++---- faststream/specification/proto/endpoint.py | 7 +- tests/cli/test_run_asgi.py | 15 +++- 28 files changed, 217 insertions(+), 236 deletions(-) rename faststream/_internal/subscriber/{call_wrapper/call.py => call_wrapper.py} (97%) delete mode 100644 faststream/_internal/subscriber/call_wrapper/__init__.py delete mode 100644 faststream/_internal/subscriber/call_wrapper/proto.py diff --git a/faststream/_internal/_compat.py b/faststream/_internal/_compat.py index ba38326ac9..b445e336b7 100644 --- a/faststream/_internal/_compat.py +++ b/faststream/_internal/_compat.py @@ -33,6 +33,7 @@ __all__ = ( "HAS_TYPER", "PYDANTIC_V2", + "BaseModel", "CoreSchema", "EmailStr", "GetJsonSchemaHandler", diff --git a/faststream/_internal/cli/main.py b/faststream/_internal/cli/main.py index 95fb8037c6..17ccbd61f7 100644 --- a/faststream/_internal/cli/main.py +++ b/faststream/_internal/cli/main.py @@ -2,13 +2,14 @@ import sys import warnings from contextlib import suppress -from typing import TYPE_CHECKING, Any, Optional +from typing import TYPE_CHECKING, Any, Optional, cast import anyio import typer from faststream import FastStream from faststream.__about__ import __version__ +from faststream._internal._compat import json_loads from faststream._internal.application import Application from faststream._internal.cli.docs import asyncapi_app from faststream._internal.cli.utils.imports import import_from_string @@ -122,6 +123,7 @@ def run( # Should be imported after sys.path changes module_path, app_obj = import_from_string(app, is_factory=is_factory) + app_obj = cast(Application, app_obj) args = (app, extra, is_factory, casted_log_level) @@ -160,7 +162,7 @@ def run( workers=workers, ).run() else: - args[1]["workers"] = workers + args[1]["workers"] = str(workers) _run(*args) else: @@ -181,6 +183,7 @@ def _run( ) -> None: """Runs the specified application.""" _, app_obj = import_from_string(app, is_factory=is_factory) + app_obj = cast(Application, app_obj) _run_imported_app( app_obj, extra_options=extra_options, @@ -235,7 +238,7 @@ def publish( ), message: str = typer.Argument( ..., - help="Message to be published.", + help="JSON Message string to publish.", ), rpc: bool = typer.Option( False, @@ -255,9 +258,9 @@ def publish( """ app, extra = parse_cli_args(app, *ctx.args) - extra["message"] = message - if "timeout" in extra: - extra["timeout"] = float(extra["timeout"]) + publish_extra: AnyDict = extra.copy() + if "timeout" in publish_extra: + publish_extra["timeout"] = float(publish_extra["timeout"]) try: _, app_obj = import_from_string(app, is_factory=is_factory) @@ -269,7 +272,7 @@ def publish( raise ValueError(msg) app_obj._setup() - result = anyio.run(publish_message, app_obj.broker, rpc, extra) + result = anyio.run(publish_message, app_obj.broker, rpc, message, publish_extra) if rpc: typer.echo(result) @@ -282,13 +285,18 @@ def publish( async def publish_message( broker: "BrokerUsecase[Any, Any]", rpc: bool, + message: str, extra: "AnyDict", ) -> Any: + with suppress(Exception): + message = json_loads(message) + try: async with broker: if rpc: - return await broker.request(**extra) - return await broker.publish(**extra) + return await broker.request(message, **extra) # type: ignore[call-arg] + return await broker.publish(message, **extra) # type: ignore[call-arg] + except Exception as e: - typer.echo(f"Error when broker was publishing: {e}") + typer.echo(f"Error when broker was publishing: {e!r}") sys.exit(1) diff --git a/faststream/_internal/fastapi/router.py b/faststream/_internal/fastapi/router.py index e0bb4b2d9b..7d99dae680 100644 --- a/faststream/_internal/fastapi/router.py +++ b/faststream/_internal/fastapi/router.py @@ -51,7 +51,7 @@ from faststream._internal.broker.broker import BrokerUsecase from faststream._internal.proto import NameRequired from faststream._internal.publisher.proto import PublisherProto - from faststream._internal.subscriber.call_wrapper.call import HandlerCallWrapper + from faststream._internal.subscriber.call_wrapper import HandlerCallWrapper from faststream._internal.types import BrokerMiddleware from faststream.message import StreamMessage from faststream.specification.base.specification import Specification diff --git a/faststream/_internal/proto.py b/faststream/_internal/proto.py index 615dec872b..9eb8ed33aa 100644 --- a/faststream/_internal/proto.py +++ b/faststream/_internal/proto.py @@ -1,8 +1,32 @@ from abc import abstractmethod -from typing import Any, Optional, Protocol, TypeVar, Union, overload +from typing import Any, Callable, Optional, Protocol, TypeVar, Union, overload +from faststream._internal.subscriber.call_wrapper import ( + HandlerCallWrapper, + ensure_call_wrapper, +) +from faststream._internal.types import ( + MsgType, + P_HandlerParams, + T_HandlerReturn, +) -class Endpoint(Protocol): + +class EndpointWrapper(Protocol[MsgType]): + def __call__( + self, + func: Union[ + Callable[P_HandlerParams, T_HandlerReturn], + HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn], + ], + ) -> HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]: + handler: HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn] = ( + ensure_call_wrapper(func) + ) + return handler + + +class Endpoint(EndpointWrapper[MsgType]): @abstractmethod def add_prefix(self, prefix: str) -> None: ... diff --git a/faststream/_internal/publisher/proto.py b/faststream/_internal/publisher/proto.py index 93e83efe94..f83be6188c 100644 --- a/faststream/_internal/publisher/proto.py +++ b/faststream/_internal/publisher/proto.py @@ -1,11 +1,16 @@ from abc import abstractmethod from collections.abc import Iterable, Sequence -from typing import TYPE_CHECKING, Any, Callable, Generic, Optional, Protocol - -from typing_extensions import override +from typing import ( + TYPE_CHECKING, + Any, + Optional, + Protocol, +) from faststream._internal.proto import Endpoint -from faststream._internal.types import MsgType +from faststream._internal.types import ( + MsgType, +) from faststream.response.response import PublishCommand if TYPE_CHECKING: @@ -14,9 +19,7 @@ from faststream._internal.types import ( AsyncCallable, BrokerMiddleware, - P_HandlerParams, PublisherMiddleware, - T_HandlerReturn, ) from faststream.response.response import PublishCommand @@ -88,28 +91,23 @@ async def request( class PublisherProto( - Endpoint, + Endpoint[MsgType], BasePublisherProto, - Generic[MsgType], ): _broker_middlewares: Sequence["BrokerMiddleware[MsgType]"] _middlewares: Sequence["PublisherMiddleware"] - _producer: Optional["ProducerProto"] + + @property + @abstractmethod + def _producer(self) -> "ProducerProto": ... @abstractmethod def add_middleware(self, middleware: "BrokerMiddleware[MsgType]") -> None: ... - @override @abstractmethod - def _setup( # type: ignore[override] + def _setup( self, *, - producer: Optional["ProducerProto"], state: "Pointer[BrokerState]", + producer: "ProducerProto", ) -> None: ... - - @abstractmethod - def __call__( - self, - func: "Callable[P_HandlerParams, T_HandlerReturn]", - ) -> "Callable[P_HandlerParams, T_HandlerReturn]": ... diff --git a/faststream/_internal/publisher/specified.py b/faststream/_internal/publisher/specified.py index a6e34a163b..db9c64a974 100644 --- a/faststream/_internal/publisher/specified.py +++ b/faststream/_internal/publisher/specified.py @@ -17,10 +17,10 @@ if TYPE_CHECKING: from faststream._internal.basic_types import AnyCallable, AnyDict from faststream._internal.state import BrokerState, Pointer - from faststream._internal.subscriber.call_wrapper.call import HandlerCallWrapper + from faststream._internal.subscriber.call_wrapper import HandlerCallWrapper -class SpecificationPublisher(EndpointSpecification[PublisherSpec]): +class SpecificationPublisher(EndpointSpecification[MsgType, PublisherSpec]): """A base class for publishers in an asynchronous API.""" _state: "Pointer[BrokerState]" # should be set in next parent @@ -44,9 +44,9 @@ def __call__( "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]", ], ) -> "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]": - func = super().__call__(func) - self.calls.append(func._original_call) - return func + handler = super().__call__(func) + self.calls.append(handler._original_call) + return handler def get_payloads(self) -> list[tuple["AnyDict", str]]: payloads: list[tuple[AnyDict, str]] = [] diff --git a/faststream/_internal/publisher/usecase.py b/faststream/_internal/publisher/usecase.py index 08094ca56f..662430fbbb 100644 --- a/faststream/_internal/publisher/usecase.py +++ b/faststream/_internal/publisher/usecase.py @@ -1,4 +1,4 @@ -from collections.abc import Awaitable, Iterable +from collections.abc import Awaitable, Iterable, Sequence from functools import partial from itertools import chain from typing import ( @@ -15,9 +15,8 @@ from faststream._internal.publisher.proto import PublisherProto from faststream._internal.state import BrokerState, EmptyBrokerState, Pointer from faststream._internal.state.producer import ProducerUnset -from faststream._internal.subscriber.call_wrapper.call import ( +from faststream._internal.subscriber.call_wrapper import ( HandlerCallWrapper, - ensure_call_wrapper, ) from faststream._internal.subscriber.utils import process_msg from faststream._internal.types import ( @@ -42,8 +41,8 @@ class PublisherUsecase(PublisherProto[MsgType]): def __init__( self, *, - broker_middlewares: Iterable["BrokerMiddleware[MsgType]"], - middlewares: Iterable["PublisherMiddleware"], + broker_middlewares: Sequence["BrokerMiddleware[MsgType]"], + middlewares: Sequence["PublisherMiddleware"], ) -> None: self.middlewares = middlewares self._broker_middlewares = broker_middlewares @@ -65,7 +64,7 @@ def _producer(self) -> "ProducerProto": return self.__producer or self._state.get().producer @override - def _setup( # type: ignore[override] + def _setup( self, *, state: "Pointer[BrokerState]", @@ -97,9 +96,7 @@ def __call__( ], ) -> HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]: """Decorate user's function by current publisher.""" - handler: HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn] = ( - ensure_call_wrapper(func) - ) + handler = super().__call__(func) handler._publishers.append(self) return handler @@ -125,7 +122,7 @@ async def _basic_publish( ): pub = partial(pub_m, pub) - await pub(cmd) + return await pub(cmd) async def _basic_request( self, @@ -163,7 +160,7 @@ async def _basic_publish_batch( cmd: "PublishCommand", *, _extra_middlewares: Iterable["PublisherMiddleware"], - ) -> Optional[Any]: + ) -> Any: pub = self._producer.publish_batch context = self._state.get().di_state.context @@ -180,4 +177,4 @@ async def _basic_publish_batch( ): pub = partial(pub_m, pub) - await pub(cmd) + return await pub(cmd) diff --git a/faststream/_internal/state/logger/logger_proxy.py b/faststream/_internal/state/logger/logger_proxy.py index 690a42c6dd..0693fd184e 100644 --- a/faststream/_internal/state/logger/logger_proxy.py +++ b/faststream/_internal/state/logger/logger_proxy.py @@ -1,3 +1,4 @@ +from abc import abstractmethod from collections.abc import Mapping from typing import Any, Optional @@ -8,6 +9,7 @@ class LoggerObject(LoggerProto): logger: Optional["LoggerProto"] + @abstractmethod def __bool__(self) -> bool: ... @@ -73,6 +75,8 @@ class RealLoggerObject(LoggerObject): or in default logger case (.params_storage.DefaultLoggerStorage). """ + logger: "LoggerProto" + def __init__(self, logger: "LoggerProto") -> None: self.logger = logger diff --git a/faststream/_internal/subscriber/call_item.py b/faststream/_internal/subscriber/call_item.py index 3ab28c58c7..bd8c7a4e49 100644 --- a/faststream/_internal/subscriber/call_item.py +++ b/faststream/_internal/subscriber/call_item.py @@ -21,7 +21,7 @@ from faststream._internal.basic_types import AsyncFuncAny, Decorator from faststream._internal.state import BrokerState, Pointer - from faststream._internal.subscriber.call_wrapper.call import HandlerCallWrapper + from faststream._internal.subscriber.call_wrapper import HandlerCallWrapper from faststream._internal.types import ( AsyncCallable, AsyncFilter, @@ -128,8 +128,8 @@ async def is_suitable( if not (parser := cast(Optional["AsyncCallable"], self.item_parser)) or not ( decoder := cast(Optional["AsyncCallable"], self.item_decoder) ): - msg = "You should setup `HandlerItem` at first." - raise SetupError(msg) + error_msg = "You should setup `HandlerItem` at first." + raise SetupError(error_msg) message = cache[parser] = cast( "StreamMessage[MsgType]", diff --git a/faststream/_internal/subscriber/call_wrapper/call.py b/faststream/_internal/subscriber/call_wrapper.py similarity index 97% rename from faststream/_internal/subscriber/call_wrapper/call.py rename to faststream/_internal/subscriber/call_wrapper.py index 14d081b52f..dfe1b45dad 100644 --- a/faststream/_internal/subscriber/call_wrapper/call.py +++ b/faststream/_internal/subscriber/call_wrapper.py @@ -24,7 +24,6 @@ if TYPE_CHECKING: from fast_depends.dependencies import Dependant - from fast_depends.use import InjectWrapper from faststream._internal.basic_types import Decorator from faststream._internal.publisher.proto import PublisherProto @@ -88,7 +87,7 @@ def __call__( async def call_wrapped( self, message: "StreamMessage[MsgType]", - ) -> Awaitable[Any]: + ) -> Any: """Calls the wrapped function with the given message.""" assert self._wrapped_call, "You should use `set_wrapped` first" # nosec B101 if self.is_test: @@ -145,7 +144,7 @@ def refresh(self, with_mock: bool = False) -> None: def set_wrapped( self, *, - dependencies: Iterable["Dependant"], + dependencies: Sequence["Dependant"], _call_decorators: Iterable["Decorator"], state: "DIState", ) -> Optional["CallModel"]: @@ -166,7 +165,7 @@ def set_wrapped( ) if state.use_fastdepends: - wrapper: InjectWrapper[Any, Any] = inject( + wrapper = inject( func=None, context__=state.context, ) diff --git a/faststream/_internal/subscriber/call_wrapper/__init__.py b/faststream/_internal/subscriber/call_wrapper/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/faststream/_internal/subscriber/call_wrapper/proto.py b/faststream/_internal/subscriber/call_wrapper/proto.py deleted file mode 100644 index fdaf8eb812..0000000000 --- a/faststream/_internal/subscriber/call_wrapper/proto.py +++ /dev/null @@ -1,79 +0,0 @@ -from collections.abc import Iterable, Sequence -from typing import ( - TYPE_CHECKING, - Any, - Callable, - Optional, - Protocol, - Union, - overload, -) - -from faststream._internal.types import ( - CustomCallable, - Filter, - MsgType, - P_HandlerParams, - SubscriberMiddleware, - T_HandlerReturn, -) - -if TYPE_CHECKING: - from fast_depends.dependencies import Dependant - - from .call import HandlerCallWrapper - - -class WrapperProto(Protocol[MsgType]): - """Annotation class to represent @subscriber return type.""" - - @overload - def __call__( - self, - func: None = None, - *, - filter: Optional["Filter[Any]"] = None, - parser: Optional["CustomCallable"] = None, - decoder: Optional["CustomCallable"] = None, - middlewares: Sequence["SubscriberMiddleware[Any]"] = (), - dependencies: Iterable["Dependant"] = (), - ) -> Callable[ - [Callable[P_HandlerParams, T_HandlerReturn]], - "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]", - ]: ... - - @overload - def __call__( - self, - func: Union[ - Callable[P_HandlerParams, T_HandlerReturn], - "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]", - ], - *, - filter: Optional["Filter[Any]"] = None, - parser: Optional["CustomCallable"] = None, - decoder: Optional["CustomCallable"] = None, - middlewares: Sequence["SubscriberMiddleware[Any]"] = (), - dependencies: Iterable["Dependant"] = (), - ) -> "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]": ... - - def __call__( - self, - func: Union[ - Callable[P_HandlerParams, T_HandlerReturn], - "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]", - None, - ] = None, - *, - filter: Optional["Filter[Any]"] = None, - parser: Optional["CustomCallable"] = None, - decoder: Optional["CustomCallable"] = None, - middlewares: Sequence["SubscriberMiddleware[Any]"] = (), - dependencies: Iterable["Dependant"] = (), - ) -> Union[ - "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]", - Callable[ - [Callable[P_HandlerParams, T_HandlerReturn]], - "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]", - ], - ]: ... diff --git a/faststream/_internal/subscriber/mixins.py b/faststream/_internal/subscriber/mixins.py index c76887b757..af96a87a41 100644 --- a/faststream/_internal/subscriber/mixins.py +++ b/faststream/_internal/subscriber/mixins.py @@ -27,7 +27,7 @@ async def close(self) -> None: if not task.done(): task.cancel() - self.tasks = [] + self.tasks.clear() class ConcurrentMixin(TasksMixin): diff --git a/faststream/_internal/subscriber/proto.py b/faststream/_internal/subscriber/proto.py index 1e8a7ce988..cb24b32295 100644 --- a/faststream/_internal/subscriber/proto.py +++ b/faststream/_internal/subscriber/proto.py @@ -2,10 +2,9 @@ from collections.abc import Iterable, Sequence from typing import TYPE_CHECKING, Any, Optional -from typing_extensions import Self, override +from typing_extensions import Self from faststream._internal.proto import Endpoint -from faststream._internal.subscriber.call_wrapper.proto import WrapperProto from faststream._internal.types import MsgType if TYPE_CHECKING: @@ -28,10 +27,7 @@ from .call_item import HandlerItem -class SubscriberProto( - Endpoint, - WrapperProto[MsgType], -): +class SubscriberProto(Endpoint[MsgType]): calls: list["HandlerItem[MsgType]"] running: bool @@ -49,9 +45,8 @@ def get_log_context( /, ) -> dict[str, str]: ... - @override @abstractmethod - def _setup( # type: ignore[override] + def _setup( self, *, extra_context: "AnyDict", diff --git a/faststream/_internal/subscriber/specified.py b/faststream/_internal/subscriber/specified.py index 3af87b590c..50c36efbf6 100644 --- a/faststream/_internal/subscriber/specified.py +++ b/faststream/_internal/subscriber/specified.py @@ -4,6 +4,7 @@ Optional, ) +from faststream._internal.types import MsgType from faststream.exceptions import SetupError from faststream.specification.asyncapi.message import parse_handler_params from faststream.specification.asyncapi.utils import to_camelcase @@ -12,16 +13,11 @@ if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict - from faststream._internal.types import ( - MsgType, - ) from .call_item import HandlerItem -class SpecificationSubscriber( - EndpointSpecification[SubscriberSpec], -): +class SpecificationSubscriber(EndpointSpecification[MsgType, SubscriberSpec]): calls: list["HandlerItem[MsgType]"] def __init__( diff --git a/faststream/_internal/subscriber/usecase.py b/faststream/_internal/subscriber/usecase.py index ba7d28e6c9..26ba99000f 100644 --- a/faststream/_internal/subscriber/usecase.py +++ b/faststream/_internal/subscriber/usecase.py @@ -7,15 +7,12 @@ Any, Callable, Optional, + Union, ) -from typing_extensions import Self, override +from typing_extensions import Self, overload, override from faststream._internal.subscriber.call_item import HandlerItem -from faststream._internal.subscriber.call_wrapper.call import ( - HandlerCallWrapper, - ensure_call_wrapper, -) from faststream._internal.subscriber.proto import SubscriberProto from faststream._internal.subscriber.utils import ( MultiLock, @@ -42,8 +39,10 @@ BasePublisherProto, ) from faststream._internal.state import BrokerState, Pointer + from faststream._internal.subscriber.call_wrapper import HandlerCallWrapper from faststream._internal.types import ( AsyncCallable, + AsyncFilter, BrokerMiddleware, CustomCallable, Filter, @@ -124,7 +123,7 @@ def add_middleware(self, middleware: "BrokerMiddleware[MsgType]") -> None: self._broker_middlewares = (*self._broker_middlewares, middleware) @override - def _setup( # type: ignore[override] + def _setup( self, *, extra_context: "AnyDict", @@ -196,35 +195,75 @@ def add_call( ) return self + @overload + def __call__( + self, + func: None = None, + *, + filter: "Filter[StreamMessage[MsgType]]" = default_filter, + parser: Optional["CustomCallable"] = None, + decoder: Optional["CustomCallable"] = None, + middlewares: Sequence["SubscriberMiddleware[Any]"] = (), + dependencies: Iterable["Dependant"] = (), + ) -> Callable[ + [Callable[P_HandlerParams, T_HandlerReturn]], + "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]", + ]: ... + + @overload + def __call__( + self, + func: Union[ + Callable[P_HandlerParams, T_HandlerReturn], + "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]", + ], + *, + filter: "Filter[StreamMessage[MsgType]]" = default_filter, + parser: Optional["CustomCallable"] = None, + decoder: Optional["CustomCallable"] = None, + middlewares: Sequence["SubscriberMiddleware[Any]"] = (), + dependencies: Iterable["Dependant"] = (), + ) -> "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]": ... + @override def __call__( self, - func: Optional[Callable[P_HandlerParams, T_HandlerReturn]] = None, + func: Union[ + Callable[P_HandlerParams, T_HandlerReturn], + "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]", + None, + ] = None, *, - filter: "Filter[Any]" = default_filter, + filter: "Filter[StreamMessage[MsgType]]" = default_filter, parser: Optional["CustomCallable"] = None, decoder: Optional["CustomCallable"] = None, middlewares: Sequence["SubscriberMiddleware[Any]"] = (), dependencies: Iterable["Dependant"] = (), - ) -> Any: + ) -> Union[ + "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]", + Callable[ + [Callable[P_HandlerParams, T_HandlerReturn]], + "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]", + ], + ]: if (options := self._call_options) is None: msg = ( "You can't create subscriber directly. Please, use `add_call` at first." ) - raise SetupError( - msg, - ) + raise SetupError(msg) total_deps = (*options.dependencies, *dependencies) total_middlewares = (*options.middlewares, *middlewares) - async_filter = to_async(filter) + async_filter: AsyncFilter[StreamMessage[MsgType]] = to_async(filter) def real_wrapper( - func: Callable[P_HandlerParams, T_HandlerReturn], + func: Union[ + Callable[P_HandlerParams, T_HandlerReturn], + "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]", + ], ) -> "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]": - handler: HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn] = ( - ensure_call_wrapper(func) - ) + handler = super(SubscriberUsecase, self).__call__(func) + self.calls.append( HandlerItem[MsgType]( handler=handler, @@ -342,13 +381,13 @@ async def process_message(self, msg: MsgType) -> "Response": if parsing_error: raise parsing_error - msg = f"There is no suitable handler for {msg=}" - raise SubscriberNotFound(msg) + error_msg = f"There is no suitable handler for {msg=}" + raise SubscriberNotFound(error_msg) # An error was raised and processed by some middleware return ensure_response(None) - def __build__middlewares_stack(self) -> tuple["BaseMiddleware", ...]: + def __build__middlewares_stack(self) -> tuple["BrokerMiddleware[MsgType]", ...]: logger_state = self._state.get().logger_state if self.ack_policy is AckPolicy.DO_NOTHING: diff --git a/faststream/_internal/subscriber/utils.py b/faststream/_internal/subscriber/utils.py index 31f2c5358d..9195087e2f 100644 --- a/faststream/_internal/subscriber/utils.py +++ b/faststream/_internal/subscriber/utils.py @@ -56,8 +56,8 @@ async def process_msg( parsed_msg.set_decoder(decoder) return await return_msg(parsed_msg) - msg = "unreachable" - raise AssertionError(msg) + error_msg = "unreachable" + raise AssertionError(error_msg) async def default_filter(msg: "StreamMessage[Any]") -> bool: @@ -66,7 +66,11 @@ async def default_filter(msg: "StreamMessage[Any]") -> bool: class MultiLock: - """A class representing a multi lock.""" + """A class representing a multi lock. + + This lock can be acquired multiple times. + `wait_release` method waits for all locks will be released. + """ def __init__(self) -> None: """Initialize a new instance of the class.""" diff --git a/faststream/_internal/types.py b/faststream/_internal/types.py index ea1ecd3dbf..b90aad9cd1 100644 --- a/faststream/_internal/types.py +++ b/faststream/_internal/types.py @@ -17,6 +17,7 @@ from faststream.response.response import PublishCommand MsgType = TypeVar("MsgType") +Msg_contra = TypeVar("Msg_contra", contravariant=True) StreamMsg = TypeVar("StreamMsg", bound=StreamMessage[Any]) ConnectionType = TypeVar("ConnectionType") @@ -63,12 +64,12 @@ ] -class BrokerMiddleware(Protocol[MsgType]): +class BrokerMiddleware(Protocol[Msg_contra]): """Middleware builder interface.""" def __call__( self, - msg: Optional[MsgType], + msg: Optional[Msg_contra], /, *, context: ContextRepo, @@ -86,6 +87,6 @@ class PublisherMiddleware(Protocol): def __call__( self, - call_next: Callable[[PublishCommand], Awaitable[PublishCommand]], - msg: PublishCommand, + call_next: Callable[[PublishCommand], Awaitable[Any]], + cmd: PublishCommand, ) -> Any: ... diff --git a/faststream/_internal/utils/data.py b/faststream/_internal/utils/data.py index 98e3729fac..8f8a133636 100644 --- a/faststream/_internal/utils/data.py +++ b/faststream/_internal/utils/data.py @@ -20,4 +20,7 @@ def filter_by_dict( else: extra_data[k] = v - return typed_dict(out_data), extra_data + return ( + typed_dict(out_data), # type: ignore[call-arg] + extra_data, + ) diff --git a/faststream/_internal/utils/functions.py b/faststream/_internal/utils/functions.py index be90e6f0a2..d81201fcf0 100644 --- a/faststream/_internal/utils/functions.py +++ b/faststream/_internal/utils/functions.py @@ -1,16 +1,15 @@ from collections.abc import AsyncIterator, Awaitable, Iterator -from contextlib import AbstractContextManager, asynccontextmanager, contextmanager +from contextlib import asynccontextmanager, contextmanager from functools import wraps from typing import ( Any, Callable, - Optional, TypeVar, Union, + cast, overload, ) -import anyio from fast_depends.core import CallModel from fast_depends.utils import ( is_coroutine_callable, @@ -25,7 +24,6 @@ "call_or_await", "drop_response_type", "fake_context", - "timeout_scope", "to_async", ) @@ -53,7 +51,9 @@ def to_async( ) -> Callable[F_Spec, Awaitable[F_Return]]: """Converts a synchronous function to an asynchronous function.""" if is_coroutine_callable(func): - return func + return cast(Callable[F_Spec, Awaitable[F_Return]], func) + + func = cast(Callable[F_Spec, F_Return], func) @wraps(func) async def to_async_wrapper(*args: F_Spec.args, **kwargs: F_Spec.kwargs) -> F_Return: @@ -63,16 +63,6 @@ async def to_async_wrapper(*args: F_Spec.args, **kwargs: F_Spec.kwargs) -> F_Ret return to_async_wrapper -def timeout_scope( - timeout: Optional[float] = 30, - raise_timeout: bool = False, -) -> AbstractContextManager[anyio.CancelScope]: - scope: Callable[[Optional[float]], AbstractContextManager[anyio.CancelScope]] - scope = anyio.fail_after if raise_timeout else anyio.move_on_after - - return scope(timeout) - - @asynccontextmanager async def fake_context(*args: Any, **kwargs: Any) -> AsyncIterator[None]: yield None diff --git a/faststream/asgi/app.py b/faststream/asgi/app.py index 02fe0cfb78..c815454401 100644 --- a/faststream/asgi/app.py +++ b/faststream/asgi/app.py @@ -183,6 +183,8 @@ def load(self) -> "ASGIApp": elif port is not None: bindings.append(f"127.0.0.1:{port}") + run_extra_options["workers"] = int(run_extra_options.pop("workers", 1)) + bind = run_extra_options.get("bind") if isinstance(bind, list): bindings.extend(bind) diff --git a/faststream/confluent/client.py b/faststream/confluent/client.py index bd1736ddb5..3c1cc2b8cf 100644 --- a/faststream/confluent/client.py +++ b/faststream/confluent/client.py @@ -311,6 +311,9 @@ def __init__( self.config = final_config self.consumer = Consumer(final_config) + # We can't read and close consumer concurrently + self._lock = asyncio.Lock() + @property def topics_to_create(self) -> list[str]: return list({*self.topics, *(p.topic for p in self.partitions)}) @@ -368,12 +371,14 @@ async def stop(self) -> None: exc_info=e, ) - # Wrap calls to async to make method cancelable by timeout - await call_or_await(self.consumer.close) + async with self._lock: + # Wrap calls to async to make method cancelable by timeout + await call_or_await(self.consumer.close) async def getone(self, timeout: float = 0.1) -> Optional[Message]: """Consumes a single message from Kafka.""" - msg = await call_or_await(self.consumer.poll, timeout) + async with self._lock: + msg = await call_or_await(self.consumer.poll, timeout) return check_msg_error(msg) async def getmany( @@ -382,11 +387,12 @@ async def getmany( max_records: Optional[int] = 10, ) -> tuple[Message, ...]: """Consumes a batch of messages from Kafka and groups them by topic and partition.""" - raw_messages: list[Optional[Message]] = await call_or_await( - self.consumer.consume, # type: ignore[arg-type] - num_messages=max_records or 10, - timeout=timeout, - ) + async with self._lock: + raw_messages: list[Optional[Message]] = await call_or_await( + self.consumer.consume, # type: ignore[arg-type] + num_messages=max_records or 10, + timeout=timeout, + ) return tuple(x for x in map(check_msg_error, raw_messages) if x is not None) diff --git a/faststream/confluent/subscriber/usecase.py b/faststream/confluent/subscriber/usecase.py index 1c46aec7fb..5d44941a22 100644 --- a/faststream/confluent/subscriber/usecase.py +++ b/faststream/confluent/subscriber/usecase.py @@ -1,5 +1,4 @@ -import asyncio -from abc import ABC, abstractmethod +from abc import abstractmethod from collections.abc import Iterable, Sequence from typing import ( TYPE_CHECKING, @@ -12,6 +11,7 @@ from confluent_kafka import KafkaException, Message from typing_extensions import override +from faststream._internal.subscriber.mixins import TasksMixin from faststream._internal.subscriber.usecase import SubscriberUsecase from faststream._internal.subscriber.utils import process_msg from faststream._internal.types import MsgType @@ -35,7 +35,7 @@ from faststream.message import StreamMessage -class LogicSubscriber(ABC, SubscriberUsecase[MsgType]): +class LogicSubscriber(TasksMixin, SubscriberUsecase[MsgType]): """A class to handle logic for consuming messages from Kafka.""" topics: Sequence[str] @@ -45,7 +45,6 @@ class LogicSubscriber(ABC, SubscriberUsecase[MsgType]): consumer: Optional["AsyncConfluentConsumer"] parser: AsyncConfluentParser - task: Optional["asyncio.Task[None]"] client_id: Optional[str] def __init__( @@ -81,7 +80,6 @@ def __init__( self.partitions = partitions self.consumer = None - self.task = None self.polling_interval = polling_interval # Setup it later @@ -130,19 +128,14 @@ async def start(self) -> None: await super().start() if self.calls: - self.task = asyncio.create_task(self._consume()) + self.add_task(self._consume()) async def close(self) -> None: - await super().close() - if self.consumer is not None: await self.consumer.stop() self.consumer = None - if self.task is not None and not self.task.done(): - self.task.cancel() - - self.task = None + await super().close() @override async def get_one( diff --git a/faststream/confluent/testing.py b/faststream/confluent/testing.py index 92676d6e7a..5f4d8711a8 100644 --- a/faststream/confluent/testing.py +++ b/faststream/confluent/testing.py @@ -54,7 +54,7 @@ async def _fake_connect( # type: ignore[override] @staticmethod def create_publisher_fake_subscriber( broker: KafkaBroker, - publisher: "SpecificationPublisher[Any]", + publisher: "SpecificationPublisher[Any, Any]", ) -> tuple["LogicSubscriber[Any]", bool]: sub: Optional[LogicSubscriber[Any]] = None for handler in broker._subscribers: diff --git a/faststream/kafka/testing.py b/faststream/kafka/testing.py index 96e0614183..fc442f9ee6 100755 --- a/faststream/kafka/testing.py +++ b/faststream/kafka/testing.py @@ -56,7 +56,7 @@ async def _fake_connect( # type: ignore[override] @staticmethod def create_publisher_fake_subscriber( broker: KafkaBroker, - publisher: "SpecificationPublisher[Any]", + publisher: "SpecificationPublisher[Any, Any]", ) -> tuple["LogicSubscriber[Any]", bool]: sub: Optional[LogicSubscriber[Any]] = None for handler in broker._subscribers: diff --git a/faststream/redis/subscriber/usecase.py b/faststream/redis/subscriber/usecase.py index c54559782a..f1c9bb880f 100644 --- a/faststream/redis/subscriber/usecase.py +++ b/faststream/redis/subscriber/usecase.py @@ -1,4 +1,3 @@ -import asyncio import math from abc import abstractmethod from collections.abc import Awaitable, Iterable, Sequence @@ -19,6 +18,7 @@ from redis.exceptions import ResponseError from typing_extensions import TypeAlias, override +from faststream._internal.subscriber.mixins import TasksMixin from faststream._internal.subscriber.usecase import SubscriberUsecase from faststream._internal.subscriber.utils import process_msg from faststream.middlewares import AckPolicy @@ -61,7 +61,7 @@ Offset: TypeAlias = bytes -class LogicSubscriber(SubscriberUsecase[UnifyRedisDict]): +class LogicSubscriber(TasksMixin, SubscriberUsecase[UnifyRedisDict]): """A class to represent a Redis handler.""" _client: Optional["Redis[bytes]"] @@ -88,7 +88,6 @@ def __init__( ) self._client = None - self.task: Optional[asyncio.Task[None]] = None @override def _setup( # type: ignore[override] @@ -128,7 +127,7 @@ async def start( self, *args: Any, ) -> None: - if self.task: + if self.tasks: return await super().start() @@ -136,9 +135,7 @@ async def start( start_signal = anyio.Event() if self.calls: - self.task = asyncio.create_task( - self._consume(*args, start_signal=start_signal), - ) + self.add_task(self._consume(*args, start_signal=start_signal)) with anyio.fail_after(3.0): await start_signal.wait() @@ -171,13 +168,6 @@ async def _consume(self, *args: Any, start_signal: anyio.Event) -> None: async def _get_msgs(self, *args: Any) -> None: raise NotImplementedError - async def close(self) -> None: - await super().close() - - if self.task is not None and not self.task.done(): - self.task.cancel() - self.task = None - @staticmethod def build_log_context( message: Optional["BrokerStreamMessage[Any]"], @@ -351,7 +341,7 @@ async def _consume( # type: ignore[override] @override async def start(self) -> None: - if self.task: + if self.tasks: return assert self._client, "You should setup subscriber at first." # nosec B101 @@ -523,7 +513,7 @@ def get_log_context( @override async def start(self) -> None: - if self.task: + if self.tasks: return assert self._client, "You should setup subscriber at first." # nosec B101 diff --git a/faststream/specification/proto/endpoint.py b/faststream/specification/proto/endpoint.py index 380acb1071..b0991d43f8 100644 --- a/faststream/specification/proto/endpoint.py +++ b/faststream/specification/proto/endpoint.py @@ -1,10 +1,13 @@ -from abc import ABC, abstractmethod +from abc import abstractmethod from typing import Any, Generic, Optional, TypeVar +from faststream._internal.proto import EndpointWrapper +from faststream._internal.types import MsgType + T = TypeVar("T") -class EndpointSpecification(ABC, Generic[T]): +class EndpointSpecification(EndpointWrapper[MsgType], Generic[MsgType, T]): """A class representing an asynchronous API operation: Pub or Sub.""" title_: Optional[str] diff --git a/tests/cli/test_run_asgi.py b/tests/cli/test_run_asgi.py index 49825f932b..5920e74d1c 100644 --- a/tests/cli/test_run_asgi.py +++ b/tests/cli/test_run_asgi.py @@ -34,8 +34,15 @@ def test_run_as_asgi(runner: CliRunner) -> None: assert result.exit_code == 0 -@pytest.mark.parametrize("workers", (pytest.param(1), pytest.param(2), pytest.param(5))) -def test_run_as_asgi_with_workers(runner: CliRunner, workers: int) -> None: +@pytest.mark.parametrize( + "workers", + ( + pytest.param("1"), + pytest.param("2"), + pytest.param("5"), + ), +) +def test_run_as_asgi_with_workers(runner: CliRunner, workers: str) -> None: app = AsgiFastStream(AsyncMock()) app.run = AsyncMock() @@ -53,10 +60,10 @@ def test_run_as_asgi_with_workers(runner: CliRunner, workers: int) -> None: "--port", "8000", "-w", - str(workers), + workers, ], ) - extra = {"workers": workers} if workers > 1 else {} + extra = {"workers": workers} if int(workers) > 1 else {} app.run.assert_awaited_once_with( logging.INFO, From f010bd37e2a7cb8fd3ffadb9ce27aa759d7a3576 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Wed, 4 Dec 2024 22:43:24 +0300 Subject: [PATCH 211/245] chore: remove useless code --- .../subscriber/usecases/core_subscriber.py | 29 ------------ .../usecases/stream_pull_subscriber.py | 31 ------------- .../usecases/stream_push_subscriber.py | 44 ------------------- 3 files changed, 104 deletions(-) diff --git a/faststream/nats/subscriber/usecases/core_subscriber.py b/faststream/nats/subscriber/usecases/core_subscriber.py index 41a058641f..bf307093b9 100644 --- a/faststream/nats/subscriber/usecases/core_subscriber.py +++ b/faststream/nats/subscriber/usecases/core_subscriber.py @@ -131,35 +131,6 @@ def get_log_context( class ConcurrentCoreSubscriber(ConcurrentMixin["Msg"], CoreSubscriber): - def __init__( - self, - *, - max_workers: int, - # default args - subject: str, - config: "ConsumerConfig", - queue: str, - extra_options: Optional["AnyDict"], - # Subscriber args - ack_policy: AckPolicy, - no_reply: bool, - broker_dependencies: Iterable["Dependant"], - broker_middlewares: Iterable["BrokerMiddleware[Msg]"], - ) -> None: - super().__init__( - max_workers=max_workers, - # basic args - subject=subject, - config=config, - queue=queue, - extra_options=extra_options, - # Propagated args - ack_policy=ack_policy, - no_reply=no_reply, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - ) - @override async def _create_subscription(self) -> None: """Create NATS subscription and start consume task.""" diff --git a/faststream/nats/subscriber/usecases/stream_pull_subscriber.py b/faststream/nats/subscriber/usecases/stream_pull_subscriber.py index 86a9196e3a..6dd7693edc 100644 --- a/faststream/nats/subscriber/usecases/stream_pull_subscriber.py +++ b/faststream/nats/subscriber/usecases/stream_pull_subscriber.py @@ -110,37 +110,6 @@ async def _consume_pull( class ConcurrentPullStreamSubscriber(ConcurrentMixin["Msg"], PullStreamSubscriber): - def __init__( - self, - *, - max_workers: int, - # default args - pull_sub: "PullSub", - stream: "JStream", - subject: str, - config: "ConsumerConfig", - extra_options: Optional["AnyDict"], - # Subscriber args - ack_policy: "AckPolicy", - no_reply: bool, - broker_dependencies: Iterable["Dependant"], - broker_middlewares: Iterable["BrokerMiddleware[Msg]"], - ) -> None: - super().__init__( - max_workers=max_workers, - # basic args - pull_sub=pull_sub, - stream=stream, - subject=subject, - config=config, - extra_options=extra_options, - # Propagated args - ack_policy=ack_policy, - no_reply=no_reply, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - ) - @override async def _create_subscription(self) -> None: """Create NATS subscription and start consume task.""" diff --git a/faststream/nats/subscriber/usecases/stream_push_subscriber.py b/faststream/nats/subscriber/usecases/stream_push_subscriber.py index fd1011fa18..c21bc6f481 100644 --- a/faststream/nats/subscriber/usecases/stream_push_subscriber.py +++ b/faststream/nats/subscriber/usecases/stream_push_subscriber.py @@ -1,4 +1,3 @@ -from collections.abc import Iterable from typing import ( TYPE_CHECKING, Optional, @@ -11,19 +10,7 @@ from .stream_basic import StreamSubscriber if TYPE_CHECKING: - from fast_depends.dependencies import Dependant - from nats.aio.msg import Msg from nats.js import JetStreamContext - from nats.js.api import ConsumerConfig - - from faststream._internal.basic_types import ( - AnyDict, - ) - from faststream._internal.types import ( - BrokerMiddleware, - ) - from faststream.middlewares import AckPolicy - from faststream.nats.schemas import JStream class PushStreamSubscription(StreamSubscriber): @@ -47,37 +34,6 @@ async def _create_subscription(self) -> None: class ConcurrentPushStreamSubscriber(ConcurrentMixin["Msg"], StreamSubscriber): subscription: Optional["JetStreamContext.PushSubscription"] - def __init__( - self, - *, - max_workers: int, - stream: "JStream", - # default args - subject: str, - config: "ConsumerConfig", - queue: str, - extra_options: Optional["AnyDict"], - # Subscriber args - ack_policy: "AckPolicy", - no_reply: bool, - broker_dependencies: Iterable["Dependant"], - broker_middlewares: Iterable["BrokerMiddleware[Msg]"], - ) -> None: - super().__init__( - max_workers=max_workers, - # basic args - stream=stream, - subject=subject, - config=config, - queue=queue, - extra_options=extra_options, - # Propagated args - ack_policy=ack_policy, - no_reply=no_reply, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - ) - @override async def _create_subscription(self) -> None: """Create NATS subscription and start consume task.""" From 9e57990acf586c945c9e7801390c7d61fe3b923b Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Thu, 5 Dec 2024 18:32:46 +0300 Subject: [PATCH 212/245] tests: make cli tests little bit clear --- tests/cli/test_run.py | 1 + tests/cli/test_run_asgi.py | 45 ++++++++++++-------------------------- 2 files changed, 15 insertions(+), 31 deletions(-) diff --git a/tests/cli/test_run.py b/tests/cli/test_run.py index f5b6df6f4e..294f0aee56 100644 --- a/tests/cli/test_run.py +++ b/tests/cli/test_run.py @@ -52,6 +52,7 @@ def test_run_factory(runner: CliRunner) -> None: assert result.exit_code == 0 + app_factory.assert_called_once() app.run.assert_awaited_once() diff --git a/tests/cli/test_run_asgi.py b/tests/cli/test_run_asgi.py index ad36186bf8..eb0e34d28a 100644 --- a/tests/cli/test_run_asgi.py +++ b/tests/cli/test_run_asgi.py @@ -29,11 +29,13 @@ def test_run_as_asgi(runner: CliRunner) -> None: "1", ], ) + + assert result.exit_code == 0 + app.run.assert_awaited_once_with( logging.INFO, {"host": "0.0.0.0", "port": "8000"}, ) - assert result.exit_code == 0 def test_run_as_asgi_with_workers(runner: CliRunner) -> None: @@ -55,20 +57,18 @@ def test_run_as_asgi_with_workers(runner: CliRunner) -> None: [ "run", "faststream:app", - "--host", - "0.0.0.0", - "--port", - "8000", "-w", str(workers), ], ) + + assert result.exit_code == 0 + asgi_runner.assert_called_once_with( target="faststream:app", - args=("faststream:app", {"host": "0.0.0.0", "port": "8000"}, False, 0), + args=("faststream:app", {}, False, 0), workers=workers, ) - assert result.exit_code == 0 def test_run_as_asgi_factory(runner: CliRunner) -> None: @@ -79,26 +79,14 @@ def test_run_as_asgi_factory(runner: CliRunner) -> None: with patch(IMPORT_FUNCTION_MOCK_PATH, return_value=(None, app_factory)): result = runner.invoke( faststream_app, - [ - "run", - "faststream:app", - "--host", - "0.0.0.0", - "--port", - "8000", - "-f", - ], + ["run", "-f", "faststream:app"], ) - # should be called twice - for check object type and for uvicorn - assert app_factory.called - - app.run.assert_awaited_once_with( - logging.INFO, - {"host": "0.0.0.0", "port": "8000"}, - ) assert result.exit_code == 0 + app_factory.assert_called_once() + app.run.assert_awaited_once_with(logging.INFO, {}) + def test_run_as_asgi_multiprocess_with_log_level(runner: CliRunner) -> None: app = AsgiFastStream(AsyncMock()) @@ -117,27 +105,22 @@ def test_run_as_asgi_multiprocess_with_log_level(runner: CliRunner) -> None: [ "run", "faststream:app", - "--host", - "0.0.0.0", - "--port", - "8000", "--workers", - "3", + "2", "--log-level", "critical", ], ) assert result.exit_code == 0 - asgi_runner.assert_called_once() asgi_runner.assert_called_once_with( target="faststream:app", args=( "faststream:app", - {"host": "0.0.0.0", "port": "8000"}, + {}, False, logging.CRITICAL, ), - workers=3, + workers=2, ) asgi_runner().run.assert_called_once() From 31d913f9b1fd11dc5c488e5db0509108b7688cf2 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Sat, 7 Dec 2024 17:30:17 +0300 Subject: [PATCH 213/245] refactor: make BaseMiddleware generic --- faststream/_internal/state/logger/state.py | 2 +- faststream/middlewares/base.py | 33 ++++++++++++++-------- faststream/middlewares/logging.py | 4 +-- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/faststream/_internal/state/logger/state.py b/faststream/_internal/state/logger/state.py index 2fc29707b8..5cec93320a 100644 --- a/faststream/_internal/state/logger/state.py +++ b/faststream/_internal/state/logger/state.py @@ -55,7 +55,7 @@ def log( message: str, log_level: Optional[int] = None, extra: Optional["AnyDict"] = None, - exc_info: Optional[Exception] = None, + exc_info: Optional[BaseException] = None, ) -> None: self.logger.log( (log_level or self.log_level), diff --git a/faststream/middlewares/base.py b/faststream/middlewares/base.py index 49ea3526d9..40801dd5d3 100644 --- a/faststream/middlewares/base.py +++ b/faststream/middlewares/base.py @@ -1,7 +1,10 @@ from collections.abc import Awaitable -from typing import TYPE_CHECKING, Any, Callable, Optional +from typing import TYPE_CHECKING, Any, Callable, Generic, Optional -from typing_extensions import Self +# We should use typing_extensions.TypeVar until python3.13 due default +from typing_extensions import Self, TypeVar + +from faststream.response.response import PublishCommand if TYPE_CHECKING: from types import TracebackType @@ -9,10 +12,16 @@ from faststream._internal.basic_types import AsyncFuncAny from faststream._internal.context.repository import ContextRepo from faststream.message import StreamMessage - from faststream.response.response import PublishCommand -class BaseMiddleware: +_PublishCommand_T = TypeVar( + "_PublishCommand_T", + bound=PublishCommand, + default=PublishCommand, +) + + +class BaseMiddleware(Generic[_PublishCommand_T]): """A base middleware class.""" def __init__( @@ -54,11 +63,11 @@ async def on_consume( self, msg: "StreamMessage[Any]", ) -> "StreamMessage[Any]": - """Asynchronously consumes a message.""" + """This option was deprecated and will be removed in 0.7.0. Please, use `consume_scope` instead.""" return msg async def after_consume(self, err: Optional[Exception]) -> None: - """A function to handle the result of consuming a resource asynchronously.""" + """This option was deprecated and will be removed in 0.7.0. Please, use `consume_scope` instead.""" if err is not None: raise err @@ -83,23 +92,23 @@ async def consume_scope( async def on_publish( self, - msg: "PublishCommand", - ) -> "PublishCommand": - """Asynchronously handle a publish event.""" + msg: _PublishCommand_T, + ) -> _PublishCommand_T: + """This option was deprecated and will be removed in 0.7.0. Please, use `publish_scope` instead.""" return msg async def after_publish( self, err: Optional[Exception], ) -> None: - """Asynchronous function to handle the after publish event.""" + """This option was deprecated and will be removed in 0.7.0. Please, use `publish_scope` instead.""" if err is not None: raise err async def publish_scope( self, - call_next: Callable[["PublishCommand"], Awaitable[Any]], - cmd: "PublishCommand", + call_next: Callable[[_PublishCommand_T], Awaitable[Any]], + cmd: _PublishCommand_T, ) -> Any: """Publish a message and return an async iterator.""" err: Optional[Exception] = None diff --git a/faststream/middlewares/logging.py b/faststream/middlewares/logging.py index fbc7412507..73b62d27ce 100644 --- a/faststream/middlewares/logging.py +++ b/faststream/middlewares/logging.py @@ -52,7 +52,7 @@ async def consume_scope( self, call_next: "AsyncFuncAny", msg: "StreamMessage[Any]", - ) -> "StreamMessage[Any]": + ) -> Any: source_type = self._source_type = msg._source_type if source_type is not SourceType.RESPONSE: @@ -78,7 +78,7 @@ async def __aexit__( if issubclass(exc_type, IgnoredException): self.logger.log( log_level=logging.INFO, - message=exc_val, + message=str(exc_val), extra=c, ) From 0bf4fc75510858243bb903c57329bcf51ee1f136 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Sat, 7 Dec 2024 18:56:15 +0300 Subject: [PATCH 214/245] refactor: make Prometheus middleware generic --- faststream/confluent/prometheus/middleware.py | 3 ++- faststream/confluent/prometheus/provider.py | 4 ++-- faststream/kafka/prometheus/middleware.py | 3 ++- faststream/kafka/prometheus/provider.py | 8 +++---- faststream/middlewares/base.py | 14 ++++++------- faststream/nats/prometheus/middleware.py | 3 ++- faststream/nats/prometheus/provider.py | 4 ++-- faststream/prometheus/middleware.py | 21 +++++++++---------- faststream/rabbit/prometheus/middleware.py | 3 ++- faststream/redis/prometheus/middleware.py | 3 ++- faststream/redis/prometheus/provider.py | 4 ++-- 11 files changed, 36 insertions(+), 34 deletions(-) diff --git a/faststream/confluent/prometheus/middleware.py b/faststream/confluent/prometheus/middleware.py index d294522330..e0aae6b9da 100644 --- a/faststream/confluent/prometheus/middleware.py +++ b/faststream/confluent/prometheus/middleware.py @@ -3,13 +3,14 @@ from faststream._internal.constants import EMPTY from faststream.confluent.prometheus.provider import settings_provider_factory +from faststream.confluent.response import KafkaPublishCommand from faststream.prometheus.middleware import PrometheusMiddleware if TYPE_CHECKING: from prometheus_client import CollectorRegistry -class KafkaPrometheusMiddleware(PrometheusMiddleware): +class KafkaPrometheusMiddleware(PrometheusMiddleware[KafkaPublishCommand]): def __init__( self, *, diff --git a/faststream/confluent/prometheus/provider.py b/faststream/confluent/prometheus/provider.py index e9e91a4587..a242bc2092 100644 --- a/faststream/confluent/prometheus/provider.py +++ b/faststream/confluent/prometheus/provider.py @@ -10,7 +10,7 @@ if TYPE_CHECKING: from confluent_kafka import Message - from faststream.confluent.response import KafkaPublishCommand + from faststream.response import PublishCommand class BaseConfluentMetricsSettingsProvider(MetricsSettingsProvider[MsgType]): @@ -21,7 +21,7 @@ def __init__(self) -> None: def get_publish_destination_name_from_cmd( self, - cmd: "KafkaPublishCommand", + cmd: "PublishCommand", ) -> str: return cmd.destination diff --git a/faststream/kafka/prometheus/middleware.py b/faststream/kafka/prometheus/middleware.py index fd5948945a..18c8b090ff 100644 --- a/faststream/kafka/prometheus/middleware.py +++ b/faststream/kafka/prometheus/middleware.py @@ -3,13 +3,14 @@ from faststream._internal.constants import EMPTY from faststream.kafka.prometheus.provider import settings_provider_factory +from faststream.kafka.response import KafkaPublishCommand from faststream.prometheus.middleware import PrometheusMiddleware if TYPE_CHECKING: from prometheus_client import CollectorRegistry -class KafkaPrometheusMiddleware(PrometheusMiddleware): +class KafkaPrometheusMiddleware(PrometheusMiddleware[KafkaPublishCommand]): def __init__( self, *, diff --git a/faststream/kafka/prometheus/provider.py b/faststream/kafka/prometheus/provider.py index 9ea5ffbd3c..1d9d19fe40 100644 --- a/faststream/kafka/prometheus/provider.py +++ b/faststream/kafka/prometheus/provider.py @@ -2,15 +2,13 @@ from typing import TYPE_CHECKING, Union, cast from faststream.message.message import MsgType, StreamMessage -from faststream.prometheus import ( - MetricsSettingsProvider, -) +from faststream.prometheus import MetricsSettingsProvider if TYPE_CHECKING: from aiokafka import ConsumerRecord - from faststream.kafka.response import KafkaPublishCommand from faststream.prometheus import ConsumeAttrs + from faststream.response import PublishCommand class BaseKafkaMetricsSettingsProvider(MetricsSettingsProvider[MsgType]): @@ -21,7 +19,7 @@ def __init__(self) -> None: def get_publish_destination_name_from_cmd( self, - cmd: "KafkaPublishCommand", + cmd: "PublishCommand", ) -> str: return cmd.destination diff --git a/faststream/middlewares/base.py b/faststream/middlewares/base.py index 40801dd5d3..75fa274dd2 100644 --- a/faststream/middlewares/base.py +++ b/faststream/middlewares/base.py @@ -14,14 +14,14 @@ from faststream.message import StreamMessage -_PublishCommand_T = TypeVar( - "_PublishCommand_T", +PublishCommand_T = TypeVar( + "PublishCommand_T", bound=PublishCommand, default=PublishCommand, ) -class BaseMiddleware(Generic[_PublishCommand_T]): +class BaseMiddleware(Generic[PublishCommand_T]): """A base middleware class.""" def __init__( @@ -92,8 +92,8 @@ async def consume_scope( async def on_publish( self, - msg: _PublishCommand_T, - ) -> _PublishCommand_T: + msg: PublishCommand_T, + ) -> PublishCommand_T: """This option was deprecated and will be removed in 0.7.0. Please, use `publish_scope` instead.""" return msg @@ -107,8 +107,8 @@ async def after_publish( async def publish_scope( self, - call_next: Callable[[_PublishCommand_T], Awaitable[Any]], - cmd: _PublishCommand_T, + call_next: Callable[[PublishCommand_T], Awaitable[Any]], + cmd: PublishCommand_T, ) -> Any: """Publish a message and return an async iterator.""" err: Optional[Exception] = None diff --git a/faststream/nats/prometheus/middleware.py b/faststream/nats/prometheus/middleware.py index 9620cd651c..b8eeb7886b 100644 --- a/faststream/nats/prometheus/middleware.py +++ b/faststream/nats/prometheus/middleware.py @@ -3,13 +3,14 @@ from faststream._internal.constants import EMPTY from faststream.nats.prometheus.provider import settings_provider_factory +from faststream.nats.response import NatsPublishCommand from faststream.prometheus.middleware import PrometheusMiddleware if TYPE_CHECKING: from prometheus_client import CollectorRegistry -class NatsPrometheusMiddleware(PrometheusMiddleware): +class NatsPrometheusMiddleware(PrometheusMiddleware[NatsPublishCommand]): def __init__( self, *, diff --git a/faststream/nats/prometheus/provider.py b/faststream/nats/prometheus/provider.py index 6b5585eeb9..eefe8ea5be 100644 --- a/faststream/nats/prometheus/provider.py +++ b/faststream/nats/prometheus/provider.py @@ -10,7 +10,7 @@ ) if TYPE_CHECKING: - from faststream.nats.response import NatsPublishCommand + from faststream.response import PublishCommand class BaseNatsMetricsSettingsProvider(MetricsSettingsProvider[MsgType]): @@ -21,7 +21,7 @@ def __init__(self) -> None: def get_publish_destination_name_from_cmd( self, - cmd: "NatsPublishCommand", + cmd: "PublishCommand", ) -> str: return cmd.destination diff --git a/faststream/prometheus/middleware.py b/faststream/prometheus/middleware.py index 18462f2de8..91b4df6382 100644 --- a/faststream/prometheus/middleware.py +++ b/faststream/prometheus/middleware.py @@ -1,11 +1,11 @@ import time -from collections.abc import Sequence -from typing import TYPE_CHECKING, Any, Callable, Optional +from collections.abc import Awaitable, Sequence +from typing import TYPE_CHECKING, Any, Callable, Generic, Optional -from faststream import BaseMiddleware from faststream._internal.constants import EMPTY from faststream.exceptions import IgnoredException from faststream.message import SourceType +from faststream.middlewares.base import BaseMiddleware, PublishCommand_T from faststream.prometheus.consts import ( PROCESSING_STATUS_BY_ACK_STATUS, PROCESSING_STATUS_BY_HANDLER_EXCEPTION_MAP, @@ -19,13 +19,12 @@ if TYPE_CHECKING: from prometheus_client import CollectorRegistry - from faststream._internal.basic_types import AsyncFunc, AsyncFuncAny + from faststream._internal.basic_types import AsyncFuncAny from faststream._internal.context.repository import ContextRepo from faststream.message.message import StreamMessage - from faststream.response.response import PublishCommand -class PrometheusMiddleware: +class PrometheusMiddleware(Generic[PublishCommand_T]): __slots__ = ("_metrics_container", "_metrics_manager", "_settings_provider_factory") def __init__( @@ -59,8 +58,8 @@ def __call__( /, *, context: "ContextRepo", - ) -> "BasePrometheusMiddleware": - return BasePrometheusMiddleware( + ) -> "BasePrometheusMiddleware[PublishCommand_T]": + return BasePrometheusMiddleware[PublishCommand_T]( msg, metrics_manager=self._metrics_manager, settings_provider_factory=self._settings_provider_factory, @@ -68,7 +67,7 @@ def __call__( ) -class BasePrometheusMiddleware(BaseMiddleware): +class BasePrometheusMiddleware(BaseMiddleware[PublishCommand_T]): def __init__( self, msg: Optional[Any], @@ -165,8 +164,8 @@ async def consume_scope( async def publish_scope( self, - call_next: "AsyncFunc", - cmd: "PublishCommand", + call_next: Callable[[PublishCommand_T], Awaitable[Any]], + cmd: PublishCommand_T, ) -> Any: if self._settings_provider is None or cmd.publish_type is PublishType.REPLY: return await call_next(cmd) diff --git a/faststream/rabbit/prometheus/middleware.py b/faststream/rabbit/prometheus/middleware.py index 78dd498576..5554f4a872 100644 --- a/faststream/rabbit/prometheus/middleware.py +++ b/faststream/rabbit/prometheus/middleware.py @@ -4,12 +4,13 @@ from faststream._internal.constants import EMPTY from faststream.prometheus.middleware import PrometheusMiddleware from faststream.rabbit.prometheus.provider import RabbitMetricsSettingsProvider +from faststream.rabbit.response import RabbitPublishCommand if TYPE_CHECKING: from prometheus_client import CollectorRegistry -class RabbitPrometheusMiddleware(PrometheusMiddleware): +class RabbitPrometheusMiddleware(PrometheusMiddleware[RabbitPublishCommand]): def __init__( self, *, diff --git a/faststream/redis/prometheus/middleware.py b/faststream/redis/prometheus/middleware.py index 8c62c745fd..5f16917a71 100644 --- a/faststream/redis/prometheus/middleware.py +++ b/faststream/redis/prometheus/middleware.py @@ -4,12 +4,13 @@ from faststream._internal.constants import EMPTY from faststream.prometheus.middleware import PrometheusMiddleware from faststream.redis.prometheus.provider import settings_provider_factory +from faststream.redis.response import RedisPublishCommand if TYPE_CHECKING: from prometheus_client import CollectorRegistry -class RedisPrometheusMiddleware(PrometheusMiddleware): +class RedisPrometheusMiddleware(PrometheusMiddleware[RedisPublishCommand]): def __init__( self, *, diff --git a/faststream/redis/prometheus/provider.py b/faststream/redis/prometheus/provider.py index 533905e6a8..a9e484ac63 100644 --- a/faststream/redis/prometheus/provider.py +++ b/faststream/redis/prometheus/provider.py @@ -8,7 +8,7 @@ if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict from faststream.message.message import StreamMessage - from faststream.redis.response import RedisPublishCommand + from faststream.response import PublishCommand class BaseRedisMetricsSettingsProvider(MetricsSettingsProvider["AnyDict"]): @@ -19,7 +19,7 @@ def __init__(self) -> None: def get_publish_destination_name_from_cmd( self, - cmd: "RedisPublishCommand", + cmd: "PublishCommand", ) -> str: return cmd.destination From 9730784d5dc72540616eb76a6c92d656431f8542 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Sat, 7 Dec 2024 19:28:04 +0300 Subject: [PATCH 215/245] refactor: make Telemetry middleware generic --- faststream/confluent/opentelemetry/middleware.py | 3 ++- faststream/confluent/opentelemetry/provider.py | 5 +++-- faststream/kafka/opentelemetry/middleware.py | 3 ++- faststream/kafka/opentelemetry/provider.py | 5 +++-- faststream/nats/opentelemetry/middleware.py | 3 ++- faststream/nats/opentelemetry/provider.py | 6 +++--- faststream/opentelemetry/middleware.py | 13 ++++++------- faststream/rabbit/opentelemetry/middleware.py | 3 ++- faststream/redis/opentelemetry/middleware.py | 3 ++- faststream/redis/opentelemetry/provider.py | 6 +++--- tests/brokers/kafka/test_consume.py | 4 ++-- tests/brokers/redis/test_publish_command.py | 16 ++++++++-------- 12 files changed, 38 insertions(+), 32 deletions(-) diff --git a/faststream/confluent/opentelemetry/middleware.py b/faststream/confluent/opentelemetry/middleware.py index d8e5906dd3..a0c265438f 100644 --- a/faststream/confluent/opentelemetry/middleware.py +++ b/faststream/confluent/opentelemetry/middleware.py @@ -6,10 +6,11 @@ from faststream.confluent.opentelemetry.provider import ( telemetry_attributes_provider_factory, ) +from faststream.confluent.response import KafkaPublishCommand from faststream.opentelemetry.middleware import TelemetryMiddleware -class KafkaTelemetryMiddleware(TelemetryMiddleware): +class KafkaTelemetryMiddleware(TelemetryMiddleware[KafkaPublishCommand]): def __init__( self, *, diff --git a/faststream/confluent/opentelemetry/provider.py b/faststream/confluent/opentelemetry/provider.py index 07031b5449..cf7445520b 100644 --- a/faststream/confluent/opentelemetry/provider.py +++ b/faststream/confluent/opentelemetry/provider.py @@ -13,6 +13,7 @@ from faststream._internal.basic_types import AnyDict from faststream.confluent.response import KafkaPublishCommand from faststream.message import StreamMessage + from faststream.response import PublishCommand class BaseConfluentTelemetrySettingsProvider(TelemetrySettingsProvider[MsgType]): @@ -25,7 +26,7 @@ def get_publish_attrs_from_cmd( self, cmd: "KafkaPublishCommand", ) -> "AnyDict": - attrs = { + attrs: AnyDict = { SpanAttributes.MESSAGING_SYSTEM: self.messaging_system, SpanAttributes.MESSAGING_DESTINATION_NAME: cmd.destination, SpanAttributes.MESSAGING_MESSAGE_CONVERSATION_ID: cmd.correlation_id, @@ -41,7 +42,7 @@ def get_publish_attrs_from_cmd( def get_publish_destination_name( self, - cmd: "KafkaPublishCommand", + cmd: "PublishCommand", ) -> str: return cmd.destination diff --git a/faststream/kafka/opentelemetry/middleware.py b/faststream/kafka/opentelemetry/middleware.py index 2f06486c33..6b845e8705 100644 --- a/faststream/kafka/opentelemetry/middleware.py +++ b/faststream/kafka/opentelemetry/middleware.py @@ -6,10 +6,11 @@ from faststream.kafka.opentelemetry.provider import ( telemetry_attributes_provider_factory, ) +from faststream.kafka.response import KafkaPublishCommand from faststream.opentelemetry.middleware import TelemetryMiddleware -class KafkaTelemetryMiddleware(TelemetryMiddleware): +class KafkaTelemetryMiddleware(TelemetryMiddleware[KafkaPublishCommand]): def __init__( self, *, diff --git a/faststream/kafka/opentelemetry/provider.py b/faststream/kafka/opentelemetry/provider.py index cd2118ed33..7e0c6434fa 100644 --- a/faststream/kafka/opentelemetry/provider.py +++ b/faststream/kafka/opentelemetry/provider.py @@ -13,6 +13,7 @@ from faststream._internal.basic_types import AnyDict from faststream.kafka.response import KafkaPublishCommand from faststream.message import StreamMessage + from faststream.response import PublishCommand class BaseKafkaTelemetrySettingsProvider(TelemetrySettingsProvider[MsgType]): @@ -25,7 +26,7 @@ def get_publish_attrs_from_cmd( self, cmd: "KafkaPublishCommand", ) -> "AnyDict": - attrs = { + attrs: AnyDict = { SpanAttributes.MESSAGING_SYSTEM: self.messaging_system, SpanAttributes.MESSAGING_DESTINATION_NAME: cmd.destination, SpanAttributes.MESSAGING_MESSAGE_CONVERSATION_ID: cmd.correlation_id, @@ -41,7 +42,7 @@ def get_publish_attrs_from_cmd( def get_publish_destination_name( self, - cmd: "KafkaPublishCommand", + cmd: "PublishCommand", ) -> str: return cmd.destination diff --git a/faststream/nats/opentelemetry/middleware.py b/faststream/nats/opentelemetry/middleware.py index cafd8787d8..ac97181ff8 100644 --- a/faststream/nats/opentelemetry/middleware.py +++ b/faststream/nats/opentelemetry/middleware.py @@ -4,10 +4,11 @@ from opentelemetry.trace import TracerProvider from faststream.nats.opentelemetry.provider import telemetry_attributes_provider_factory +from faststream.nats.response import NatsPublishCommand from faststream.opentelemetry.middleware import TelemetryMiddleware -class NatsTelemetryMiddleware(TelemetryMiddleware): +class NatsTelemetryMiddleware(TelemetryMiddleware[NatsPublishCommand]): def __init__( self, *, diff --git a/faststream/nats/opentelemetry/provider.py b/faststream/nats/opentelemetry/provider.py index 32d9d2d4e1..d877c911e2 100644 --- a/faststream/nats/opentelemetry/provider.py +++ b/faststream/nats/opentelemetry/provider.py @@ -11,7 +11,7 @@ if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict from faststream.message import StreamMessage - from faststream.nats.response import NatsPublishCommand + from faststream.response import PublishCommand class BaseNatsTelemetrySettingsProvider(TelemetrySettingsProvider[MsgType]): @@ -22,7 +22,7 @@ def __init__(self) -> None: def get_publish_attrs_from_cmd( self, - cmd: "NatsPublishCommand", + cmd: "PublishCommand", ) -> "AnyDict": return { SpanAttributes.MESSAGING_SYSTEM: self.messaging_system, @@ -32,7 +32,7 @@ def get_publish_attrs_from_cmd( def get_publish_destination_name( self, - cmd: "NatsPublishCommand", + cmd: "PublishCommand", ) -> str: return cmd.destination diff --git a/faststream/opentelemetry/middleware.py b/faststream/opentelemetry/middleware.py index 853b85ccc7..0bbe97aa86 100644 --- a/faststream/opentelemetry/middleware.py +++ b/faststream/opentelemetry/middleware.py @@ -1,7 +1,7 @@ import time from collections import defaultdict from copy import copy -from typing import TYPE_CHECKING, Any, Callable, Optional, cast +from typing import TYPE_CHECKING, Any, Callable, Generic, Optional, cast from opentelemetry import baggage, context, metrics, trace from opentelemetry.baggage.propagation import W3CBaggagePropagator @@ -10,7 +10,7 @@ from opentelemetry.trace import Link, Span from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator -from faststream import BaseMiddleware +from faststream.middlewares.base import BaseMiddleware, PublishCommand_T from faststream.opentelemetry.baggage import Baggage from faststream.opentelemetry.consts import ( ERROR_TYPE, @@ -39,8 +39,7 @@ _TRACE_PROPAGATOR = TraceContextTextMapPropagator() -class TelemetryMiddleware: - # NOTE: should it be class or function? +class TelemetryMiddleware(Generic[PublishCommand_T]): __slots__ = ( "_meter", "_metrics", @@ -71,8 +70,8 @@ def __call__( /, *, context: "ContextRepo", - ) -> "_BaseTelemetryMiddleware": - return _BaseTelemetryMiddleware( + ) -> "BaseTelemetryMiddleware[PublishCommand_T]": + return BaseTelemetryMiddleware[PublishCommand_T]( msg, tracer=self._tracer, metrics_container=self._metrics, @@ -153,7 +152,7 @@ def observe_consume( ) -class _BaseTelemetryMiddleware(BaseMiddleware): +class BaseTelemetryMiddleware(BaseMiddleware[PublishCommand_T]): def __init__( self, msg: Optional[Any], diff --git a/faststream/rabbit/opentelemetry/middleware.py b/faststream/rabbit/opentelemetry/middleware.py index 29a553a7f0..2973fc60dc 100644 --- a/faststream/rabbit/opentelemetry/middleware.py +++ b/faststream/rabbit/opentelemetry/middleware.py @@ -5,9 +5,10 @@ from faststream.opentelemetry.middleware import TelemetryMiddleware from faststream.rabbit.opentelemetry.provider import RabbitTelemetrySettingsProvider +from faststream.rabbit.response import RabbitPublishCommand -class RabbitTelemetryMiddleware(TelemetryMiddleware): +class RabbitTelemetryMiddleware(TelemetryMiddleware[RabbitPublishCommand]): def __init__( self, *, diff --git a/faststream/redis/opentelemetry/middleware.py b/faststream/redis/opentelemetry/middleware.py index 54c0024143..64f3b57b71 100644 --- a/faststream/redis/opentelemetry/middleware.py +++ b/faststream/redis/opentelemetry/middleware.py @@ -5,9 +5,10 @@ from faststream.opentelemetry.middleware import TelemetryMiddleware from faststream.redis.opentelemetry.provider import RedisTelemetrySettingsProvider +from faststream.redis.response import RedisPublishCommand -class RedisTelemetryMiddleware(TelemetryMiddleware): +class RedisTelemetryMiddleware(TelemetryMiddleware[RedisPublishCommand]): def __init__( self, *, diff --git a/faststream/redis/opentelemetry/provider.py b/faststream/redis/opentelemetry/provider.py index d818864973..799e68f803 100644 --- a/faststream/redis/opentelemetry/provider.py +++ b/faststream/redis/opentelemetry/provider.py @@ -8,7 +8,7 @@ if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict from faststream.message import StreamMessage - from faststream.redis.response import RedisPublishCommand + from faststream.response import PublishCommand class RedisTelemetrySettingsProvider(TelemetrySettingsProvider["AnyDict"]): @@ -44,7 +44,7 @@ def get_consume_destination_name( def get_publish_attrs_from_cmd( self, - cmd: "RedisPublishCommand", + cmd: "PublishCommand", ) -> "AnyDict": return { SpanAttributes.MESSAGING_SYSTEM: self.messaging_system, @@ -54,7 +54,7 @@ def get_publish_attrs_from_cmd( def get_publish_destination_name( self, - cmd: "RedisPublishCommand", + cmd: "PublishCommand", ) -> str: return cmd.destination diff --git a/tests/brokers/kafka/test_consume.py b/tests/brokers/kafka/test_consume.py index 959d4c51e3..c030e19756 100644 --- a/tests/brokers/kafka/test_consume.py +++ b/tests/brokers/kafka/test_consume.py @@ -380,7 +380,7 @@ async def handler(msg) -> None: assert event2.is_set() assert mock.call_count == 2, mock.call_count - @pytest.mark.asyncio + @pytest.mark.asyncio() async def test_consume_without_value( self, mock: MagicMock, @@ -407,7 +407,7 @@ async def handler(msg): mock.assert_called_once_with(b"") - @pytest.mark.asyncio + @pytest.mark.asyncio() async def test_consume_batch_without_value( self, mock: MagicMock, diff --git a/tests/brokers/redis/test_publish_command.py b/tests/brokers/redis/test_publish_command.py index 6539ee0b62..3da0619eac 100644 --- a/tests/brokers/redis/test_publish_command.py +++ b/tests/brokers/redis/test_publish_command.py @@ -7,24 +7,24 @@ from faststream.response import ensure_response -def test_simple_reponse(): +def test_simple_reponse() -> None: response = ensure_response(1) cmd = RedisPublishCommand.from_cmd(response.as_publish_command()) assert cmd.body == 1 -def test_base_response_class(): - response = ensure_response(Response(body=1, headers={1: 1})) +def test_base_response_class() -> None: + response = ensure_response(Response(body=1, headers={"1": 1})) cmd = RedisPublishCommand.from_cmd(response.as_publish_command()) assert cmd.body == 1 - assert cmd.headers == {1: 1} + assert cmd.headers == {"1": 1} -def test_kafka_response_class(): - response = ensure_response(RedisResponse(body=1, headers={1: 1}, maxlen=1)) +def test_kafka_response_class() -> None: + response = ensure_response(RedisResponse(body=1, headers={"1": 1}, maxlen=1)) cmd = RedisPublishCommand.from_cmd(response.as_publish_command()) assert cmd.body == 1 - assert cmd.headers == {1: 1} + assert cmd.headers == {"1": 1} assert cmd.maxlen == 1 @@ -38,7 +38,7 @@ def test_kafka_response_class(): pytest.param([0, 1, 2], (0, 1, 2), id="Sequence Data with False first element"), ), ) -def test_batch_response(data: Any, expected_body: Any): +def test_batch_response(data: Any, expected_body: Any) -> None: response = ensure_response(data) cmd = RedisPublishCommand.from_cmd( response.as_publish_command(), From 00cce6a52be238a10a5dbd6bd259b9c6e9536148 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Sat, 7 Dec 2024 19:44:07 +0300 Subject: [PATCH 216/245] refactor: deprecate subscriber/publisher-level middlewares --- faststream/confluent/broker/registrator.py | 32 ++++++++++++++++++++++ faststream/confluent/fastapi/fastapi.py | 32 ++++++++++++++++++++++ faststream/confluent/router.py | 8 ++++++ faststream/kafka/broker/registrator.py | 32 ++++++++++++++++++++++ faststream/kafka/fastapi/fastapi.py | 32 ++++++++++++++++++++++ faststream/kafka/router.py | 8 ++++++ faststream/nats/broker/registrator.py | 8 ++++++ faststream/nats/fastapi/fastapi.py | 8 ++++++ faststream/nats/router.py | 8 ++++++ faststream/rabbit/broker/registrator.py | 8 ++++++ faststream/rabbit/fastapi/fastapi.py | 8 ++++++ faststream/rabbit/router.py | 10 ++++++- faststream/redis/broker/registrator.py | 8 ++++++ faststream/redis/fastapi/fastapi.py | 8 ++++++ faststream/redis/router.py | 13 ++++++--- 15 files changed, 218 insertions(+), 5 deletions(-) diff --git a/faststream/confluent/broker/registrator.py b/faststream/confluent/broker/registrator.py index 462f288fcb..ae30e0e181 100644 --- a/faststream/confluent/broker/registrator.py +++ b/faststream/confluent/broker/registrator.py @@ -307,6 +307,10 @@ def subscriber( ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[KafkaMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), no_ack: Annotated[ @@ -585,6 +589,10 @@ def subscriber( ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[KafkaMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), no_ack: Annotated[ @@ -866,6 +874,10 @@ def subscriber( ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[KafkaMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), no_ack: Annotated[ @@ -1148,6 +1160,10 @@ def subscriber( ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[KafkaMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), no_ack: Annotated[ @@ -1292,6 +1308,10 @@ def publisher( # basic args middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # Specification args @@ -1366,6 +1386,10 @@ def publisher( # basic args middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # Specification args @@ -1440,6 +1464,10 @@ def publisher( # basic args middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # Specification args @@ -1517,6 +1545,10 @@ def publisher( # basic args middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # Specification args diff --git a/faststream/confluent/fastapi/fastapi.py b/faststream/confluent/fastapi/fastapi.py index 66192b21a1..9df8c7ccb7 100644 --- a/faststream/confluent/fastapi/fastapi.py +++ b/faststream/confluent/fastapi/fastapi.py @@ -839,6 +839,10 @@ def subscriber( ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[KafkaMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), no_ack: Annotated[ @@ -1243,6 +1247,10 @@ def subscriber( ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[KafkaMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), # Specification args @@ -1629,6 +1637,10 @@ def subscriber( ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[KafkaMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), no_ack: Annotated[ @@ -2034,6 +2046,10 @@ def subscriber( ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[KafkaMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), no_ack: Annotated[ @@ -2298,6 +2314,10 @@ def publisher( # basic args middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # Specification args @@ -2372,6 +2392,10 @@ def publisher( # basic args middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # Specification args @@ -2446,6 +2470,10 @@ def publisher( # basic args middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # Specification args @@ -2523,6 +2551,10 @@ def publisher( # basic args middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # Specification args diff --git a/faststream/confluent/router.py b/faststream/confluent/router.py index 4441440c59..7d884aa835 100644 --- a/faststream/confluent/router.py +++ b/faststream/confluent/router.py @@ -90,6 +90,10 @@ def __init__( # basic args middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # AsyncAPI args @@ -386,6 +390,10 @@ def __init__( ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[KafkaMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), no_ack: Annotated[ diff --git a/faststream/kafka/broker/registrator.py b/faststream/kafka/broker/registrator.py index 09a88264e2..6f804bda02 100644 --- a/faststream/kafka/broker/registrator.py +++ b/faststream/kafka/broker/registrator.py @@ -407,6 +407,10 @@ def subscriber( ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[KafkaMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), no_ack: Annotated[ @@ -784,6 +788,10 @@ def subscriber( ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[KafkaMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), no_ack: Annotated[ @@ -1161,6 +1169,10 @@ def subscriber( ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[KafkaMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), no_ack: Annotated[ @@ -1541,6 +1553,10 @@ def subscriber( ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[KafkaMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), max_workers: Annotated[ @@ -1693,6 +1709,10 @@ def publisher( # basic args middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # Specification args @@ -1767,6 +1787,10 @@ def publisher( # basic args middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # Specification args @@ -1841,6 +1865,10 @@ def publisher( # basic args middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # Specification args @@ -1918,6 +1946,10 @@ def publisher( # basic args middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # Specification args diff --git a/faststream/kafka/fastapi/fastapi.py b/faststream/kafka/fastapi/fastapi.py index 322d6ce813..b7f1bf0ec7 100644 --- a/faststream/kafka/fastapi/fastapi.py +++ b/faststream/kafka/fastapi/fastapi.py @@ -950,6 +950,10 @@ def subscriber( ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[KafkaMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), no_ack: Annotated[ @@ -1447,6 +1451,10 @@ def subscriber( ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[KafkaMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), no_ack: Annotated[ @@ -1944,6 +1952,10 @@ def subscriber( ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[KafkaMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), no_ack: Annotated[ @@ -2444,6 +2456,10 @@ def subscriber( ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[KafkaMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), no_ack: Annotated[ @@ -2715,6 +2731,10 @@ def publisher( # basic args middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # Specification args @@ -2789,6 +2809,10 @@ def publisher( # basic args middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # Specification args @@ -2863,6 +2887,10 @@ def publisher( # basic args middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # Specification args @@ -2940,6 +2968,10 @@ def publisher( # basic args middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # Specification args diff --git a/faststream/kafka/router.py b/faststream/kafka/router.py index 2e85783aec..008589b897 100644 --- a/faststream/kafka/router.py +++ b/faststream/kafka/router.py @@ -92,6 +92,10 @@ def __init__( # basic args middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # AsyncAPI args @@ -489,6 +493,10 @@ def __init__( ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[KafkaMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), no_ack: Annotated[ diff --git a/faststream/nats/broker/registrator.py b/faststream/nats/broker/registrator.py index 40aa70edd8..2fe3306fbe 100644 --- a/faststream/nats/broker/registrator.py +++ b/faststream/nats/broker/registrator.py @@ -162,6 +162,10 @@ def subscriber( # type: ignore[override] ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[NatsMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), max_workers: Annotated[ @@ -289,6 +293,10 @@ def publisher( # type: ignore[override] # basic args middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # AsyncAPI information diff --git a/faststream/nats/fastapi/fastapi.py b/faststream/nats/fastapi/fastapi.py index 6ccb1a5822..ab3a3cb4f5 100644 --- a/faststream/nats/fastapi/fastapi.py +++ b/faststream/nats/fastapi/fastapi.py @@ -682,6 +682,10 @@ def subscriber( # type: ignore[override] ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[NatsMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), max_workers: Annotated[ @@ -920,6 +924,10 @@ def publisher( # type: ignore[override] # specific middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # AsyncAPI information diff --git a/faststream/nats/router.py b/faststream/nats/router.py index d04d7e8c1b..2ff270aed0 100644 --- a/faststream/nats/router.py +++ b/faststream/nats/router.py @@ -75,6 +75,10 @@ def __init__( # basic args middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # AsyncAPI information @@ -252,6 +256,10 @@ def __init__( ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[NatsMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), max_workers: Annotated[ diff --git a/faststream/rabbit/broker/registrator.py b/faststream/rabbit/broker/registrator.py index 1d77ba8e10..d58b7a6a09 100644 --- a/faststream/rabbit/broker/registrator.py +++ b/faststream/rabbit/broker/registrator.py @@ -83,6 +83,10 @@ def subscriber( # type: ignore[override] ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[RabbitMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), no_reply: Annotated[ @@ -190,6 +194,10 @@ def publisher( # type: ignore[override] # specific middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # AsyncAPI information diff --git a/faststream/rabbit/fastapi/fastapi.py b/faststream/rabbit/fastapi/fastapi.py index 94a2a04886..5535194842 100644 --- a/faststream/rabbit/fastapi/fastapi.py +++ b/faststream/rabbit/fastapi/fastapi.py @@ -510,6 +510,10 @@ def subscriber( # type: ignore[override] ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[RabbitMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), no_ack: Annotated[ @@ -748,6 +752,10 @@ def publisher( # specific middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # AsyncAPI information diff --git a/faststream/rabbit/router.py b/faststream/rabbit/router.py index 5b020caff1..3ea1a30b61 100644 --- a/faststream/rabbit/router.py +++ b/faststream/rabbit/router.py @@ -91,6 +91,10 @@ def __init__( # basic args middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # AsyncAPI args @@ -229,6 +233,10 @@ def __init__( ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[RabbitMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), no_ack: Annotated[ @@ -284,7 +292,7 @@ def __init__( class RabbitRouter( RabbitRegistrator, - BrokerRouter["IncomingMessage"], + BrokerRouter["IncomingMessage"] ): """Includable to RabbitBroker router.""" diff --git a/faststream/redis/broker/registrator.py b/faststream/redis/broker/registrator.py index c4f51e3d4d..632652d91e 100644 --- a/faststream/redis/broker/registrator.py +++ b/faststream/redis/broker/registrator.py @@ -65,6 +65,10 @@ def subscriber( # type: ignore[override] ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[UnifyRedisMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), no_ack: Annotated[ @@ -156,6 +160,10 @@ def publisher( # type: ignore[override] ] = "", middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # AsyncAPI information diff --git a/faststream/redis/fastapi/fastapi.py b/faststream/redis/fastapi/fastapi.py index 0d201dd0bf..b10a4610e1 100644 --- a/faststream/redis/fastapi/fastapi.py +++ b/faststream/redis/fastapi/fastapi.py @@ -460,6 +460,10 @@ def subscriber( # type: ignore[override] ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[UnifyRedisMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), no_ack: Annotated[ @@ -672,6 +676,10 @@ def publisher( ] = "", middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # AsyncAPI information diff --git a/faststream/redis/router.py b/faststream/redis/router.py index 44982be180..96576801bd 100644 --- a/faststream/redis/router.py +++ b/faststream/redis/router.py @@ -61,6 +61,10 @@ def __init__( ] = "", middlewares: Annotated[ Sequence["PublisherMiddleware"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), # AsyncAPI information @@ -147,6 +151,10 @@ def __init__( ] = None, middlewares: Annotated[ Sequence["SubscriberMiddleware[UnifyRedisMessage]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.7.0" + ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), no_ack: Annotated[ @@ -200,10 +208,7 @@ def __init__( ) -class RedisRouter( - RedisRegistrator, - BrokerRouter[BaseMessage], -): +class RedisRouter(RedisRegistrator, BrokerRouter[BaseMessage]): """Includable to RedisBroker router.""" def __init__( From 7b00966764a45cefd508db375c0aabbbb2f4ee9c Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Sat, 7 Dec 2024 20:37:08 +0300 Subject: [PATCH 217/245] refactor: deprecate filter middlewares --- faststream/_internal/subscriber/usecase.py | 27 +++++++++++++++--- faststream/confluent/broker/registrator.py | 32 +++++++++++----------- faststream/confluent/fastapi/fastapi.py | 30 ++++++++++---------- faststream/confluent/router.py | 8 +++--- faststream/confluent/subscriber/factory.py | 4 +-- faststream/kafka/broker/registrator.py | 32 +++++++++++----------- faststream/kafka/fastapi/fastapi.py | 32 +++++++++++----------- faststream/kafka/router.py | 8 +++--- faststream/kafka/subscriber/factory.py | 4 +-- faststream/middlewares/base.py | 8 +++--- faststream/nats/broker/registrator.py | 8 +++--- faststream/nats/fastapi/fastapi.py | 8 +++--- faststream/nats/router.py | 8 +++--- faststream/nats/subscriber/factory.py | 4 +-- faststream/rabbit/broker/registrator.py | 6 ++-- faststream/rabbit/fastapi/fastapi.py | 6 ++-- faststream/rabbit/router.py | 6 ++-- faststream/rabbit/subscriber/factory.py | 2 +- faststream/redis/broker/registrator.py | 6 ++-- faststream/redis/fastapi/fastapi.py | 6 ++-- faststream/redis/router.py | 6 ++-- faststream/redis/subscriber/factory.py | 2 +- 22 files changed, 136 insertions(+), 117 deletions(-) diff --git a/faststream/_internal/subscriber/usecase.py b/faststream/_internal/subscriber/usecase.py index 26ba99000f..948cff37ec 100644 --- a/faststream/_internal/subscriber/usecase.py +++ b/faststream/_internal/subscriber/usecase.py @@ -4,13 +4,14 @@ from itertools import chain from typing import ( TYPE_CHECKING, + Annotated, Any, Callable, Optional, Union, ) -from typing_extensions import Self, overload, override +from typing_extensions import Self, deprecated, overload, override from faststream._internal.subscriber.call_item import HandlerItem from faststream._internal.subscriber.proto import SubscriberProto @@ -203,7 +204,13 @@ def __call__( filter: "Filter[StreamMessage[MsgType]]" = default_filter, parser: Optional["CustomCallable"] = None, decoder: Optional["CustomCallable"] = None, - middlewares: Sequence["SubscriberMiddleware[Any]"] = (), + middlewares: Annotated[ + Sequence["SubscriberMiddleware[Any]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.6.10" + ), + ] = (), dependencies: Iterable["Dependant"] = (), ) -> Callable[ [Callable[P_HandlerParams, T_HandlerReturn]], @@ -221,7 +228,13 @@ def __call__( filter: "Filter[StreamMessage[MsgType]]" = default_filter, parser: Optional["CustomCallable"] = None, decoder: Optional["CustomCallable"] = None, - middlewares: Sequence["SubscriberMiddleware[Any]"] = (), + middlewares: Annotated[ + Sequence["SubscriberMiddleware[Any]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.6.10" + ), + ] = (), dependencies: Iterable["Dependant"] = (), ) -> "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]": ... @@ -237,7 +250,13 @@ def __call__( filter: "Filter[StreamMessage[MsgType]]" = default_filter, parser: Optional["CustomCallable"] = None, decoder: Optional["CustomCallable"] = None, - middlewares: Sequence["SubscriberMiddleware[Any]"] = (), + middlewares: Annotated[ + Sequence["SubscriberMiddleware[Any]"], + deprecated( + "This option was deprecated in 0.6.0. Use router-level middlewares instead." + "Scheduled to remove in 0.6.10" + ), + ] = (), dependencies: Iterable["Dependant"] = (), ) -> Union[ "HandlerCallWrapper[MsgType, P_HandlerParams, T_HandlerReturn]", diff --git a/faststream/confluent/broker/registrator.py b/faststream/confluent/broker/registrator.py index ae30e0e181..ad1d13d712 100644 --- a/faststream/confluent/broker/registrator.py +++ b/faststream/confluent/broker/registrator.py @@ -170,7 +170,7 @@ def subscriber( ), deprecated( """ - This option is deprecated and will be removed in 0.7.0 release. + This option is deprecated and will be removed in 0.6.10 release. Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. """, ), @@ -309,7 +309,7 @@ def subscriber( Sequence["SubscriberMiddleware[KafkaMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -318,7 +318,7 @@ def subscriber( Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), deprecated( "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), ] = EMPTY, ack_policy: AckPolicy = EMPTY, @@ -452,7 +452,7 @@ def subscriber( ), deprecated( """ - This option is deprecated and will be removed in 0.7.0 release. + This option is deprecated and will be removed in 0.6.10 release. Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. """, ), @@ -591,7 +591,7 @@ def subscriber( Sequence["SubscriberMiddleware[KafkaMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -600,7 +600,7 @@ def subscriber( Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), deprecated( "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), ] = EMPTY, ack_policy: AckPolicy = EMPTY, @@ -737,7 +737,7 @@ def subscriber( ), deprecated( """ - This option is deprecated and will be removed in 0.7.0 release. + This option is deprecated and will be removed in 0.6.10 release. Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. """, ), @@ -876,7 +876,7 @@ def subscriber( Sequence["SubscriberMiddleware[KafkaMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -885,7 +885,7 @@ def subscriber( Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), deprecated( "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), ] = EMPTY, ack_policy: AckPolicy = EMPTY, @@ -1023,7 +1023,7 @@ def subscriber( ), deprecated( """ - This option is deprecated and will be removed in 0.7.0 release. + This option is deprecated and will be removed in 0.6.10 release. Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. """, ), @@ -1162,7 +1162,7 @@ def subscriber( Sequence["SubscriberMiddleware[KafkaMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -1171,7 +1171,7 @@ def subscriber( Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), deprecated( "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), ] = EMPTY, ack_policy: AckPolicy = EMPTY, @@ -1310,7 +1310,7 @@ def publisher( Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), @@ -1388,7 +1388,7 @@ def publisher( Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), @@ -1466,7 +1466,7 @@ def publisher( Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), @@ -1547,7 +1547,7 @@ def publisher( Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), diff --git a/faststream/confluent/fastapi/fastapi.py b/faststream/confluent/fastapi/fastapi.py index 9df8c7ccb7..ee9697f8f0 100644 --- a/faststream/confluent/fastapi/fastapi.py +++ b/faststream/confluent/fastapi/fastapi.py @@ -702,7 +702,7 @@ def subscriber( ), deprecated( """ - This option is deprecated and will be removed in 0.7.0 release. + This option is deprecated and will be removed in 0.6.10 release. Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. """, ), @@ -841,7 +841,7 @@ def subscriber( Sequence["SubscriberMiddleware[KafkaMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -850,7 +850,7 @@ def subscriber( Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), deprecated( "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), ] = EMPTY, ack_policy: AckPolicy = EMPTY, @@ -1110,7 +1110,7 @@ def subscriber( ), deprecated( """ - This option is deprecated and will be removed in 0.7.0 release. + This option is deprecated and will be removed in 0.6.10 release. Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. """, ), @@ -1249,7 +1249,7 @@ def subscriber( Sequence["SubscriberMiddleware[KafkaMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -1500,7 +1500,7 @@ def subscriber( ), deprecated( """ - This option is deprecated and will be removed in 0.7.0 release. + This option is deprecated and will be removed in 0.6.10 release. Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. """, ), @@ -1639,7 +1639,7 @@ def subscriber( Sequence["SubscriberMiddleware[KafkaMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -1648,7 +1648,7 @@ def subscriber( Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), deprecated( "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), ] = EMPTY, ack_policy: AckPolicy = EMPTY, @@ -1909,7 +1909,7 @@ def subscriber( ), deprecated( """ - This option is deprecated and will be removed in 0.7.0 release. + This option is deprecated and will be removed in 0.6.10 release. Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. """, ), @@ -2048,7 +2048,7 @@ def subscriber( Sequence["SubscriberMiddleware[KafkaMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -2057,7 +2057,7 @@ def subscriber( Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), deprecated( "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), ] = EMPTY, ack_policy: AckPolicy = EMPTY, @@ -2316,7 +2316,7 @@ def publisher( Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), @@ -2394,7 +2394,7 @@ def publisher( Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), @@ -2472,7 +2472,7 @@ def publisher( Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), @@ -2553,7 +2553,7 @@ def publisher( Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), diff --git a/faststream/confluent/router.py b/faststream/confluent/router.py index 7d884aa835..53a3d97426 100644 --- a/faststream/confluent/router.py +++ b/faststream/confluent/router.py @@ -92,7 +92,7 @@ def __init__( Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), @@ -253,7 +253,7 @@ def __init__( ), deprecated( """ - This option is deprecated and will be removed in 0.7.0 release. + This option is deprecated and will be removed in 0.6.10 release. Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. """, ), @@ -392,7 +392,7 @@ def __init__( Sequence["SubscriberMiddleware[KafkaMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -401,7 +401,7 @@ def __init__( Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), deprecated( "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), ] = EMPTY, ack_policy: AckPolicy = EMPTY, diff --git a/faststream/confluent/subscriber/factory.py b/faststream/confluent/subscriber/factory.py index c5b1c10f73..1954c3a40d 100644 --- a/faststream/confluent/subscriber/factory.py +++ b/faststream/confluent/subscriber/factory.py @@ -235,7 +235,7 @@ def _validate_input_for_misconfigure( ) -> None: if auto_commit is not EMPTY: warnings.warn( - "`auto_commit` option was deprecated in prior to `ack_policy=AckPolicy.ACK_FIRST`. Scheduled to remove in 0.7.0", + "`auto_commit` option was deprecated in prior to `ack_policy=AckPolicy.ACK_FIRST`. Scheduled to remove in 0.6.10", category=DeprecationWarning, stacklevel=4, ) @@ -248,7 +248,7 @@ def _validate_input_for_misconfigure( if no_ack is not EMPTY: warnings.warn( - "`no_ack` option was deprecated in prior to `ack_policy=AckPolicy.DO_NOTHING`. Scheduled to remove in 0.7.0", + "`no_ack` option was deprecated in prior to `ack_policy=AckPolicy.DO_NOTHING`. Scheduled to remove in 0.6.10", category=DeprecationWarning, stacklevel=4, ) diff --git a/faststream/kafka/broker/registrator.py b/faststream/kafka/broker/registrator.py index 6f804bda02..b1385d073e 100644 --- a/faststream/kafka/broker/registrator.py +++ b/faststream/kafka/broker/registrator.py @@ -174,7 +174,7 @@ def subscriber( ), deprecated( """ - This option is deprecated and will be removed in 0.7.0 release. + This option is deprecated and will be removed in 0.6.10 release. Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. """, ), @@ -409,7 +409,7 @@ def subscriber( Sequence["SubscriberMiddleware[KafkaMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -418,7 +418,7 @@ def subscriber( Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), deprecated( "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), ] = EMPTY, ack_policy: AckPolicy = EMPTY, @@ -555,7 +555,7 @@ def subscriber( ), deprecated( """ - This option is deprecated and will be removed in 0.7.0 release. + This option is deprecated and will be removed in 0.6.10 release. Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. """, ), @@ -790,7 +790,7 @@ def subscriber( Sequence["SubscriberMiddleware[KafkaMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -799,7 +799,7 @@ def subscriber( Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), deprecated( "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), ] = EMPTY, ack_policy: AckPolicy = EMPTY, @@ -936,7 +936,7 @@ def subscriber( ), deprecated( """ - This option is deprecated and will be removed in 0.7.0 release. + This option is deprecated and will be removed in 0.6.10 release. Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. """, ), @@ -1171,7 +1171,7 @@ def subscriber( Sequence["SubscriberMiddleware[KafkaMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -1180,7 +1180,7 @@ def subscriber( Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), deprecated( "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), ] = EMPTY, ack_policy: AckPolicy = EMPTY, @@ -1320,7 +1320,7 @@ def subscriber( ), deprecated( """ - This option is deprecated and will be removed in 0.7.0 release. + This option is deprecated and will be removed in 0.6.10 release. Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. """, ), @@ -1555,7 +1555,7 @@ def subscriber( Sequence["SubscriberMiddleware[KafkaMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -1568,7 +1568,7 @@ def subscriber( Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), deprecated( "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), ] = EMPTY, ack_policy: AckPolicy = EMPTY, @@ -1711,7 +1711,7 @@ def publisher( Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), @@ -1789,7 +1789,7 @@ def publisher( Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), @@ -1867,7 +1867,7 @@ def publisher( Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), @@ -1948,7 +1948,7 @@ def publisher( Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), diff --git a/faststream/kafka/fastapi/fastapi.py b/faststream/kafka/fastapi/fastapi.py index b7f1bf0ec7..b5b2b6e8c8 100644 --- a/faststream/kafka/fastapi/fastapi.py +++ b/faststream/kafka/fastapi/fastapi.py @@ -713,7 +713,7 @@ def subscriber( ), deprecated( """ - This option is deprecated and will be removed in 0.7.0 release. + This option is deprecated and will be removed in 0.6.10 release. Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. """, ), @@ -952,7 +952,7 @@ def subscriber( Sequence["SubscriberMiddleware[KafkaMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -961,7 +961,7 @@ def subscriber( Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), deprecated( "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), ] = EMPTY, ack_policy: AckPolicy = EMPTY, @@ -1214,7 +1214,7 @@ def subscriber( ), deprecated( """ - This option is deprecated and will be removed in 0.7.0 release. + This option is deprecated and will be removed in 0.6.10 release. Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. """, ), @@ -1453,7 +1453,7 @@ def subscriber( Sequence["SubscriberMiddleware[KafkaMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -1462,7 +1462,7 @@ def subscriber( Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), deprecated( "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), ] = EMPTY, ack_policy: AckPolicy = EMPTY, @@ -1715,7 +1715,7 @@ def subscriber( ), deprecated( """ - This option is deprecated and will be removed in 0.7.0 release. + This option is deprecated and will be removed in 0.6.10 release. Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. """, ), @@ -1954,7 +1954,7 @@ def subscriber( Sequence["SubscriberMiddleware[KafkaMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -1963,7 +1963,7 @@ def subscriber( Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), deprecated( "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), ] = EMPTY, ack_policy: AckPolicy = EMPTY, @@ -2219,7 +2219,7 @@ def subscriber( ), deprecated( """ - This option is deprecated and will be removed in 0.7.0 release. + This option is deprecated and will be removed in 0.6.10 release. Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. """, ), @@ -2458,7 +2458,7 @@ def subscriber( Sequence["SubscriberMiddleware[KafkaMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -2467,7 +2467,7 @@ def subscriber( Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), deprecated( "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), ] = EMPTY, ack_policy: AckPolicy = EMPTY, @@ -2733,7 +2733,7 @@ def publisher( Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), @@ -2811,7 +2811,7 @@ def publisher( Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), @@ -2889,7 +2889,7 @@ def publisher( Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), @@ -2970,7 +2970,7 @@ def publisher( Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), diff --git a/faststream/kafka/router.py b/faststream/kafka/router.py index 008589b897..31b21fccf0 100644 --- a/faststream/kafka/router.py +++ b/faststream/kafka/router.py @@ -94,7 +94,7 @@ def __init__( Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), @@ -261,7 +261,7 @@ def __init__( ), deprecated( """ - This option is deprecated and will be removed in 0.7.0 release. + This option is deprecated and will be removed in 0.6.10 release. Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. """, ), @@ -495,7 +495,7 @@ def __init__( Sequence["SubscriberMiddleware[KafkaMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -504,7 +504,7 @@ def __init__( Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), deprecated( "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), ] = EMPTY, ack_policy: AckPolicy = EMPTY, diff --git a/faststream/kafka/subscriber/factory.py b/faststream/kafka/subscriber/factory.py index 45edbefea3..c27d19182a 100644 --- a/faststream/kafka/subscriber/factory.py +++ b/faststream/kafka/subscriber/factory.py @@ -235,7 +235,7 @@ def _validate_input_for_misconfigure( ) -> None: if auto_commit is not EMPTY: warnings.warn( - "`auto_commit` option was deprecated in prior to `ack_policy=AckPolicy.ACK_FIRST`. Scheduled to remove in 0.7.0", + "`auto_commit` option was deprecated in prior to `ack_policy=AckPolicy.ACK_FIRST`. Scheduled to remove in 0.6.10", category=DeprecationWarning, stacklevel=4, ) @@ -248,7 +248,7 @@ def _validate_input_for_misconfigure( if no_ack is not EMPTY: warnings.warn( - "`no_ack` option was deprecated in prior to `ack_policy=AckPolicy.DO_NOTHING`. Scheduled to remove in 0.7.0", + "`no_ack` option was deprecated in prior to `ack_policy=AckPolicy.DO_NOTHING`. Scheduled to remove in 0.6.10", category=DeprecationWarning, stacklevel=4, ) diff --git a/faststream/middlewares/base.py b/faststream/middlewares/base.py index 75fa274dd2..9604d7b5da 100644 --- a/faststream/middlewares/base.py +++ b/faststream/middlewares/base.py @@ -63,11 +63,11 @@ async def on_consume( self, msg: "StreamMessage[Any]", ) -> "StreamMessage[Any]": - """This option was deprecated and will be removed in 0.7.0. Please, use `consume_scope` instead.""" + """This option was deprecated and will be removed in 0.6.10. Please, use `consume_scope` instead.""" return msg async def after_consume(self, err: Optional[Exception]) -> None: - """This option was deprecated and will be removed in 0.7.0. Please, use `consume_scope` instead.""" + """This option was deprecated and will be removed in 0.6.10. Please, use `consume_scope` instead.""" if err is not None: raise err @@ -94,14 +94,14 @@ async def on_publish( self, msg: PublishCommand_T, ) -> PublishCommand_T: - """This option was deprecated and will be removed in 0.7.0. Please, use `publish_scope` instead.""" + """This option was deprecated and will be removed in 0.6.10. Please, use `publish_scope` instead.""" return msg async def after_publish( self, err: Optional[Exception], ) -> None: - """This option was deprecated and will be removed in 0.7.0. Please, use `publish_scope` instead.""" + """This option was deprecated and will be removed in 0.6.10. Please, use `publish_scope` instead.""" if err is not None: raise err diff --git a/faststream/nats/broker/registrator.py b/faststream/nats/broker/registrator.py index 2fe3306fbe..4dddc88bad 100644 --- a/faststream/nats/broker/registrator.py +++ b/faststream/nats/broker/registrator.py @@ -138,7 +138,7 @@ def subscriber( # type: ignore[override] Doc("Whether to `ack` message at start of consuming or not."), deprecated( """ - This option is deprecated and will be removed in 0.7.0 release. + This option is deprecated and will be removed in 0.6.10 release. Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. """, ), @@ -164,7 +164,7 @@ def subscriber( # type: ignore[override] Sequence["SubscriberMiddleware[NatsMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -177,7 +177,7 @@ def subscriber( # type: ignore[override] Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), deprecated( "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), ] = EMPTY, ack_policy: AckPolicy = EMPTY, @@ -295,7 +295,7 @@ def publisher( # type: ignore[override] Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), diff --git a/faststream/nats/fastapi/fastapi.py b/faststream/nats/fastapi/fastapi.py index ab3a3cb4f5..a967a2e692 100644 --- a/faststream/nats/fastapi/fastapi.py +++ b/faststream/nats/fastapi/fastapi.py @@ -658,7 +658,7 @@ def subscriber( # type: ignore[override] Doc("Whether to `ack` message at start of consuming or not."), deprecated( """ - This option is deprecated and will be removed in 0.7.0 release. + This option is deprecated and will be removed in 0.6.10 release. Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. """, ), @@ -684,7 +684,7 @@ def subscriber( # type: ignore[override] Sequence["SubscriberMiddleware[NatsMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -697,7 +697,7 @@ def subscriber( # type: ignore[override] Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), deprecated( "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), ] = EMPTY, ack_policy: AckPolicy = EMPTY, @@ -926,7 +926,7 @@ def publisher( # type: ignore[override] Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), diff --git a/faststream/nats/router.py b/faststream/nats/router.py index 2ff270aed0..556bfb7f66 100644 --- a/faststream/nats/router.py +++ b/faststream/nats/router.py @@ -77,7 +77,7 @@ def __init__( Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), @@ -232,7 +232,7 @@ def __init__( Doc("Whether to `ack` message at start of consuming or not."), deprecated( """ - This option is deprecated and will be removed in 0.7.0 release. + This option is deprecated and will be removed in 0.6.10 release. Please, use `ack_policy=AckPolicy.ACK_FIRST` instead. """, ), @@ -258,7 +258,7 @@ def __init__( Sequence["SubscriberMiddleware[NatsMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -271,7 +271,7 @@ def __init__( Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), deprecated( "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), ] = EMPTY, ack_policy: AckPolicy = EMPTY, diff --git a/faststream/nats/subscriber/factory.py b/faststream/nats/subscriber/factory.py index 4256601f41..9a7db0c9ad 100644 --- a/faststream/nats/subscriber/factory.py +++ b/faststream/nats/subscriber/factory.py @@ -381,7 +381,7 @@ def _validate_input_for_misconfigure( # noqa: PLR0915 if ack_first is not EMPTY: warnings.warn( - "`ack_first` option was deprecated in prior to `ack_policy=AckPolicy.ACK_FIRST`. Scheduled to remove in 0.7.0", + "`ack_first` option was deprecated in prior to `ack_policy=AckPolicy.ACK_FIRST`. Scheduled to remove in 0.6.10", category=DeprecationWarning, stacklevel=4, ) @@ -394,7 +394,7 @@ def _validate_input_for_misconfigure( # noqa: PLR0915 if no_ack is not EMPTY: warnings.warn( - "`no_ack` option was deprecated in prior to `ack_policy=AckPolicy.DO_NOTHING`. Scheduled to remove in 0.7.0", + "`no_ack` option was deprecated in prior to `ack_policy=AckPolicy.DO_NOTHING`. Scheduled to remove in 0.6.10", category=DeprecationWarning, stacklevel=4, ) diff --git a/faststream/rabbit/broker/registrator.py b/faststream/rabbit/broker/registrator.py index d58b7a6a09..371c80d708 100644 --- a/faststream/rabbit/broker/registrator.py +++ b/faststream/rabbit/broker/registrator.py @@ -64,7 +64,7 @@ def subscriber( # type: ignore[override] Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), deprecated( "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), ] = EMPTY, ack_policy: AckPolicy = EMPTY, @@ -85,7 +85,7 @@ def subscriber( # type: ignore[override] Sequence["SubscriberMiddleware[RabbitMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -196,7 +196,7 @@ def publisher( # type: ignore[override] Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), diff --git a/faststream/rabbit/fastapi/fastapi.py b/faststream/rabbit/fastapi/fastapi.py index 5535194842..d5d2631f2f 100644 --- a/faststream/rabbit/fastapi/fastapi.py +++ b/faststream/rabbit/fastapi/fastapi.py @@ -512,7 +512,7 @@ def subscriber( # type: ignore[override] Sequence["SubscriberMiddleware[RabbitMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -521,7 +521,7 @@ def subscriber( # type: ignore[override] Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), deprecated( "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), ] = EMPTY, ack_policy: AckPolicy = EMPTY, @@ -754,7 +754,7 @@ def publisher( Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), diff --git a/faststream/rabbit/router.py b/faststream/rabbit/router.py index 3ea1a30b61..cccc6bc3c6 100644 --- a/faststream/rabbit/router.py +++ b/faststream/rabbit/router.py @@ -93,7 +93,7 @@ def __init__( Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), @@ -235,7 +235,7 @@ def __init__( Sequence["SubscriberMiddleware[RabbitMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -244,7 +244,7 @@ def __init__( Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), deprecated( "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), ] = EMPTY, ack_policy: AckPolicy = EMPTY, diff --git a/faststream/rabbit/subscriber/factory.py b/faststream/rabbit/subscriber/factory.py index e10e04dd95..4d3d720475 100644 --- a/faststream/rabbit/subscriber/factory.py +++ b/faststream/rabbit/subscriber/factory.py @@ -58,7 +58,7 @@ def _validate_input_for_misconfigure( ) -> None: if no_ack is not EMPTY: warnings.warn( - "`no_ack` option was deprecated in prior to `ack_policy=AckPolicy.DO_NOTHING`. Scheduled to remove in 0.7.0", + "`no_ack` option was deprecated in prior to `ack_policy=AckPolicy.DO_NOTHING`. Scheduled to remove in 0.6.10", category=DeprecationWarning, stacklevel=4, ) diff --git a/faststream/redis/broker/registrator.py b/faststream/redis/broker/registrator.py index 632652d91e..9b1556b0c1 100644 --- a/faststream/redis/broker/registrator.py +++ b/faststream/redis/broker/registrator.py @@ -67,7 +67,7 @@ def subscriber( # type: ignore[override] Sequence["SubscriberMiddleware[UnifyRedisMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -76,7 +76,7 @@ def subscriber( # type: ignore[override] Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), deprecated( "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), ] = EMPTY, ack_policy: AckPolicy = EMPTY, @@ -162,7 +162,7 @@ def publisher( # type: ignore[override] Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), diff --git a/faststream/redis/fastapi/fastapi.py b/faststream/redis/fastapi/fastapi.py index b10a4610e1..f544eb2363 100644 --- a/faststream/redis/fastapi/fastapi.py +++ b/faststream/redis/fastapi/fastapi.py @@ -462,7 +462,7 @@ def subscriber( # type: ignore[override] Sequence["SubscriberMiddleware[UnifyRedisMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -471,7 +471,7 @@ def subscriber( # type: ignore[override] Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), deprecated( "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), ] = EMPTY, ack_policy: AckPolicy = EMPTY, @@ -678,7 +678,7 @@ def publisher( Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), diff --git a/faststream/redis/router.py b/faststream/redis/router.py index 96576801bd..0c048b4e2e 100644 --- a/faststream/redis/router.py +++ b/faststream/redis/router.py @@ -63,7 +63,7 @@ def __init__( Sequence["PublisherMiddleware"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Publisher middlewares to wrap outgoing messages."), ] = (), @@ -153,7 +153,7 @@ def __init__( Sequence["SubscriberMiddleware[UnifyRedisMessage]"], deprecated( "This option was deprecated in 0.6.0. Use router-level middlewares instead." - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), Doc("Subscriber middlewares to wrap incoming message processing."), ] = (), @@ -162,7 +162,7 @@ def __init__( Doc("Whether to disable **FastStream** auto acknowledgement logic or not."), deprecated( "This option was deprecated in 0.6.0 to prior to **ack_policy=AckPolicy.DO_NOTHING**. " - "Scheduled to remove in 0.7.0" + "Scheduled to remove in 0.6.10" ), ] = EMPTY, ack_policy: AckPolicy = EMPTY, diff --git a/faststream/redis/subscriber/factory.py b/faststream/redis/subscriber/factory.py index 58bec025c8..1a2a4cc31c 100644 --- a/faststream/redis/subscriber/factory.py +++ b/faststream/redis/subscriber/factory.py @@ -141,7 +141,7 @@ def _validate_input_for_misconfigure( if no_ack is not EMPTY: warnings.warn( - "`no_ack` option was deprecated in prior to `ack_policy=AckPolicy.DO_NOTHING`. Scheduled to remove in 0.7.0", + "`no_ack` option was deprecated in prior to `ack_policy=AckPolicy.DO_NOTHING`. Scheduled to remove in 0.6.10", category=DeprecationWarning, stacklevel=4, ) From 82e3969dd93ae3e03c4824d7d48d61fe5c2a9229 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Mon, 9 Dec 2024 07:52:14 +0300 Subject: [PATCH 218/245] tests: fix Kafka tests from main branch --- faststream/_internal/broker/abc_broker.py | 33 ++++++++++++++++------- faststream/rabbit/router.py | 5 +--- tests/brokers/kafka/test_consume.py | 4 +-- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/faststream/_internal/broker/abc_broker.py b/faststream/_internal/broker/abc_broker.py index ecbf5e5394..93d62accf0 100644 --- a/faststream/_internal/broker/abc_broker.py +++ b/faststream/_internal/broker/abc_broker.py @@ -7,19 +7,34 @@ Optional, ) +from faststream._internal.publisher.proto import PublisherProto from faststream._internal.state import BrokerState, Pointer +from faststream._internal.subscriber.proto import SubscriberProto from faststream._internal.types import BrokerMiddleware, CustomCallable, MsgType +from faststream.specification.proto import EndpointSpecification +from faststream.specification.schema import PublisherSpec, SubscriberSpec if TYPE_CHECKING: from fast_depends.dependencies import Dependant - from faststream._internal.publisher.proto import PublisherProto - from faststream._internal.subscriber.proto import SubscriberProto + +class FinalSubscriber( + EndpointSpecification[MsgType, SubscriberSpec], + SubscriberProto[MsgType], +): + pass + + +class FinalPublisher( + EndpointSpecification[MsgType, PublisherSpec], + PublisherProto[MsgType], +): + pass class ABCBroker(Generic[MsgType]): - _subscribers: list["SubscriberProto[MsgType]"] - _publishers: list["PublisherProto[MsgType]"] + _subscribers: list[FinalSubscriber[MsgType]] + _publishers: list[FinalPublisher[MsgType]] def __init__( self, @@ -61,9 +76,9 @@ def add_middleware(self, middleware: "BrokerMiddleware[MsgType]") -> None: @abstractmethod def subscriber( self, - subscriber: "SubscriberProto[MsgType]", + subscriber: "FinalSubscriber[MsgType]", is_running: bool = False, - ) -> "SubscriberProto[MsgType]": + ) -> "FinalSubscriber[MsgType]": subscriber.add_prefix(self.prefix) if not is_running: self._subscribers.append(subscriber) @@ -72,9 +87,9 @@ def subscriber( @abstractmethod def publisher( self, - publisher: "PublisherProto[MsgType]", + publisher: "FinalPublisher[MsgType]", is_running: bool = False, - ) -> "PublisherProto[MsgType]": + ) -> "FinalPublisher[MsgType]": publisher.add_prefix(self.prefix) if not is_running: self._publishers.append(publisher) @@ -82,7 +97,7 @@ def publisher( def setup_publisher( self, - publisher: "PublisherProto[MsgType]", + publisher: "FinalPublisher[MsgType]", **kwargs: Any, ) -> None: """Setup the Publisher to prepare it to starting.""" diff --git a/faststream/rabbit/router.py b/faststream/rabbit/router.py index cccc6bc3c6..d272dd0ae8 100644 --- a/faststream/rabbit/router.py +++ b/faststream/rabbit/router.py @@ -290,10 +290,7 @@ def __init__( ) -class RabbitRouter( - RabbitRegistrator, - BrokerRouter["IncomingMessage"] -): +class RabbitRouter(RabbitRegistrator, BrokerRouter["IncomingMessage"]): """Includable to RabbitBroker router.""" def __init__( diff --git a/tests/brokers/kafka/test_consume.py b/tests/brokers/kafka/test_consume.py index c030e19756..3c9bd4ca90 100644 --- a/tests/brokers/kafka/test_consume.py +++ b/tests/brokers/kafka/test_consume.py @@ -399,7 +399,7 @@ async def handler(msg): await asyncio.wait( ( - asyncio.create_task(br._producer._producer.send(queue, key=b"")), + asyncio.create_task(br._producer._producer.producer.send(queue, key=b"")), asyncio.create_task(event.wait()), ), timeout=3, @@ -426,7 +426,7 @@ async def handler(msg): await asyncio.wait( ( - asyncio.create_task(br._producer._producer.send(queue, key=b"")), + asyncio.create_task(br._producer._producer.producer.send(queue, key=b"")), asyncio.create_task(event.wait()), ), timeout=3, From baf617855ddf47f78c89b0634ac11f342fff3cbc Mon Sep 17 00:00:00 2001 From: Ruslan Alimov Date: Tue, 10 Dec 2024 19:40:25 +0300 Subject: [PATCH 219/245] feat: init_routes added routes to init broker (#1981) * feat: init_routes added routes to init broker * docs: generate API References --------- Co-authored-by: Rusich90 --- docs/docs/SUMMARY.md | 1276 +++++++++++++++++ docs/docs/en/api/faststream/AckPolicy.md | 11 + docs/docs/en/api/faststream/BaseMiddleware.md | 11 + docs/docs/en/api/faststream/Context.md | 11 + docs/docs/en/api/faststream/Depends.md | 11 + .../en/api/faststream/ExceptionMiddleware.md | 11 + docs/docs/en/api/faststream/FastStream.md | 11 + docs/docs/en/api/faststream/Header.md | 11 + docs/docs/en/api/faststream/Path.md | 11 + docs/docs/en/api/faststream/Response.md | 11 + docs/docs/en/api/faststream/TestApp.md | 11 + docs/docs/en/api/faststream/app/FastStream.md | 11 + docs/docs/en/api/faststream/apply_types.md | 11 + .../en/api/faststream/asgi/AsgiFastStream.md | 11 + .../en/api/faststream/asgi/AsgiResponse.md | 11 + .../api/faststream/asgi/app/AsgiFastStream.md | 11 + .../en/api/faststream/asgi/app/CliRunState.md | 11 + .../api/faststream/asgi/app/OuterRunState.md | 11 + .../en/api/faststream/asgi/app/ServerState.md | 11 + .../asgi/app/cast_uvicorn_params.md | 11 + .../asgi/factories/make_asyncapi_asgi.md | 11 + .../asgi/factories/make_ping_asgi.md | 11 + docs/docs/en/api/faststream/asgi/get.md | 11 + .../en/api/faststream/asgi/handlers/get.md | 11 + .../api/faststream/asgi/make_asyncapi_asgi.md | 11 + .../en/api/faststream/asgi/make_ping_asgi.md | 11 + .../faststream/asgi/response/AsgiResponse.md | 11 + .../asgi/websocket/WebSocketClose.md | 11 + .../api/faststream/confluent/KafkaBroker.md | 11 + .../faststream/confluent/KafkaPublisher.md | 11 + .../api/faststream/confluent/KafkaResponse.md | 11 + .../en/api/faststream/confluent/KafkaRoute.md | 11 + .../api/faststream/confluent/KafkaRouter.md | 11 + .../en/api/faststream/confluent/TestApp.md | 11 + .../faststream/confluent/TestKafkaBroker.md | 11 + .../faststream/confluent/TopicPartition.md | 11 + .../confluent/broker/KafkaBroker.md | 11 + .../confluent/broker/broker/KafkaBroker.md | 11 + .../broker/logging/KafkaParamsStorage.md | 11 + .../broker/registrator/KafkaRegistrator.md | 11 + .../client/AsyncConfluentConsumer.md | 11 + .../client/AsyncConfluentProducer.md | 11 + .../confluent/client/BatchBuilder.md | 11 + .../confluent/client/check_msg_error.md | 11 + .../confluent/client/create_topics.md | 11 + .../confluent/config/BrokerAddressFamily.md | 11 + .../confluent/config/BuiltinFeatures.md | 11 + .../confluent/config/ClientDNSLookup.md | 11 + .../confluent/config/CompressionCodec.md | 11 + .../confluent/config/CompressionType.md | 11 + .../confluent/config/ConfluentConfig.md | 11 + .../confluent/config/ConfluentFastConfig.md | 11 + .../api/faststream/confluent/config/Debug.md | 11 + .../confluent/config/GroupProtocol.md | 11 + .../confluent/config/IsolationLevel.md | 11 + .../confluent/config/OffsetStoreMethod.md | 11 + .../confluent/config/SASLOAUTHBearerMethod.md | 11 + .../confluent/config/SecurityProtocol.md | 11 + .../faststream/confluent/fastapi/Context.md | 11 + .../confluent/fastapi/KafkaRouter.md | 11 + .../confluent/fastapi/fastapi/KafkaRouter.md | 11 + .../confluent/message/ConsumerProtocol.md | 11 + .../confluent/message/FakeConsumer.md | 11 + .../confluent/message/KafkaMessage.md | 11 + .../opentelemetry/KafkaTelemetryMiddleware.md | 11 + .../middleware/KafkaTelemetryMiddleware.md | 11 + .../BaseConfluentTelemetrySettingsProvider.md | 11 + ...BatchConfluentTelemetrySettingsProvider.md | 11 + .../ConfluentTelemetrySettingsProvider.md | 11 + .../telemetry_attributes_provider_factory.md | 11 + .../confluent/parser/AsyncConfluentParser.md | 11 + .../prometheus/KafkaPrometheusMiddleware.md | 11 + .../middleware/KafkaPrometheusMiddleware.md | 11 + .../BaseConfluentMetricsSettingsProvider.md | 11 + .../BatchConfluentMetricsSettingsProvider.md | 11 + .../ConfluentMetricsSettingsProvider.md | 11 + .../provider/settings_provider_factory.md | 11 + .../publisher/factory/create_publisher.md | 11 + .../publisher/fake/KafkaFakePublisher.md | 11 + .../producer/AsyncConfluentFastProducer.md | 11 + .../specified/SpecificationBatchPublisher.md | 11 + .../SpecificationDefaultPublisher.md | 11 + .../specified/SpecificationPublisher.md | 11 + .../publisher/state/EmptyProducerState.md | 11 + .../publisher/state/ProducerState.md | 11 + .../confluent/publisher/state/RealProducer.md | 11 + .../publisher/usecase/BatchPublisher.md | 11 + .../publisher/usecase/DefaultPublisher.md | 11 + .../publisher/usecase/LogicPublisher.md | 11 + .../confluent/response/KafkaPublishCommand.md | 11 + .../confluent/response/KafkaResponse.md | 11 + .../confluent/router/KafkaPublisher.md | 11 + .../faststream/confluent/router/KafkaRoute.md | 11 + .../confluent/router/KafkaRouter.md | 11 + .../confluent/schemas/TopicPartition.md | 11 + .../params/ConsumerConnectionParams.md | 11 + .../schemas/partition/TopicPartition.md | 11 + .../confluent/security/parse_security.md | 11 + .../subscriber/factory/create_subscriber.md | 11 + .../specified/SpecificationBatchSubscriber.md | 11 + ...pecificationConcurrentDefaultSubscriber.md | 11 + .../SpecificationDefaultSubscriber.md | 11 + .../specified/SpecificationSubscriber.md | 11 + .../subscriber/usecase/BatchSubscriber.md | 11 + .../usecase/ConcurrentDefaultSubscriber.md | 11 + .../subscriber/usecase/DefaultSubscriber.md | 11 + .../subscriber/usecase/LogicSubscriber.md | 11 + .../confluent/testing/FakeProducer.md | 11 + .../confluent/testing/MockConfluentMessage.md | 11 + .../confluent/testing/TestKafkaBroker.md | 11 + .../confluent/testing/build_message.md | 11 + .../api/faststream/exceptions/AckMessage.md | 11 + .../api/faststream/exceptions/ContextError.md | 11 + .../exceptions/FastStreamException.md | 11 + .../FeatureNotSupportedException.md | 11 + .../faststream/exceptions/HandlerException.md | 11 + .../faststream/exceptions/IgnoredException.md | 11 + .../faststream/exceptions/IncorrectState.md | 11 + .../api/faststream/exceptions/NackMessage.md | 11 + .../faststream/exceptions/RejectMessage.md | 11 + .../api/faststream/exceptions/SetupError.md | 11 + .../api/faststream/exceptions/SkipMessage.md | 11 + .../exceptions/StartupValidationError.md | 11 + .../faststream/exceptions/StopApplication.md | 11 + .../api/faststream/exceptions/StopConsume.md | 11 + .../exceptions/SubscriberNotFound.md | 11 + .../en/api/faststream/kafka/KafkaBroker.md | 11 + .../en/api/faststream/kafka/KafkaPublisher.md | 11 + .../en/api/faststream/kafka/KafkaResponse.md | 11 + .../en/api/faststream/kafka/KafkaRoute.md | 11 + .../en/api/faststream/kafka/KafkaRouter.md | 11 + docs/docs/en/api/faststream/kafka/TestApp.md | 11 + .../api/faststream/kafka/TestKafkaBroker.md | 11 + .../en/api/faststream/kafka/TopicPartition.md | 11 + .../faststream/kafka/broker/KafkaBroker.md | 11 + .../kafka/broker/broker/KafkaBroker.md | 11 + .../broker/logging/KafkaParamsStorage.md | 11 + .../broker/registrator/KafkaRegistrator.md | 11 + .../api/faststream/kafka/fastapi/Context.md | 11 + .../faststream/kafka/fastapi/KafkaRouter.md | 11 + .../kafka/fastapi/fastapi/KafkaRouter.md | 11 + .../kafka/message/ConsumerProtocol.md | 11 + .../faststream/kafka/message/FakeConsumer.md | 11 + .../kafka/message/KafkaAckableMessage.md | 11 + .../faststream/kafka/message/KafkaMessage.md | 11 + .../opentelemetry/KafkaTelemetryMiddleware.md | 11 + .../middleware/KafkaTelemetryMiddleware.md | 11 + .../BaseKafkaTelemetrySettingsProvider.md | 11 + .../BatchKafkaTelemetrySettingsProvider.md | 11 + .../KafkaTelemetrySettingsProvider.md | 11 + .../telemetry_attributes_provider_factory.md | 11 + .../kafka/parser/AioKafkaBatchParser.md | 11 + .../faststream/kafka/parser/AioKafkaParser.md | 11 + .../prometheus/KafkaPrometheusMiddleware.md | 11 + .../middleware/KafkaPrometheusMiddleware.md | 11 + .../BaseKafkaMetricsSettingsProvider.md | 11 + .../BatchKafkaMetricsSettingsProvider.md | 11 + .../provider/KafkaMetricsSettingsProvider.md | 11 + .../provider/settings_provider_factory.md | 11 + .../publisher/factory/create_publisher.md | 11 + .../publisher/fake/KafkaFakePublisher.md | 11 + .../producer/AioKafkaFastProducer.md | 11 + .../specified/SpecificationBatchPublisher.md | 11 + .../SpecificationDefaultPublisher.md | 11 + .../specified/SpecificationPublisher.md | 11 + .../publisher/state/EmptyProducerState.md | 11 + .../kafka/publisher/state/ProducerState.md | 11 + .../kafka/publisher/state/RealProducer.md | 11 + .../kafka/publisher/usecase/BatchPublisher.md | 11 + .../publisher/usecase/DefaultPublisher.md | 11 + .../kafka/publisher/usecase/LogicPublisher.md | 11 + .../kafka/response/KafkaPublishCommand.md | 11 + .../kafka/response/KafkaResponse.md | 11 + .../faststream/kafka/router/KafkaPublisher.md | 11 + .../api/faststream/kafka/router/KafkaRoute.md | 11 + .../faststream/kafka/router/KafkaRouter.md | 11 + .../params/ConsumerConnectionParams.md | 11 + .../kafka/security/parse_security.md | 11 + .../subscriber/factory/create_subscriber.md | 11 + .../specified/SpecificationBatchSubscriber.md | 11 + ...pecificationConcurrentDefaultSubscriber.md | 11 + .../SpecificationDefaultSubscriber.md | 11 + .../specified/SpecificationSubscriber.md | 11 + .../subscriber/usecase/BatchSubscriber.md | 11 + .../usecase/ConcurrentDefaultSubscriber.md | 11 + .../subscriber/usecase/DefaultSubscriber.md | 11 + .../subscriber/usecase/LogicSubscriber.md | 11 + .../faststream/kafka/testing/FakeProducer.md | 11 + .../kafka/testing/TestKafkaBroker.md | 11 + .../faststream/kafka/testing/build_message.md | 11 + .../en/api/faststream/message/AckStatus.md | 11 + .../en/api/faststream/message/SourceType.md | 11 + .../api/faststream/message/StreamMessage.md | 11 + .../api/faststream/message/decode_message.md | 11 + .../api/faststream/message/encode_message.md | 11 + .../en/api/faststream/message/gen_cor_id.md | 11 + .../faststream/message/message/AckStatus.md | 11 + .../message/message/StreamMessage.md | 11 + .../message/source_type/SourceType.md | 11 + .../message/utils/decode_message.md | 11 + .../message/utils/encode_message.md | 11 + .../faststream/message/utils/gen_cor_id.md | 11 + .../api/faststream/middlewares/AckPolicy.md | 11 + .../middlewares/AcknowledgementMiddleware.md | 11 + .../faststream/middlewares/BaseMiddleware.md | 11 + .../middlewares/ExceptionMiddleware.md | 11 + .../acknowledgement/conf/AckPolicy.md | 11 + .../middleware/AcknowledgementMiddleware.md | 11 + .../middlewares/base/BaseMiddleware.md | 11 + .../exception/ExceptionMiddleware.md | 11 + .../middlewares/exception/ignore_handler.md | 11 + .../logging/CriticalLogMiddleware.md | 11 + docs/docs/en/api/faststream/nats/AckPolicy.md | 11 + .../en/api/faststream/nats/ConsumerConfig.md | 11 + .../en/api/faststream/nats/DeliverPolicy.md | 11 + .../en/api/faststream/nats/DiscardPolicy.md | 11 + .../en/api/faststream/nats/ExternalStream.md | 11 + docs/docs/en/api/faststream/nats/JStream.md | 11 + docs/docs/en/api/faststream/nats/KvWatch.md | 11 + .../docs/en/api/faststream/nats/NatsBroker.md | 11 + .../en/api/faststream/nats/NatsPublisher.md | 11 + .../en/api/faststream/nats/NatsResponse.md | 11 + docs/docs/en/api/faststream/nats/NatsRoute.md | 11 + .../docs/en/api/faststream/nats/NatsRouter.md | 11 + docs/docs/en/api/faststream/nats/ObjWatch.md | 11 + docs/docs/en/api/faststream/nats/Placement.md | 11 + docs/docs/en/api/faststream/nats/PubAck.md | 11 + docs/docs/en/api/faststream/nats/PullSub.md | 11 + docs/docs/en/api/faststream/nats/RePublish.md | 11 + .../en/api/faststream/nats/ReplayPolicy.md | 11 + .../en/api/faststream/nats/RetentionPolicy.md | 11 + .../en/api/faststream/nats/StorageType.md | 11 + .../en/api/faststream/nats/StreamConfig.md | 11 + .../en/api/faststream/nats/StreamSource.md | 11 + docs/docs/en/api/faststream/nats/TestApp.md | 11 + .../en/api/faststream/nats/TestNatsBroker.md | 11 + .../api/faststream/nats/broker/NatsBroker.md | 11 + .../nats/broker/broker/NatsBroker.md | 11 + .../nats/broker/logging/NatsParamsStorage.md | 11 + .../broker/registrator/NatsRegistrator.md | 11 + .../nats/broker/state/BrokerState.md | 11 + .../nats/broker/state/ConnectedState.md | 11 + .../broker/state/ConnectionBrokenState.md | 11 + .../nats/broker/state/EmptyBrokerState.md | 11 + .../en/api/faststream/nats/fastapi/Context.md | 11 + .../api/faststream/nats/fastapi/NatsRouter.md | 11 + .../nats/fastapi/fastapi/NatsRouter.md | 11 + .../nats/helpers/KVBucketDeclarer.md | 11 + .../nats/helpers/OSBucketDeclarer.md | 11 + .../faststream/nats/helpers/StreamBuilder.md | 11 + .../bucket_declarer/KVBucketDeclarer.md | 11 + .../obj_storage_declarer/OSBucketDeclarer.md | 11 + .../helpers/object_builder/StreamBuilder.md | 11 + .../nats/helpers/state/ConnectedState.md | 11 + .../nats/helpers/state/ConnectionState.md | 11 + .../helpers/state/EmptyConnectionState.md | 11 + .../nats/message/NatsBatchMessage.md | 11 + .../faststream/nats/message/NatsKvMessage.md | 11 + .../faststream/nats/message/NatsMessage.md | 11 + .../faststream/nats/message/NatsObjMessage.md | 11 + .../opentelemetry/NatsTelemetryMiddleware.md | 11 + .../middleware/NatsTelemetryMiddleware.md | 11 + .../BaseNatsTelemetrySettingsProvider.md | 11 + .../NatsBatchTelemetrySettingsProvider.md | 11 + .../provider/NatsTelemetrySettingsProvider.md | 11 + .../telemetry_attributes_provider_factory.md | 11 + .../api/faststream/nats/parser/BatchParser.md | 11 + .../en/api/faststream/nats/parser/JsParser.md | 11 + .../en/api/faststream/nats/parser/KvParser.md | 11 + .../faststream/nats/parser/NatsBaseParser.md | 11 + .../api/faststream/nats/parser/NatsParser.md | 11 + .../api/faststream/nats/parser/ObjParser.md | 11 + .../prometheus/NatsPrometheusMiddleware.md | 11 + .../middleware/NatsPrometheusMiddleware.md | 11 + .../BaseNatsMetricsSettingsProvider.md | 11 + .../BatchNatsMetricsSettingsProvider.md | 11 + .../provider/NatsMetricsSettingsProvider.md | 11 + .../provider/settings_provider_factory.md | 11 + .../publisher/factory/create_publisher.md | 11 + .../nats/publisher/fake/NatsFakePublisher.md | 11 + .../publisher/producer/NatsFastProducer.md | 11 + .../publisher/producer/NatsJSFastProducer.md | 11 + .../specified/SpecificationPublisher.md | 11 + .../nats/publisher/usecase/LogicPublisher.md | 11 + .../nats/response/NatsPublishCommand.md | 11 + .../faststream/nats/response/NatsResponse.md | 11 + .../faststream/nats/router/NatsPublisher.md | 11 + .../api/faststream/nats/router/NatsRoute.md | 11 + .../api/faststream/nats/router/NatsRouter.md | 11 + .../en/api/faststream/nats/schemas/JStream.md | 11 + .../en/api/faststream/nats/schemas/KvWatch.md | 11 + .../api/faststream/nats/schemas/ObjWatch.md | 11 + .../en/api/faststream/nats/schemas/PubAck.md | 11 + .../en/api/faststream/nats/schemas/PullSub.md | 11 + .../nats/schemas/js_stream/JStream.md | 11 + .../js_stream/compile_nats_wildcard.md | 11 + .../js_stream/is_subject_match_wildcard.md | 11 + .../nats/schemas/kv_watch/KvWatch.md | 11 + .../nats/schemas/obj_watch/ObjWatch.md | 11 + .../nats/schemas/pull_sub/PullSub.md | 11 + .../nats/security/parse_security.md | 11 + .../subscriber/adapters/UnsubscribeAdapter.md | 11 + .../subscriber/adapters/Unsubscriptable.md | 11 + .../nats/subscriber/adapters/Watchable.md | 11 + .../subscriber/factory/create_subscriber.md | 11 + .../SpecificationBatchPullStreamSubscriber.md | 11 + .../SpecificationConcurrentCoreSubscriber.md | 11 + ...ificationConcurrentPullStreamSubscriber.md | 11 + ...ificationConcurrentPushStreamSubscriber.md | 11 + .../specified/SpecificationCoreSubscriber.md | 11 + .../SpecificationKeyValueWatchSubscriber.md | 11 + .../SpecificationObjStoreWatchSubscriber.md | 11 + .../SpecificationPullStreamSubscriber.md | 11 + .../SpecificationPushStreamSubscriber.md | 11 + .../specified/SpecificationSubscriber.md | 11 + .../state/ConnectedSubscriberState.md | 11 + .../subscriber/state/EmptySubscriberState.md | 11 + .../nats/subscriber/state/SubscriberState.md | 11 + .../usecases/BatchPullStreamSubscriber.md | 11 + .../usecases/ConcurrentCoreSubscriber.md | 11 + .../ConcurrentPullStreamSubscriber.md | 11 + .../ConcurrentPushStreamSubscriber.md | 11 + .../subscriber/usecases/CoreSubscriber.md | 11 + .../usecases/KeyValueWatchSubscriber.md | 11 + .../subscriber/usecases/LogicSubscriber.md | 11 + .../usecases/ObjStoreWatchSubscriber.md | 11 + .../usecases/PullStreamSubscriber.md | 11 + .../usecases/PushStreamSubscription.md | 11 + .../usecases/basic/DefaultSubscriber.md | 11 + .../usecases/basic/LogicSubscriber.md | 11 + .../ConcurrentCoreSubscriber.md | 11 + .../core_subscriber/CoreSubscriber.md | 11 + .../KeyValueWatchSubscriber.md | 11 + .../ObjStoreWatchSubscriber.md | 11 + .../usecases/stream_basic/StreamSubscriber.md | 11 + .../BatchPullStreamSubscriber.md | 11 + .../ConcurrentPullStreamSubscriber.md | 11 + .../PullStreamSubscriber.md | 11 + .../ConcurrentPushStreamSubscriber.md | 11 + .../PushStreamSubscription.md | 11 + .../faststream/nats/testing/FakeProducer.md | 11 + .../faststream/nats/testing/PatchedMessage.md | 11 + .../faststream/nats/testing/TestNatsBroker.md | 11 + .../faststream/nats/testing/build_message.md | 11 + .../api/faststream/opentelemetry/Baggage.md | 11 + .../opentelemetry/TelemetryMiddleware.md | 11 + .../TelemetrySettingsProvider.md | 11 + .../opentelemetry/baggage/Baggage.md | 11 + .../opentelemetry/consts/MessageAction.md | 11 + .../middleware/BaseTelemetryMiddleware.md | 11 + .../middleware/TelemetryMiddleware.md | 11 + .../provider/TelemetrySettingsProvider.md | 11 + docs/docs/en/api/faststream/params/Context.md | 11 + docs/docs/en/api/faststream/params/Depends.md | 11 + docs/docs/en/api/faststream/params/Header.md | 11 + docs/docs/en/api/faststream/params/Path.md | 11 + .../faststream/params/no_cast/NoCastField.md | 11 + .../api/faststream/params/params/Context.md | 11 + .../en/api/faststream/params/params/Header.md | 11 + .../en/api/faststream/params/params/Path.md | 11 + .../api/faststream/prometheus/ConsumeAttrs.md | 11 + .../prometheus/MetricsSettingsProvider.md | 11 + .../prometheus/PrometheusMiddleware.md | 11 + .../prometheus/container/MetricsContainer.md | 11 + .../prometheus/manager/MetricsManager.md | 11 + .../middleware/BasePrometheusMiddleware.md | 11 + .../middleware/PrometheusMiddleware.md | 11 + .../provider/MetricsSettingsProvider.md | 11 + .../prometheus/types/ConsumeAttrs.md | 11 + .../prometheus/types/ProcessingStatus.md | 11 + .../prometheus/types/PublishingStatus.md | 11 + .../en/api/faststream/rabbit/ExchangeType.md | 11 + .../en/api/faststream/rabbit/RabbitBroker.md | 11 + .../api/faststream/rabbit/RabbitExchange.md | 11 + .../api/faststream/rabbit/RabbitPublisher.md | 11 + .../en/api/faststream/rabbit/RabbitQueue.md | 11 + .../api/faststream/rabbit/RabbitResponse.md | 11 + .../en/api/faststream/rabbit/RabbitRoute.md | 11 + .../en/api/faststream/rabbit/RabbitRouter.md | 11 + docs/docs/en/api/faststream/rabbit/TestApp.md | 11 + .../api/faststream/rabbit/TestRabbitBroker.md | 11 + .../faststream/rabbit/broker/RabbitBroker.md | 11 + .../rabbit/broker/broker/RabbitBroker.md | 11 + .../broker/logging/RabbitParamsStorage.md | 11 + .../broker/registrator/RabbitRegistrator.md | 11 + .../api/faststream/rabbit/fastapi/Context.md | 11 + .../faststream/rabbit/fastapi/RabbitRouter.md | 11 + .../rabbit/fastapi/fastapi/RabbitRouter.md | 11 + .../rabbit/helpers/declarer/RabbitDeclarer.md | 11 + .../rabbit/helpers/state/ConnectedState.md | 11 + .../rabbit/helpers/state/ConnectionState.md | 11 + .../helpers/state/EmptyConnectionState.md | 11 + .../rabbit/message/RabbitMessage.md | 11 + .../RabbitTelemetryMiddleware.md | 11 + .../middleware/RabbitTelemetryMiddleware.md | 11 + .../RabbitTelemetrySettingsProvider.md | 11 + .../faststream/rabbit/parser/AioPikaParser.md | 11 + .../prometheus/RabbitPrometheusMiddleware.md | 11 + .../middleware/RabbitPrometheusMiddleware.md | 11 + .../provider/RabbitMetricsSettingsProvider.md | 11 + .../publisher/factory/create_publisher.md | 11 + .../publisher/fake/RabbitFakePublisher.md | 11 + .../publisher/options/MessageOptions.md | 11 + .../publisher/options/PublishOptions.md | 11 + .../publisher/producer/AioPikaFastProducer.md | 11 + .../rabbit/publisher/producer/LockState.md | 11 + .../rabbit/publisher/producer/LockUnset.md | 11 + .../rabbit/publisher/producer/RealLock.md | 11 + .../specified/SpecificationPublisher.md | 11 + .../publisher/usecase/LogicPublisher.md | 11 + .../rabbit/publisher/usecase/PublishKwargs.md | 11 + .../publisher/usecase/RequestPublishKwargs.md | 11 + .../rabbit/response/RabbitPublishCommand.md | 11 + .../rabbit/response/RabbitResponse.md | 11 + .../rabbit/router/RabbitPublisher.md | 11 + .../faststream/rabbit/router/RabbitRoute.md | 11 + .../faststream/rabbit/router/RabbitRouter.md | 11 + .../rabbit/schemas/BaseRMQInformation.md | 11 + .../faststream/rabbit/schemas/ExchangeType.md | 11 + .../rabbit/schemas/RabbitExchange.md | 11 + .../faststream/rabbit/schemas/RabbitQueue.md | 11 + .../rabbit/schemas/constants/ExchangeType.md | 11 + .../rabbit/schemas/exchange/RabbitExchange.md | 11 + .../schemas/proto/BaseRMQInformation.md | 11 + .../rabbit/schemas/queue/RabbitQueue.md | 11 + .../rabbit/security/parse_security.md | 11 + .../subscriber/factory/create_subscriber.md | 11 + .../specified/SpecificationSubscriber.md | 11 + .../subscriber/usecase/LogicSubscriber.md | 11 + .../faststream/rabbit/testing/FakeProducer.md | 11 + .../rabbit/testing/PatchedMessage.md | 11 + .../rabbit/testing/TestRabbitBroker.md | 11 + .../rabbit/testing/apply_pattern.md | 11 + .../rabbit/testing/build_message.md | 11 + .../api/faststream/rabbit/utils/build_url.md | 11 + .../rabbit/utils/is_routing_exchange.md | 11 + docs/docs/en/api/faststream/redis/ListSub.md | 11 + docs/docs/en/api/faststream/redis/PubSub.md | 11 + .../en/api/faststream/redis/RedisBroker.md | 11 + .../en/api/faststream/redis/RedisPublisher.md | 11 + .../en/api/faststream/redis/RedisResponse.md | 11 + .../en/api/faststream/redis/RedisRoute.md | 11 + .../en/api/faststream/redis/RedisRouter.md | 11 + .../docs/en/api/faststream/redis/StreamSub.md | 11 + docs/docs/en/api/faststream/redis/TestApp.md | 11 + .../api/faststream/redis/TestRedisBroker.md | 11 + .../redis/broker/broker/RedisBroker.md | 11 + .../broker/logging/RedisParamsStorage.md | 11 + .../broker/registrator/RedisRegistrator.md | 11 + .../api/faststream/redis/fastapi/Context.md | 11 + .../faststream/redis/fastapi/RedisRouter.md | 11 + .../redis/fastapi/fastapi/RedisRouter.md | 11 + .../redis/helpers/state/ConnectedState.md | 11 + .../redis/helpers/state/ConnectionState.md | 11 + .../helpers/state/EmptyConnectionState.md | 11 + .../redis/message/BatchListMessage.md | 11 + .../redis/message/BatchStreamMessage.md | 11 + .../redis/message/DefaultListMessage.md | 11 + .../redis/message/DefaultStreamMessage.md | 11 + .../faststream/redis/message/PubSubMessage.md | 11 + .../redis/message/RedisBatchListMessage.md | 11 + .../redis/message/RedisBatchStreamMessage.md | 11 + .../redis/message/RedisListMessage.md | 11 + .../faststream/redis/message/RedisMessage.md | 11 + .../redis/message/RedisStreamMessage.md | 11 + .../redis/message/UnifyRedisDict.md | 11 + .../redis/message/UnifyRedisMessage.md | 11 + .../opentelemetry/RedisTelemetryMiddleware.md | 11 + .../middleware/RedisTelemetryMiddleware.md | 11 + .../RedisTelemetrySettingsProvider.md | 11 + .../api/faststream/redis/parser/RawMessage.md | 11 + .../redis/parser/RedisBatchListParser.md | 11 + .../redis/parser/RedisBatchStreamParser.md | 11 + .../redis/parser/RedisListParser.md | 11 + .../redis/parser/RedisPubSubParser.md | 11 + .../redis/parser/RedisStreamParser.md | 11 + .../faststream/redis/parser/SimpleParser.md | 11 + .../prometheus/RedisPrometheusMiddleware.md | 11 + .../middleware/RedisPrometheusMiddleware.md | 11 + .../BaseRedisMetricsSettingsProvider.md | 11 + .../BatchRedisMetricsSettingsProvider.md | 11 + .../provider/RedisMetricsSettingsProvider.md | 11 + .../provider/settings_provider_factory.md | 11 + .../publisher/factory/create_publisher.md | 11 + .../publisher/fake/RedisFakePublisher.md | 11 + .../publisher/producer/RedisFastProducer.md | 11 + .../SpecificationChannelPublisher.md | 11 + .../SpecificationListBatchPublisher.md | 11 + .../specified/SpecificationListPublisher.md | 11 + .../specified/SpecificationPublisher.md | 11 + .../specified/SpecificationStreamPublisher.md | 11 + .../publisher/usecase/ChannelPublisher.md | 11 + .../publisher/usecase/ListBatchPublisher.md | 11 + .../redis/publisher/usecase/ListPublisher.md | 11 + .../redis/publisher/usecase/LogicPublisher.md | 11 + .../publisher/usecase/StreamPublisher.md | 11 + .../redis/response/DestinationType.md | 11 + .../redis/response/RedisPublishCommand.md | 11 + .../redis/response/RedisResponse.md | 11 + .../faststream/redis/router/RedisPublisher.md | 11 + .../api/faststream/redis/router/RedisRoute.md | 11 + .../faststream/redis/router/RedisRouter.md | 11 + .../api/faststream/redis/schemas/ListSub.md | 11 + .../en/api/faststream/redis/schemas/PubSub.md | 11 + .../api/faststream/redis/schemas/StreamSub.md | 11 + .../redis/schemas/list_sub/ListSub.md | 11 + .../proto/RedisSpecificationProtocol.md | 11 + .../redis/schemas/proto/validate_options.md | 11 + .../redis/schemas/pub_sub/PubSub.md | 11 + .../redis/schemas/stream_sub/StreamSub.md | 11 + .../redis/security/parse_security.md | 11 + .../subscriber/factory/create_subscriber.md | 11 + .../SpecificationChannelSubscriber.md | 11 + .../SpecificationListBatchSubscriber.md | 11 + .../specified/SpecificationListSubscriber.md | 11 + .../SpecificationStreamBatchSubscriber.md | 11 + .../SpecificationStreamSubscriber.md | 11 + .../specified/SpecificationSubscriber.md | 11 + .../subscriber/usecase/BatchListSubscriber.md | 11 + .../subscriber/usecase/ChannelSubscriber.md | 11 + .../subscriber/usecase/ListSubscriber.md | 11 + .../subscriber/usecase/LogicSubscriber.md | 11 + .../usecase/StreamBatchSubscriber.md | 11 + .../subscriber/usecase/StreamSubscriber.md | 11 + .../redis/testing/ChannelVisitor.md | 11 + .../faststream/redis/testing/FakeProducer.md | 11 + .../faststream/redis/testing/ListVisitor.md | 11 + .../faststream/redis/testing/StreamVisitor.md | 11 + .../redis/testing/TestRedisBroker.md | 11 + .../api/faststream/redis/testing/Visitor.md | 11 + .../faststream/redis/testing/build_message.md | 11 + .../api/faststream/response/PublishCommand.md | 11 + .../en/api/faststream/response/PublishType.md | 11 + .../en/api/faststream/response/Response.md | 11 + .../faststream/response/ensure_response.md | 11 + .../response/publish_type/PublishType.md | 11 + .../response/response/PublishCommand.md | 11 + .../faststream/response/response/Response.md | 11 + .../response/utils/ensure_response.md | 11 + .../api/faststream/security/BaseSecurity.md | 11 + .../en/api/faststream/security/SASLGSSAPI.md | 11 + .../faststream/security/SASLOAuthBearer.md | 11 + .../api/faststream/security/SASLPlaintext.md | 11 + .../api/faststream/security/SASLScram256.md | 11 + .../api/faststream/security/SASLScram512.md | 11 + .../api/faststream/specification/AsyncAPI.md | 11 + .../api/faststream/specification/Contact.md | 11 + .../faststream/specification/ExternalDocs.md | 11 + .../api/faststream/specification/License.md | 11 + .../en/api/faststream/specification/Tag.md | 11 + .../specification/asyncapi/AsyncAPI.md | 11 + .../asyncapi/factory/AsyncAPI.md | 11 + .../asyncapi/get_asyncapi_html.md | 11 + .../asyncapi/message/get_model_schema.md | 11 + .../asyncapi/message/get_response_schema.md | 11 + .../asyncapi/message/parse_handler_params.md | 11 + .../asyncapi/site/get_asyncapi_html.md | 11 + .../specification/asyncapi/site/serve_app.md | 11 + .../specification/asyncapi/utils/clear_key.md | 11 + .../asyncapi/utils/move_pydantic_refs.md | 11 + .../asyncapi/utils/resolve_payloads.md | 11 + .../asyncapi/utils/to_camelcase.md | 11 + .../asyncapi/v2_6_0/AsyncAPI2.md | 11 + .../asyncapi/v2_6_0/facade/AsyncAPI2.md | 11 + .../v2_6_0/generate/get_app_schema.md | 11 + .../v2_6_0/generate/get_broker_channels.md | 11 + .../v2_6_0/generate/get_broker_server.md | 11 + .../generate/resolve_channel_messages.md | 11 + .../asyncapi/v2_6_0/get_app_schema.md | 11 + .../asyncapi/v2_6_0/schema/ApplicationInfo.md | 11 + .../v2_6_0/schema/ApplicationSchema.md | 11 + .../asyncapi/v2_6_0/schema/Channel.md | 11 + .../asyncapi/v2_6_0/schema/Components.md | 11 + .../asyncapi/v2_6_0/schema/Contact.md | 11 + .../asyncapi/v2_6_0/schema/CorrelationId.md | 11 + .../asyncapi/v2_6_0/schema/ExternalDocs.md | 11 + .../asyncapi/v2_6_0/schema/License.md | 11 + .../asyncapi/v2_6_0/schema/Message.md | 11 + .../asyncapi/v2_6_0/schema/Operation.md | 11 + .../asyncapi/v2_6_0/schema/Parameter.md | 11 + .../asyncapi/v2_6_0/schema/Reference.md | 11 + .../asyncapi/v2_6_0/schema/Server.md | 11 + .../asyncapi/v2_6_0/schema/ServerVariable.md | 11 + .../asyncapi/v2_6_0/schema/Tag.md | 11 + .../v2_6_0/schema/bindings/ChannelBinding.md | 11 + .../schema/bindings/OperationBinding.md | 11 + .../schema/bindings/amqp/ChannelBinding.md | 11 + .../schema/bindings/amqp/OperationBinding.md | 11 + .../bindings/amqp/channel/ChannelBinding.md | 11 + .../schema/bindings/amqp/channel/Exchange.md | 11 + .../schema/bindings/amqp/channel/Queue.md | 11 + .../amqp/operation/OperationBinding.md | 11 + .../schema/bindings/kafka/ChannelBinding.md | 11 + .../schema/bindings/kafka/OperationBinding.md | 11 + .../bindings/kafka/channel/ChannelBinding.md | 11 + .../kafka/operation/OperationBinding.md | 11 + .../schema/bindings/main/ChannelBinding.md | 11 + .../schema/bindings/main/OperationBinding.md | 11 + .../bindings/main/channel/ChannelBinding.md | 11 + .../main/operation/OperationBinding.md | 11 + .../schema/bindings/nats/ChannelBinding.md | 11 + .../schema/bindings/nats/OperationBinding.md | 11 + .../bindings/nats/channel/ChannelBinding.md | 11 + .../nats/operation/OperationBinding.md | 11 + .../schema/bindings/redis/ChannelBinding.md | 11 + .../schema/bindings/redis/OperationBinding.md | 11 + .../bindings/redis/channel/ChannelBinding.md | 11 + .../redis/operation/OperationBinding.md | 11 + .../schema/bindings/sqs/ChannelBinding.md | 11 + .../schema/bindings/sqs/OperationBinding.md | 11 + .../bindings/sqs/channel/ChannelBinding.md | 11 + .../schema/bindings/sqs/channel/from_spec.md | 11 + .../sqs/operation/OperationBinding.md | 11 + .../bindings/sqs/operation/from_spec.md | 11 + .../v2_6_0/schema/channels/Channel.md | 11 + .../v2_6_0/schema/components/Components.md | 11 + .../asyncapi/v2_6_0/schema/contact/Contact.md | 11 + .../v2_6_0/schema/docs/ExternalDocs.md | 11 + .../v2_6_0/schema/info/ApplicationInfo.md | 11 + .../asyncapi/v2_6_0/schema/license/License.md | 11 + .../v2_6_0/schema/message/CorrelationId.md | 11 + .../asyncapi/v2_6_0/schema/message/Message.md | 11 + .../v2_6_0/schema/operations/Operation.md | 11 + .../v2_6_0/schema/schema/ApplicationSchema.md | 11 + .../asyncapi/v2_6_0/schema/servers/Server.md | 11 + .../v2_6_0/schema/servers/ServerVariable.md | 11 + .../asyncapi/v2_6_0/schema/tag/Tag.md | 11 + .../asyncapi/v2_6_0/schema/utils/Parameter.md | 11 + .../asyncapi/v2_6_0/schema/utils/Reference.md | 11 + .../asyncapi/v3_0_0/AsyncAPI3.md | 11 + .../asyncapi/v3_0_0/facade/AsyncAPI3.md | 11 + .../v3_0_0/generate/get_app_schema.md | 11 + .../v3_0_0/generate/get_broker_channels.md | 11 + .../v3_0_0/generate/get_broker_server.md | 11 + .../asyncapi/v3_0_0/get_app_schema.md | 11 + .../asyncapi/v3_0_0/schema/ApplicationInfo.md | 11 + .../v3_0_0/schema/ApplicationSchema.md | 11 + .../asyncapi/v3_0_0/schema/Channel.md | 11 + .../asyncapi/v3_0_0/schema/Components.md | 11 + .../asyncapi/v3_0_0/schema/Contact.md | 11 + .../asyncapi/v3_0_0/schema/CorrelationId.md | 11 + .../asyncapi/v3_0_0/schema/ExternalDocs.md | 11 + .../asyncapi/v3_0_0/schema/License.md | 11 + .../asyncapi/v3_0_0/schema/Message.md | 11 + .../asyncapi/v3_0_0/schema/Operation.md | 11 + .../asyncapi/v3_0_0/schema/Parameter.md | 11 + .../asyncapi/v3_0_0/schema/Reference.md | 11 + .../asyncapi/v3_0_0/schema/Server.md | 11 + .../asyncapi/v3_0_0/schema/ServerVariable.md | 11 + .../asyncapi/v3_0_0/schema/Tag.md | 11 + .../v3_0_0/schema/bindings/ChannelBinding.md | 11 + .../schema/bindings/OperationBinding.md | 11 + .../schema/bindings/amqp/ChannelBinding.md | 11 + .../schema/bindings/amqp/OperationBinding.md | 11 + .../bindings/amqp/channel/ChannelBinding.md | 11 + .../amqp/operation/OperationBinding.md | 11 + .../schema/bindings/kafka/ChannelBinding.md | 11 + .../schema/bindings/kafka/OperationBinding.md | 11 + .../schema/bindings/main/ChannelBinding.md | 11 + .../schema/bindings/main/OperationBinding.md | 11 + .../bindings/main/channel/ChannelBinding.md | 11 + .../main/operation/OperationBinding.md | 11 + .../schema/bindings/nats/ChannelBinding.md | 11 + .../schema/bindings/nats/OperationBinding.md | 11 + .../schema/bindings/redis/ChannelBinding.md | 11 + .../schema/bindings/redis/OperationBinding.md | 11 + .../schema/bindings/sqs/ChannelBinding.md | 11 + .../schema/bindings/sqs/OperationBinding.md | 11 + .../v3_0_0/schema/channels/Channel.md | 11 + .../v3_0_0/schema/components/Components.md | 11 + .../asyncapi/v3_0_0/schema/contact/Contact.md | 11 + .../v3_0_0/schema/docs/ExternalDocs.md | 11 + .../v3_0_0/schema/info/ApplicationInfo.md | 11 + .../asyncapi/v3_0_0/schema/license/License.md | 11 + .../v3_0_0/schema/message/CorrelationId.md | 11 + .../asyncapi/v3_0_0/schema/message/Message.md | 11 + .../v3_0_0/schema/operations/Action.md | 11 + .../v3_0_0/schema/operations/Operation.md | 11 + .../v3_0_0/schema/schema/ApplicationSchema.md | 11 + .../asyncapi/v3_0_0/schema/servers/Server.md | 11 + .../asyncapi/v3_0_0/schema/tag/Tag.md | 11 + .../asyncapi/v3_0_0/schema/utils/Parameter.md | 11 + .../asyncapi/v3_0_0/schema/utils/Reference.md | 11 + .../base/info/BaseApplicationInfo.md | 11 + .../base/schema/BaseApplicationSchema.md | 11 + .../base/specification/Specification.md | 11 + .../proto/EndpointSpecification.md | 11 + .../proto/ServerSpecification.md | 11 + .../proto/broker/ServerSpecification.md | 11 + .../proto/endpoint/EndpointSpecification.md | 11 + .../specification/schema/Contact.md | 11 + .../specification/schema/ContactDict.md | 11 + .../specification/schema/ExternalDocs.md | 11 + .../specification/schema/ExternalDocsDict.md | 11 + .../specification/schema/License.md | 11 + .../specification/schema/LicenseDict.md | 11 + .../specification/schema/Message.md | 11 + .../specification/schema/Operation.md | 11 + .../specification/schema/PublisherSpec.md | 11 + .../specification/schema/SubscriberSpec.md | 11 + .../faststream/specification/schema/Tag.md | 11 + .../specification/schema/TagDict.md | 11 + .../schema/bindings/ChannelBinding.md | 11 + .../schema/bindings/OperationBinding.md | 11 + .../schema/bindings/amqp/ChannelBinding.md | 11 + .../schema/bindings/amqp/Exchange.md | 11 + .../schema/bindings/amqp/OperationBinding.md | 11 + .../schema/bindings/amqp/Queue.md | 11 + .../schema/bindings/kafka/ChannelBinding.md | 11 + .../schema/bindings/kafka/OperationBinding.md | 11 + .../schema/bindings/main/ChannelBinding.md | 11 + .../schema/bindings/main/OperationBinding.md | 11 + .../schema/bindings/nats/ChannelBinding.md | 11 + .../schema/bindings/nats/OperationBinding.md | 11 + .../schema/bindings/redis/ChannelBinding.md | 11 + .../schema/bindings/redis/OperationBinding.md | 11 + .../schema/bindings/sqs/ChannelBinding.md | 11 + .../schema/bindings/sqs/OperationBinding.md | 11 + .../specification/schema/extra/Contact.md | 11 + .../specification/schema/extra/ContactDict.md | 11 + .../schema/extra/ExternalDocs.md | 11 + .../schema/extra/ExternalDocsDict.md | 11 + .../specification/schema/extra/License.md | 11 + .../specification/schema/extra/LicenseDict.md | 11 + .../specification/schema/extra/Tag.md | 11 + .../specification/schema/extra/TagDict.md | 11 + .../schema/extra/contact/Contact.md | 11 + .../schema/extra/contact/ContactDict.md | 11 + .../extra/external_docs/ExternalDocs.md | 11 + .../extra/external_docs/ExternalDocsDict.md | 11 + .../schema/extra/license/License.md | 11 + .../schema/extra/license/LicenseDict.md | 11 + .../specification/schema/extra/tag/Tag.md | 11 + .../specification/schema/extra/tag/TagDict.md | 11 + .../specification/schema/message/Message.md | 11 + .../schema/message/model/Message.md | 11 + .../schema/operation/Operation.md | 11 + .../schema/operation/model/Operation.md | 11 + .../schema/publisher/PublisherSpec.md | 11 + .../schema/subscriber/SubscriberSpec.md | 11 + faststream/_internal/broker/abc_broker.py | 3 + faststream/_internal/broker/broker.py | 5 + faststream/_internal/broker/router.py | 2 + faststream/confluent/broker/broker.py | 6 + faststream/confluent/router.py | 6 + faststream/kafka/broker/broker.py | 6 + faststream/kafka/router.py | 6 + faststream/nats/broker/broker.py | 6 + faststream/nats/router.py | 6 + faststream/rabbit/broker/broker.py | 5 + faststream/rabbit/router.py | 6 + faststream/redis/broker/broker.py | 6 + faststream/redis/router.py | 6 + tests/brokers/base/router.py | 28 + 754 files changed, 9502 insertions(+) create mode 100644 docs/docs/SUMMARY.md create mode 100644 docs/docs/en/api/faststream/AckPolicy.md create mode 100644 docs/docs/en/api/faststream/BaseMiddleware.md create mode 100644 docs/docs/en/api/faststream/Context.md create mode 100644 docs/docs/en/api/faststream/Depends.md create mode 100644 docs/docs/en/api/faststream/ExceptionMiddleware.md create mode 100644 docs/docs/en/api/faststream/FastStream.md create mode 100644 docs/docs/en/api/faststream/Header.md create mode 100644 docs/docs/en/api/faststream/Path.md create mode 100644 docs/docs/en/api/faststream/Response.md create mode 100644 docs/docs/en/api/faststream/TestApp.md create mode 100644 docs/docs/en/api/faststream/app/FastStream.md create mode 100644 docs/docs/en/api/faststream/apply_types.md create mode 100644 docs/docs/en/api/faststream/asgi/AsgiFastStream.md create mode 100644 docs/docs/en/api/faststream/asgi/AsgiResponse.md create mode 100644 docs/docs/en/api/faststream/asgi/app/AsgiFastStream.md create mode 100644 docs/docs/en/api/faststream/asgi/app/CliRunState.md create mode 100644 docs/docs/en/api/faststream/asgi/app/OuterRunState.md create mode 100644 docs/docs/en/api/faststream/asgi/app/ServerState.md create mode 100644 docs/docs/en/api/faststream/asgi/app/cast_uvicorn_params.md create mode 100644 docs/docs/en/api/faststream/asgi/factories/make_asyncapi_asgi.md create mode 100644 docs/docs/en/api/faststream/asgi/factories/make_ping_asgi.md create mode 100644 docs/docs/en/api/faststream/asgi/get.md create mode 100644 docs/docs/en/api/faststream/asgi/handlers/get.md create mode 100644 docs/docs/en/api/faststream/asgi/make_asyncapi_asgi.md create mode 100644 docs/docs/en/api/faststream/asgi/make_ping_asgi.md create mode 100644 docs/docs/en/api/faststream/asgi/response/AsgiResponse.md create mode 100644 docs/docs/en/api/faststream/asgi/websocket/WebSocketClose.md create mode 100644 docs/docs/en/api/faststream/confluent/KafkaBroker.md create mode 100644 docs/docs/en/api/faststream/confluent/KafkaPublisher.md create mode 100644 docs/docs/en/api/faststream/confluent/KafkaResponse.md create mode 100644 docs/docs/en/api/faststream/confluent/KafkaRoute.md create mode 100644 docs/docs/en/api/faststream/confluent/KafkaRouter.md create mode 100644 docs/docs/en/api/faststream/confluent/TestApp.md create mode 100644 docs/docs/en/api/faststream/confluent/TestKafkaBroker.md create mode 100644 docs/docs/en/api/faststream/confluent/TopicPartition.md create mode 100644 docs/docs/en/api/faststream/confluent/broker/KafkaBroker.md create mode 100644 docs/docs/en/api/faststream/confluent/broker/broker/KafkaBroker.md create mode 100644 docs/docs/en/api/faststream/confluent/broker/logging/KafkaParamsStorage.md create mode 100644 docs/docs/en/api/faststream/confluent/broker/registrator/KafkaRegistrator.md create mode 100644 docs/docs/en/api/faststream/confluent/client/AsyncConfluentConsumer.md create mode 100644 docs/docs/en/api/faststream/confluent/client/AsyncConfluentProducer.md create mode 100644 docs/docs/en/api/faststream/confluent/client/BatchBuilder.md create mode 100644 docs/docs/en/api/faststream/confluent/client/check_msg_error.md create mode 100644 docs/docs/en/api/faststream/confluent/client/create_topics.md create mode 100644 docs/docs/en/api/faststream/confluent/config/BrokerAddressFamily.md create mode 100644 docs/docs/en/api/faststream/confluent/config/BuiltinFeatures.md create mode 100644 docs/docs/en/api/faststream/confluent/config/ClientDNSLookup.md create mode 100644 docs/docs/en/api/faststream/confluent/config/CompressionCodec.md create mode 100644 docs/docs/en/api/faststream/confluent/config/CompressionType.md create mode 100644 docs/docs/en/api/faststream/confluent/config/ConfluentConfig.md create mode 100644 docs/docs/en/api/faststream/confluent/config/ConfluentFastConfig.md create mode 100644 docs/docs/en/api/faststream/confluent/config/Debug.md create mode 100644 docs/docs/en/api/faststream/confluent/config/GroupProtocol.md create mode 100644 docs/docs/en/api/faststream/confluent/config/IsolationLevel.md create mode 100644 docs/docs/en/api/faststream/confluent/config/OffsetStoreMethod.md create mode 100644 docs/docs/en/api/faststream/confluent/config/SASLOAUTHBearerMethod.md create mode 100644 docs/docs/en/api/faststream/confluent/config/SecurityProtocol.md create mode 100644 docs/docs/en/api/faststream/confluent/fastapi/Context.md create mode 100644 docs/docs/en/api/faststream/confluent/fastapi/KafkaRouter.md create mode 100644 docs/docs/en/api/faststream/confluent/fastapi/fastapi/KafkaRouter.md create mode 100644 docs/docs/en/api/faststream/confluent/message/ConsumerProtocol.md create mode 100644 docs/docs/en/api/faststream/confluent/message/FakeConsumer.md create mode 100644 docs/docs/en/api/faststream/confluent/message/KafkaMessage.md create mode 100644 docs/docs/en/api/faststream/confluent/opentelemetry/KafkaTelemetryMiddleware.md create mode 100644 docs/docs/en/api/faststream/confluent/opentelemetry/middleware/KafkaTelemetryMiddleware.md create mode 100644 docs/docs/en/api/faststream/confluent/opentelemetry/provider/BaseConfluentTelemetrySettingsProvider.md create mode 100644 docs/docs/en/api/faststream/confluent/opentelemetry/provider/BatchConfluentTelemetrySettingsProvider.md create mode 100644 docs/docs/en/api/faststream/confluent/opentelemetry/provider/ConfluentTelemetrySettingsProvider.md create mode 100644 docs/docs/en/api/faststream/confluent/opentelemetry/provider/telemetry_attributes_provider_factory.md create mode 100644 docs/docs/en/api/faststream/confluent/parser/AsyncConfluentParser.md create mode 100644 docs/docs/en/api/faststream/confluent/prometheus/KafkaPrometheusMiddleware.md create mode 100644 docs/docs/en/api/faststream/confluent/prometheus/middleware/KafkaPrometheusMiddleware.md create mode 100644 docs/docs/en/api/faststream/confluent/prometheus/provider/BaseConfluentMetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/confluent/prometheus/provider/BatchConfluentMetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/confluent/prometheus/provider/ConfluentMetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/confluent/prometheus/provider/settings_provider_factory.md create mode 100644 docs/docs/en/api/faststream/confluent/publisher/factory/create_publisher.md create mode 100644 docs/docs/en/api/faststream/confluent/publisher/fake/KafkaFakePublisher.md create mode 100644 docs/docs/en/api/faststream/confluent/publisher/producer/AsyncConfluentFastProducer.md create mode 100644 docs/docs/en/api/faststream/confluent/publisher/specified/SpecificationBatchPublisher.md create mode 100644 docs/docs/en/api/faststream/confluent/publisher/specified/SpecificationDefaultPublisher.md create mode 100644 docs/docs/en/api/faststream/confluent/publisher/specified/SpecificationPublisher.md create mode 100644 docs/docs/en/api/faststream/confluent/publisher/state/EmptyProducerState.md create mode 100644 docs/docs/en/api/faststream/confluent/publisher/state/ProducerState.md create mode 100644 docs/docs/en/api/faststream/confluent/publisher/state/RealProducer.md create mode 100644 docs/docs/en/api/faststream/confluent/publisher/usecase/BatchPublisher.md create mode 100644 docs/docs/en/api/faststream/confluent/publisher/usecase/DefaultPublisher.md create mode 100644 docs/docs/en/api/faststream/confluent/publisher/usecase/LogicPublisher.md create mode 100644 docs/docs/en/api/faststream/confluent/response/KafkaPublishCommand.md create mode 100644 docs/docs/en/api/faststream/confluent/response/KafkaResponse.md create mode 100644 docs/docs/en/api/faststream/confluent/router/KafkaPublisher.md create mode 100644 docs/docs/en/api/faststream/confluent/router/KafkaRoute.md create mode 100644 docs/docs/en/api/faststream/confluent/router/KafkaRouter.md create mode 100644 docs/docs/en/api/faststream/confluent/schemas/TopicPartition.md create mode 100644 docs/docs/en/api/faststream/confluent/schemas/params/ConsumerConnectionParams.md create mode 100644 docs/docs/en/api/faststream/confluent/schemas/partition/TopicPartition.md create mode 100644 docs/docs/en/api/faststream/confluent/security/parse_security.md create mode 100644 docs/docs/en/api/faststream/confluent/subscriber/factory/create_subscriber.md create mode 100644 docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationBatchSubscriber.md create mode 100644 docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationConcurrentDefaultSubscriber.md create mode 100644 docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationDefaultSubscriber.md create mode 100644 docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationSubscriber.md create mode 100644 docs/docs/en/api/faststream/confluent/subscriber/usecase/BatchSubscriber.md create mode 100644 docs/docs/en/api/faststream/confluent/subscriber/usecase/ConcurrentDefaultSubscriber.md create mode 100644 docs/docs/en/api/faststream/confluent/subscriber/usecase/DefaultSubscriber.md create mode 100644 docs/docs/en/api/faststream/confluent/subscriber/usecase/LogicSubscriber.md create mode 100644 docs/docs/en/api/faststream/confluent/testing/FakeProducer.md create mode 100644 docs/docs/en/api/faststream/confluent/testing/MockConfluentMessage.md create mode 100644 docs/docs/en/api/faststream/confluent/testing/TestKafkaBroker.md create mode 100644 docs/docs/en/api/faststream/confluent/testing/build_message.md create mode 100644 docs/docs/en/api/faststream/exceptions/AckMessage.md create mode 100644 docs/docs/en/api/faststream/exceptions/ContextError.md create mode 100644 docs/docs/en/api/faststream/exceptions/FastStreamException.md create mode 100644 docs/docs/en/api/faststream/exceptions/FeatureNotSupportedException.md create mode 100644 docs/docs/en/api/faststream/exceptions/HandlerException.md create mode 100644 docs/docs/en/api/faststream/exceptions/IgnoredException.md create mode 100644 docs/docs/en/api/faststream/exceptions/IncorrectState.md create mode 100644 docs/docs/en/api/faststream/exceptions/NackMessage.md create mode 100644 docs/docs/en/api/faststream/exceptions/RejectMessage.md create mode 100644 docs/docs/en/api/faststream/exceptions/SetupError.md create mode 100644 docs/docs/en/api/faststream/exceptions/SkipMessage.md create mode 100644 docs/docs/en/api/faststream/exceptions/StartupValidationError.md create mode 100644 docs/docs/en/api/faststream/exceptions/StopApplication.md create mode 100644 docs/docs/en/api/faststream/exceptions/StopConsume.md create mode 100644 docs/docs/en/api/faststream/exceptions/SubscriberNotFound.md create mode 100644 docs/docs/en/api/faststream/kafka/KafkaBroker.md create mode 100644 docs/docs/en/api/faststream/kafka/KafkaPublisher.md create mode 100644 docs/docs/en/api/faststream/kafka/KafkaResponse.md create mode 100644 docs/docs/en/api/faststream/kafka/KafkaRoute.md create mode 100644 docs/docs/en/api/faststream/kafka/KafkaRouter.md create mode 100644 docs/docs/en/api/faststream/kafka/TestApp.md create mode 100644 docs/docs/en/api/faststream/kafka/TestKafkaBroker.md create mode 100644 docs/docs/en/api/faststream/kafka/TopicPartition.md create mode 100644 docs/docs/en/api/faststream/kafka/broker/KafkaBroker.md create mode 100644 docs/docs/en/api/faststream/kafka/broker/broker/KafkaBroker.md create mode 100644 docs/docs/en/api/faststream/kafka/broker/logging/KafkaParamsStorage.md create mode 100644 docs/docs/en/api/faststream/kafka/broker/registrator/KafkaRegistrator.md create mode 100644 docs/docs/en/api/faststream/kafka/fastapi/Context.md create mode 100644 docs/docs/en/api/faststream/kafka/fastapi/KafkaRouter.md create mode 100644 docs/docs/en/api/faststream/kafka/fastapi/fastapi/KafkaRouter.md create mode 100644 docs/docs/en/api/faststream/kafka/message/ConsumerProtocol.md create mode 100644 docs/docs/en/api/faststream/kafka/message/FakeConsumer.md create mode 100644 docs/docs/en/api/faststream/kafka/message/KafkaAckableMessage.md create mode 100644 docs/docs/en/api/faststream/kafka/message/KafkaMessage.md create mode 100644 docs/docs/en/api/faststream/kafka/opentelemetry/KafkaTelemetryMiddleware.md create mode 100644 docs/docs/en/api/faststream/kafka/opentelemetry/middleware/KafkaTelemetryMiddleware.md create mode 100644 docs/docs/en/api/faststream/kafka/opentelemetry/provider/BaseKafkaTelemetrySettingsProvider.md create mode 100644 docs/docs/en/api/faststream/kafka/opentelemetry/provider/BatchKafkaTelemetrySettingsProvider.md create mode 100644 docs/docs/en/api/faststream/kafka/opentelemetry/provider/KafkaTelemetrySettingsProvider.md create mode 100644 docs/docs/en/api/faststream/kafka/opentelemetry/provider/telemetry_attributes_provider_factory.md create mode 100644 docs/docs/en/api/faststream/kafka/parser/AioKafkaBatchParser.md create mode 100644 docs/docs/en/api/faststream/kafka/parser/AioKafkaParser.md create mode 100644 docs/docs/en/api/faststream/kafka/prometheus/KafkaPrometheusMiddleware.md create mode 100644 docs/docs/en/api/faststream/kafka/prometheus/middleware/KafkaPrometheusMiddleware.md create mode 100644 docs/docs/en/api/faststream/kafka/prometheus/provider/BaseKafkaMetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/kafka/prometheus/provider/BatchKafkaMetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/kafka/prometheus/provider/KafkaMetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/kafka/prometheus/provider/settings_provider_factory.md create mode 100644 docs/docs/en/api/faststream/kafka/publisher/factory/create_publisher.md create mode 100644 docs/docs/en/api/faststream/kafka/publisher/fake/KafkaFakePublisher.md create mode 100644 docs/docs/en/api/faststream/kafka/publisher/producer/AioKafkaFastProducer.md create mode 100644 docs/docs/en/api/faststream/kafka/publisher/specified/SpecificationBatchPublisher.md create mode 100644 docs/docs/en/api/faststream/kafka/publisher/specified/SpecificationDefaultPublisher.md create mode 100644 docs/docs/en/api/faststream/kafka/publisher/specified/SpecificationPublisher.md create mode 100644 docs/docs/en/api/faststream/kafka/publisher/state/EmptyProducerState.md create mode 100644 docs/docs/en/api/faststream/kafka/publisher/state/ProducerState.md create mode 100644 docs/docs/en/api/faststream/kafka/publisher/state/RealProducer.md create mode 100644 docs/docs/en/api/faststream/kafka/publisher/usecase/BatchPublisher.md create mode 100644 docs/docs/en/api/faststream/kafka/publisher/usecase/DefaultPublisher.md create mode 100644 docs/docs/en/api/faststream/kafka/publisher/usecase/LogicPublisher.md create mode 100644 docs/docs/en/api/faststream/kafka/response/KafkaPublishCommand.md create mode 100644 docs/docs/en/api/faststream/kafka/response/KafkaResponse.md create mode 100644 docs/docs/en/api/faststream/kafka/router/KafkaPublisher.md create mode 100644 docs/docs/en/api/faststream/kafka/router/KafkaRoute.md create mode 100644 docs/docs/en/api/faststream/kafka/router/KafkaRouter.md create mode 100644 docs/docs/en/api/faststream/kafka/schemas/params/ConsumerConnectionParams.md create mode 100644 docs/docs/en/api/faststream/kafka/security/parse_security.md create mode 100644 docs/docs/en/api/faststream/kafka/subscriber/factory/create_subscriber.md create mode 100644 docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationBatchSubscriber.md create mode 100644 docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationConcurrentDefaultSubscriber.md create mode 100644 docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationDefaultSubscriber.md create mode 100644 docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationSubscriber.md create mode 100644 docs/docs/en/api/faststream/kafka/subscriber/usecase/BatchSubscriber.md create mode 100644 docs/docs/en/api/faststream/kafka/subscriber/usecase/ConcurrentDefaultSubscriber.md create mode 100644 docs/docs/en/api/faststream/kafka/subscriber/usecase/DefaultSubscriber.md create mode 100644 docs/docs/en/api/faststream/kafka/subscriber/usecase/LogicSubscriber.md create mode 100644 docs/docs/en/api/faststream/kafka/testing/FakeProducer.md create mode 100644 docs/docs/en/api/faststream/kafka/testing/TestKafkaBroker.md create mode 100644 docs/docs/en/api/faststream/kafka/testing/build_message.md create mode 100644 docs/docs/en/api/faststream/message/AckStatus.md create mode 100644 docs/docs/en/api/faststream/message/SourceType.md create mode 100644 docs/docs/en/api/faststream/message/StreamMessage.md create mode 100644 docs/docs/en/api/faststream/message/decode_message.md create mode 100644 docs/docs/en/api/faststream/message/encode_message.md create mode 100644 docs/docs/en/api/faststream/message/gen_cor_id.md create mode 100644 docs/docs/en/api/faststream/message/message/AckStatus.md create mode 100644 docs/docs/en/api/faststream/message/message/StreamMessage.md create mode 100644 docs/docs/en/api/faststream/message/source_type/SourceType.md create mode 100644 docs/docs/en/api/faststream/message/utils/decode_message.md create mode 100644 docs/docs/en/api/faststream/message/utils/encode_message.md create mode 100644 docs/docs/en/api/faststream/message/utils/gen_cor_id.md create mode 100644 docs/docs/en/api/faststream/middlewares/AckPolicy.md create mode 100644 docs/docs/en/api/faststream/middlewares/AcknowledgementMiddleware.md create mode 100644 docs/docs/en/api/faststream/middlewares/BaseMiddleware.md create mode 100644 docs/docs/en/api/faststream/middlewares/ExceptionMiddleware.md create mode 100644 docs/docs/en/api/faststream/middlewares/acknowledgement/conf/AckPolicy.md create mode 100644 docs/docs/en/api/faststream/middlewares/acknowledgement/middleware/AcknowledgementMiddleware.md create mode 100644 docs/docs/en/api/faststream/middlewares/base/BaseMiddleware.md create mode 100644 docs/docs/en/api/faststream/middlewares/exception/ExceptionMiddleware.md create mode 100644 docs/docs/en/api/faststream/middlewares/exception/ignore_handler.md create mode 100644 docs/docs/en/api/faststream/middlewares/logging/CriticalLogMiddleware.md create mode 100644 docs/docs/en/api/faststream/nats/AckPolicy.md create mode 100644 docs/docs/en/api/faststream/nats/ConsumerConfig.md create mode 100644 docs/docs/en/api/faststream/nats/DeliverPolicy.md create mode 100644 docs/docs/en/api/faststream/nats/DiscardPolicy.md create mode 100644 docs/docs/en/api/faststream/nats/ExternalStream.md create mode 100644 docs/docs/en/api/faststream/nats/JStream.md create mode 100644 docs/docs/en/api/faststream/nats/KvWatch.md create mode 100644 docs/docs/en/api/faststream/nats/NatsBroker.md create mode 100644 docs/docs/en/api/faststream/nats/NatsPublisher.md create mode 100644 docs/docs/en/api/faststream/nats/NatsResponse.md create mode 100644 docs/docs/en/api/faststream/nats/NatsRoute.md create mode 100644 docs/docs/en/api/faststream/nats/NatsRouter.md create mode 100644 docs/docs/en/api/faststream/nats/ObjWatch.md create mode 100644 docs/docs/en/api/faststream/nats/Placement.md create mode 100644 docs/docs/en/api/faststream/nats/PubAck.md create mode 100644 docs/docs/en/api/faststream/nats/PullSub.md create mode 100644 docs/docs/en/api/faststream/nats/RePublish.md create mode 100644 docs/docs/en/api/faststream/nats/ReplayPolicy.md create mode 100644 docs/docs/en/api/faststream/nats/RetentionPolicy.md create mode 100644 docs/docs/en/api/faststream/nats/StorageType.md create mode 100644 docs/docs/en/api/faststream/nats/StreamConfig.md create mode 100644 docs/docs/en/api/faststream/nats/StreamSource.md create mode 100644 docs/docs/en/api/faststream/nats/TestApp.md create mode 100644 docs/docs/en/api/faststream/nats/TestNatsBroker.md create mode 100644 docs/docs/en/api/faststream/nats/broker/NatsBroker.md create mode 100644 docs/docs/en/api/faststream/nats/broker/broker/NatsBroker.md create mode 100644 docs/docs/en/api/faststream/nats/broker/logging/NatsParamsStorage.md create mode 100644 docs/docs/en/api/faststream/nats/broker/registrator/NatsRegistrator.md create mode 100644 docs/docs/en/api/faststream/nats/broker/state/BrokerState.md create mode 100644 docs/docs/en/api/faststream/nats/broker/state/ConnectedState.md create mode 100644 docs/docs/en/api/faststream/nats/broker/state/ConnectionBrokenState.md create mode 100644 docs/docs/en/api/faststream/nats/broker/state/EmptyBrokerState.md create mode 100644 docs/docs/en/api/faststream/nats/fastapi/Context.md create mode 100644 docs/docs/en/api/faststream/nats/fastapi/NatsRouter.md create mode 100644 docs/docs/en/api/faststream/nats/fastapi/fastapi/NatsRouter.md create mode 100644 docs/docs/en/api/faststream/nats/helpers/KVBucketDeclarer.md create mode 100644 docs/docs/en/api/faststream/nats/helpers/OSBucketDeclarer.md create mode 100644 docs/docs/en/api/faststream/nats/helpers/StreamBuilder.md create mode 100644 docs/docs/en/api/faststream/nats/helpers/bucket_declarer/KVBucketDeclarer.md create mode 100644 docs/docs/en/api/faststream/nats/helpers/obj_storage_declarer/OSBucketDeclarer.md create mode 100644 docs/docs/en/api/faststream/nats/helpers/object_builder/StreamBuilder.md create mode 100644 docs/docs/en/api/faststream/nats/helpers/state/ConnectedState.md create mode 100644 docs/docs/en/api/faststream/nats/helpers/state/ConnectionState.md create mode 100644 docs/docs/en/api/faststream/nats/helpers/state/EmptyConnectionState.md create mode 100644 docs/docs/en/api/faststream/nats/message/NatsBatchMessage.md create mode 100644 docs/docs/en/api/faststream/nats/message/NatsKvMessage.md create mode 100644 docs/docs/en/api/faststream/nats/message/NatsMessage.md create mode 100644 docs/docs/en/api/faststream/nats/message/NatsObjMessage.md create mode 100644 docs/docs/en/api/faststream/nats/opentelemetry/NatsTelemetryMiddleware.md create mode 100644 docs/docs/en/api/faststream/nats/opentelemetry/middleware/NatsTelemetryMiddleware.md create mode 100644 docs/docs/en/api/faststream/nats/opentelemetry/provider/BaseNatsTelemetrySettingsProvider.md create mode 100644 docs/docs/en/api/faststream/nats/opentelemetry/provider/NatsBatchTelemetrySettingsProvider.md create mode 100644 docs/docs/en/api/faststream/nats/opentelemetry/provider/NatsTelemetrySettingsProvider.md create mode 100644 docs/docs/en/api/faststream/nats/opentelemetry/provider/telemetry_attributes_provider_factory.md create mode 100644 docs/docs/en/api/faststream/nats/parser/BatchParser.md create mode 100644 docs/docs/en/api/faststream/nats/parser/JsParser.md create mode 100644 docs/docs/en/api/faststream/nats/parser/KvParser.md create mode 100644 docs/docs/en/api/faststream/nats/parser/NatsBaseParser.md create mode 100644 docs/docs/en/api/faststream/nats/parser/NatsParser.md create mode 100644 docs/docs/en/api/faststream/nats/parser/ObjParser.md create mode 100644 docs/docs/en/api/faststream/nats/prometheus/NatsPrometheusMiddleware.md create mode 100644 docs/docs/en/api/faststream/nats/prometheus/middleware/NatsPrometheusMiddleware.md create mode 100644 docs/docs/en/api/faststream/nats/prometheus/provider/BaseNatsMetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/nats/prometheus/provider/BatchNatsMetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/nats/prometheus/provider/NatsMetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/nats/prometheus/provider/settings_provider_factory.md create mode 100644 docs/docs/en/api/faststream/nats/publisher/factory/create_publisher.md create mode 100644 docs/docs/en/api/faststream/nats/publisher/fake/NatsFakePublisher.md create mode 100644 docs/docs/en/api/faststream/nats/publisher/producer/NatsFastProducer.md create mode 100644 docs/docs/en/api/faststream/nats/publisher/producer/NatsJSFastProducer.md create mode 100644 docs/docs/en/api/faststream/nats/publisher/specified/SpecificationPublisher.md create mode 100644 docs/docs/en/api/faststream/nats/publisher/usecase/LogicPublisher.md create mode 100644 docs/docs/en/api/faststream/nats/response/NatsPublishCommand.md create mode 100644 docs/docs/en/api/faststream/nats/response/NatsResponse.md create mode 100644 docs/docs/en/api/faststream/nats/router/NatsPublisher.md create mode 100644 docs/docs/en/api/faststream/nats/router/NatsRoute.md create mode 100644 docs/docs/en/api/faststream/nats/router/NatsRouter.md create mode 100644 docs/docs/en/api/faststream/nats/schemas/JStream.md create mode 100644 docs/docs/en/api/faststream/nats/schemas/KvWatch.md create mode 100644 docs/docs/en/api/faststream/nats/schemas/ObjWatch.md create mode 100644 docs/docs/en/api/faststream/nats/schemas/PubAck.md create mode 100644 docs/docs/en/api/faststream/nats/schemas/PullSub.md create mode 100644 docs/docs/en/api/faststream/nats/schemas/js_stream/JStream.md create mode 100644 docs/docs/en/api/faststream/nats/schemas/js_stream/compile_nats_wildcard.md create mode 100644 docs/docs/en/api/faststream/nats/schemas/js_stream/is_subject_match_wildcard.md create mode 100644 docs/docs/en/api/faststream/nats/schemas/kv_watch/KvWatch.md create mode 100644 docs/docs/en/api/faststream/nats/schemas/obj_watch/ObjWatch.md create mode 100644 docs/docs/en/api/faststream/nats/schemas/pull_sub/PullSub.md create mode 100644 docs/docs/en/api/faststream/nats/security/parse_security.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/adapters/UnsubscribeAdapter.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/adapters/Unsubscriptable.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/adapters/Watchable.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/factory/create_subscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationBatchPullStreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationConcurrentCoreSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationConcurrentPullStreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationConcurrentPushStreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationCoreSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationKeyValueWatchSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationObjStoreWatchSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationPullStreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationPushStreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/state/ConnectedSubscriberState.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/state/EmptySubscriberState.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/state/SubscriberState.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/BatchPullStreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentCoreSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentPullStreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentPushStreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/CoreSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/KeyValueWatchSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/LogicSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/ObjStoreWatchSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/PullStreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/PushStreamSubscription.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/basic/DefaultSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/basic/LogicSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/core_subscriber/ConcurrentCoreSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/core_subscriber/CoreSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/key_value_subscriber/KeyValueWatchSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/object_storage_subscriber/ObjStoreWatchSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/stream_basic/StreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/BatchPullStreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/ConcurrentPullStreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/PullStreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/stream_push_subscriber/ConcurrentPushStreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/stream_push_subscriber/PushStreamSubscription.md create mode 100644 docs/docs/en/api/faststream/nats/testing/FakeProducer.md create mode 100644 docs/docs/en/api/faststream/nats/testing/PatchedMessage.md create mode 100644 docs/docs/en/api/faststream/nats/testing/TestNatsBroker.md create mode 100644 docs/docs/en/api/faststream/nats/testing/build_message.md create mode 100644 docs/docs/en/api/faststream/opentelemetry/Baggage.md create mode 100644 docs/docs/en/api/faststream/opentelemetry/TelemetryMiddleware.md create mode 100644 docs/docs/en/api/faststream/opentelemetry/TelemetrySettingsProvider.md create mode 100644 docs/docs/en/api/faststream/opentelemetry/baggage/Baggage.md create mode 100644 docs/docs/en/api/faststream/opentelemetry/consts/MessageAction.md create mode 100644 docs/docs/en/api/faststream/opentelemetry/middleware/BaseTelemetryMiddleware.md create mode 100644 docs/docs/en/api/faststream/opentelemetry/middleware/TelemetryMiddleware.md create mode 100644 docs/docs/en/api/faststream/opentelemetry/provider/TelemetrySettingsProvider.md create mode 100644 docs/docs/en/api/faststream/params/Context.md create mode 100644 docs/docs/en/api/faststream/params/Depends.md create mode 100644 docs/docs/en/api/faststream/params/Header.md create mode 100644 docs/docs/en/api/faststream/params/Path.md create mode 100644 docs/docs/en/api/faststream/params/no_cast/NoCastField.md create mode 100644 docs/docs/en/api/faststream/params/params/Context.md create mode 100644 docs/docs/en/api/faststream/params/params/Header.md create mode 100644 docs/docs/en/api/faststream/params/params/Path.md create mode 100644 docs/docs/en/api/faststream/prometheus/ConsumeAttrs.md create mode 100644 docs/docs/en/api/faststream/prometheus/MetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/prometheus/PrometheusMiddleware.md create mode 100644 docs/docs/en/api/faststream/prometheus/container/MetricsContainer.md create mode 100644 docs/docs/en/api/faststream/prometheus/manager/MetricsManager.md create mode 100644 docs/docs/en/api/faststream/prometheus/middleware/BasePrometheusMiddleware.md create mode 100644 docs/docs/en/api/faststream/prometheus/middleware/PrometheusMiddleware.md create mode 100644 docs/docs/en/api/faststream/prometheus/provider/MetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/prometheus/types/ConsumeAttrs.md create mode 100644 docs/docs/en/api/faststream/prometheus/types/ProcessingStatus.md create mode 100644 docs/docs/en/api/faststream/prometheus/types/PublishingStatus.md create mode 100644 docs/docs/en/api/faststream/rabbit/ExchangeType.md create mode 100644 docs/docs/en/api/faststream/rabbit/RabbitBroker.md create mode 100644 docs/docs/en/api/faststream/rabbit/RabbitExchange.md create mode 100644 docs/docs/en/api/faststream/rabbit/RabbitPublisher.md create mode 100644 docs/docs/en/api/faststream/rabbit/RabbitQueue.md create mode 100644 docs/docs/en/api/faststream/rabbit/RabbitResponse.md create mode 100644 docs/docs/en/api/faststream/rabbit/RabbitRoute.md create mode 100644 docs/docs/en/api/faststream/rabbit/RabbitRouter.md create mode 100644 docs/docs/en/api/faststream/rabbit/TestApp.md create mode 100644 docs/docs/en/api/faststream/rabbit/TestRabbitBroker.md create mode 100644 docs/docs/en/api/faststream/rabbit/broker/RabbitBroker.md create mode 100644 docs/docs/en/api/faststream/rabbit/broker/broker/RabbitBroker.md create mode 100644 docs/docs/en/api/faststream/rabbit/broker/logging/RabbitParamsStorage.md create mode 100644 docs/docs/en/api/faststream/rabbit/broker/registrator/RabbitRegistrator.md create mode 100644 docs/docs/en/api/faststream/rabbit/fastapi/Context.md create mode 100644 docs/docs/en/api/faststream/rabbit/fastapi/RabbitRouter.md create mode 100644 docs/docs/en/api/faststream/rabbit/fastapi/fastapi/RabbitRouter.md create mode 100644 docs/docs/en/api/faststream/rabbit/helpers/declarer/RabbitDeclarer.md create mode 100644 docs/docs/en/api/faststream/rabbit/helpers/state/ConnectedState.md create mode 100644 docs/docs/en/api/faststream/rabbit/helpers/state/ConnectionState.md create mode 100644 docs/docs/en/api/faststream/rabbit/helpers/state/EmptyConnectionState.md create mode 100644 docs/docs/en/api/faststream/rabbit/message/RabbitMessage.md create mode 100644 docs/docs/en/api/faststream/rabbit/opentelemetry/RabbitTelemetryMiddleware.md create mode 100644 docs/docs/en/api/faststream/rabbit/opentelemetry/middleware/RabbitTelemetryMiddleware.md create mode 100644 docs/docs/en/api/faststream/rabbit/opentelemetry/provider/RabbitTelemetrySettingsProvider.md create mode 100644 docs/docs/en/api/faststream/rabbit/parser/AioPikaParser.md create mode 100644 docs/docs/en/api/faststream/rabbit/prometheus/RabbitPrometheusMiddleware.md create mode 100644 docs/docs/en/api/faststream/rabbit/prometheus/middleware/RabbitPrometheusMiddleware.md create mode 100644 docs/docs/en/api/faststream/rabbit/prometheus/provider/RabbitMetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/rabbit/publisher/factory/create_publisher.md create mode 100644 docs/docs/en/api/faststream/rabbit/publisher/fake/RabbitFakePublisher.md create mode 100644 docs/docs/en/api/faststream/rabbit/publisher/options/MessageOptions.md create mode 100644 docs/docs/en/api/faststream/rabbit/publisher/options/PublishOptions.md create mode 100644 docs/docs/en/api/faststream/rabbit/publisher/producer/AioPikaFastProducer.md create mode 100644 docs/docs/en/api/faststream/rabbit/publisher/producer/LockState.md create mode 100644 docs/docs/en/api/faststream/rabbit/publisher/producer/LockUnset.md create mode 100644 docs/docs/en/api/faststream/rabbit/publisher/producer/RealLock.md create mode 100644 docs/docs/en/api/faststream/rabbit/publisher/specified/SpecificationPublisher.md create mode 100644 docs/docs/en/api/faststream/rabbit/publisher/usecase/LogicPublisher.md create mode 100644 docs/docs/en/api/faststream/rabbit/publisher/usecase/PublishKwargs.md create mode 100644 docs/docs/en/api/faststream/rabbit/publisher/usecase/RequestPublishKwargs.md create mode 100644 docs/docs/en/api/faststream/rabbit/response/RabbitPublishCommand.md create mode 100644 docs/docs/en/api/faststream/rabbit/response/RabbitResponse.md create mode 100644 docs/docs/en/api/faststream/rabbit/router/RabbitPublisher.md create mode 100644 docs/docs/en/api/faststream/rabbit/router/RabbitRoute.md create mode 100644 docs/docs/en/api/faststream/rabbit/router/RabbitRouter.md create mode 100644 docs/docs/en/api/faststream/rabbit/schemas/BaseRMQInformation.md create mode 100644 docs/docs/en/api/faststream/rabbit/schemas/ExchangeType.md create mode 100644 docs/docs/en/api/faststream/rabbit/schemas/RabbitExchange.md create mode 100644 docs/docs/en/api/faststream/rabbit/schemas/RabbitQueue.md create mode 100644 docs/docs/en/api/faststream/rabbit/schemas/constants/ExchangeType.md create mode 100644 docs/docs/en/api/faststream/rabbit/schemas/exchange/RabbitExchange.md create mode 100644 docs/docs/en/api/faststream/rabbit/schemas/proto/BaseRMQInformation.md create mode 100644 docs/docs/en/api/faststream/rabbit/schemas/queue/RabbitQueue.md create mode 100644 docs/docs/en/api/faststream/rabbit/security/parse_security.md create mode 100644 docs/docs/en/api/faststream/rabbit/subscriber/factory/create_subscriber.md create mode 100644 docs/docs/en/api/faststream/rabbit/subscriber/specified/SpecificationSubscriber.md create mode 100644 docs/docs/en/api/faststream/rabbit/subscriber/usecase/LogicSubscriber.md create mode 100644 docs/docs/en/api/faststream/rabbit/testing/FakeProducer.md create mode 100644 docs/docs/en/api/faststream/rabbit/testing/PatchedMessage.md create mode 100644 docs/docs/en/api/faststream/rabbit/testing/TestRabbitBroker.md create mode 100644 docs/docs/en/api/faststream/rabbit/testing/apply_pattern.md create mode 100644 docs/docs/en/api/faststream/rabbit/testing/build_message.md create mode 100644 docs/docs/en/api/faststream/rabbit/utils/build_url.md create mode 100644 docs/docs/en/api/faststream/rabbit/utils/is_routing_exchange.md create mode 100644 docs/docs/en/api/faststream/redis/ListSub.md create mode 100644 docs/docs/en/api/faststream/redis/PubSub.md create mode 100644 docs/docs/en/api/faststream/redis/RedisBroker.md create mode 100644 docs/docs/en/api/faststream/redis/RedisPublisher.md create mode 100644 docs/docs/en/api/faststream/redis/RedisResponse.md create mode 100644 docs/docs/en/api/faststream/redis/RedisRoute.md create mode 100644 docs/docs/en/api/faststream/redis/RedisRouter.md create mode 100644 docs/docs/en/api/faststream/redis/StreamSub.md create mode 100644 docs/docs/en/api/faststream/redis/TestApp.md create mode 100644 docs/docs/en/api/faststream/redis/TestRedisBroker.md create mode 100644 docs/docs/en/api/faststream/redis/broker/broker/RedisBroker.md create mode 100644 docs/docs/en/api/faststream/redis/broker/logging/RedisParamsStorage.md create mode 100644 docs/docs/en/api/faststream/redis/broker/registrator/RedisRegistrator.md create mode 100644 docs/docs/en/api/faststream/redis/fastapi/Context.md create mode 100644 docs/docs/en/api/faststream/redis/fastapi/RedisRouter.md create mode 100644 docs/docs/en/api/faststream/redis/fastapi/fastapi/RedisRouter.md create mode 100644 docs/docs/en/api/faststream/redis/helpers/state/ConnectedState.md create mode 100644 docs/docs/en/api/faststream/redis/helpers/state/ConnectionState.md create mode 100644 docs/docs/en/api/faststream/redis/helpers/state/EmptyConnectionState.md create mode 100644 docs/docs/en/api/faststream/redis/message/BatchListMessage.md create mode 100644 docs/docs/en/api/faststream/redis/message/BatchStreamMessage.md create mode 100644 docs/docs/en/api/faststream/redis/message/DefaultListMessage.md create mode 100644 docs/docs/en/api/faststream/redis/message/DefaultStreamMessage.md create mode 100644 docs/docs/en/api/faststream/redis/message/PubSubMessage.md create mode 100644 docs/docs/en/api/faststream/redis/message/RedisBatchListMessage.md create mode 100644 docs/docs/en/api/faststream/redis/message/RedisBatchStreamMessage.md create mode 100644 docs/docs/en/api/faststream/redis/message/RedisListMessage.md create mode 100644 docs/docs/en/api/faststream/redis/message/RedisMessage.md create mode 100644 docs/docs/en/api/faststream/redis/message/RedisStreamMessage.md create mode 100644 docs/docs/en/api/faststream/redis/message/UnifyRedisDict.md create mode 100644 docs/docs/en/api/faststream/redis/message/UnifyRedisMessage.md create mode 100644 docs/docs/en/api/faststream/redis/opentelemetry/RedisTelemetryMiddleware.md create mode 100644 docs/docs/en/api/faststream/redis/opentelemetry/middleware/RedisTelemetryMiddleware.md create mode 100644 docs/docs/en/api/faststream/redis/opentelemetry/provider/RedisTelemetrySettingsProvider.md create mode 100644 docs/docs/en/api/faststream/redis/parser/RawMessage.md create mode 100644 docs/docs/en/api/faststream/redis/parser/RedisBatchListParser.md create mode 100644 docs/docs/en/api/faststream/redis/parser/RedisBatchStreamParser.md create mode 100644 docs/docs/en/api/faststream/redis/parser/RedisListParser.md create mode 100644 docs/docs/en/api/faststream/redis/parser/RedisPubSubParser.md create mode 100644 docs/docs/en/api/faststream/redis/parser/RedisStreamParser.md create mode 100644 docs/docs/en/api/faststream/redis/parser/SimpleParser.md create mode 100644 docs/docs/en/api/faststream/redis/prometheus/RedisPrometheusMiddleware.md create mode 100644 docs/docs/en/api/faststream/redis/prometheus/middleware/RedisPrometheusMiddleware.md create mode 100644 docs/docs/en/api/faststream/redis/prometheus/provider/BaseRedisMetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/redis/prometheus/provider/BatchRedisMetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/redis/prometheus/provider/RedisMetricsSettingsProvider.md create mode 100644 docs/docs/en/api/faststream/redis/prometheus/provider/settings_provider_factory.md create mode 100644 docs/docs/en/api/faststream/redis/publisher/factory/create_publisher.md create mode 100644 docs/docs/en/api/faststream/redis/publisher/fake/RedisFakePublisher.md create mode 100644 docs/docs/en/api/faststream/redis/publisher/producer/RedisFastProducer.md create mode 100644 docs/docs/en/api/faststream/redis/publisher/specified/SpecificationChannelPublisher.md create mode 100644 docs/docs/en/api/faststream/redis/publisher/specified/SpecificationListBatchPublisher.md create mode 100644 docs/docs/en/api/faststream/redis/publisher/specified/SpecificationListPublisher.md create mode 100644 docs/docs/en/api/faststream/redis/publisher/specified/SpecificationPublisher.md create mode 100644 docs/docs/en/api/faststream/redis/publisher/specified/SpecificationStreamPublisher.md create mode 100644 docs/docs/en/api/faststream/redis/publisher/usecase/ChannelPublisher.md create mode 100644 docs/docs/en/api/faststream/redis/publisher/usecase/ListBatchPublisher.md create mode 100644 docs/docs/en/api/faststream/redis/publisher/usecase/ListPublisher.md create mode 100644 docs/docs/en/api/faststream/redis/publisher/usecase/LogicPublisher.md create mode 100644 docs/docs/en/api/faststream/redis/publisher/usecase/StreamPublisher.md create mode 100644 docs/docs/en/api/faststream/redis/response/DestinationType.md create mode 100644 docs/docs/en/api/faststream/redis/response/RedisPublishCommand.md create mode 100644 docs/docs/en/api/faststream/redis/response/RedisResponse.md create mode 100644 docs/docs/en/api/faststream/redis/router/RedisPublisher.md create mode 100644 docs/docs/en/api/faststream/redis/router/RedisRoute.md create mode 100644 docs/docs/en/api/faststream/redis/router/RedisRouter.md create mode 100644 docs/docs/en/api/faststream/redis/schemas/ListSub.md create mode 100644 docs/docs/en/api/faststream/redis/schemas/PubSub.md create mode 100644 docs/docs/en/api/faststream/redis/schemas/StreamSub.md create mode 100644 docs/docs/en/api/faststream/redis/schemas/list_sub/ListSub.md create mode 100644 docs/docs/en/api/faststream/redis/schemas/proto/RedisSpecificationProtocol.md create mode 100644 docs/docs/en/api/faststream/redis/schemas/proto/validate_options.md create mode 100644 docs/docs/en/api/faststream/redis/schemas/pub_sub/PubSub.md create mode 100644 docs/docs/en/api/faststream/redis/schemas/stream_sub/StreamSub.md create mode 100644 docs/docs/en/api/faststream/redis/security/parse_security.md create mode 100644 docs/docs/en/api/faststream/redis/subscriber/factory/create_subscriber.md create mode 100644 docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationChannelSubscriber.md create mode 100644 docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationListBatchSubscriber.md create mode 100644 docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationListSubscriber.md create mode 100644 docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationStreamBatchSubscriber.md create mode 100644 docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationStreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationSubscriber.md create mode 100644 docs/docs/en/api/faststream/redis/subscriber/usecase/BatchListSubscriber.md create mode 100644 docs/docs/en/api/faststream/redis/subscriber/usecase/ChannelSubscriber.md create mode 100644 docs/docs/en/api/faststream/redis/subscriber/usecase/ListSubscriber.md create mode 100644 docs/docs/en/api/faststream/redis/subscriber/usecase/LogicSubscriber.md create mode 100644 docs/docs/en/api/faststream/redis/subscriber/usecase/StreamBatchSubscriber.md create mode 100644 docs/docs/en/api/faststream/redis/subscriber/usecase/StreamSubscriber.md create mode 100644 docs/docs/en/api/faststream/redis/testing/ChannelVisitor.md create mode 100644 docs/docs/en/api/faststream/redis/testing/FakeProducer.md create mode 100644 docs/docs/en/api/faststream/redis/testing/ListVisitor.md create mode 100644 docs/docs/en/api/faststream/redis/testing/StreamVisitor.md create mode 100644 docs/docs/en/api/faststream/redis/testing/TestRedisBroker.md create mode 100644 docs/docs/en/api/faststream/redis/testing/Visitor.md create mode 100644 docs/docs/en/api/faststream/redis/testing/build_message.md create mode 100644 docs/docs/en/api/faststream/response/PublishCommand.md create mode 100644 docs/docs/en/api/faststream/response/PublishType.md create mode 100644 docs/docs/en/api/faststream/response/Response.md create mode 100644 docs/docs/en/api/faststream/response/ensure_response.md create mode 100644 docs/docs/en/api/faststream/response/publish_type/PublishType.md create mode 100644 docs/docs/en/api/faststream/response/response/PublishCommand.md create mode 100644 docs/docs/en/api/faststream/response/response/Response.md create mode 100644 docs/docs/en/api/faststream/response/utils/ensure_response.md create mode 100644 docs/docs/en/api/faststream/security/BaseSecurity.md create mode 100644 docs/docs/en/api/faststream/security/SASLGSSAPI.md create mode 100644 docs/docs/en/api/faststream/security/SASLOAuthBearer.md create mode 100644 docs/docs/en/api/faststream/security/SASLPlaintext.md create mode 100644 docs/docs/en/api/faststream/security/SASLScram256.md create mode 100644 docs/docs/en/api/faststream/security/SASLScram512.md create mode 100644 docs/docs/en/api/faststream/specification/AsyncAPI.md create mode 100644 docs/docs/en/api/faststream/specification/Contact.md create mode 100644 docs/docs/en/api/faststream/specification/ExternalDocs.md create mode 100644 docs/docs/en/api/faststream/specification/License.md create mode 100644 docs/docs/en/api/faststream/specification/Tag.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/AsyncAPI.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/factory/AsyncAPI.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/get_asyncapi_html.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/message/get_model_schema.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/message/get_response_schema.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/message/parse_handler_params.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/site/get_asyncapi_html.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/site/serve_app.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/utils/clear_key.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/utils/move_pydantic_refs.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/utils/resolve_payloads.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/utils/to_camelcase.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/AsyncAPI2.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/facade/AsyncAPI2.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_app_schema.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_channels.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_server.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/resolve_channel_messages.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/get_app_schema.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ApplicationInfo.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ApplicationSchema.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Channel.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Components.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Contact.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/CorrelationId.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ExternalDocs.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/License.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Message.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Operation.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Parameter.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Reference.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Server.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ServerVariable.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Tag.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Exchange.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Queue.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/from_spec.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channels/Channel.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/components/Components.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact/Contact.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs/ExternalDocs.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/info/ApplicationInfo.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license/License.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/CorrelationId.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/Message.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operations/Operation.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/schema/ApplicationSchema.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/servers/Server.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/servers/ServerVariable.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag/Tag.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/utils/Parameter.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/utils/Reference.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/AsyncAPI3.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/facade/AsyncAPI3.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_app_schema.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_channels.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_server.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/get_app_schema.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationInfo.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationSchema.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Channel.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Components.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Contact.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/CorrelationId.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ExternalDocs.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/License.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Message.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Operation.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Parameter.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Reference.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Server.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ServerVariable.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Tag.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channels/Channel.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/components/Components.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/contact/Contact.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/docs/ExternalDocs.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/info/ApplicationInfo.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/license/License.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/message/CorrelationId.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/message/Message.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/Action.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/Operation.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/schema/ApplicationSchema.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/servers/Server.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/tag/Tag.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/utils/Parameter.md create mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/utils/Reference.md create mode 100644 docs/docs/en/api/faststream/specification/base/info/BaseApplicationInfo.md create mode 100644 docs/docs/en/api/faststream/specification/base/schema/BaseApplicationSchema.md create mode 100644 docs/docs/en/api/faststream/specification/base/specification/Specification.md create mode 100644 docs/docs/en/api/faststream/specification/proto/EndpointSpecification.md create mode 100644 docs/docs/en/api/faststream/specification/proto/ServerSpecification.md create mode 100644 docs/docs/en/api/faststream/specification/proto/broker/ServerSpecification.md create mode 100644 docs/docs/en/api/faststream/specification/proto/endpoint/EndpointSpecification.md create mode 100644 docs/docs/en/api/faststream/specification/schema/Contact.md create mode 100644 docs/docs/en/api/faststream/specification/schema/ContactDict.md create mode 100644 docs/docs/en/api/faststream/specification/schema/ExternalDocs.md create mode 100644 docs/docs/en/api/faststream/specification/schema/ExternalDocsDict.md create mode 100644 docs/docs/en/api/faststream/specification/schema/License.md create mode 100644 docs/docs/en/api/faststream/specification/schema/LicenseDict.md create mode 100644 docs/docs/en/api/faststream/specification/schema/Message.md create mode 100644 docs/docs/en/api/faststream/specification/schema/Operation.md create mode 100644 docs/docs/en/api/faststream/specification/schema/PublisherSpec.md create mode 100644 docs/docs/en/api/faststream/specification/schema/SubscriberSpec.md create mode 100644 docs/docs/en/api/faststream/specification/schema/Tag.md create mode 100644 docs/docs/en/api/faststream/specification/schema/TagDict.md create mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/amqp/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/amqp/Exchange.md create mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/amqp/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/amqp/Queue.md create mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/kafka/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/kafka/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/main/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/main/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/nats/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/nats/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/redis/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/redis/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/sqs/ChannelBinding.md create mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/sqs/OperationBinding.md create mode 100644 docs/docs/en/api/faststream/specification/schema/extra/Contact.md create mode 100644 docs/docs/en/api/faststream/specification/schema/extra/ContactDict.md create mode 100644 docs/docs/en/api/faststream/specification/schema/extra/ExternalDocs.md create mode 100644 docs/docs/en/api/faststream/specification/schema/extra/ExternalDocsDict.md create mode 100644 docs/docs/en/api/faststream/specification/schema/extra/License.md create mode 100644 docs/docs/en/api/faststream/specification/schema/extra/LicenseDict.md create mode 100644 docs/docs/en/api/faststream/specification/schema/extra/Tag.md create mode 100644 docs/docs/en/api/faststream/specification/schema/extra/TagDict.md create mode 100644 docs/docs/en/api/faststream/specification/schema/extra/contact/Contact.md create mode 100644 docs/docs/en/api/faststream/specification/schema/extra/contact/ContactDict.md create mode 100644 docs/docs/en/api/faststream/specification/schema/extra/external_docs/ExternalDocs.md create mode 100644 docs/docs/en/api/faststream/specification/schema/extra/external_docs/ExternalDocsDict.md create mode 100644 docs/docs/en/api/faststream/specification/schema/extra/license/License.md create mode 100644 docs/docs/en/api/faststream/specification/schema/extra/license/LicenseDict.md create mode 100644 docs/docs/en/api/faststream/specification/schema/extra/tag/Tag.md create mode 100644 docs/docs/en/api/faststream/specification/schema/extra/tag/TagDict.md create mode 100644 docs/docs/en/api/faststream/specification/schema/message/Message.md create mode 100644 docs/docs/en/api/faststream/specification/schema/message/model/Message.md create mode 100644 docs/docs/en/api/faststream/specification/schema/operation/Operation.md create mode 100644 docs/docs/en/api/faststream/specification/schema/operation/model/Operation.md create mode 100644 docs/docs/en/api/faststream/specification/schema/publisher/PublisherSpec.md create mode 100644 docs/docs/en/api/faststream/specification/schema/subscriber/SubscriberSpec.md diff --git a/docs/docs/SUMMARY.md b/docs/docs/SUMMARY.md new file mode 100644 index 0000000000..a859135d0e --- /dev/null +++ b/docs/docs/SUMMARY.md @@ -0,0 +1,1276 @@ +--- +search: + exclude: true +--- +- [Features](faststream.md) +- Tutorial + - [Getting Started](getting-started/index.md) + - [Subscription and Serialization](getting-started/subscription/index.md) + - [Annotation Serialization](getting-started/subscription/annotation.md) + - [Pydantic Serialization](getting-started/subscription/pydantic.md) + - [Filtering](getting-started/subscription/filtering.md) + - [Testing](getting-started/subscription/test.md) + - [Publishing](getting-started/publishing/index.md) + - [Broker Publish](getting-started/publishing/broker.md) + - [Decorator](getting-started/publishing/decorator.md) + - [Object Decorator](getting-started/publishing/object.md) + - [Direct Publishing](getting-started/publishing/direct.md) + - [Testing](getting-started/publishing/test.md) + - [Routers](getting-started/routers/index.md) + - [Dependencies](getting-started/dependencies/index.md) + - [Context](getting-started/context/index.md) + - [Existing Fields](getting-started/context/existed.md) + - [Custom Context](getting-started/context/custom.md) + - [Fields Access](getting-started/context/fields.md) + - [Extra Options](getting-started/context/extra.md) + - [Custom Serialization](getting-started/serialization/index.md) + - [Parser](getting-started/serialization/parser.md) + - [Decoder](getting-started/serialization/decoder.md) + - [Examples](getting-started/serialization/examples.md) + - [Lifespan](getting-started/lifespan/index.md) + - [Hooks](getting-started/lifespan/hooks.md) + - [Context](getting-started/lifespan/context.md) + - [Testing](getting-started/lifespan/test.md) + - [Middlewares](getting-started/middlewares/index.md) + - [Exception Middleware](getting-started/middlewares/exception.md) + - AsyncAPI + - [Schema Export](getting-started/asyncapi/export.md) + - [Schema Hosting](getting-started/asyncapi/hosting.md) + - [Customize Information](getting-started/asyncapi/custom.md) + - Integrations + - [HTTP Async Frameworks](getting-started/integrations/frameworks/index.md) + - [FastAPI Plugin](getting-started/integrations/fastapi/index.md) + - [Django](getting-started/integrations/django/index.md) + - [CLI](getting-started/cli/index.md) + - [ASGI](getting-started/asgi.md) + - [OpenTelemetry](getting-started/opentelemetry/index.md) + - [Prometheus](getting-started/prometheus/index.md) + - [Logging](getting-started/logging.md) + - [Config Management](getting-started/config/index.md) + - [Task Scheduling](scheduling.md) + - [FastStream Project Template](getting-started/template/index.md) +- [Kafka](kafka/kafka.md) + - [AIOKafka](kafka/index.md) + - [Subscription](kafka/Subscriber/index.md) + - [Batch Subscriber](kafka/Subscriber/batch_subscriber.md) + - [Publishing](kafka/Publisher/index.md) + - [Batch Publishing](kafka/Publisher/batch_publisher.md) + - [Publish With Key](kafka/Publisher/using_a_key.md) + - [Acknowledgement](kafka/ack.md) + - [Message Information](kafka/message.md) + - [Security Configuration](kafka/security.md) + - [Confluent](confluent/index.md) + - [Subscription](confluent/Subscriber/index.md) + - [Batch Subscriber](confluent/Subscriber/batch_subscriber.md) + - [Publishing](confluent/Publisher/index.md) + - [Batch Publishing](confluent/Publisher/batch_publisher.md) + - [Publish With Key](confluent/Publisher/using_a_key.md) + - [Acknowledgement](confluent/ack.md) + - [Message Information](confluent/message.md) + - [Security Configuration](confluent/security.md) + - [Additional Configuration](confluent/additional-configuration.md) + - [How-To](howto/kafka/index.md) + - [Kafka RPC](howto/kafka/rpc.md) +- [RabbitMQ](rabbit/index.md) + - [Subscription](rabbit/examples/index.md) + - [Direct](rabbit/examples/direct.md) + - [Fanout](rabbit/examples/fanout.md) + - [Topic](rabbit/examples/topic.md) + - [Headers](rabbit/examples/headers.md) + - [Stream](rabbit/examples/stream.md) + - [Publishing](rabbit/publishing.md) + - [RPC](rabbit/rpc.md) + - [Acknowledgement](rabbit/ack.md) + - [Declare Queue/Exchange](rabbit/declare.md) + - [Message Information](rabbit/message.md) + - [Security Configuration](rabbit/security.md) +- [NATS](nats/index.md) + - Subscription + - [Direct](nats/examples/direct.md) + - [Pattern](nats/examples/pattern.md) + - [JetStream](nats/jetstream/index.md) + - [Pull Subscriber](nats/jetstream/pull.md) + - [Key-Value Storage](nats/jetstream/key-value.md) + - [Object Storage](nats/jetstream/object.md) + - [Acknowledgement](nats/jetstream/ack.md) + - [Publishing](nats/publishing/index.md) + - [RPC](nats/rpc.md) + - [Message Information](nats/message.md) + - [How-To](howto/nats/index.md) + - [DynaConf](howto/nats/dynaconf.md) + - [In-Progess](howto/nats/in-progress.md) +- [Redis](redis/index.md) + - [Pub/Sub](redis/pubsub/index.md) + - [Subscription](redis/pubsub/subscription.md) + - [Publishing](redis/pubsub/publishing.md) + - [List](redis/list/index.md) + - [Subscription](redis/list/subscription.md) + - [Publishing](redis/list/publishing.md) + - [Batching](redis/list/batch.md) + - [Streams](redis/streams/index.md) + - [Subscription](redis/streams/subscription.md) + - [Publishing](redis/streams/publishing.md) + - [Groups](redis/streams/groups.md) + - [Batching](redis/streams/batch.md) + - [Acknowledgement](redis/streams/ack.md) + - [RPC](redis/rpc.md) + - [Message Information](redis/message.md) + - [Security Configuration](redis/security.md) +- [Reference - Code API](api/index.md) + - Public API + - faststream + - [AckPolicy](public_api/faststream/AckPolicy.md) + - [BaseMiddleware](public_api/faststream/BaseMiddleware.md) + - [Context](public_api/faststream/Context.md) + - [Depends](public_api/faststream/Depends.md) + - [ExceptionMiddleware](public_api/faststream/ExceptionMiddleware.md) + - [FastStream](public_api/faststream/FastStream.md) + - [Header](public_api/faststream/Header.md) + - [Path](public_api/faststream/Path.md) + - [Response](public_api/faststream/Response.md) + - [TestApp](public_api/faststream/TestApp.md) + - [apply_types](public_api/faststream/apply_types.md) + - asgi + - [AsgiFastStream](public_api/faststream/asgi/AsgiFastStream.md) + - [AsgiResponse](public_api/faststream/asgi/AsgiResponse.md) + - [get](public_api/faststream/asgi/get.md) + - [make_asyncapi_asgi](public_api/faststream/asgi/make_asyncapi_asgi.md) + - [make_ping_asgi](public_api/faststream/asgi/make_ping_asgi.md) + - confluent + - [KafkaBroker](public_api/faststream/confluent/KafkaBroker.md) + - [KafkaPublisher](public_api/faststream/confluent/KafkaPublisher.md) + - [KafkaResponse](public_api/faststream/confluent/KafkaResponse.md) + - [KafkaRoute](public_api/faststream/confluent/KafkaRoute.md) + - [KafkaRouter](public_api/faststream/confluent/KafkaRouter.md) + - [TestApp](public_api/faststream/confluent/TestApp.md) + - [TestKafkaBroker](public_api/faststream/confluent/TestKafkaBroker.md) + - [TopicPartition](public_api/faststream/confluent/TopicPartition.md) + - kafka + - [KafkaBroker](public_api/faststream/kafka/KafkaBroker.md) + - [KafkaPublisher](public_api/faststream/kafka/KafkaPublisher.md) + - [KafkaResponse](public_api/faststream/kafka/KafkaResponse.md) + - [KafkaRoute](public_api/faststream/kafka/KafkaRoute.md) + - [KafkaRouter](public_api/faststream/kafka/KafkaRouter.md) + - [TestApp](public_api/faststream/kafka/TestApp.md) + - [TestKafkaBroker](public_api/faststream/kafka/TestKafkaBroker.md) + - [TopicPartition](public_api/faststream/kafka/TopicPartition.md) + - nats + - [AckPolicy](public_api/faststream/nats/AckPolicy.md) + - [ConsumerConfig](public_api/faststream/nats/ConsumerConfig.md) + - [DeliverPolicy](public_api/faststream/nats/DeliverPolicy.md) + - [DiscardPolicy](public_api/faststream/nats/DiscardPolicy.md) + - [ExternalStream](public_api/faststream/nats/ExternalStream.md) + - [JStream](public_api/faststream/nats/JStream.md) + - [KvWatch](public_api/faststream/nats/KvWatch.md) + - [NatsBroker](public_api/faststream/nats/NatsBroker.md) + - [NatsPublisher](public_api/faststream/nats/NatsPublisher.md) + - [NatsResponse](public_api/faststream/nats/NatsResponse.md) + - [NatsRoute](public_api/faststream/nats/NatsRoute.md) + - [NatsRouter](public_api/faststream/nats/NatsRouter.md) + - [ObjWatch](public_api/faststream/nats/ObjWatch.md) + - [Placement](public_api/faststream/nats/Placement.md) + - [PubAck](public_api/faststream/nats/PubAck.md) + - [PullSub](public_api/faststream/nats/PullSub.md) + - [RePublish](public_api/faststream/nats/RePublish.md) + - [ReplayPolicy](public_api/faststream/nats/ReplayPolicy.md) + - [RetentionPolicy](public_api/faststream/nats/RetentionPolicy.md) + - [StorageType](public_api/faststream/nats/StorageType.md) + - [StreamConfig](public_api/faststream/nats/StreamConfig.md) + - [StreamSource](public_api/faststream/nats/StreamSource.md) + - [TestApp](public_api/faststream/nats/TestApp.md) + - [TestNatsBroker](public_api/faststream/nats/TestNatsBroker.md) + - opentelemetry + - [Baggage](public_api/faststream/opentelemetry/Baggage.md) + - [TelemetryMiddleware](public_api/faststream/opentelemetry/TelemetryMiddleware.md) + - [TelemetrySettingsProvider](public_api/faststream/opentelemetry/TelemetrySettingsProvider.md) + - rabbit + - [ExchangeType](public_api/faststream/rabbit/ExchangeType.md) + - [RabbitBroker](public_api/faststream/rabbit/RabbitBroker.md) + - [RabbitExchange](public_api/faststream/rabbit/RabbitExchange.md) + - [RabbitPublisher](public_api/faststream/rabbit/RabbitPublisher.md) + - [RabbitQueue](public_api/faststream/rabbit/RabbitQueue.md) + - [RabbitResponse](public_api/faststream/rabbit/RabbitResponse.md) + - [RabbitRoute](public_api/faststream/rabbit/RabbitRoute.md) + - [RabbitRouter](public_api/faststream/rabbit/RabbitRouter.md) + - [TestApp](public_api/faststream/rabbit/TestApp.md) + - [TestRabbitBroker](public_api/faststream/rabbit/TestRabbitBroker.md) + - redis + - [ListSub](public_api/faststream/redis/ListSub.md) + - [PubSub](public_api/faststream/redis/PubSub.md) + - [RedisBroker](public_api/faststream/redis/RedisBroker.md) + - [RedisPublisher](public_api/faststream/redis/RedisPublisher.md) + - [RedisResponse](public_api/faststream/redis/RedisResponse.md) + - [RedisRoute](public_api/faststream/redis/RedisRoute.md) + - [RedisRouter](public_api/faststream/redis/RedisRouter.md) + - [StreamSub](public_api/faststream/redis/StreamSub.md) + - [TestApp](public_api/faststream/redis/TestApp.md) + - [TestRedisBroker](public_api/faststream/redis/TestRedisBroker.md) + - All API + - faststream + - [AckPolicy](api/faststream/AckPolicy.md) + - [BaseMiddleware](api/faststream/BaseMiddleware.md) + - [Context](api/faststream/Context.md) + - [Depends](api/faststream/Depends.md) + - [ExceptionMiddleware](api/faststream/ExceptionMiddleware.md) + - [FastStream](api/faststream/FastStream.md) + - [Header](api/faststream/Header.md) + - [Path](api/faststream/Path.md) + - [Response](api/faststream/Response.md) + - [TestApp](api/faststream/TestApp.md) + - [apply_types](api/faststream/apply_types.md) + - app + - [FastStream](api/faststream/app/FastStream.md) + - asgi + - [AsgiFastStream](api/faststream/asgi/AsgiFastStream.md) + - [AsgiResponse](api/faststream/asgi/AsgiResponse.md) + - [get](api/faststream/asgi/get.md) + - [make_asyncapi_asgi](api/faststream/asgi/make_asyncapi_asgi.md) + - [make_ping_asgi](api/faststream/asgi/make_ping_asgi.md) + - app + - [AsgiFastStream](api/faststream/asgi/app/AsgiFastStream.md) + - [CliRunState](api/faststream/asgi/app/CliRunState.md) + - [OuterRunState](api/faststream/asgi/app/OuterRunState.md) + - [ServerState](api/faststream/asgi/app/ServerState.md) + - [cast_uvicorn_params](api/faststream/asgi/app/cast_uvicorn_params.md) + - factories + - [make_asyncapi_asgi](api/faststream/asgi/factories/make_asyncapi_asgi.md) + - [make_ping_asgi](api/faststream/asgi/factories/make_ping_asgi.md) + - handlers + - [get](api/faststream/asgi/handlers/get.md) + - response + - [AsgiResponse](api/faststream/asgi/response/AsgiResponse.md) + - websocket + - [WebSocketClose](api/faststream/asgi/websocket/WebSocketClose.md) + - confluent + - [KafkaBroker](api/faststream/confluent/KafkaBroker.md) + - [KafkaPublisher](api/faststream/confluent/KafkaPublisher.md) + - [KafkaResponse](api/faststream/confluent/KafkaResponse.md) + - [KafkaRoute](api/faststream/confluent/KafkaRoute.md) + - [KafkaRouter](api/faststream/confluent/KafkaRouter.md) + - [TestApp](api/faststream/confluent/TestApp.md) + - [TestKafkaBroker](api/faststream/confluent/TestKafkaBroker.md) + - [TopicPartition](api/faststream/confluent/TopicPartition.md) + - broker + - [KafkaBroker](api/faststream/confluent/broker/KafkaBroker.md) + - broker + - [KafkaBroker](api/faststream/confluent/broker/broker/KafkaBroker.md) + - logging + - [KafkaParamsStorage](api/faststream/confluent/broker/logging/KafkaParamsStorage.md) + - registrator + - [KafkaRegistrator](api/faststream/confluent/broker/registrator/KafkaRegistrator.md) + - client + - [AsyncConfluentConsumer](api/faststream/confluent/client/AsyncConfluentConsumer.md) + - [AsyncConfluentProducer](api/faststream/confluent/client/AsyncConfluentProducer.md) + - [BatchBuilder](api/faststream/confluent/client/BatchBuilder.md) + - [check_msg_error](api/faststream/confluent/client/check_msg_error.md) + - [create_topics](api/faststream/confluent/client/create_topics.md) + - config + - [BrokerAddressFamily](api/faststream/confluent/config/BrokerAddressFamily.md) + - [BuiltinFeatures](api/faststream/confluent/config/BuiltinFeatures.md) + - [ClientDNSLookup](api/faststream/confluent/config/ClientDNSLookup.md) + - [CompressionCodec](api/faststream/confluent/config/CompressionCodec.md) + - [CompressionType](api/faststream/confluent/config/CompressionType.md) + - [ConfluentConfig](api/faststream/confluent/config/ConfluentConfig.md) + - [ConfluentFastConfig](api/faststream/confluent/config/ConfluentFastConfig.md) + - [Debug](api/faststream/confluent/config/Debug.md) + - [GroupProtocol](api/faststream/confluent/config/GroupProtocol.md) + - [IsolationLevel](api/faststream/confluent/config/IsolationLevel.md) + - [OffsetStoreMethod](api/faststream/confluent/config/OffsetStoreMethod.md) + - [SASLOAUTHBearerMethod](api/faststream/confluent/config/SASLOAUTHBearerMethod.md) + - [SecurityProtocol](api/faststream/confluent/config/SecurityProtocol.md) + - fastapi + - [Context](api/faststream/confluent/fastapi/Context.md) + - [KafkaRouter](api/faststream/confluent/fastapi/KafkaRouter.md) + - fastapi + - [KafkaRouter](api/faststream/confluent/fastapi/fastapi/KafkaRouter.md) + - message + - [ConsumerProtocol](api/faststream/confluent/message/ConsumerProtocol.md) + - [FakeConsumer](api/faststream/confluent/message/FakeConsumer.md) + - [KafkaMessage](api/faststream/confluent/message/KafkaMessage.md) + - opentelemetry + - [KafkaTelemetryMiddleware](api/faststream/confluent/opentelemetry/KafkaTelemetryMiddleware.md) + - middleware + - [KafkaTelemetryMiddleware](api/faststream/confluent/opentelemetry/middleware/KafkaTelemetryMiddleware.md) + - provider + - [BaseConfluentTelemetrySettingsProvider](api/faststream/confluent/opentelemetry/provider/BaseConfluentTelemetrySettingsProvider.md) + - [BatchConfluentTelemetrySettingsProvider](api/faststream/confluent/opentelemetry/provider/BatchConfluentTelemetrySettingsProvider.md) + - [ConfluentTelemetrySettingsProvider](api/faststream/confluent/opentelemetry/provider/ConfluentTelemetrySettingsProvider.md) + - [telemetry_attributes_provider_factory](api/faststream/confluent/opentelemetry/provider/telemetry_attributes_provider_factory.md) + - parser + - [AsyncConfluentParser](api/faststream/confluent/parser/AsyncConfluentParser.md) + - prometheus + - [KafkaPrometheusMiddleware](api/faststream/confluent/prometheus/KafkaPrometheusMiddleware.md) + - middleware + - [KafkaPrometheusMiddleware](api/faststream/confluent/prometheus/middleware/KafkaPrometheusMiddleware.md) + - provider + - [BaseConfluentMetricsSettingsProvider](api/faststream/confluent/prometheus/provider/BaseConfluentMetricsSettingsProvider.md) + - [BatchConfluentMetricsSettingsProvider](api/faststream/confluent/prometheus/provider/BatchConfluentMetricsSettingsProvider.md) + - [ConfluentMetricsSettingsProvider](api/faststream/confluent/prometheus/provider/ConfluentMetricsSettingsProvider.md) + - [settings_provider_factory](api/faststream/confluent/prometheus/provider/settings_provider_factory.md) + - publisher + - factory + - [create_publisher](api/faststream/confluent/publisher/factory/create_publisher.md) + - fake + - [KafkaFakePublisher](api/faststream/confluent/publisher/fake/KafkaFakePublisher.md) + - producer + - [AsyncConfluentFastProducer](api/faststream/confluent/publisher/producer/AsyncConfluentFastProducer.md) + - specified + - [SpecificationBatchPublisher](api/faststream/confluent/publisher/specified/SpecificationBatchPublisher.md) + - [SpecificationDefaultPublisher](api/faststream/confluent/publisher/specified/SpecificationDefaultPublisher.md) + - [SpecificationPublisher](api/faststream/confluent/publisher/specified/SpecificationPublisher.md) + - state + - [EmptyProducerState](api/faststream/confluent/publisher/state/EmptyProducerState.md) + - [ProducerState](api/faststream/confluent/publisher/state/ProducerState.md) + - [RealProducer](api/faststream/confluent/publisher/state/RealProducer.md) + - usecase + - [BatchPublisher](api/faststream/confluent/publisher/usecase/BatchPublisher.md) + - [DefaultPublisher](api/faststream/confluent/publisher/usecase/DefaultPublisher.md) + - [LogicPublisher](api/faststream/confluent/publisher/usecase/LogicPublisher.md) + - response + - [KafkaPublishCommand](api/faststream/confluent/response/KafkaPublishCommand.md) + - [KafkaResponse](api/faststream/confluent/response/KafkaResponse.md) + - router + - [KafkaPublisher](api/faststream/confluent/router/KafkaPublisher.md) + - [KafkaRoute](api/faststream/confluent/router/KafkaRoute.md) + - [KafkaRouter](api/faststream/confluent/router/KafkaRouter.md) + - schemas + - [TopicPartition](api/faststream/confluent/schemas/TopicPartition.md) + - params + - [ConsumerConnectionParams](api/faststream/confluent/schemas/params/ConsumerConnectionParams.md) + - partition + - [TopicPartition](api/faststream/confluent/schemas/partition/TopicPartition.md) + - security + - [parse_security](api/faststream/confluent/security/parse_security.md) + - subscriber + - factory + - [create_subscriber](api/faststream/confluent/subscriber/factory/create_subscriber.md) + - specified + - [SpecificationBatchSubscriber](api/faststream/confluent/subscriber/specified/SpecificationBatchSubscriber.md) + - [SpecificationConcurrentDefaultSubscriber](api/faststream/confluent/subscriber/specified/SpecificationConcurrentDefaultSubscriber.md) + - [SpecificationDefaultSubscriber](api/faststream/confluent/subscriber/specified/SpecificationDefaultSubscriber.md) + - [SpecificationSubscriber](api/faststream/confluent/subscriber/specified/SpecificationSubscriber.md) + - usecase + - [BatchSubscriber](api/faststream/confluent/subscriber/usecase/BatchSubscriber.md) + - [ConcurrentDefaultSubscriber](api/faststream/confluent/subscriber/usecase/ConcurrentDefaultSubscriber.md) + - [DefaultSubscriber](api/faststream/confluent/subscriber/usecase/DefaultSubscriber.md) + - [LogicSubscriber](api/faststream/confluent/subscriber/usecase/LogicSubscriber.md) + - testing + - [FakeProducer](api/faststream/confluent/testing/FakeProducer.md) + - [MockConfluentMessage](api/faststream/confluent/testing/MockConfluentMessage.md) + - [TestKafkaBroker](api/faststream/confluent/testing/TestKafkaBroker.md) + - [build_message](api/faststream/confluent/testing/build_message.md) + - exceptions + - [AckMessage](api/faststream/exceptions/AckMessage.md) + - [ContextError](api/faststream/exceptions/ContextError.md) + - [FastStreamException](api/faststream/exceptions/FastStreamException.md) + - [FeatureNotSupportedException](api/faststream/exceptions/FeatureNotSupportedException.md) + - [HandlerException](api/faststream/exceptions/HandlerException.md) + - [IgnoredException](api/faststream/exceptions/IgnoredException.md) + - [IncorrectState](api/faststream/exceptions/IncorrectState.md) + - [NackMessage](api/faststream/exceptions/NackMessage.md) + - [RejectMessage](api/faststream/exceptions/RejectMessage.md) + - [SetupError](api/faststream/exceptions/SetupError.md) + - [SkipMessage](api/faststream/exceptions/SkipMessage.md) + - [StartupValidationError](api/faststream/exceptions/StartupValidationError.md) + - [StopApplication](api/faststream/exceptions/StopApplication.md) + - [StopConsume](api/faststream/exceptions/StopConsume.md) + - [SubscriberNotFound](api/faststream/exceptions/SubscriberNotFound.md) + - kafka + - [KafkaBroker](api/faststream/kafka/KafkaBroker.md) + - [KafkaPublisher](api/faststream/kafka/KafkaPublisher.md) + - [KafkaResponse](api/faststream/kafka/KafkaResponse.md) + - [KafkaRoute](api/faststream/kafka/KafkaRoute.md) + - [KafkaRouter](api/faststream/kafka/KafkaRouter.md) + - [TestApp](api/faststream/kafka/TestApp.md) + - [TestKafkaBroker](api/faststream/kafka/TestKafkaBroker.md) + - [TopicPartition](api/faststream/kafka/TopicPartition.md) + - broker + - [KafkaBroker](api/faststream/kafka/broker/KafkaBroker.md) + - broker + - [KafkaBroker](api/faststream/kafka/broker/broker/KafkaBroker.md) + - logging + - [KafkaParamsStorage](api/faststream/kafka/broker/logging/KafkaParamsStorage.md) + - registrator + - [KafkaRegistrator](api/faststream/kafka/broker/registrator/KafkaRegistrator.md) + - fastapi + - [Context](api/faststream/kafka/fastapi/Context.md) + - [KafkaRouter](api/faststream/kafka/fastapi/KafkaRouter.md) + - fastapi + - [KafkaRouter](api/faststream/kafka/fastapi/fastapi/KafkaRouter.md) + - message + - [ConsumerProtocol](api/faststream/kafka/message/ConsumerProtocol.md) + - [FakeConsumer](api/faststream/kafka/message/FakeConsumer.md) + - [KafkaAckableMessage](api/faststream/kafka/message/KafkaAckableMessage.md) + - [KafkaMessage](api/faststream/kafka/message/KafkaMessage.md) + - opentelemetry + - [KafkaTelemetryMiddleware](api/faststream/kafka/opentelemetry/KafkaTelemetryMiddleware.md) + - middleware + - [KafkaTelemetryMiddleware](api/faststream/kafka/opentelemetry/middleware/KafkaTelemetryMiddleware.md) + - provider + - [BaseKafkaTelemetrySettingsProvider](api/faststream/kafka/opentelemetry/provider/BaseKafkaTelemetrySettingsProvider.md) + - [BatchKafkaTelemetrySettingsProvider](api/faststream/kafka/opentelemetry/provider/BatchKafkaTelemetrySettingsProvider.md) + - [KafkaTelemetrySettingsProvider](api/faststream/kafka/opentelemetry/provider/KafkaTelemetrySettingsProvider.md) + - [telemetry_attributes_provider_factory](api/faststream/kafka/opentelemetry/provider/telemetry_attributes_provider_factory.md) + - parser + - [AioKafkaBatchParser](api/faststream/kafka/parser/AioKafkaBatchParser.md) + - [AioKafkaParser](api/faststream/kafka/parser/AioKafkaParser.md) + - prometheus + - [KafkaPrometheusMiddleware](api/faststream/kafka/prometheus/KafkaPrometheusMiddleware.md) + - middleware + - [KafkaPrometheusMiddleware](api/faststream/kafka/prometheus/middleware/KafkaPrometheusMiddleware.md) + - provider + - [BaseKafkaMetricsSettingsProvider](api/faststream/kafka/prometheus/provider/BaseKafkaMetricsSettingsProvider.md) + - [BatchKafkaMetricsSettingsProvider](api/faststream/kafka/prometheus/provider/BatchKafkaMetricsSettingsProvider.md) + - [KafkaMetricsSettingsProvider](api/faststream/kafka/prometheus/provider/KafkaMetricsSettingsProvider.md) + - [settings_provider_factory](api/faststream/kafka/prometheus/provider/settings_provider_factory.md) + - publisher + - factory + - [create_publisher](api/faststream/kafka/publisher/factory/create_publisher.md) + - fake + - [KafkaFakePublisher](api/faststream/kafka/publisher/fake/KafkaFakePublisher.md) + - producer + - [AioKafkaFastProducer](api/faststream/kafka/publisher/producer/AioKafkaFastProducer.md) + - specified + - [SpecificationBatchPublisher](api/faststream/kafka/publisher/specified/SpecificationBatchPublisher.md) + - [SpecificationDefaultPublisher](api/faststream/kafka/publisher/specified/SpecificationDefaultPublisher.md) + - [SpecificationPublisher](api/faststream/kafka/publisher/specified/SpecificationPublisher.md) + - state + - [EmptyProducerState](api/faststream/kafka/publisher/state/EmptyProducerState.md) + - [ProducerState](api/faststream/kafka/publisher/state/ProducerState.md) + - [RealProducer](api/faststream/kafka/publisher/state/RealProducer.md) + - usecase + - [BatchPublisher](api/faststream/kafka/publisher/usecase/BatchPublisher.md) + - [DefaultPublisher](api/faststream/kafka/publisher/usecase/DefaultPublisher.md) + - [LogicPublisher](api/faststream/kafka/publisher/usecase/LogicPublisher.md) + - response + - [KafkaPublishCommand](api/faststream/kafka/response/KafkaPublishCommand.md) + - [KafkaResponse](api/faststream/kafka/response/KafkaResponse.md) + - router + - [KafkaPublisher](api/faststream/kafka/router/KafkaPublisher.md) + - [KafkaRoute](api/faststream/kafka/router/KafkaRoute.md) + - [KafkaRouter](api/faststream/kafka/router/KafkaRouter.md) + - schemas + - params + - [ConsumerConnectionParams](api/faststream/kafka/schemas/params/ConsumerConnectionParams.md) + - security + - [parse_security](api/faststream/kafka/security/parse_security.md) + - subscriber + - factory + - [create_subscriber](api/faststream/kafka/subscriber/factory/create_subscriber.md) + - specified + - [SpecificationBatchSubscriber](api/faststream/kafka/subscriber/specified/SpecificationBatchSubscriber.md) + - [SpecificationConcurrentDefaultSubscriber](api/faststream/kafka/subscriber/specified/SpecificationConcurrentDefaultSubscriber.md) + - [SpecificationDefaultSubscriber](api/faststream/kafka/subscriber/specified/SpecificationDefaultSubscriber.md) + - [SpecificationSubscriber](api/faststream/kafka/subscriber/specified/SpecificationSubscriber.md) + - usecase + - [BatchSubscriber](api/faststream/kafka/subscriber/usecase/BatchSubscriber.md) + - [ConcurrentDefaultSubscriber](api/faststream/kafka/subscriber/usecase/ConcurrentDefaultSubscriber.md) + - [DefaultSubscriber](api/faststream/kafka/subscriber/usecase/DefaultSubscriber.md) + - [LogicSubscriber](api/faststream/kafka/subscriber/usecase/LogicSubscriber.md) + - testing + - [FakeProducer](api/faststream/kafka/testing/FakeProducer.md) + - [TestKafkaBroker](api/faststream/kafka/testing/TestKafkaBroker.md) + - [build_message](api/faststream/kafka/testing/build_message.md) + - message + - [AckStatus](api/faststream/message/AckStatus.md) + - [SourceType](api/faststream/message/SourceType.md) + - [StreamMessage](api/faststream/message/StreamMessage.md) + - [decode_message](api/faststream/message/decode_message.md) + - [encode_message](api/faststream/message/encode_message.md) + - [gen_cor_id](api/faststream/message/gen_cor_id.md) + - message + - [AckStatus](api/faststream/message/message/AckStatus.md) + - [StreamMessage](api/faststream/message/message/StreamMessage.md) + - source_type + - [SourceType](api/faststream/message/source_type/SourceType.md) + - utils + - [decode_message](api/faststream/message/utils/decode_message.md) + - [encode_message](api/faststream/message/utils/encode_message.md) + - [gen_cor_id](api/faststream/message/utils/gen_cor_id.md) + - middlewares + - [AckPolicy](api/faststream/middlewares/AckPolicy.md) + - [AcknowledgementMiddleware](api/faststream/middlewares/AcknowledgementMiddleware.md) + - [BaseMiddleware](api/faststream/middlewares/BaseMiddleware.md) + - [ExceptionMiddleware](api/faststream/middlewares/ExceptionMiddleware.md) + - acknowledgement + - conf + - [AckPolicy](api/faststream/middlewares/acknowledgement/conf/AckPolicy.md) + - middleware + - [AcknowledgementMiddleware](api/faststream/middlewares/acknowledgement/middleware/AcknowledgementMiddleware.md) + - base + - [BaseMiddleware](api/faststream/middlewares/base/BaseMiddleware.md) + - exception + - [ExceptionMiddleware](api/faststream/middlewares/exception/ExceptionMiddleware.md) + - [ignore_handler](api/faststream/middlewares/exception/ignore_handler.md) + - logging + - [CriticalLogMiddleware](api/faststream/middlewares/logging/CriticalLogMiddleware.md) + - nats + - [AckPolicy](api/faststream/nats/AckPolicy.md) + - [ConsumerConfig](api/faststream/nats/ConsumerConfig.md) + - [DeliverPolicy](api/faststream/nats/DeliverPolicy.md) + - [DiscardPolicy](api/faststream/nats/DiscardPolicy.md) + - [ExternalStream](api/faststream/nats/ExternalStream.md) + - [JStream](api/faststream/nats/JStream.md) + - [KvWatch](api/faststream/nats/KvWatch.md) + - [NatsBroker](api/faststream/nats/NatsBroker.md) + - [NatsPublisher](api/faststream/nats/NatsPublisher.md) + - [NatsResponse](api/faststream/nats/NatsResponse.md) + - [NatsRoute](api/faststream/nats/NatsRoute.md) + - [NatsRouter](api/faststream/nats/NatsRouter.md) + - [ObjWatch](api/faststream/nats/ObjWatch.md) + - [Placement](api/faststream/nats/Placement.md) + - [PubAck](api/faststream/nats/PubAck.md) + - [PullSub](api/faststream/nats/PullSub.md) + - [RePublish](api/faststream/nats/RePublish.md) + - [ReplayPolicy](api/faststream/nats/ReplayPolicy.md) + - [RetentionPolicy](api/faststream/nats/RetentionPolicy.md) + - [StorageType](api/faststream/nats/StorageType.md) + - [StreamConfig](api/faststream/nats/StreamConfig.md) + - [StreamSource](api/faststream/nats/StreamSource.md) + - [TestApp](api/faststream/nats/TestApp.md) + - [TestNatsBroker](api/faststream/nats/TestNatsBroker.md) + - broker + - [NatsBroker](api/faststream/nats/broker/NatsBroker.md) + - broker + - [NatsBroker](api/faststream/nats/broker/broker/NatsBroker.md) + - logging + - [NatsParamsStorage](api/faststream/nats/broker/logging/NatsParamsStorage.md) + - registrator + - [NatsRegistrator](api/faststream/nats/broker/registrator/NatsRegistrator.md) + - state + - [BrokerState](api/faststream/nats/broker/state/BrokerState.md) + - [ConnectedState](api/faststream/nats/broker/state/ConnectedState.md) + - [ConnectionBrokenState](api/faststream/nats/broker/state/ConnectionBrokenState.md) + - [EmptyBrokerState](api/faststream/nats/broker/state/EmptyBrokerState.md) + - fastapi + - [Context](api/faststream/nats/fastapi/Context.md) + - [NatsRouter](api/faststream/nats/fastapi/NatsRouter.md) + - fastapi + - [NatsRouter](api/faststream/nats/fastapi/fastapi/NatsRouter.md) + - helpers + - [KVBucketDeclarer](api/faststream/nats/helpers/KVBucketDeclarer.md) + - [OSBucketDeclarer](api/faststream/nats/helpers/OSBucketDeclarer.md) + - [StreamBuilder](api/faststream/nats/helpers/StreamBuilder.md) + - bucket_declarer + - [KVBucketDeclarer](api/faststream/nats/helpers/bucket_declarer/KVBucketDeclarer.md) + - obj_storage_declarer + - [OSBucketDeclarer](api/faststream/nats/helpers/obj_storage_declarer/OSBucketDeclarer.md) + - object_builder + - [StreamBuilder](api/faststream/nats/helpers/object_builder/StreamBuilder.md) + - state + - [ConnectedState](api/faststream/nats/helpers/state/ConnectedState.md) + - [ConnectionState](api/faststream/nats/helpers/state/ConnectionState.md) + - [EmptyConnectionState](api/faststream/nats/helpers/state/EmptyConnectionState.md) + - message + - [NatsBatchMessage](api/faststream/nats/message/NatsBatchMessage.md) + - [NatsKvMessage](api/faststream/nats/message/NatsKvMessage.md) + - [NatsMessage](api/faststream/nats/message/NatsMessage.md) + - [NatsObjMessage](api/faststream/nats/message/NatsObjMessage.md) + - opentelemetry + - [NatsTelemetryMiddleware](api/faststream/nats/opentelemetry/NatsTelemetryMiddleware.md) + - middleware + - [NatsTelemetryMiddleware](api/faststream/nats/opentelemetry/middleware/NatsTelemetryMiddleware.md) + - provider + - [BaseNatsTelemetrySettingsProvider](api/faststream/nats/opentelemetry/provider/BaseNatsTelemetrySettingsProvider.md) + - [NatsBatchTelemetrySettingsProvider](api/faststream/nats/opentelemetry/provider/NatsBatchTelemetrySettingsProvider.md) + - [NatsTelemetrySettingsProvider](api/faststream/nats/opentelemetry/provider/NatsTelemetrySettingsProvider.md) + - [telemetry_attributes_provider_factory](api/faststream/nats/opentelemetry/provider/telemetry_attributes_provider_factory.md) + - parser + - [BatchParser](api/faststream/nats/parser/BatchParser.md) + - [JsParser](api/faststream/nats/parser/JsParser.md) + - [KvParser](api/faststream/nats/parser/KvParser.md) + - [NatsBaseParser](api/faststream/nats/parser/NatsBaseParser.md) + - [NatsParser](api/faststream/nats/parser/NatsParser.md) + - [ObjParser](api/faststream/nats/parser/ObjParser.md) + - prometheus + - [NatsPrometheusMiddleware](api/faststream/nats/prometheus/NatsPrometheusMiddleware.md) + - middleware + - [NatsPrometheusMiddleware](api/faststream/nats/prometheus/middleware/NatsPrometheusMiddleware.md) + - provider + - [BaseNatsMetricsSettingsProvider](api/faststream/nats/prometheus/provider/BaseNatsMetricsSettingsProvider.md) + - [BatchNatsMetricsSettingsProvider](api/faststream/nats/prometheus/provider/BatchNatsMetricsSettingsProvider.md) + - [NatsMetricsSettingsProvider](api/faststream/nats/prometheus/provider/NatsMetricsSettingsProvider.md) + - [settings_provider_factory](api/faststream/nats/prometheus/provider/settings_provider_factory.md) + - publisher + - factory + - [create_publisher](api/faststream/nats/publisher/factory/create_publisher.md) + - fake + - [NatsFakePublisher](api/faststream/nats/publisher/fake/NatsFakePublisher.md) + - producer + - [NatsFastProducer](api/faststream/nats/publisher/producer/NatsFastProducer.md) + - [NatsJSFastProducer](api/faststream/nats/publisher/producer/NatsJSFastProducer.md) + - specified + - [SpecificationPublisher](api/faststream/nats/publisher/specified/SpecificationPublisher.md) + - usecase + - [LogicPublisher](api/faststream/nats/publisher/usecase/LogicPublisher.md) + - response + - [NatsPublishCommand](api/faststream/nats/response/NatsPublishCommand.md) + - [NatsResponse](api/faststream/nats/response/NatsResponse.md) + - router + - [NatsPublisher](api/faststream/nats/router/NatsPublisher.md) + - [NatsRoute](api/faststream/nats/router/NatsRoute.md) + - [NatsRouter](api/faststream/nats/router/NatsRouter.md) + - schemas + - [JStream](api/faststream/nats/schemas/JStream.md) + - [KvWatch](api/faststream/nats/schemas/KvWatch.md) + - [ObjWatch](api/faststream/nats/schemas/ObjWatch.md) + - [PubAck](api/faststream/nats/schemas/PubAck.md) + - [PullSub](api/faststream/nats/schemas/PullSub.md) + - js_stream + - [JStream](api/faststream/nats/schemas/js_stream/JStream.md) + - [compile_nats_wildcard](api/faststream/nats/schemas/js_stream/compile_nats_wildcard.md) + - [is_subject_match_wildcard](api/faststream/nats/schemas/js_stream/is_subject_match_wildcard.md) + - kv_watch + - [KvWatch](api/faststream/nats/schemas/kv_watch/KvWatch.md) + - obj_watch + - [ObjWatch](api/faststream/nats/schemas/obj_watch/ObjWatch.md) + - pull_sub + - [PullSub](api/faststream/nats/schemas/pull_sub/PullSub.md) + - security + - [parse_security](api/faststream/nats/security/parse_security.md) + - subscriber + - adapters + - [UnsubscribeAdapter](api/faststream/nats/subscriber/adapters/UnsubscribeAdapter.md) + - [Unsubscriptable](api/faststream/nats/subscriber/adapters/Unsubscriptable.md) + - [Watchable](api/faststream/nats/subscriber/adapters/Watchable.md) + - factory + - [create_subscriber](api/faststream/nats/subscriber/factory/create_subscriber.md) + - specified + - [SpecificationBatchPullStreamSubscriber](api/faststream/nats/subscriber/specified/SpecificationBatchPullStreamSubscriber.md) + - [SpecificationConcurrentCoreSubscriber](api/faststream/nats/subscriber/specified/SpecificationConcurrentCoreSubscriber.md) + - [SpecificationConcurrentPullStreamSubscriber](api/faststream/nats/subscriber/specified/SpecificationConcurrentPullStreamSubscriber.md) + - [SpecificationConcurrentPushStreamSubscriber](api/faststream/nats/subscriber/specified/SpecificationConcurrentPushStreamSubscriber.md) + - [SpecificationCoreSubscriber](api/faststream/nats/subscriber/specified/SpecificationCoreSubscriber.md) + - [SpecificationKeyValueWatchSubscriber](api/faststream/nats/subscriber/specified/SpecificationKeyValueWatchSubscriber.md) + - [SpecificationObjStoreWatchSubscriber](api/faststream/nats/subscriber/specified/SpecificationObjStoreWatchSubscriber.md) + - [SpecificationPullStreamSubscriber](api/faststream/nats/subscriber/specified/SpecificationPullStreamSubscriber.md) + - [SpecificationPushStreamSubscriber](api/faststream/nats/subscriber/specified/SpecificationPushStreamSubscriber.md) + - [SpecificationSubscriber](api/faststream/nats/subscriber/specified/SpecificationSubscriber.md) + - state + - [ConnectedSubscriberState](api/faststream/nats/subscriber/state/ConnectedSubscriberState.md) + - [EmptySubscriberState](api/faststream/nats/subscriber/state/EmptySubscriberState.md) + - [SubscriberState](api/faststream/nats/subscriber/state/SubscriberState.md) + - usecases + - [BatchPullStreamSubscriber](api/faststream/nats/subscriber/usecases/BatchPullStreamSubscriber.md) + - [ConcurrentCoreSubscriber](api/faststream/nats/subscriber/usecases/ConcurrentCoreSubscriber.md) + - [ConcurrentPullStreamSubscriber](api/faststream/nats/subscriber/usecases/ConcurrentPullStreamSubscriber.md) + - [ConcurrentPushStreamSubscriber](api/faststream/nats/subscriber/usecases/ConcurrentPushStreamSubscriber.md) + - [CoreSubscriber](api/faststream/nats/subscriber/usecases/CoreSubscriber.md) + - [KeyValueWatchSubscriber](api/faststream/nats/subscriber/usecases/KeyValueWatchSubscriber.md) + - [LogicSubscriber](api/faststream/nats/subscriber/usecases/LogicSubscriber.md) + - [ObjStoreWatchSubscriber](api/faststream/nats/subscriber/usecases/ObjStoreWatchSubscriber.md) + - [PullStreamSubscriber](api/faststream/nats/subscriber/usecases/PullStreamSubscriber.md) + - [PushStreamSubscription](api/faststream/nats/subscriber/usecases/PushStreamSubscription.md) + - basic + - [DefaultSubscriber](api/faststream/nats/subscriber/usecases/basic/DefaultSubscriber.md) + - [LogicSubscriber](api/faststream/nats/subscriber/usecases/basic/LogicSubscriber.md) + - core_subscriber + - [ConcurrentCoreSubscriber](api/faststream/nats/subscriber/usecases/core_subscriber/ConcurrentCoreSubscriber.md) + - [CoreSubscriber](api/faststream/nats/subscriber/usecases/core_subscriber/CoreSubscriber.md) + - key_value_subscriber + - [KeyValueWatchSubscriber](api/faststream/nats/subscriber/usecases/key_value_subscriber/KeyValueWatchSubscriber.md) + - object_storage_subscriber + - [ObjStoreWatchSubscriber](api/faststream/nats/subscriber/usecases/object_storage_subscriber/ObjStoreWatchSubscriber.md) + - stream_basic + - [StreamSubscriber](api/faststream/nats/subscriber/usecases/stream_basic/StreamSubscriber.md) + - stream_pull_subscriber + - [BatchPullStreamSubscriber](api/faststream/nats/subscriber/usecases/stream_pull_subscriber/BatchPullStreamSubscriber.md) + - [ConcurrentPullStreamSubscriber](api/faststream/nats/subscriber/usecases/stream_pull_subscriber/ConcurrentPullStreamSubscriber.md) + - [PullStreamSubscriber](api/faststream/nats/subscriber/usecases/stream_pull_subscriber/PullStreamSubscriber.md) + - stream_push_subscriber + - [ConcurrentPushStreamSubscriber](api/faststream/nats/subscriber/usecases/stream_push_subscriber/ConcurrentPushStreamSubscriber.md) + - [PushStreamSubscription](api/faststream/nats/subscriber/usecases/stream_push_subscriber/PushStreamSubscription.md) + - testing + - [FakeProducer](api/faststream/nats/testing/FakeProducer.md) + - [PatchedMessage](api/faststream/nats/testing/PatchedMessage.md) + - [TestNatsBroker](api/faststream/nats/testing/TestNatsBroker.md) + - [build_message](api/faststream/nats/testing/build_message.md) + - opentelemetry + - [Baggage](api/faststream/opentelemetry/Baggage.md) + - [TelemetryMiddleware](api/faststream/opentelemetry/TelemetryMiddleware.md) + - [TelemetrySettingsProvider](api/faststream/opentelemetry/TelemetrySettingsProvider.md) + - baggage + - [Baggage](api/faststream/opentelemetry/baggage/Baggage.md) + - consts + - [MessageAction](api/faststream/opentelemetry/consts/MessageAction.md) + - middleware + - [BaseTelemetryMiddleware](api/faststream/opentelemetry/middleware/BaseTelemetryMiddleware.md) + - [TelemetryMiddleware](api/faststream/opentelemetry/middleware/TelemetryMiddleware.md) + - provider + - [TelemetrySettingsProvider](api/faststream/opentelemetry/provider/TelemetrySettingsProvider.md) + - params + - [Context](api/faststream/params/Context.md) + - [Depends](api/faststream/params/Depends.md) + - [Header](api/faststream/params/Header.md) + - [Path](api/faststream/params/Path.md) + - no_cast + - [NoCastField](api/faststream/params/no_cast/NoCastField.md) + - params + - [Context](api/faststream/params/params/Context.md) + - [Header](api/faststream/params/params/Header.md) + - [Path](api/faststream/params/params/Path.md) + - prometheus + - [ConsumeAttrs](api/faststream/prometheus/ConsumeAttrs.md) + - [MetricsSettingsProvider](api/faststream/prometheus/MetricsSettingsProvider.md) + - [PrometheusMiddleware](api/faststream/prometheus/PrometheusMiddleware.md) + - container + - [MetricsContainer](api/faststream/prometheus/container/MetricsContainer.md) + - manager + - [MetricsManager](api/faststream/prometheus/manager/MetricsManager.md) + - middleware + - [BasePrometheusMiddleware](api/faststream/prometheus/middleware/BasePrometheusMiddleware.md) + - [PrometheusMiddleware](api/faststream/prometheus/middleware/PrometheusMiddleware.md) + - provider + - [MetricsSettingsProvider](api/faststream/prometheus/provider/MetricsSettingsProvider.md) + - types + - [ConsumeAttrs](api/faststream/prometheus/types/ConsumeAttrs.md) + - [ProcessingStatus](api/faststream/prometheus/types/ProcessingStatus.md) + - [PublishingStatus](api/faststream/prometheus/types/PublishingStatus.md) + - rabbit + - [ExchangeType](api/faststream/rabbit/ExchangeType.md) + - [RabbitBroker](api/faststream/rabbit/RabbitBroker.md) + - [RabbitExchange](api/faststream/rabbit/RabbitExchange.md) + - [RabbitPublisher](api/faststream/rabbit/RabbitPublisher.md) + - [RabbitQueue](api/faststream/rabbit/RabbitQueue.md) + - [RabbitResponse](api/faststream/rabbit/RabbitResponse.md) + - [RabbitRoute](api/faststream/rabbit/RabbitRoute.md) + - [RabbitRouter](api/faststream/rabbit/RabbitRouter.md) + - [TestApp](api/faststream/rabbit/TestApp.md) + - [TestRabbitBroker](api/faststream/rabbit/TestRabbitBroker.md) + - broker + - [RabbitBroker](api/faststream/rabbit/broker/RabbitBroker.md) + - broker + - [RabbitBroker](api/faststream/rabbit/broker/broker/RabbitBroker.md) + - logging + - [RabbitParamsStorage](api/faststream/rabbit/broker/logging/RabbitParamsStorage.md) + - registrator + - [RabbitRegistrator](api/faststream/rabbit/broker/registrator/RabbitRegistrator.md) + - fastapi + - [Context](api/faststream/rabbit/fastapi/Context.md) + - [RabbitRouter](api/faststream/rabbit/fastapi/RabbitRouter.md) + - fastapi + - [RabbitRouter](api/faststream/rabbit/fastapi/fastapi/RabbitRouter.md) + - helpers + - declarer + - [RabbitDeclarer](api/faststream/rabbit/helpers/declarer/RabbitDeclarer.md) + - state + - [ConnectedState](api/faststream/rabbit/helpers/state/ConnectedState.md) + - [ConnectionState](api/faststream/rabbit/helpers/state/ConnectionState.md) + - [EmptyConnectionState](api/faststream/rabbit/helpers/state/EmptyConnectionState.md) + - message + - [RabbitMessage](api/faststream/rabbit/message/RabbitMessage.md) + - opentelemetry + - [RabbitTelemetryMiddleware](api/faststream/rabbit/opentelemetry/RabbitTelemetryMiddleware.md) + - middleware + - [RabbitTelemetryMiddleware](api/faststream/rabbit/opentelemetry/middleware/RabbitTelemetryMiddleware.md) + - provider + - [RabbitTelemetrySettingsProvider](api/faststream/rabbit/opentelemetry/provider/RabbitTelemetrySettingsProvider.md) + - parser + - [AioPikaParser](api/faststream/rabbit/parser/AioPikaParser.md) + - prometheus + - [RabbitPrometheusMiddleware](api/faststream/rabbit/prometheus/RabbitPrometheusMiddleware.md) + - middleware + - [RabbitPrometheusMiddleware](api/faststream/rabbit/prometheus/middleware/RabbitPrometheusMiddleware.md) + - provider + - [RabbitMetricsSettingsProvider](api/faststream/rabbit/prometheus/provider/RabbitMetricsSettingsProvider.md) + - publisher + - factory + - [create_publisher](api/faststream/rabbit/publisher/factory/create_publisher.md) + - fake + - [RabbitFakePublisher](api/faststream/rabbit/publisher/fake/RabbitFakePublisher.md) + - options + - [MessageOptions](api/faststream/rabbit/publisher/options/MessageOptions.md) + - [PublishOptions](api/faststream/rabbit/publisher/options/PublishOptions.md) + - producer + - [AioPikaFastProducer](api/faststream/rabbit/publisher/producer/AioPikaFastProducer.md) + - [LockState](api/faststream/rabbit/publisher/producer/LockState.md) + - [LockUnset](api/faststream/rabbit/publisher/producer/LockUnset.md) + - [RealLock](api/faststream/rabbit/publisher/producer/RealLock.md) + - specified + - [SpecificationPublisher](api/faststream/rabbit/publisher/specified/SpecificationPublisher.md) + - usecase + - [LogicPublisher](api/faststream/rabbit/publisher/usecase/LogicPublisher.md) + - [PublishKwargs](api/faststream/rabbit/publisher/usecase/PublishKwargs.md) + - [RequestPublishKwargs](api/faststream/rabbit/publisher/usecase/RequestPublishKwargs.md) + - response + - [RabbitPublishCommand](api/faststream/rabbit/response/RabbitPublishCommand.md) + - [RabbitResponse](api/faststream/rabbit/response/RabbitResponse.md) + - router + - [RabbitPublisher](api/faststream/rabbit/router/RabbitPublisher.md) + - [RabbitRoute](api/faststream/rabbit/router/RabbitRoute.md) + - [RabbitRouter](api/faststream/rabbit/router/RabbitRouter.md) + - schemas + - [BaseRMQInformation](api/faststream/rabbit/schemas/BaseRMQInformation.md) + - [ExchangeType](api/faststream/rabbit/schemas/ExchangeType.md) + - [RabbitExchange](api/faststream/rabbit/schemas/RabbitExchange.md) + - [RabbitQueue](api/faststream/rabbit/schemas/RabbitQueue.md) + - constants + - [ExchangeType](api/faststream/rabbit/schemas/constants/ExchangeType.md) + - exchange + - [RabbitExchange](api/faststream/rabbit/schemas/exchange/RabbitExchange.md) + - proto + - [BaseRMQInformation](api/faststream/rabbit/schemas/proto/BaseRMQInformation.md) + - queue + - [RabbitQueue](api/faststream/rabbit/schemas/queue/RabbitQueue.md) + - security + - [parse_security](api/faststream/rabbit/security/parse_security.md) + - subscriber + - factory + - [create_subscriber](api/faststream/rabbit/subscriber/factory/create_subscriber.md) + - specified + - [SpecificationSubscriber](api/faststream/rabbit/subscriber/specified/SpecificationSubscriber.md) + - usecase + - [LogicSubscriber](api/faststream/rabbit/subscriber/usecase/LogicSubscriber.md) + - testing + - [FakeProducer](api/faststream/rabbit/testing/FakeProducer.md) + - [PatchedMessage](api/faststream/rabbit/testing/PatchedMessage.md) + - [TestRabbitBroker](api/faststream/rabbit/testing/TestRabbitBroker.md) + - [apply_pattern](api/faststream/rabbit/testing/apply_pattern.md) + - [build_message](api/faststream/rabbit/testing/build_message.md) + - utils + - [build_url](api/faststream/rabbit/utils/build_url.md) + - [is_routing_exchange](api/faststream/rabbit/utils/is_routing_exchange.md) + - redis + - [ListSub](api/faststream/redis/ListSub.md) + - [PubSub](api/faststream/redis/PubSub.md) + - [RedisBroker](api/faststream/redis/RedisBroker.md) + - [RedisPublisher](api/faststream/redis/RedisPublisher.md) + - [RedisResponse](api/faststream/redis/RedisResponse.md) + - [RedisRoute](api/faststream/redis/RedisRoute.md) + - [RedisRouter](api/faststream/redis/RedisRouter.md) + - [StreamSub](api/faststream/redis/StreamSub.md) + - [TestApp](api/faststream/redis/TestApp.md) + - [TestRedisBroker](api/faststream/redis/TestRedisBroker.md) + - broker + - broker + - [RedisBroker](api/faststream/redis/broker/broker/RedisBroker.md) + - logging + - [RedisParamsStorage](api/faststream/redis/broker/logging/RedisParamsStorage.md) + - registrator + - [RedisRegistrator](api/faststream/redis/broker/registrator/RedisRegistrator.md) + - fastapi + - [Context](api/faststream/redis/fastapi/Context.md) + - [RedisRouter](api/faststream/redis/fastapi/RedisRouter.md) + - fastapi + - [RedisRouter](api/faststream/redis/fastapi/fastapi/RedisRouter.md) + - helpers + - state + - [ConnectedState](api/faststream/redis/helpers/state/ConnectedState.md) + - [ConnectionState](api/faststream/redis/helpers/state/ConnectionState.md) + - [EmptyConnectionState](api/faststream/redis/helpers/state/EmptyConnectionState.md) + - message + - [BatchListMessage](api/faststream/redis/message/BatchListMessage.md) + - [BatchStreamMessage](api/faststream/redis/message/BatchStreamMessage.md) + - [DefaultListMessage](api/faststream/redis/message/DefaultListMessage.md) + - [DefaultStreamMessage](api/faststream/redis/message/DefaultStreamMessage.md) + - [PubSubMessage](api/faststream/redis/message/PubSubMessage.md) + - [RedisBatchListMessage](api/faststream/redis/message/RedisBatchListMessage.md) + - [RedisBatchStreamMessage](api/faststream/redis/message/RedisBatchStreamMessage.md) + - [RedisListMessage](api/faststream/redis/message/RedisListMessage.md) + - [RedisMessage](api/faststream/redis/message/RedisMessage.md) + - [RedisStreamMessage](api/faststream/redis/message/RedisStreamMessage.md) + - [UnifyRedisDict](api/faststream/redis/message/UnifyRedisDict.md) + - [UnifyRedisMessage](api/faststream/redis/message/UnifyRedisMessage.md) + - opentelemetry + - [RedisTelemetryMiddleware](api/faststream/redis/opentelemetry/RedisTelemetryMiddleware.md) + - middleware + - [RedisTelemetryMiddleware](api/faststream/redis/opentelemetry/middleware/RedisTelemetryMiddleware.md) + - provider + - [RedisTelemetrySettingsProvider](api/faststream/redis/opentelemetry/provider/RedisTelemetrySettingsProvider.md) + - parser + - [RawMessage](api/faststream/redis/parser/RawMessage.md) + - [RedisBatchListParser](api/faststream/redis/parser/RedisBatchListParser.md) + - [RedisBatchStreamParser](api/faststream/redis/parser/RedisBatchStreamParser.md) + - [RedisListParser](api/faststream/redis/parser/RedisListParser.md) + - [RedisPubSubParser](api/faststream/redis/parser/RedisPubSubParser.md) + - [RedisStreamParser](api/faststream/redis/parser/RedisStreamParser.md) + - [SimpleParser](api/faststream/redis/parser/SimpleParser.md) + - prometheus + - [RedisPrometheusMiddleware](api/faststream/redis/prometheus/RedisPrometheusMiddleware.md) + - middleware + - [RedisPrometheusMiddleware](api/faststream/redis/prometheus/middleware/RedisPrometheusMiddleware.md) + - provider + - [BaseRedisMetricsSettingsProvider](api/faststream/redis/prometheus/provider/BaseRedisMetricsSettingsProvider.md) + - [BatchRedisMetricsSettingsProvider](api/faststream/redis/prometheus/provider/BatchRedisMetricsSettingsProvider.md) + - [RedisMetricsSettingsProvider](api/faststream/redis/prometheus/provider/RedisMetricsSettingsProvider.md) + - [settings_provider_factory](api/faststream/redis/prometheus/provider/settings_provider_factory.md) + - publisher + - factory + - [create_publisher](api/faststream/redis/publisher/factory/create_publisher.md) + - fake + - [RedisFakePublisher](api/faststream/redis/publisher/fake/RedisFakePublisher.md) + - producer + - [RedisFastProducer](api/faststream/redis/publisher/producer/RedisFastProducer.md) + - specified + - [SpecificationChannelPublisher](api/faststream/redis/publisher/specified/SpecificationChannelPublisher.md) + - [SpecificationListBatchPublisher](api/faststream/redis/publisher/specified/SpecificationListBatchPublisher.md) + - [SpecificationListPublisher](api/faststream/redis/publisher/specified/SpecificationListPublisher.md) + - [SpecificationPublisher](api/faststream/redis/publisher/specified/SpecificationPublisher.md) + - [SpecificationStreamPublisher](api/faststream/redis/publisher/specified/SpecificationStreamPublisher.md) + - usecase + - [ChannelPublisher](api/faststream/redis/publisher/usecase/ChannelPublisher.md) + - [ListBatchPublisher](api/faststream/redis/publisher/usecase/ListBatchPublisher.md) + - [ListPublisher](api/faststream/redis/publisher/usecase/ListPublisher.md) + - [LogicPublisher](api/faststream/redis/publisher/usecase/LogicPublisher.md) + - [StreamPublisher](api/faststream/redis/publisher/usecase/StreamPublisher.md) + - response + - [DestinationType](api/faststream/redis/response/DestinationType.md) + - [RedisPublishCommand](api/faststream/redis/response/RedisPublishCommand.md) + - [RedisResponse](api/faststream/redis/response/RedisResponse.md) + - router + - [RedisPublisher](api/faststream/redis/router/RedisPublisher.md) + - [RedisRoute](api/faststream/redis/router/RedisRoute.md) + - [RedisRouter](api/faststream/redis/router/RedisRouter.md) + - schemas + - [ListSub](api/faststream/redis/schemas/ListSub.md) + - [PubSub](api/faststream/redis/schemas/PubSub.md) + - [StreamSub](api/faststream/redis/schemas/StreamSub.md) + - list_sub + - [ListSub](api/faststream/redis/schemas/list_sub/ListSub.md) + - proto + - [RedisSpecificationProtocol](api/faststream/redis/schemas/proto/RedisSpecificationProtocol.md) + - [validate_options](api/faststream/redis/schemas/proto/validate_options.md) + - pub_sub + - [PubSub](api/faststream/redis/schemas/pub_sub/PubSub.md) + - stream_sub + - [StreamSub](api/faststream/redis/schemas/stream_sub/StreamSub.md) + - security + - [parse_security](api/faststream/redis/security/parse_security.md) + - subscriber + - factory + - [create_subscriber](api/faststream/redis/subscriber/factory/create_subscriber.md) + - specified + - [SpecificationChannelSubscriber](api/faststream/redis/subscriber/specified/SpecificationChannelSubscriber.md) + - [SpecificationListBatchSubscriber](api/faststream/redis/subscriber/specified/SpecificationListBatchSubscriber.md) + - [SpecificationListSubscriber](api/faststream/redis/subscriber/specified/SpecificationListSubscriber.md) + - [SpecificationStreamBatchSubscriber](api/faststream/redis/subscriber/specified/SpecificationStreamBatchSubscriber.md) + - [SpecificationStreamSubscriber](api/faststream/redis/subscriber/specified/SpecificationStreamSubscriber.md) + - [SpecificationSubscriber](api/faststream/redis/subscriber/specified/SpecificationSubscriber.md) + - usecase + - [BatchListSubscriber](api/faststream/redis/subscriber/usecase/BatchListSubscriber.md) + - [ChannelSubscriber](api/faststream/redis/subscriber/usecase/ChannelSubscriber.md) + - [ListSubscriber](api/faststream/redis/subscriber/usecase/ListSubscriber.md) + - [LogicSubscriber](api/faststream/redis/subscriber/usecase/LogicSubscriber.md) + - [StreamBatchSubscriber](api/faststream/redis/subscriber/usecase/StreamBatchSubscriber.md) + - [StreamSubscriber](api/faststream/redis/subscriber/usecase/StreamSubscriber.md) + - testing + - [ChannelVisitor](api/faststream/redis/testing/ChannelVisitor.md) + - [FakeProducer](api/faststream/redis/testing/FakeProducer.md) + - [ListVisitor](api/faststream/redis/testing/ListVisitor.md) + - [StreamVisitor](api/faststream/redis/testing/StreamVisitor.md) + - [TestRedisBroker](api/faststream/redis/testing/TestRedisBroker.md) + - [Visitor](api/faststream/redis/testing/Visitor.md) + - [build_message](api/faststream/redis/testing/build_message.md) + - response + - [PublishCommand](api/faststream/response/PublishCommand.md) + - [PublishType](api/faststream/response/PublishType.md) + - [Response](api/faststream/response/Response.md) + - [ensure_response](api/faststream/response/ensure_response.md) + - publish_type + - [PublishType](api/faststream/response/publish_type/PublishType.md) + - response + - [PublishCommand](api/faststream/response/response/PublishCommand.md) + - [Response](api/faststream/response/response/Response.md) + - utils + - [ensure_response](api/faststream/response/utils/ensure_response.md) + - security + - [BaseSecurity](api/faststream/security/BaseSecurity.md) + - [SASLGSSAPI](api/faststream/security/SASLGSSAPI.md) + - [SASLOAuthBearer](api/faststream/security/SASLOAuthBearer.md) + - [SASLPlaintext](api/faststream/security/SASLPlaintext.md) + - [SASLScram256](api/faststream/security/SASLScram256.md) + - [SASLScram512](api/faststream/security/SASLScram512.md) + - specification + - [AsyncAPI](api/faststream/specification/AsyncAPI.md) + - [Contact](api/faststream/specification/Contact.md) + - [ExternalDocs](api/faststream/specification/ExternalDocs.md) + - [License](api/faststream/specification/License.md) + - [Tag](api/faststream/specification/Tag.md) + - asyncapi + - [AsyncAPI](api/faststream/specification/asyncapi/AsyncAPI.md) + - [get_asyncapi_html](api/faststream/specification/asyncapi/get_asyncapi_html.md) + - factory + - [AsyncAPI](api/faststream/specification/asyncapi/factory/AsyncAPI.md) + - message + - [get_model_schema](api/faststream/specification/asyncapi/message/get_model_schema.md) + - [get_response_schema](api/faststream/specification/asyncapi/message/get_response_schema.md) + - [parse_handler_params](api/faststream/specification/asyncapi/message/parse_handler_params.md) + - site + - [get_asyncapi_html](api/faststream/specification/asyncapi/site/get_asyncapi_html.md) + - [serve_app](api/faststream/specification/asyncapi/site/serve_app.md) + - utils + - [clear_key](api/faststream/specification/asyncapi/utils/clear_key.md) + - [move_pydantic_refs](api/faststream/specification/asyncapi/utils/move_pydantic_refs.md) + - [resolve_payloads](api/faststream/specification/asyncapi/utils/resolve_payloads.md) + - [to_camelcase](api/faststream/specification/asyncapi/utils/to_camelcase.md) + - v2_6_0 + - [AsyncAPI2](api/faststream/specification/asyncapi/v2_6_0/AsyncAPI2.md) + - [get_app_schema](api/faststream/specification/asyncapi/v2_6_0/get_app_schema.md) + - facade + - [AsyncAPI2](api/faststream/specification/asyncapi/v2_6_0/facade/AsyncAPI2.md) + - generate + - [get_app_schema](api/faststream/specification/asyncapi/v2_6_0/generate/get_app_schema.md) + - [get_broker_channels](api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_channels.md) + - [get_broker_server](api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_server.md) + - [resolve_channel_messages](api/faststream/specification/asyncapi/v2_6_0/generate/resolve_channel_messages.md) + - schema + - [ApplicationInfo](api/faststream/specification/asyncapi/v2_6_0/schema/ApplicationInfo.md) + - [ApplicationSchema](api/faststream/specification/asyncapi/v2_6_0/schema/ApplicationSchema.md) + - [Channel](api/faststream/specification/asyncapi/v2_6_0/schema/Channel.md) + - [Components](api/faststream/specification/asyncapi/v2_6_0/schema/Components.md) + - [Contact](api/faststream/specification/asyncapi/v2_6_0/schema/Contact.md) + - [CorrelationId](api/faststream/specification/asyncapi/v2_6_0/schema/CorrelationId.md) + - [ExternalDocs](api/faststream/specification/asyncapi/v2_6_0/schema/ExternalDocs.md) + - [License](api/faststream/specification/asyncapi/v2_6_0/schema/License.md) + - [Message](api/faststream/specification/asyncapi/v2_6_0/schema/Message.md) + - [Operation](api/faststream/specification/asyncapi/v2_6_0/schema/Operation.md) + - [Parameter](api/faststream/specification/asyncapi/v2_6_0/schema/Parameter.md) + - [Reference](api/faststream/specification/asyncapi/v2_6_0/schema/Reference.md) + - [Server](api/faststream/specification/asyncapi/v2_6_0/schema/Server.md) + - [ServerVariable](api/faststream/specification/asyncapi/v2_6_0/schema/ServerVariable.md) + - [Tag](api/faststream/specification/asyncapi/v2_6_0/schema/Tag.md) + - bindings + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/OperationBinding.md) + - amqp + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/OperationBinding.md) + - channel + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/ChannelBinding.md) + - [Exchange](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Exchange.md) + - [Queue](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Queue.md) + - operation + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/OperationBinding.md) + - kafka + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/OperationBinding.md) + - channel + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel/ChannelBinding.md) + - operation + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/OperationBinding.md) + - main + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/OperationBinding.md) + - channel + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/ChannelBinding.md) + - operation + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/OperationBinding.md) + - nats + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/OperationBinding.md) + - channel + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel/ChannelBinding.md) + - operation + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/OperationBinding.md) + - redis + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/OperationBinding.md) + - channel + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel/ChannelBinding.md) + - operation + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/OperationBinding.md) + - sqs + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/OperationBinding.md) + - channel + - [ChannelBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/ChannelBinding.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/from_spec.md) + - operation + - [OperationBinding](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/OperationBinding.md) + - [from_spec](api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/from_spec.md) + - channels + - [Channel](api/faststream/specification/asyncapi/v2_6_0/schema/channels/Channel.md) + - components + - [Components](api/faststream/specification/asyncapi/v2_6_0/schema/components/Components.md) + - contact + - [Contact](api/faststream/specification/asyncapi/v2_6_0/schema/contact/Contact.md) + - docs + - [ExternalDocs](api/faststream/specification/asyncapi/v2_6_0/schema/docs/ExternalDocs.md) + - info + - [ApplicationInfo](api/faststream/specification/asyncapi/v2_6_0/schema/info/ApplicationInfo.md) + - license + - [License](api/faststream/specification/asyncapi/v2_6_0/schema/license/License.md) + - message + - [CorrelationId](api/faststream/specification/asyncapi/v2_6_0/schema/message/CorrelationId.md) + - [Message](api/faststream/specification/asyncapi/v2_6_0/schema/message/Message.md) + - operations + - [Operation](api/faststream/specification/asyncapi/v2_6_0/schema/operations/Operation.md) + - schema + - [ApplicationSchema](api/faststream/specification/asyncapi/v2_6_0/schema/schema/ApplicationSchema.md) + - servers + - [Server](api/faststream/specification/asyncapi/v2_6_0/schema/servers/Server.md) + - [ServerVariable](api/faststream/specification/asyncapi/v2_6_0/schema/servers/ServerVariable.md) + - tag + - [Tag](api/faststream/specification/asyncapi/v2_6_0/schema/tag/Tag.md) + - utils + - [Parameter](api/faststream/specification/asyncapi/v2_6_0/schema/utils/Parameter.md) + - [Reference](api/faststream/specification/asyncapi/v2_6_0/schema/utils/Reference.md) + - v3_0_0 + - [AsyncAPI3](api/faststream/specification/asyncapi/v3_0_0/AsyncAPI3.md) + - [get_app_schema](api/faststream/specification/asyncapi/v3_0_0/get_app_schema.md) + - facade + - [AsyncAPI3](api/faststream/specification/asyncapi/v3_0_0/facade/AsyncAPI3.md) + - generate + - [get_app_schema](api/faststream/specification/asyncapi/v3_0_0/generate/get_app_schema.md) + - [get_broker_channels](api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_channels.md) + - [get_broker_server](api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_server.md) + - schema + - [ApplicationInfo](api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationInfo.md) + - [ApplicationSchema](api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationSchema.md) + - [Channel](api/faststream/specification/asyncapi/v3_0_0/schema/Channel.md) + - [Components](api/faststream/specification/asyncapi/v3_0_0/schema/Components.md) + - [Contact](api/faststream/specification/asyncapi/v3_0_0/schema/Contact.md) + - [CorrelationId](api/faststream/specification/asyncapi/v3_0_0/schema/CorrelationId.md) + - [ExternalDocs](api/faststream/specification/asyncapi/v3_0_0/schema/ExternalDocs.md) + - [License](api/faststream/specification/asyncapi/v3_0_0/schema/License.md) + - [Message](api/faststream/specification/asyncapi/v3_0_0/schema/Message.md) + - [Operation](api/faststream/specification/asyncapi/v3_0_0/schema/Operation.md) + - [Parameter](api/faststream/specification/asyncapi/v3_0_0/schema/Parameter.md) + - [Reference](api/faststream/specification/asyncapi/v3_0_0/schema/Reference.md) + - [Server](api/faststream/specification/asyncapi/v3_0_0/schema/Server.md) + - [ServerVariable](api/faststream/specification/asyncapi/v3_0_0/schema/ServerVariable.md) + - [Tag](api/faststream/specification/asyncapi/v3_0_0/schema/Tag.md) + - bindings + - [ChannelBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/OperationBinding.md) + - amqp + - [ChannelBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/OperationBinding.md) + - channel + - [ChannelBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel/ChannelBinding.md) + - operation + - [OperationBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation/OperationBinding.md) + - kafka + - [ChannelBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka/OperationBinding.md) + - main + - [ChannelBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/OperationBinding.md) + - channel + - [ChannelBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel/ChannelBinding.md) + - operation + - [OperationBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation/OperationBinding.md) + - nats + - [ChannelBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats/OperationBinding.md) + - redis + - [ChannelBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis/OperationBinding.md) + - sqs + - [ChannelBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs/OperationBinding.md) + - channels + - [Channel](api/faststream/specification/asyncapi/v3_0_0/schema/channels/Channel.md) + - components + - [Components](api/faststream/specification/asyncapi/v3_0_0/schema/components/Components.md) + - contact + - [Contact](api/faststream/specification/asyncapi/v3_0_0/schema/contact/Contact.md) + - docs + - [ExternalDocs](api/faststream/specification/asyncapi/v3_0_0/schema/docs/ExternalDocs.md) + - info + - [ApplicationInfo](api/faststream/specification/asyncapi/v3_0_0/schema/info/ApplicationInfo.md) + - license + - [License](api/faststream/specification/asyncapi/v3_0_0/schema/license/License.md) + - message + - [CorrelationId](api/faststream/specification/asyncapi/v3_0_0/schema/message/CorrelationId.md) + - [Message](api/faststream/specification/asyncapi/v3_0_0/schema/message/Message.md) + - operations + - [Action](api/faststream/specification/asyncapi/v3_0_0/schema/operations/Action.md) + - [Operation](api/faststream/specification/asyncapi/v3_0_0/schema/operations/Operation.md) + - schema + - [ApplicationSchema](api/faststream/specification/asyncapi/v3_0_0/schema/schema/ApplicationSchema.md) + - servers + - [Server](api/faststream/specification/asyncapi/v3_0_0/schema/servers/Server.md) + - tag + - [Tag](api/faststream/specification/asyncapi/v3_0_0/schema/tag/Tag.md) + - utils + - [Parameter](api/faststream/specification/asyncapi/v3_0_0/schema/utils/Parameter.md) + - [Reference](api/faststream/specification/asyncapi/v3_0_0/schema/utils/Reference.md) + - base + - info + - [BaseApplicationInfo](api/faststream/specification/base/info/BaseApplicationInfo.md) + - schema + - [BaseApplicationSchema](api/faststream/specification/base/schema/BaseApplicationSchema.md) + - specification + - [Specification](api/faststream/specification/base/specification/Specification.md) + - proto + - [EndpointSpecification](api/faststream/specification/proto/EndpointSpecification.md) + - [ServerSpecification](api/faststream/specification/proto/ServerSpecification.md) + - broker + - [ServerSpecification](api/faststream/specification/proto/broker/ServerSpecification.md) + - endpoint + - [EndpointSpecification](api/faststream/specification/proto/endpoint/EndpointSpecification.md) + - schema + - [Contact](api/faststream/specification/schema/Contact.md) + - [ContactDict](api/faststream/specification/schema/ContactDict.md) + - [ExternalDocs](api/faststream/specification/schema/ExternalDocs.md) + - [ExternalDocsDict](api/faststream/specification/schema/ExternalDocsDict.md) + - [License](api/faststream/specification/schema/License.md) + - [LicenseDict](api/faststream/specification/schema/LicenseDict.md) + - [Message](api/faststream/specification/schema/Message.md) + - [Operation](api/faststream/specification/schema/Operation.md) + - [PublisherSpec](api/faststream/specification/schema/PublisherSpec.md) + - [SubscriberSpec](api/faststream/specification/schema/SubscriberSpec.md) + - [Tag](api/faststream/specification/schema/Tag.md) + - [TagDict](api/faststream/specification/schema/TagDict.md) + - bindings + - [ChannelBinding](api/faststream/specification/schema/bindings/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/schema/bindings/OperationBinding.md) + - amqp + - [ChannelBinding](api/faststream/specification/schema/bindings/amqp/ChannelBinding.md) + - [Exchange](api/faststream/specification/schema/bindings/amqp/Exchange.md) + - [OperationBinding](api/faststream/specification/schema/bindings/amqp/OperationBinding.md) + - [Queue](api/faststream/specification/schema/bindings/amqp/Queue.md) + - kafka + - [ChannelBinding](api/faststream/specification/schema/bindings/kafka/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/schema/bindings/kafka/OperationBinding.md) + - main + - [ChannelBinding](api/faststream/specification/schema/bindings/main/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/schema/bindings/main/OperationBinding.md) + - nats + - [ChannelBinding](api/faststream/specification/schema/bindings/nats/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/schema/bindings/nats/OperationBinding.md) + - redis + - [ChannelBinding](api/faststream/specification/schema/bindings/redis/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/schema/bindings/redis/OperationBinding.md) + - sqs + - [ChannelBinding](api/faststream/specification/schema/bindings/sqs/ChannelBinding.md) + - [OperationBinding](api/faststream/specification/schema/bindings/sqs/OperationBinding.md) + - extra + - [Contact](api/faststream/specification/schema/extra/Contact.md) + - [ContactDict](api/faststream/specification/schema/extra/ContactDict.md) + - [ExternalDocs](api/faststream/specification/schema/extra/ExternalDocs.md) + - [ExternalDocsDict](api/faststream/specification/schema/extra/ExternalDocsDict.md) + - [License](api/faststream/specification/schema/extra/License.md) + - [LicenseDict](api/faststream/specification/schema/extra/LicenseDict.md) + - [Tag](api/faststream/specification/schema/extra/Tag.md) + - [TagDict](api/faststream/specification/schema/extra/TagDict.md) + - contact + - [Contact](api/faststream/specification/schema/extra/contact/Contact.md) + - [ContactDict](api/faststream/specification/schema/extra/contact/ContactDict.md) + - external_docs + - [ExternalDocs](api/faststream/specification/schema/extra/external_docs/ExternalDocs.md) + - [ExternalDocsDict](api/faststream/specification/schema/extra/external_docs/ExternalDocsDict.md) + - license + - [License](api/faststream/specification/schema/extra/license/License.md) + - [LicenseDict](api/faststream/specification/schema/extra/license/LicenseDict.md) + - tag + - [Tag](api/faststream/specification/schema/extra/tag/Tag.md) + - [TagDict](api/faststream/specification/schema/extra/tag/TagDict.md) + - message + - [Message](api/faststream/specification/schema/message/Message.md) + - model + - [Message](api/faststream/specification/schema/message/model/Message.md) + - operation + - [Operation](api/faststream/specification/schema/operation/Operation.md) + - model + - [Operation](api/faststream/specification/schema/operation/model/Operation.md) + - publisher + - [PublisherSpec](api/faststream/specification/schema/publisher/PublisherSpec.md) + - subscriber + - [SubscriberSpec](api/faststream/specification/schema/subscriber/SubscriberSpec.md) +- [FastStream People](faststream-people.md) +- Contributing + - [Development](getting-started/contributing/CONTRIBUTING.md) + - [Documentation](getting-started/contributing/docs.md) +- [Release Notes](release.md) \ No newline at end of file diff --git a/docs/docs/en/api/faststream/AckPolicy.md b/docs/docs/en/api/faststream/AckPolicy.md new file mode 100644 index 0000000000..4d7218c81b --- /dev/null +++ b/docs/docs/en/api/faststream/AckPolicy.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.AckPolicy diff --git a/docs/docs/en/api/faststream/BaseMiddleware.md b/docs/docs/en/api/faststream/BaseMiddleware.md new file mode 100644 index 0000000000..21145bf983 --- /dev/null +++ b/docs/docs/en/api/faststream/BaseMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.BaseMiddleware diff --git a/docs/docs/en/api/faststream/Context.md b/docs/docs/en/api/faststream/Context.md new file mode 100644 index 0000000000..c6400b1e56 --- /dev/null +++ b/docs/docs/en/api/faststream/Context.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.Context diff --git a/docs/docs/en/api/faststream/Depends.md b/docs/docs/en/api/faststream/Depends.md new file mode 100644 index 0000000000..c0704687e8 --- /dev/null +++ b/docs/docs/en/api/faststream/Depends.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: fast_depends.use.Depends diff --git a/docs/docs/en/api/faststream/ExceptionMiddleware.md b/docs/docs/en/api/faststream/ExceptionMiddleware.md new file mode 100644 index 0000000000..a5e2038f22 --- /dev/null +++ b/docs/docs/en/api/faststream/ExceptionMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.ExceptionMiddleware diff --git a/docs/docs/en/api/faststream/FastStream.md b/docs/docs/en/api/faststream/FastStream.md new file mode 100644 index 0000000000..8d79ba3921 --- /dev/null +++ b/docs/docs/en/api/faststream/FastStream.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.FastStream diff --git a/docs/docs/en/api/faststream/Header.md b/docs/docs/en/api/faststream/Header.md new file mode 100644 index 0000000000..98bdb592a7 --- /dev/null +++ b/docs/docs/en/api/faststream/Header.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.Header diff --git a/docs/docs/en/api/faststream/Path.md b/docs/docs/en/api/faststream/Path.md new file mode 100644 index 0000000000..7716f47c23 --- /dev/null +++ b/docs/docs/en/api/faststream/Path.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.Path diff --git a/docs/docs/en/api/faststream/Response.md b/docs/docs/en/api/faststream/Response.md new file mode 100644 index 0000000000..3475e3f584 --- /dev/null +++ b/docs/docs/en/api/faststream/Response.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.Response diff --git a/docs/docs/en/api/faststream/TestApp.md b/docs/docs/en/api/faststream/TestApp.md new file mode 100644 index 0000000000..2301790c21 --- /dev/null +++ b/docs/docs/en/api/faststream/TestApp.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.TestApp diff --git a/docs/docs/en/api/faststream/app/FastStream.md b/docs/docs/en/api/faststream/app/FastStream.md new file mode 100644 index 0000000000..24235253c2 --- /dev/null +++ b/docs/docs/en/api/faststream/app/FastStream.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.app.FastStream diff --git a/docs/docs/en/api/faststream/apply_types.md b/docs/docs/en/api/faststream/apply_types.md new file mode 100644 index 0000000000..9dc4603bd2 --- /dev/null +++ b/docs/docs/en/api/faststream/apply_types.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: fast_depends.use.inject diff --git a/docs/docs/en/api/faststream/asgi/AsgiFastStream.md b/docs/docs/en/api/faststream/asgi/AsgiFastStream.md new file mode 100644 index 0000000000..49a94bd574 --- /dev/null +++ b/docs/docs/en/api/faststream/asgi/AsgiFastStream.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.asgi.AsgiFastStream diff --git a/docs/docs/en/api/faststream/asgi/AsgiResponse.md b/docs/docs/en/api/faststream/asgi/AsgiResponse.md new file mode 100644 index 0000000000..4814f18557 --- /dev/null +++ b/docs/docs/en/api/faststream/asgi/AsgiResponse.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.asgi.AsgiResponse diff --git a/docs/docs/en/api/faststream/asgi/app/AsgiFastStream.md b/docs/docs/en/api/faststream/asgi/app/AsgiFastStream.md new file mode 100644 index 0000000000..9d58b9576c --- /dev/null +++ b/docs/docs/en/api/faststream/asgi/app/AsgiFastStream.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.asgi.app.AsgiFastStream diff --git a/docs/docs/en/api/faststream/asgi/app/CliRunState.md b/docs/docs/en/api/faststream/asgi/app/CliRunState.md new file mode 100644 index 0000000000..1124f2d50b --- /dev/null +++ b/docs/docs/en/api/faststream/asgi/app/CliRunState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.asgi.app.CliRunState diff --git a/docs/docs/en/api/faststream/asgi/app/OuterRunState.md b/docs/docs/en/api/faststream/asgi/app/OuterRunState.md new file mode 100644 index 0000000000..3789ea0461 --- /dev/null +++ b/docs/docs/en/api/faststream/asgi/app/OuterRunState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.asgi.app.OuterRunState diff --git a/docs/docs/en/api/faststream/asgi/app/ServerState.md b/docs/docs/en/api/faststream/asgi/app/ServerState.md new file mode 100644 index 0000000000..6d5e2c20c6 --- /dev/null +++ b/docs/docs/en/api/faststream/asgi/app/ServerState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.asgi.app.ServerState diff --git a/docs/docs/en/api/faststream/asgi/app/cast_uvicorn_params.md b/docs/docs/en/api/faststream/asgi/app/cast_uvicorn_params.md new file mode 100644 index 0000000000..1431e2c833 --- /dev/null +++ b/docs/docs/en/api/faststream/asgi/app/cast_uvicorn_params.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.asgi.app.cast_uvicorn_params diff --git a/docs/docs/en/api/faststream/asgi/factories/make_asyncapi_asgi.md b/docs/docs/en/api/faststream/asgi/factories/make_asyncapi_asgi.md new file mode 100644 index 0000000000..e96de51b01 --- /dev/null +++ b/docs/docs/en/api/faststream/asgi/factories/make_asyncapi_asgi.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.asgi.factories.make_asyncapi_asgi diff --git a/docs/docs/en/api/faststream/asgi/factories/make_ping_asgi.md b/docs/docs/en/api/faststream/asgi/factories/make_ping_asgi.md new file mode 100644 index 0000000000..fb163d02a1 --- /dev/null +++ b/docs/docs/en/api/faststream/asgi/factories/make_ping_asgi.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.asgi.factories.make_ping_asgi diff --git a/docs/docs/en/api/faststream/asgi/get.md b/docs/docs/en/api/faststream/asgi/get.md new file mode 100644 index 0000000000..044c05ed81 --- /dev/null +++ b/docs/docs/en/api/faststream/asgi/get.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.asgi.get diff --git a/docs/docs/en/api/faststream/asgi/handlers/get.md b/docs/docs/en/api/faststream/asgi/handlers/get.md new file mode 100644 index 0000000000..8f3c04a050 --- /dev/null +++ b/docs/docs/en/api/faststream/asgi/handlers/get.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.asgi.handlers.get diff --git a/docs/docs/en/api/faststream/asgi/make_asyncapi_asgi.md b/docs/docs/en/api/faststream/asgi/make_asyncapi_asgi.md new file mode 100644 index 0000000000..5e57a1a2db --- /dev/null +++ b/docs/docs/en/api/faststream/asgi/make_asyncapi_asgi.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.asgi.make_asyncapi_asgi diff --git a/docs/docs/en/api/faststream/asgi/make_ping_asgi.md b/docs/docs/en/api/faststream/asgi/make_ping_asgi.md new file mode 100644 index 0000000000..5c24aaef19 --- /dev/null +++ b/docs/docs/en/api/faststream/asgi/make_ping_asgi.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.asgi.make_ping_asgi diff --git a/docs/docs/en/api/faststream/asgi/response/AsgiResponse.md b/docs/docs/en/api/faststream/asgi/response/AsgiResponse.md new file mode 100644 index 0000000000..037739b09d --- /dev/null +++ b/docs/docs/en/api/faststream/asgi/response/AsgiResponse.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.asgi.response.AsgiResponse diff --git a/docs/docs/en/api/faststream/asgi/websocket/WebSocketClose.md b/docs/docs/en/api/faststream/asgi/websocket/WebSocketClose.md new file mode 100644 index 0000000000..130ee9a59a --- /dev/null +++ b/docs/docs/en/api/faststream/asgi/websocket/WebSocketClose.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.asgi.websocket.WebSocketClose diff --git a/docs/docs/en/api/faststream/confluent/KafkaBroker.md b/docs/docs/en/api/faststream/confluent/KafkaBroker.md new file mode 100644 index 0000000000..99fd644946 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/KafkaBroker.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.KafkaBroker diff --git a/docs/docs/en/api/faststream/confluent/KafkaPublisher.md b/docs/docs/en/api/faststream/confluent/KafkaPublisher.md new file mode 100644 index 0000000000..73e485fcc5 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/KafkaPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.KafkaPublisher diff --git a/docs/docs/en/api/faststream/confluent/KafkaResponse.md b/docs/docs/en/api/faststream/confluent/KafkaResponse.md new file mode 100644 index 0000000000..eb0eab479c --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/KafkaResponse.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.KafkaResponse diff --git a/docs/docs/en/api/faststream/confluent/KafkaRoute.md b/docs/docs/en/api/faststream/confluent/KafkaRoute.md new file mode 100644 index 0000000000..723012794f --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/KafkaRoute.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.KafkaRoute diff --git a/docs/docs/en/api/faststream/confluent/KafkaRouter.md b/docs/docs/en/api/faststream/confluent/KafkaRouter.md new file mode 100644 index 0000000000..b9e7b0d991 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/KafkaRouter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.KafkaRouter diff --git a/docs/docs/en/api/faststream/confluent/TestApp.md b/docs/docs/en/api/faststream/confluent/TestApp.md new file mode 100644 index 0000000000..ad101303af --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/TestApp.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream._internal.testing.app.TestApp diff --git a/docs/docs/en/api/faststream/confluent/TestKafkaBroker.md b/docs/docs/en/api/faststream/confluent/TestKafkaBroker.md new file mode 100644 index 0000000000..0a24384f69 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/TestKafkaBroker.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.TestKafkaBroker diff --git a/docs/docs/en/api/faststream/confluent/TopicPartition.md b/docs/docs/en/api/faststream/confluent/TopicPartition.md new file mode 100644 index 0000000000..9b5e09bdf9 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/TopicPartition.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.TopicPartition diff --git a/docs/docs/en/api/faststream/confluent/broker/KafkaBroker.md b/docs/docs/en/api/faststream/confluent/broker/KafkaBroker.md new file mode 100644 index 0000000000..cdfdbc6ef1 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/broker/KafkaBroker.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.broker.KafkaBroker diff --git a/docs/docs/en/api/faststream/confluent/broker/broker/KafkaBroker.md b/docs/docs/en/api/faststream/confluent/broker/broker/KafkaBroker.md new file mode 100644 index 0000000000..05c8356f26 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/broker/broker/KafkaBroker.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.broker.broker.KafkaBroker diff --git a/docs/docs/en/api/faststream/confluent/broker/logging/KafkaParamsStorage.md b/docs/docs/en/api/faststream/confluent/broker/logging/KafkaParamsStorage.md new file mode 100644 index 0000000000..900f945037 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/broker/logging/KafkaParamsStorage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.broker.logging.KafkaParamsStorage diff --git a/docs/docs/en/api/faststream/confluent/broker/registrator/KafkaRegistrator.md b/docs/docs/en/api/faststream/confluent/broker/registrator/KafkaRegistrator.md new file mode 100644 index 0000000000..80068d2349 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/broker/registrator/KafkaRegistrator.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.broker.registrator.KafkaRegistrator diff --git a/docs/docs/en/api/faststream/confluent/client/AsyncConfluentConsumer.md b/docs/docs/en/api/faststream/confluent/client/AsyncConfluentConsumer.md new file mode 100644 index 0000000000..25374c405d --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/client/AsyncConfluentConsumer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.client.AsyncConfluentConsumer diff --git a/docs/docs/en/api/faststream/confluent/client/AsyncConfluentProducer.md b/docs/docs/en/api/faststream/confluent/client/AsyncConfluentProducer.md new file mode 100644 index 0000000000..29bfac283f --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/client/AsyncConfluentProducer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.client.AsyncConfluentProducer diff --git a/docs/docs/en/api/faststream/confluent/client/BatchBuilder.md b/docs/docs/en/api/faststream/confluent/client/BatchBuilder.md new file mode 100644 index 0000000000..232f9ecdf2 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/client/BatchBuilder.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.client.BatchBuilder diff --git a/docs/docs/en/api/faststream/confluent/client/check_msg_error.md b/docs/docs/en/api/faststream/confluent/client/check_msg_error.md new file mode 100644 index 0000000000..71ac291b6e --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/client/check_msg_error.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.client.check_msg_error diff --git a/docs/docs/en/api/faststream/confluent/client/create_topics.md b/docs/docs/en/api/faststream/confluent/client/create_topics.md new file mode 100644 index 0000000000..8efc1a80c4 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/client/create_topics.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.client.create_topics diff --git a/docs/docs/en/api/faststream/confluent/config/BrokerAddressFamily.md b/docs/docs/en/api/faststream/confluent/config/BrokerAddressFamily.md new file mode 100644 index 0000000000..bf5cfbaca7 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/config/BrokerAddressFamily.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.config.BrokerAddressFamily diff --git a/docs/docs/en/api/faststream/confluent/config/BuiltinFeatures.md b/docs/docs/en/api/faststream/confluent/config/BuiltinFeatures.md new file mode 100644 index 0000000000..41e324305d --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/config/BuiltinFeatures.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.config.BuiltinFeatures diff --git a/docs/docs/en/api/faststream/confluent/config/ClientDNSLookup.md b/docs/docs/en/api/faststream/confluent/config/ClientDNSLookup.md new file mode 100644 index 0000000000..15f67688f1 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/config/ClientDNSLookup.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.config.ClientDNSLookup diff --git a/docs/docs/en/api/faststream/confluent/config/CompressionCodec.md b/docs/docs/en/api/faststream/confluent/config/CompressionCodec.md new file mode 100644 index 0000000000..dd9640afd4 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/config/CompressionCodec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.config.CompressionCodec diff --git a/docs/docs/en/api/faststream/confluent/config/CompressionType.md b/docs/docs/en/api/faststream/confluent/config/CompressionType.md new file mode 100644 index 0000000000..8139bfcdda --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/config/CompressionType.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.config.CompressionType diff --git a/docs/docs/en/api/faststream/confluent/config/ConfluentConfig.md b/docs/docs/en/api/faststream/confluent/config/ConfluentConfig.md new file mode 100644 index 0000000000..9ebd97c1ff --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/config/ConfluentConfig.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.config.ConfluentConfig diff --git a/docs/docs/en/api/faststream/confluent/config/ConfluentFastConfig.md b/docs/docs/en/api/faststream/confluent/config/ConfluentFastConfig.md new file mode 100644 index 0000000000..27861ffd5b --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/config/ConfluentFastConfig.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.config.ConfluentFastConfig diff --git a/docs/docs/en/api/faststream/confluent/config/Debug.md b/docs/docs/en/api/faststream/confluent/config/Debug.md new file mode 100644 index 0000000000..2036046f5d --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/config/Debug.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.config.Debug diff --git a/docs/docs/en/api/faststream/confluent/config/GroupProtocol.md b/docs/docs/en/api/faststream/confluent/config/GroupProtocol.md new file mode 100644 index 0000000000..a5cab4b1d9 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/config/GroupProtocol.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.config.GroupProtocol diff --git a/docs/docs/en/api/faststream/confluent/config/IsolationLevel.md b/docs/docs/en/api/faststream/confluent/config/IsolationLevel.md new file mode 100644 index 0000000000..d122261f0f --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/config/IsolationLevel.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.config.IsolationLevel diff --git a/docs/docs/en/api/faststream/confluent/config/OffsetStoreMethod.md b/docs/docs/en/api/faststream/confluent/config/OffsetStoreMethod.md new file mode 100644 index 0000000000..4b203e65e9 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/config/OffsetStoreMethod.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.config.OffsetStoreMethod diff --git a/docs/docs/en/api/faststream/confluent/config/SASLOAUTHBearerMethod.md b/docs/docs/en/api/faststream/confluent/config/SASLOAUTHBearerMethod.md new file mode 100644 index 0000000000..2cb635c6b0 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/config/SASLOAUTHBearerMethod.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.config.SASLOAUTHBearerMethod diff --git a/docs/docs/en/api/faststream/confluent/config/SecurityProtocol.md b/docs/docs/en/api/faststream/confluent/config/SecurityProtocol.md new file mode 100644 index 0000000000..8415d3214e --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/config/SecurityProtocol.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.config.SecurityProtocol diff --git a/docs/docs/en/api/faststream/confluent/fastapi/Context.md b/docs/docs/en/api/faststream/confluent/fastapi/Context.md new file mode 100644 index 0000000000..99bf141f5c --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/fastapi/Context.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream._internal.fastapi.context.Context diff --git a/docs/docs/en/api/faststream/confluent/fastapi/KafkaRouter.md b/docs/docs/en/api/faststream/confluent/fastapi/KafkaRouter.md new file mode 100644 index 0000000000..034203e103 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/fastapi/KafkaRouter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.fastapi.KafkaRouter diff --git a/docs/docs/en/api/faststream/confluent/fastapi/fastapi/KafkaRouter.md b/docs/docs/en/api/faststream/confluent/fastapi/fastapi/KafkaRouter.md new file mode 100644 index 0000000000..87edcc2c3d --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/fastapi/fastapi/KafkaRouter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.fastapi.fastapi.KafkaRouter diff --git a/docs/docs/en/api/faststream/confluent/message/ConsumerProtocol.md b/docs/docs/en/api/faststream/confluent/message/ConsumerProtocol.md new file mode 100644 index 0000000000..18971d0829 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/message/ConsumerProtocol.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.message.ConsumerProtocol diff --git a/docs/docs/en/api/faststream/confluent/message/FakeConsumer.md b/docs/docs/en/api/faststream/confluent/message/FakeConsumer.md new file mode 100644 index 0000000000..19e60bb461 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/message/FakeConsumer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.message.FakeConsumer diff --git a/docs/docs/en/api/faststream/confluent/message/KafkaMessage.md b/docs/docs/en/api/faststream/confluent/message/KafkaMessage.md new file mode 100644 index 0000000000..02004c7d37 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/message/KafkaMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.message.KafkaMessage diff --git a/docs/docs/en/api/faststream/confluent/opentelemetry/KafkaTelemetryMiddleware.md b/docs/docs/en/api/faststream/confluent/opentelemetry/KafkaTelemetryMiddleware.md new file mode 100644 index 0000000000..743c494591 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/opentelemetry/KafkaTelemetryMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.opentelemetry.KafkaTelemetryMiddleware diff --git a/docs/docs/en/api/faststream/confluent/opentelemetry/middleware/KafkaTelemetryMiddleware.md b/docs/docs/en/api/faststream/confluent/opentelemetry/middleware/KafkaTelemetryMiddleware.md new file mode 100644 index 0000000000..b34265dfbb --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/opentelemetry/middleware/KafkaTelemetryMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.opentelemetry.middleware.KafkaTelemetryMiddleware diff --git a/docs/docs/en/api/faststream/confluent/opentelemetry/provider/BaseConfluentTelemetrySettingsProvider.md b/docs/docs/en/api/faststream/confluent/opentelemetry/provider/BaseConfluentTelemetrySettingsProvider.md new file mode 100644 index 0000000000..730662fae5 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/opentelemetry/provider/BaseConfluentTelemetrySettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.opentelemetry.provider.BaseConfluentTelemetrySettingsProvider diff --git a/docs/docs/en/api/faststream/confluent/opentelemetry/provider/BatchConfluentTelemetrySettingsProvider.md b/docs/docs/en/api/faststream/confluent/opentelemetry/provider/BatchConfluentTelemetrySettingsProvider.md new file mode 100644 index 0000000000..a6db133484 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/opentelemetry/provider/BatchConfluentTelemetrySettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.opentelemetry.provider.BatchConfluentTelemetrySettingsProvider diff --git a/docs/docs/en/api/faststream/confluent/opentelemetry/provider/ConfluentTelemetrySettingsProvider.md b/docs/docs/en/api/faststream/confluent/opentelemetry/provider/ConfluentTelemetrySettingsProvider.md new file mode 100644 index 0000000000..2c5242e6e5 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/opentelemetry/provider/ConfluentTelemetrySettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.opentelemetry.provider.ConfluentTelemetrySettingsProvider diff --git a/docs/docs/en/api/faststream/confluent/opentelemetry/provider/telemetry_attributes_provider_factory.md b/docs/docs/en/api/faststream/confluent/opentelemetry/provider/telemetry_attributes_provider_factory.md new file mode 100644 index 0000000000..7dd0e1d0fd --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/opentelemetry/provider/telemetry_attributes_provider_factory.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.opentelemetry.provider.telemetry_attributes_provider_factory diff --git a/docs/docs/en/api/faststream/confluent/parser/AsyncConfluentParser.md b/docs/docs/en/api/faststream/confluent/parser/AsyncConfluentParser.md new file mode 100644 index 0000000000..e5029a60d1 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/parser/AsyncConfluentParser.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.parser.AsyncConfluentParser diff --git a/docs/docs/en/api/faststream/confluent/prometheus/KafkaPrometheusMiddleware.md b/docs/docs/en/api/faststream/confluent/prometheus/KafkaPrometheusMiddleware.md new file mode 100644 index 0000000000..e84e84acc3 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/prometheus/KafkaPrometheusMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.prometheus.KafkaPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/confluent/prometheus/middleware/KafkaPrometheusMiddleware.md b/docs/docs/en/api/faststream/confluent/prometheus/middleware/KafkaPrometheusMiddleware.md new file mode 100644 index 0000000000..6603893f74 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/prometheus/middleware/KafkaPrometheusMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.prometheus.middleware.KafkaPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/confluent/prometheus/provider/BaseConfluentMetricsSettingsProvider.md b/docs/docs/en/api/faststream/confluent/prometheus/provider/BaseConfluentMetricsSettingsProvider.md new file mode 100644 index 0000000000..27c186c098 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/prometheus/provider/BaseConfluentMetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.prometheus.provider.BaseConfluentMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/confluent/prometheus/provider/BatchConfluentMetricsSettingsProvider.md b/docs/docs/en/api/faststream/confluent/prometheus/provider/BatchConfluentMetricsSettingsProvider.md new file mode 100644 index 0000000000..f784a64e9f --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/prometheus/provider/BatchConfluentMetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.prometheus.provider.BatchConfluentMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/confluent/prometheus/provider/ConfluentMetricsSettingsProvider.md b/docs/docs/en/api/faststream/confluent/prometheus/provider/ConfluentMetricsSettingsProvider.md new file mode 100644 index 0000000000..65f0a8348e --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/prometheus/provider/ConfluentMetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.prometheus.provider.ConfluentMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/confluent/prometheus/provider/settings_provider_factory.md b/docs/docs/en/api/faststream/confluent/prometheus/provider/settings_provider_factory.md new file mode 100644 index 0000000000..78358f46e3 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/prometheus/provider/settings_provider_factory.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.prometheus.provider.settings_provider_factory diff --git a/docs/docs/en/api/faststream/confluent/publisher/factory/create_publisher.md b/docs/docs/en/api/faststream/confluent/publisher/factory/create_publisher.md new file mode 100644 index 0000000000..60e9664052 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/publisher/factory/create_publisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.publisher.factory.create_publisher diff --git a/docs/docs/en/api/faststream/confluent/publisher/fake/KafkaFakePublisher.md b/docs/docs/en/api/faststream/confluent/publisher/fake/KafkaFakePublisher.md new file mode 100644 index 0000000000..019fbf855f --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/publisher/fake/KafkaFakePublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.publisher.fake.KafkaFakePublisher diff --git a/docs/docs/en/api/faststream/confluent/publisher/producer/AsyncConfluentFastProducer.md b/docs/docs/en/api/faststream/confluent/publisher/producer/AsyncConfluentFastProducer.md new file mode 100644 index 0000000000..fd614d1593 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/publisher/producer/AsyncConfluentFastProducer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.publisher.producer.AsyncConfluentFastProducer diff --git a/docs/docs/en/api/faststream/confluent/publisher/specified/SpecificationBatchPublisher.md b/docs/docs/en/api/faststream/confluent/publisher/specified/SpecificationBatchPublisher.md new file mode 100644 index 0000000000..2879b0d6c3 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/publisher/specified/SpecificationBatchPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.publisher.specified.SpecificationBatchPublisher diff --git a/docs/docs/en/api/faststream/confluent/publisher/specified/SpecificationDefaultPublisher.md b/docs/docs/en/api/faststream/confluent/publisher/specified/SpecificationDefaultPublisher.md new file mode 100644 index 0000000000..581ae19fd8 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/publisher/specified/SpecificationDefaultPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.publisher.specified.SpecificationDefaultPublisher diff --git a/docs/docs/en/api/faststream/confluent/publisher/specified/SpecificationPublisher.md b/docs/docs/en/api/faststream/confluent/publisher/specified/SpecificationPublisher.md new file mode 100644 index 0000000000..55ed49caf5 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/publisher/specified/SpecificationPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.publisher.specified.SpecificationPublisher diff --git a/docs/docs/en/api/faststream/confluent/publisher/state/EmptyProducerState.md b/docs/docs/en/api/faststream/confluent/publisher/state/EmptyProducerState.md new file mode 100644 index 0000000000..a72476a6d3 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/publisher/state/EmptyProducerState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.publisher.state.EmptyProducerState diff --git a/docs/docs/en/api/faststream/confluent/publisher/state/ProducerState.md b/docs/docs/en/api/faststream/confluent/publisher/state/ProducerState.md new file mode 100644 index 0000000000..5a5a35dddd --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/publisher/state/ProducerState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.publisher.state.ProducerState diff --git a/docs/docs/en/api/faststream/confluent/publisher/state/RealProducer.md b/docs/docs/en/api/faststream/confluent/publisher/state/RealProducer.md new file mode 100644 index 0000000000..52143d1596 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/publisher/state/RealProducer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.publisher.state.RealProducer diff --git a/docs/docs/en/api/faststream/confluent/publisher/usecase/BatchPublisher.md b/docs/docs/en/api/faststream/confluent/publisher/usecase/BatchPublisher.md new file mode 100644 index 0000000000..23e8baeed9 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/publisher/usecase/BatchPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.publisher.usecase.BatchPublisher diff --git a/docs/docs/en/api/faststream/confluent/publisher/usecase/DefaultPublisher.md b/docs/docs/en/api/faststream/confluent/publisher/usecase/DefaultPublisher.md new file mode 100644 index 0000000000..faa20eaa11 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/publisher/usecase/DefaultPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.publisher.usecase.DefaultPublisher diff --git a/docs/docs/en/api/faststream/confluent/publisher/usecase/LogicPublisher.md b/docs/docs/en/api/faststream/confluent/publisher/usecase/LogicPublisher.md new file mode 100644 index 0000000000..d9a8594d12 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/publisher/usecase/LogicPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.publisher.usecase.LogicPublisher diff --git a/docs/docs/en/api/faststream/confluent/response/KafkaPublishCommand.md b/docs/docs/en/api/faststream/confluent/response/KafkaPublishCommand.md new file mode 100644 index 0000000000..2a4efcf180 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/response/KafkaPublishCommand.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.response.KafkaPublishCommand diff --git a/docs/docs/en/api/faststream/confluent/response/KafkaResponse.md b/docs/docs/en/api/faststream/confluent/response/KafkaResponse.md new file mode 100644 index 0000000000..7fa5542613 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/response/KafkaResponse.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.response.KafkaResponse diff --git a/docs/docs/en/api/faststream/confluent/router/KafkaPublisher.md b/docs/docs/en/api/faststream/confluent/router/KafkaPublisher.md new file mode 100644 index 0000000000..ee1c818707 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/router/KafkaPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.router.KafkaPublisher diff --git a/docs/docs/en/api/faststream/confluent/router/KafkaRoute.md b/docs/docs/en/api/faststream/confluent/router/KafkaRoute.md new file mode 100644 index 0000000000..60d7bb1c99 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/router/KafkaRoute.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.router.KafkaRoute diff --git a/docs/docs/en/api/faststream/confluent/router/KafkaRouter.md b/docs/docs/en/api/faststream/confluent/router/KafkaRouter.md new file mode 100644 index 0000000000..dac6c1a646 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/router/KafkaRouter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.router.KafkaRouter diff --git a/docs/docs/en/api/faststream/confluent/schemas/TopicPartition.md b/docs/docs/en/api/faststream/confluent/schemas/TopicPartition.md new file mode 100644 index 0000000000..0c52345b4e --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/schemas/TopicPartition.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.schemas.TopicPartition diff --git a/docs/docs/en/api/faststream/confluent/schemas/params/ConsumerConnectionParams.md b/docs/docs/en/api/faststream/confluent/schemas/params/ConsumerConnectionParams.md new file mode 100644 index 0000000000..f4ed5b2004 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/schemas/params/ConsumerConnectionParams.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.schemas.params.ConsumerConnectionParams diff --git a/docs/docs/en/api/faststream/confluent/schemas/partition/TopicPartition.md b/docs/docs/en/api/faststream/confluent/schemas/partition/TopicPartition.md new file mode 100644 index 0000000000..11e0bc2b3c --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/schemas/partition/TopicPartition.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.schemas.partition.TopicPartition diff --git a/docs/docs/en/api/faststream/confluent/security/parse_security.md b/docs/docs/en/api/faststream/confluent/security/parse_security.md new file mode 100644 index 0000000000..1eb84ceed6 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/security/parse_security.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.security.parse_security diff --git a/docs/docs/en/api/faststream/confluent/subscriber/factory/create_subscriber.md b/docs/docs/en/api/faststream/confluent/subscriber/factory/create_subscriber.md new file mode 100644 index 0000000000..ce811a99d9 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/subscriber/factory/create_subscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.subscriber.factory.create_subscriber diff --git a/docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationBatchSubscriber.md b/docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationBatchSubscriber.md new file mode 100644 index 0000000000..ae9e9f42e8 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationBatchSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.subscriber.specified.SpecificationBatchSubscriber diff --git a/docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationConcurrentDefaultSubscriber.md b/docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationConcurrentDefaultSubscriber.md new file mode 100644 index 0000000000..a42a4cb21b --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationConcurrentDefaultSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.subscriber.specified.SpecificationConcurrentDefaultSubscriber diff --git a/docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationDefaultSubscriber.md b/docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationDefaultSubscriber.md new file mode 100644 index 0000000000..d4dd2d304e --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationDefaultSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.subscriber.specified.SpecificationDefaultSubscriber diff --git a/docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationSubscriber.md b/docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationSubscriber.md new file mode 100644 index 0000000000..8887278921 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.subscriber.specified.SpecificationSubscriber diff --git a/docs/docs/en/api/faststream/confluent/subscriber/usecase/BatchSubscriber.md b/docs/docs/en/api/faststream/confluent/subscriber/usecase/BatchSubscriber.md new file mode 100644 index 0000000000..4642abd4a8 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/subscriber/usecase/BatchSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.subscriber.usecase.BatchSubscriber diff --git a/docs/docs/en/api/faststream/confluent/subscriber/usecase/ConcurrentDefaultSubscriber.md b/docs/docs/en/api/faststream/confluent/subscriber/usecase/ConcurrentDefaultSubscriber.md new file mode 100644 index 0000000000..13d0f308c1 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/subscriber/usecase/ConcurrentDefaultSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.subscriber.usecase.ConcurrentDefaultSubscriber diff --git a/docs/docs/en/api/faststream/confluent/subscriber/usecase/DefaultSubscriber.md b/docs/docs/en/api/faststream/confluent/subscriber/usecase/DefaultSubscriber.md new file mode 100644 index 0000000000..c2d7ed227e --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/subscriber/usecase/DefaultSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.subscriber.usecase.DefaultSubscriber diff --git a/docs/docs/en/api/faststream/confluent/subscriber/usecase/LogicSubscriber.md b/docs/docs/en/api/faststream/confluent/subscriber/usecase/LogicSubscriber.md new file mode 100644 index 0000000000..c47daf891f --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/subscriber/usecase/LogicSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.subscriber.usecase.LogicSubscriber diff --git a/docs/docs/en/api/faststream/confluent/testing/FakeProducer.md b/docs/docs/en/api/faststream/confluent/testing/FakeProducer.md new file mode 100644 index 0000000000..aeaee2a2d7 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/testing/FakeProducer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.testing.FakeProducer diff --git a/docs/docs/en/api/faststream/confluent/testing/MockConfluentMessage.md b/docs/docs/en/api/faststream/confluent/testing/MockConfluentMessage.md new file mode 100644 index 0000000000..78791486ab --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/testing/MockConfluentMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.testing.MockConfluentMessage diff --git a/docs/docs/en/api/faststream/confluent/testing/TestKafkaBroker.md b/docs/docs/en/api/faststream/confluent/testing/TestKafkaBroker.md new file mode 100644 index 0000000000..53dfed8f24 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/testing/TestKafkaBroker.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.testing.TestKafkaBroker diff --git a/docs/docs/en/api/faststream/confluent/testing/build_message.md b/docs/docs/en/api/faststream/confluent/testing/build_message.md new file mode 100644 index 0000000000..75787a13b3 --- /dev/null +++ b/docs/docs/en/api/faststream/confluent/testing/build_message.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.confluent.testing.build_message diff --git a/docs/docs/en/api/faststream/exceptions/AckMessage.md b/docs/docs/en/api/faststream/exceptions/AckMessage.md new file mode 100644 index 0000000000..175efc68ed --- /dev/null +++ b/docs/docs/en/api/faststream/exceptions/AckMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.exceptions.AckMessage diff --git a/docs/docs/en/api/faststream/exceptions/ContextError.md b/docs/docs/en/api/faststream/exceptions/ContextError.md new file mode 100644 index 0000000000..73b4fcdd21 --- /dev/null +++ b/docs/docs/en/api/faststream/exceptions/ContextError.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.exceptions.ContextError diff --git a/docs/docs/en/api/faststream/exceptions/FastStreamException.md b/docs/docs/en/api/faststream/exceptions/FastStreamException.md new file mode 100644 index 0000000000..bd988e9332 --- /dev/null +++ b/docs/docs/en/api/faststream/exceptions/FastStreamException.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.exceptions.FastStreamException diff --git a/docs/docs/en/api/faststream/exceptions/FeatureNotSupportedException.md b/docs/docs/en/api/faststream/exceptions/FeatureNotSupportedException.md new file mode 100644 index 0000000000..bbf1f32d2b --- /dev/null +++ b/docs/docs/en/api/faststream/exceptions/FeatureNotSupportedException.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.exceptions.FeatureNotSupportedException diff --git a/docs/docs/en/api/faststream/exceptions/HandlerException.md b/docs/docs/en/api/faststream/exceptions/HandlerException.md new file mode 100644 index 0000000000..64495519a4 --- /dev/null +++ b/docs/docs/en/api/faststream/exceptions/HandlerException.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.exceptions.HandlerException diff --git a/docs/docs/en/api/faststream/exceptions/IgnoredException.md b/docs/docs/en/api/faststream/exceptions/IgnoredException.md new file mode 100644 index 0000000000..18452057c1 --- /dev/null +++ b/docs/docs/en/api/faststream/exceptions/IgnoredException.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.exceptions.IgnoredException diff --git a/docs/docs/en/api/faststream/exceptions/IncorrectState.md b/docs/docs/en/api/faststream/exceptions/IncorrectState.md new file mode 100644 index 0000000000..2c890d5358 --- /dev/null +++ b/docs/docs/en/api/faststream/exceptions/IncorrectState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.exceptions.IncorrectState diff --git a/docs/docs/en/api/faststream/exceptions/NackMessage.md b/docs/docs/en/api/faststream/exceptions/NackMessage.md new file mode 100644 index 0000000000..05502ca14d --- /dev/null +++ b/docs/docs/en/api/faststream/exceptions/NackMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.exceptions.NackMessage diff --git a/docs/docs/en/api/faststream/exceptions/RejectMessage.md b/docs/docs/en/api/faststream/exceptions/RejectMessage.md new file mode 100644 index 0000000000..be491d89c1 --- /dev/null +++ b/docs/docs/en/api/faststream/exceptions/RejectMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.exceptions.RejectMessage diff --git a/docs/docs/en/api/faststream/exceptions/SetupError.md b/docs/docs/en/api/faststream/exceptions/SetupError.md new file mode 100644 index 0000000000..588e66557f --- /dev/null +++ b/docs/docs/en/api/faststream/exceptions/SetupError.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.exceptions.SetupError diff --git a/docs/docs/en/api/faststream/exceptions/SkipMessage.md b/docs/docs/en/api/faststream/exceptions/SkipMessage.md new file mode 100644 index 0000000000..e2a6ac135e --- /dev/null +++ b/docs/docs/en/api/faststream/exceptions/SkipMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.exceptions.SkipMessage diff --git a/docs/docs/en/api/faststream/exceptions/StartupValidationError.md b/docs/docs/en/api/faststream/exceptions/StartupValidationError.md new file mode 100644 index 0000000000..05b8e7b74d --- /dev/null +++ b/docs/docs/en/api/faststream/exceptions/StartupValidationError.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.exceptions.StartupValidationError diff --git a/docs/docs/en/api/faststream/exceptions/StopApplication.md b/docs/docs/en/api/faststream/exceptions/StopApplication.md new file mode 100644 index 0000000000..12059837a4 --- /dev/null +++ b/docs/docs/en/api/faststream/exceptions/StopApplication.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.exceptions.StopApplication diff --git a/docs/docs/en/api/faststream/exceptions/StopConsume.md b/docs/docs/en/api/faststream/exceptions/StopConsume.md new file mode 100644 index 0000000000..9733dcc2e9 --- /dev/null +++ b/docs/docs/en/api/faststream/exceptions/StopConsume.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.exceptions.StopConsume diff --git a/docs/docs/en/api/faststream/exceptions/SubscriberNotFound.md b/docs/docs/en/api/faststream/exceptions/SubscriberNotFound.md new file mode 100644 index 0000000000..89428f8251 --- /dev/null +++ b/docs/docs/en/api/faststream/exceptions/SubscriberNotFound.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.exceptions.SubscriberNotFound diff --git a/docs/docs/en/api/faststream/kafka/KafkaBroker.md b/docs/docs/en/api/faststream/kafka/KafkaBroker.md new file mode 100644 index 0000000000..7ee56a5e01 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/KafkaBroker.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.KafkaBroker diff --git a/docs/docs/en/api/faststream/kafka/KafkaPublisher.md b/docs/docs/en/api/faststream/kafka/KafkaPublisher.md new file mode 100644 index 0000000000..c379528109 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/KafkaPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.KafkaPublisher diff --git a/docs/docs/en/api/faststream/kafka/KafkaResponse.md b/docs/docs/en/api/faststream/kafka/KafkaResponse.md new file mode 100644 index 0000000000..4aab0b965d --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/KafkaResponse.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.KafkaResponse diff --git a/docs/docs/en/api/faststream/kafka/KafkaRoute.md b/docs/docs/en/api/faststream/kafka/KafkaRoute.md new file mode 100644 index 0000000000..89a8d8cca1 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/KafkaRoute.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.KafkaRoute diff --git a/docs/docs/en/api/faststream/kafka/KafkaRouter.md b/docs/docs/en/api/faststream/kafka/KafkaRouter.md new file mode 100644 index 0000000000..c60f3ca6f4 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/KafkaRouter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.KafkaRouter diff --git a/docs/docs/en/api/faststream/kafka/TestApp.md b/docs/docs/en/api/faststream/kafka/TestApp.md new file mode 100644 index 0000000000..ad101303af --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/TestApp.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream._internal.testing.app.TestApp diff --git a/docs/docs/en/api/faststream/kafka/TestKafkaBroker.md b/docs/docs/en/api/faststream/kafka/TestKafkaBroker.md new file mode 100644 index 0000000000..096df3b1d1 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/TestKafkaBroker.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.TestKafkaBroker diff --git a/docs/docs/en/api/faststream/kafka/TopicPartition.md b/docs/docs/en/api/faststream/kafka/TopicPartition.md new file mode 100644 index 0000000000..41fbd7f624 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/TopicPartition.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: aiokafka.structs.TopicPartition diff --git a/docs/docs/en/api/faststream/kafka/broker/KafkaBroker.md b/docs/docs/en/api/faststream/kafka/broker/KafkaBroker.md new file mode 100644 index 0000000000..2cee711d14 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/broker/KafkaBroker.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.broker.KafkaBroker diff --git a/docs/docs/en/api/faststream/kafka/broker/broker/KafkaBroker.md b/docs/docs/en/api/faststream/kafka/broker/broker/KafkaBroker.md new file mode 100644 index 0000000000..ca32dd3865 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/broker/broker/KafkaBroker.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.broker.broker.KafkaBroker diff --git a/docs/docs/en/api/faststream/kafka/broker/logging/KafkaParamsStorage.md b/docs/docs/en/api/faststream/kafka/broker/logging/KafkaParamsStorage.md new file mode 100644 index 0000000000..f7c8136115 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/broker/logging/KafkaParamsStorage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.broker.logging.KafkaParamsStorage diff --git a/docs/docs/en/api/faststream/kafka/broker/registrator/KafkaRegistrator.md b/docs/docs/en/api/faststream/kafka/broker/registrator/KafkaRegistrator.md new file mode 100644 index 0000000000..aa06d38f65 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/broker/registrator/KafkaRegistrator.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.broker.registrator.KafkaRegistrator diff --git a/docs/docs/en/api/faststream/kafka/fastapi/Context.md b/docs/docs/en/api/faststream/kafka/fastapi/Context.md new file mode 100644 index 0000000000..99bf141f5c --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/fastapi/Context.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream._internal.fastapi.context.Context diff --git a/docs/docs/en/api/faststream/kafka/fastapi/KafkaRouter.md b/docs/docs/en/api/faststream/kafka/fastapi/KafkaRouter.md new file mode 100644 index 0000000000..2ab7254e79 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/fastapi/KafkaRouter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.fastapi.KafkaRouter diff --git a/docs/docs/en/api/faststream/kafka/fastapi/fastapi/KafkaRouter.md b/docs/docs/en/api/faststream/kafka/fastapi/fastapi/KafkaRouter.md new file mode 100644 index 0000000000..80fc17dd4a --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/fastapi/fastapi/KafkaRouter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.fastapi.fastapi.KafkaRouter diff --git a/docs/docs/en/api/faststream/kafka/message/ConsumerProtocol.md b/docs/docs/en/api/faststream/kafka/message/ConsumerProtocol.md new file mode 100644 index 0000000000..c9fd16a983 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/message/ConsumerProtocol.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.message.ConsumerProtocol diff --git a/docs/docs/en/api/faststream/kafka/message/FakeConsumer.md b/docs/docs/en/api/faststream/kafka/message/FakeConsumer.md new file mode 100644 index 0000000000..d41724b288 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/message/FakeConsumer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.message.FakeConsumer diff --git a/docs/docs/en/api/faststream/kafka/message/KafkaAckableMessage.md b/docs/docs/en/api/faststream/kafka/message/KafkaAckableMessage.md new file mode 100644 index 0000000000..16461be675 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/message/KafkaAckableMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.message.KafkaAckableMessage diff --git a/docs/docs/en/api/faststream/kafka/message/KafkaMessage.md b/docs/docs/en/api/faststream/kafka/message/KafkaMessage.md new file mode 100644 index 0000000000..7a7a30bae3 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/message/KafkaMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.message.KafkaMessage diff --git a/docs/docs/en/api/faststream/kafka/opentelemetry/KafkaTelemetryMiddleware.md b/docs/docs/en/api/faststream/kafka/opentelemetry/KafkaTelemetryMiddleware.md new file mode 100644 index 0000000000..02fb4805ac --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/opentelemetry/KafkaTelemetryMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.opentelemetry.KafkaTelemetryMiddleware diff --git a/docs/docs/en/api/faststream/kafka/opentelemetry/middleware/KafkaTelemetryMiddleware.md b/docs/docs/en/api/faststream/kafka/opentelemetry/middleware/KafkaTelemetryMiddleware.md new file mode 100644 index 0000000000..aba78378f2 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/opentelemetry/middleware/KafkaTelemetryMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.opentelemetry.middleware.KafkaTelemetryMiddleware diff --git a/docs/docs/en/api/faststream/kafka/opentelemetry/provider/BaseKafkaTelemetrySettingsProvider.md b/docs/docs/en/api/faststream/kafka/opentelemetry/provider/BaseKafkaTelemetrySettingsProvider.md new file mode 100644 index 0000000000..5cb13be947 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/opentelemetry/provider/BaseKafkaTelemetrySettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.opentelemetry.provider.BaseKafkaTelemetrySettingsProvider diff --git a/docs/docs/en/api/faststream/kafka/opentelemetry/provider/BatchKafkaTelemetrySettingsProvider.md b/docs/docs/en/api/faststream/kafka/opentelemetry/provider/BatchKafkaTelemetrySettingsProvider.md new file mode 100644 index 0000000000..d3d7080509 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/opentelemetry/provider/BatchKafkaTelemetrySettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.opentelemetry.provider.BatchKafkaTelemetrySettingsProvider diff --git a/docs/docs/en/api/faststream/kafka/opentelemetry/provider/KafkaTelemetrySettingsProvider.md b/docs/docs/en/api/faststream/kafka/opentelemetry/provider/KafkaTelemetrySettingsProvider.md new file mode 100644 index 0000000000..0859c0df3d --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/opentelemetry/provider/KafkaTelemetrySettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.opentelemetry.provider.KafkaTelemetrySettingsProvider diff --git a/docs/docs/en/api/faststream/kafka/opentelemetry/provider/telemetry_attributes_provider_factory.md b/docs/docs/en/api/faststream/kafka/opentelemetry/provider/telemetry_attributes_provider_factory.md new file mode 100644 index 0000000000..3b2a1ad394 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/opentelemetry/provider/telemetry_attributes_provider_factory.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.opentelemetry.provider.telemetry_attributes_provider_factory diff --git a/docs/docs/en/api/faststream/kafka/parser/AioKafkaBatchParser.md b/docs/docs/en/api/faststream/kafka/parser/AioKafkaBatchParser.md new file mode 100644 index 0000000000..25df2532c6 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/parser/AioKafkaBatchParser.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.parser.AioKafkaBatchParser diff --git a/docs/docs/en/api/faststream/kafka/parser/AioKafkaParser.md b/docs/docs/en/api/faststream/kafka/parser/AioKafkaParser.md new file mode 100644 index 0000000000..e7e37cce97 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/parser/AioKafkaParser.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.parser.AioKafkaParser diff --git a/docs/docs/en/api/faststream/kafka/prometheus/KafkaPrometheusMiddleware.md b/docs/docs/en/api/faststream/kafka/prometheus/KafkaPrometheusMiddleware.md new file mode 100644 index 0000000000..c2ffd5356a --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/prometheus/KafkaPrometheusMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.prometheus.KafkaPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/kafka/prometheus/middleware/KafkaPrometheusMiddleware.md b/docs/docs/en/api/faststream/kafka/prometheus/middleware/KafkaPrometheusMiddleware.md new file mode 100644 index 0000000000..451b7080c0 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/prometheus/middleware/KafkaPrometheusMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.prometheus.middleware.KafkaPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/kafka/prometheus/provider/BaseKafkaMetricsSettingsProvider.md b/docs/docs/en/api/faststream/kafka/prometheus/provider/BaseKafkaMetricsSettingsProvider.md new file mode 100644 index 0000000000..0fd044f694 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/prometheus/provider/BaseKafkaMetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.prometheus.provider.BaseKafkaMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/kafka/prometheus/provider/BatchKafkaMetricsSettingsProvider.md b/docs/docs/en/api/faststream/kafka/prometheus/provider/BatchKafkaMetricsSettingsProvider.md new file mode 100644 index 0000000000..9bd01d5e71 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/prometheus/provider/BatchKafkaMetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.prometheus.provider.BatchKafkaMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/kafka/prometheus/provider/KafkaMetricsSettingsProvider.md b/docs/docs/en/api/faststream/kafka/prometheus/provider/KafkaMetricsSettingsProvider.md new file mode 100644 index 0000000000..ae7c490da8 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/prometheus/provider/KafkaMetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.prometheus.provider.KafkaMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/kafka/prometheus/provider/settings_provider_factory.md b/docs/docs/en/api/faststream/kafka/prometheus/provider/settings_provider_factory.md new file mode 100644 index 0000000000..1393fd9065 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/prometheus/provider/settings_provider_factory.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.prometheus.provider.settings_provider_factory diff --git a/docs/docs/en/api/faststream/kafka/publisher/factory/create_publisher.md b/docs/docs/en/api/faststream/kafka/publisher/factory/create_publisher.md new file mode 100644 index 0000000000..7ec33758af --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/publisher/factory/create_publisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.publisher.factory.create_publisher diff --git a/docs/docs/en/api/faststream/kafka/publisher/fake/KafkaFakePublisher.md b/docs/docs/en/api/faststream/kafka/publisher/fake/KafkaFakePublisher.md new file mode 100644 index 0000000000..6bacca904e --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/publisher/fake/KafkaFakePublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.publisher.fake.KafkaFakePublisher diff --git a/docs/docs/en/api/faststream/kafka/publisher/producer/AioKafkaFastProducer.md b/docs/docs/en/api/faststream/kafka/publisher/producer/AioKafkaFastProducer.md new file mode 100644 index 0000000000..83b116989b --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/publisher/producer/AioKafkaFastProducer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.publisher.producer.AioKafkaFastProducer diff --git a/docs/docs/en/api/faststream/kafka/publisher/specified/SpecificationBatchPublisher.md b/docs/docs/en/api/faststream/kafka/publisher/specified/SpecificationBatchPublisher.md new file mode 100644 index 0000000000..795766b030 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/publisher/specified/SpecificationBatchPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.publisher.specified.SpecificationBatchPublisher diff --git a/docs/docs/en/api/faststream/kafka/publisher/specified/SpecificationDefaultPublisher.md b/docs/docs/en/api/faststream/kafka/publisher/specified/SpecificationDefaultPublisher.md new file mode 100644 index 0000000000..e191045545 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/publisher/specified/SpecificationDefaultPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.publisher.specified.SpecificationDefaultPublisher diff --git a/docs/docs/en/api/faststream/kafka/publisher/specified/SpecificationPublisher.md b/docs/docs/en/api/faststream/kafka/publisher/specified/SpecificationPublisher.md new file mode 100644 index 0000000000..ed687d7e08 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/publisher/specified/SpecificationPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.publisher.specified.SpecificationPublisher diff --git a/docs/docs/en/api/faststream/kafka/publisher/state/EmptyProducerState.md b/docs/docs/en/api/faststream/kafka/publisher/state/EmptyProducerState.md new file mode 100644 index 0000000000..0152ee7c2f --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/publisher/state/EmptyProducerState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.publisher.state.EmptyProducerState diff --git a/docs/docs/en/api/faststream/kafka/publisher/state/ProducerState.md b/docs/docs/en/api/faststream/kafka/publisher/state/ProducerState.md new file mode 100644 index 0000000000..c937179471 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/publisher/state/ProducerState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.publisher.state.ProducerState diff --git a/docs/docs/en/api/faststream/kafka/publisher/state/RealProducer.md b/docs/docs/en/api/faststream/kafka/publisher/state/RealProducer.md new file mode 100644 index 0000000000..a576226b3c --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/publisher/state/RealProducer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.publisher.state.RealProducer diff --git a/docs/docs/en/api/faststream/kafka/publisher/usecase/BatchPublisher.md b/docs/docs/en/api/faststream/kafka/publisher/usecase/BatchPublisher.md new file mode 100644 index 0000000000..045cfbf45f --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/publisher/usecase/BatchPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.publisher.usecase.BatchPublisher diff --git a/docs/docs/en/api/faststream/kafka/publisher/usecase/DefaultPublisher.md b/docs/docs/en/api/faststream/kafka/publisher/usecase/DefaultPublisher.md new file mode 100644 index 0000000000..07518c75b3 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/publisher/usecase/DefaultPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.publisher.usecase.DefaultPublisher diff --git a/docs/docs/en/api/faststream/kafka/publisher/usecase/LogicPublisher.md b/docs/docs/en/api/faststream/kafka/publisher/usecase/LogicPublisher.md new file mode 100644 index 0000000000..615da58f90 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/publisher/usecase/LogicPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.publisher.usecase.LogicPublisher diff --git a/docs/docs/en/api/faststream/kafka/response/KafkaPublishCommand.md b/docs/docs/en/api/faststream/kafka/response/KafkaPublishCommand.md new file mode 100644 index 0000000000..4852098fcc --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/response/KafkaPublishCommand.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.response.KafkaPublishCommand diff --git a/docs/docs/en/api/faststream/kafka/response/KafkaResponse.md b/docs/docs/en/api/faststream/kafka/response/KafkaResponse.md new file mode 100644 index 0000000000..05ecd69c2d --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/response/KafkaResponse.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.response.KafkaResponse diff --git a/docs/docs/en/api/faststream/kafka/router/KafkaPublisher.md b/docs/docs/en/api/faststream/kafka/router/KafkaPublisher.md new file mode 100644 index 0000000000..5027c18f20 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/router/KafkaPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.router.KafkaPublisher diff --git a/docs/docs/en/api/faststream/kafka/router/KafkaRoute.md b/docs/docs/en/api/faststream/kafka/router/KafkaRoute.md new file mode 100644 index 0000000000..e7e6184deb --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/router/KafkaRoute.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.router.KafkaRoute diff --git a/docs/docs/en/api/faststream/kafka/router/KafkaRouter.md b/docs/docs/en/api/faststream/kafka/router/KafkaRouter.md new file mode 100644 index 0000000000..5d7578bbfc --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/router/KafkaRouter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.router.KafkaRouter diff --git a/docs/docs/en/api/faststream/kafka/schemas/params/ConsumerConnectionParams.md b/docs/docs/en/api/faststream/kafka/schemas/params/ConsumerConnectionParams.md new file mode 100644 index 0000000000..b289e61e5a --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/schemas/params/ConsumerConnectionParams.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.schemas.params.ConsumerConnectionParams diff --git a/docs/docs/en/api/faststream/kafka/security/parse_security.md b/docs/docs/en/api/faststream/kafka/security/parse_security.md new file mode 100644 index 0000000000..e325a99ad8 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/security/parse_security.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.security.parse_security diff --git a/docs/docs/en/api/faststream/kafka/subscriber/factory/create_subscriber.md b/docs/docs/en/api/faststream/kafka/subscriber/factory/create_subscriber.md new file mode 100644 index 0000000000..d9e5fcb4a4 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/subscriber/factory/create_subscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.subscriber.factory.create_subscriber diff --git a/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationBatchSubscriber.md b/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationBatchSubscriber.md new file mode 100644 index 0000000000..9e0ce90401 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationBatchSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.subscriber.specified.SpecificationBatchSubscriber diff --git a/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationConcurrentDefaultSubscriber.md b/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationConcurrentDefaultSubscriber.md new file mode 100644 index 0000000000..16f0f81d14 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationConcurrentDefaultSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.subscriber.specified.SpecificationConcurrentDefaultSubscriber diff --git a/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationDefaultSubscriber.md b/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationDefaultSubscriber.md new file mode 100644 index 0000000000..fe8ac61ac2 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationDefaultSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.subscriber.specified.SpecificationDefaultSubscriber diff --git a/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationSubscriber.md b/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationSubscriber.md new file mode 100644 index 0000000000..79dca87d97 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.subscriber.specified.SpecificationSubscriber diff --git a/docs/docs/en/api/faststream/kafka/subscriber/usecase/BatchSubscriber.md b/docs/docs/en/api/faststream/kafka/subscriber/usecase/BatchSubscriber.md new file mode 100644 index 0000000000..6f8978f38b --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/subscriber/usecase/BatchSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.subscriber.usecase.BatchSubscriber diff --git a/docs/docs/en/api/faststream/kafka/subscriber/usecase/ConcurrentDefaultSubscriber.md b/docs/docs/en/api/faststream/kafka/subscriber/usecase/ConcurrentDefaultSubscriber.md new file mode 100644 index 0000000000..16f09d9334 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/subscriber/usecase/ConcurrentDefaultSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.subscriber.usecase.ConcurrentDefaultSubscriber diff --git a/docs/docs/en/api/faststream/kafka/subscriber/usecase/DefaultSubscriber.md b/docs/docs/en/api/faststream/kafka/subscriber/usecase/DefaultSubscriber.md new file mode 100644 index 0000000000..78949c27dd --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/subscriber/usecase/DefaultSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.subscriber.usecase.DefaultSubscriber diff --git a/docs/docs/en/api/faststream/kafka/subscriber/usecase/LogicSubscriber.md b/docs/docs/en/api/faststream/kafka/subscriber/usecase/LogicSubscriber.md new file mode 100644 index 0000000000..297013e037 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/subscriber/usecase/LogicSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.subscriber.usecase.LogicSubscriber diff --git a/docs/docs/en/api/faststream/kafka/testing/FakeProducer.md b/docs/docs/en/api/faststream/kafka/testing/FakeProducer.md new file mode 100644 index 0000000000..63eb94c3ca --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/testing/FakeProducer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.testing.FakeProducer diff --git a/docs/docs/en/api/faststream/kafka/testing/TestKafkaBroker.md b/docs/docs/en/api/faststream/kafka/testing/TestKafkaBroker.md new file mode 100644 index 0000000000..96f257a15f --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/testing/TestKafkaBroker.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.testing.TestKafkaBroker diff --git a/docs/docs/en/api/faststream/kafka/testing/build_message.md b/docs/docs/en/api/faststream/kafka/testing/build_message.md new file mode 100644 index 0000000000..354d7a82f3 --- /dev/null +++ b/docs/docs/en/api/faststream/kafka/testing/build_message.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.kafka.testing.build_message diff --git a/docs/docs/en/api/faststream/message/AckStatus.md b/docs/docs/en/api/faststream/message/AckStatus.md new file mode 100644 index 0000000000..b8d3d6c6c8 --- /dev/null +++ b/docs/docs/en/api/faststream/message/AckStatus.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.message.AckStatus diff --git a/docs/docs/en/api/faststream/message/SourceType.md b/docs/docs/en/api/faststream/message/SourceType.md new file mode 100644 index 0000000000..7df391eac3 --- /dev/null +++ b/docs/docs/en/api/faststream/message/SourceType.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.message.SourceType diff --git a/docs/docs/en/api/faststream/message/StreamMessage.md b/docs/docs/en/api/faststream/message/StreamMessage.md new file mode 100644 index 0000000000..5f072b2410 --- /dev/null +++ b/docs/docs/en/api/faststream/message/StreamMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.message.StreamMessage diff --git a/docs/docs/en/api/faststream/message/decode_message.md b/docs/docs/en/api/faststream/message/decode_message.md new file mode 100644 index 0000000000..c0dce11670 --- /dev/null +++ b/docs/docs/en/api/faststream/message/decode_message.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.message.decode_message diff --git a/docs/docs/en/api/faststream/message/encode_message.md b/docs/docs/en/api/faststream/message/encode_message.md new file mode 100644 index 0000000000..7d33d8d904 --- /dev/null +++ b/docs/docs/en/api/faststream/message/encode_message.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.message.encode_message diff --git a/docs/docs/en/api/faststream/message/gen_cor_id.md b/docs/docs/en/api/faststream/message/gen_cor_id.md new file mode 100644 index 0000000000..0abdf298b9 --- /dev/null +++ b/docs/docs/en/api/faststream/message/gen_cor_id.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.message.gen_cor_id diff --git a/docs/docs/en/api/faststream/message/message/AckStatus.md b/docs/docs/en/api/faststream/message/message/AckStatus.md new file mode 100644 index 0000000000..80940a8ba7 --- /dev/null +++ b/docs/docs/en/api/faststream/message/message/AckStatus.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.message.message.AckStatus diff --git a/docs/docs/en/api/faststream/message/message/StreamMessage.md b/docs/docs/en/api/faststream/message/message/StreamMessage.md new file mode 100644 index 0000000000..a41232b74c --- /dev/null +++ b/docs/docs/en/api/faststream/message/message/StreamMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.message.message.StreamMessage diff --git a/docs/docs/en/api/faststream/message/source_type/SourceType.md b/docs/docs/en/api/faststream/message/source_type/SourceType.md new file mode 100644 index 0000000000..8a6fc990e4 --- /dev/null +++ b/docs/docs/en/api/faststream/message/source_type/SourceType.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.message.source_type.SourceType diff --git a/docs/docs/en/api/faststream/message/utils/decode_message.md b/docs/docs/en/api/faststream/message/utils/decode_message.md new file mode 100644 index 0000000000..b2ec48dac0 --- /dev/null +++ b/docs/docs/en/api/faststream/message/utils/decode_message.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.message.utils.decode_message diff --git a/docs/docs/en/api/faststream/message/utils/encode_message.md b/docs/docs/en/api/faststream/message/utils/encode_message.md new file mode 100644 index 0000000000..7401e07da5 --- /dev/null +++ b/docs/docs/en/api/faststream/message/utils/encode_message.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.message.utils.encode_message diff --git a/docs/docs/en/api/faststream/message/utils/gen_cor_id.md b/docs/docs/en/api/faststream/message/utils/gen_cor_id.md new file mode 100644 index 0000000000..74b49c30d2 --- /dev/null +++ b/docs/docs/en/api/faststream/message/utils/gen_cor_id.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.message.utils.gen_cor_id diff --git a/docs/docs/en/api/faststream/middlewares/AckPolicy.md b/docs/docs/en/api/faststream/middlewares/AckPolicy.md new file mode 100644 index 0000000000..82d0033dfb --- /dev/null +++ b/docs/docs/en/api/faststream/middlewares/AckPolicy.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.middlewares.AckPolicy diff --git a/docs/docs/en/api/faststream/middlewares/AcknowledgementMiddleware.md b/docs/docs/en/api/faststream/middlewares/AcknowledgementMiddleware.md new file mode 100644 index 0000000000..d3e7d6a763 --- /dev/null +++ b/docs/docs/en/api/faststream/middlewares/AcknowledgementMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.middlewares.AcknowledgementMiddleware diff --git a/docs/docs/en/api/faststream/middlewares/BaseMiddleware.md b/docs/docs/en/api/faststream/middlewares/BaseMiddleware.md new file mode 100644 index 0000000000..30f98187a1 --- /dev/null +++ b/docs/docs/en/api/faststream/middlewares/BaseMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.middlewares.BaseMiddleware diff --git a/docs/docs/en/api/faststream/middlewares/ExceptionMiddleware.md b/docs/docs/en/api/faststream/middlewares/ExceptionMiddleware.md new file mode 100644 index 0000000000..c1d21850c8 --- /dev/null +++ b/docs/docs/en/api/faststream/middlewares/ExceptionMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.middlewares.ExceptionMiddleware diff --git a/docs/docs/en/api/faststream/middlewares/acknowledgement/conf/AckPolicy.md b/docs/docs/en/api/faststream/middlewares/acknowledgement/conf/AckPolicy.md new file mode 100644 index 0000000000..8a92ec0a54 --- /dev/null +++ b/docs/docs/en/api/faststream/middlewares/acknowledgement/conf/AckPolicy.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.middlewares.acknowledgement.conf.AckPolicy diff --git a/docs/docs/en/api/faststream/middlewares/acknowledgement/middleware/AcknowledgementMiddleware.md b/docs/docs/en/api/faststream/middlewares/acknowledgement/middleware/AcknowledgementMiddleware.md new file mode 100644 index 0000000000..79b2956eb4 --- /dev/null +++ b/docs/docs/en/api/faststream/middlewares/acknowledgement/middleware/AcknowledgementMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.middlewares.acknowledgement.middleware.AcknowledgementMiddleware diff --git a/docs/docs/en/api/faststream/middlewares/base/BaseMiddleware.md b/docs/docs/en/api/faststream/middlewares/base/BaseMiddleware.md new file mode 100644 index 0000000000..d3319e7441 --- /dev/null +++ b/docs/docs/en/api/faststream/middlewares/base/BaseMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.middlewares.base.BaseMiddleware diff --git a/docs/docs/en/api/faststream/middlewares/exception/ExceptionMiddleware.md b/docs/docs/en/api/faststream/middlewares/exception/ExceptionMiddleware.md new file mode 100644 index 0000000000..da1693a722 --- /dev/null +++ b/docs/docs/en/api/faststream/middlewares/exception/ExceptionMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.middlewares.exception.ExceptionMiddleware diff --git a/docs/docs/en/api/faststream/middlewares/exception/ignore_handler.md b/docs/docs/en/api/faststream/middlewares/exception/ignore_handler.md new file mode 100644 index 0000000000..1eea49ddbe --- /dev/null +++ b/docs/docs/en/api/faststream/middlewares/exception/ignore_handler.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.middlewares.exception.ignore_handler diff --git a/docs/docs/en/api/faststream/middlewares/logging/CriticalLogMiddleware.md b/docs/docs/en/api/faststream/middlewares/logging/CriticalLogMiddleware.md new file mode 100644 index 0000000000..58be3830e6 --- /dev/null +++ b/docs/docs/en/api/faststream/middlewares/logging/CriticalLogMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.middlewares.logging.CriticalLogMiddleware diff --git a/docs/docs/en/api/faststream/nats/AckPolicy.md b/docs/docs/en/api/faststream/nats/AckPolicy.md new file mode 100644 index 0000000000..308d12ac63 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/AckPolicy.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: nats.js.api.AckPolicy diff --git a/docs/docs/en/api/faststream/nats/ConsumerConfig.md b/docs/docs/en/api/faststream/nats/ConsumerConfig.md new file mode 100644 index 0000000000..56c357cc07 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/ConsumerConfig.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: nats.js.api.ConsumerConfig diff --git a/docs/docs/en/api/faststream/nats/DeliverPolicy.md b/docs/docs/en/api/faststream/nats/DeliverPolicy.md new file mode 100644 index 0000000000..ebb664d0d9 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/DeliverPolicy.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: nats.js.api.DeliverPolicy diff --git a/docs/docs/en/api/faststream/nats/DiscardPolicy.md b/docs/docs/en/api/faststream/nats/DiscardPolicy.md new file mode 100644 index 0000000000..9eacd12198 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/DiscardPolicy.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: nats.js.api.DiscardPolicy diff --git a/docs/docs/en/api/faststream/nats/ExternalStream.md b/docs/docs/en/api/faststream/nats/ExternalStream.md new file mode 100644 index 0000000000..5ea0eacbbc --- /dev/null +++ b/docs/docs/en/api/faststream/nats/ExternalStream.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: nats.js.api.ExternalStream diff --git a/docs/docs/en/api/faststream/nats/JStream.md b/docs/docs/en/api/faststream/nats/JStream.md new file mode 100644 index 0000000000..70ca7cab69 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/JStream.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.JStream diff --git a/docs/docs/en/api/faststream/nats/KvWatch.md b/docs/docs/en/api/faststream/nats/KvWatch.md new file mode 100644 index 0000000000..1527be51fd --- /dev/null +++ b/docs/docs/en/api/faststream/nats/KvWatch.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.KvWatch diff --git a/docs/docs/en/api/faststream/nats/NatsBroker.md b/docs/docs/en/api/faststream/nats/NatsBroker.md new file mode 100644 index 0000000000..376231c4cd --- /dev/null +++ b/docs/docs/en/api/faststream/nats/NatsBroker.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.NatsBroker diff --git a/docs/docs/en/api/faststream/nats/NatsPublisher.md b/docs/docs/en/api/faststream/nats/NatsPublisher.md new file mode 100644 index 0000000000..1f1ffbca2a --- /dev/null +++ b/docs/docs/en/api/faststream/nats/NatsPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.NatsPublisher diff --git a/docs/docs/en/api/faststream/nats/NatsResponse.md b/docs/docs/en/api/faststream/nats/NatsResponse.md new file mode 100644 index 0000000000..6b967b527a --- /dev/null +++ b/docs/docs/en/api/faststream/nats/NatsResponse.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.NatsResponse diff --git a/docs/docs/en/api/faststream/nats/NatsRoute.md b/docs/docs/en/api/faststream/nats/NatsRoute.md new file mode 100644 index 0000000000..b76a8481dc --- /dev/null +++ b/docs/docs/en/api/faststream/nats/NatsRoute.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.NatsRoute diff --git a/docs/docs/en/api/faststream/nats/NatsRouter.md b/docs/docs/en/api/faststream/nats/NatsRouter.md new file mode 100644 index 0000000000..89e975235b --- /dev/null +++ b/docs/docs/en/api/faststream/nats/NatsRouter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.NatsRouter diff --git a/docs/docs/en/api/faststream/nats/ObjWatch.md b/docs/docs/en/api/faststream/nats/ObjWatch.md new file mode 100644 index 0000000000..50102ecf31 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/ObjWatch.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.ObjWatch diff --git a/docs/docs/en/api/faststream/nats/Placement.md b/docs/docs/en/api/faststream/nats/Placement.md new file mode 100644 index 0000000000..bff8b3d4b8 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/Placement.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: nats.js.api.Placement diff --git a/docs/docs/en/api/faststream/nats/PubAck.md b/docs/docs/en/api/faststream/nats/PubAck.md new file mode 100644 index 0000000000..697f22abe6 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/PubAck.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: nats.js.api.PubAck diff --git a/docs/docs/en/api/faststream/nats/PullSub.md b/docs/docs/en/api/faststream/nats/PullSub.md new file mode 100644 index 0000000000..dbfaf68f54 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/PullSub.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.PullSub diff --git a/docs/docs/en/api/faststream/nats/RePublish.md b/docs/docs/en/api/faststream/nats/RePublish.md new file mode 100644 index 0000000000..35ad498def --- /dev/null +++ b/docs/docs/en/api/faststream/nats/RePublish.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: nats.js.api.RePublish diff --git a/docs/docs/en/api/faststream/nats/ReplayPolicy.md b/docs/docs/en/api/faststream/nats/ReplayPolicy.md new file mode 100644 index 0000000000..6430f0a22f --- /dev/null +++ b/docs/docs/en/api/faststream/nats/ReplayPolicy.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: nats.js.api.ReplayPolicy diff --git a/docs/docs/en/api/faststream/nats/RetentionPolicy.md b/docs/docs/en/api/faststream/nats/RetentionPolicy.md new file mode 100644 index 0000000000..919b818c9e --- /dev/null +++ b/docs/docs/en/api/faststream/nats/RetentionPolicy.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: nats.js.api.RetentionPolicy diff --git a/docs/docs/en/api/faststream/nats/StorageType.md b/docs/docs/en/api/faststream/nats/StorageType.md new file mode 100644 index 0000000000..78a6bc4d8f --- /dev/null +++ b/docs/docs/en/api/faststream/nats/StorageType.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: nats.js.api.StorageType diff --git a/docs/docs/en/api/faststream/nats/StreamConfig.md b/docs/docs/en/api/faststream/nats/StreamConfig.md new file mode 100644 index 0000000000..3bce18f7de --- /dev/null +++ b/docs/docs/en/api/faststream/nats/StreamConfig.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: nats.js.api.StreamConfig diff --git a/docs/docs/en/api/faststream/nats/StreamSource.md b/docs/docs/en/api/faststream/nats/StreamSource.md new file mode 100644 index 0000000000..4d85db37e5 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/StreamSource.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: nats.js.api.StreamSource diff --git a/docs/docs/en/api/faststream/nats/TestApp.md b/docs/docs/en/api/faststream/nats/TestApp.md new file mode 100644 index 0000000000..ad101303af --- /dev/null +++ b/docs/docs/en/api/faststream/nats/TestApp.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream._internal.testing.app.TestApp diff --git a/docs/docs/en/api/faststream/nats/TestNatsBroker.md b/docs/docs/en/api/faststream/nats/TestNatsBroker.md new file mode 100644 index 0000000000..8557295619 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/TestNatsBroker.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.TestNatsBroker diff --git a/docs/docs/en/api/faststream/nats/broker/NatsBroker.md b/docs/docs/en/api/faststream/nats/broker/NatsBroker.md new file mode 100644 index 0000000000..eeea31372b --- /dev/null +++ b/docs/docs/en/api/faststream/nats/broker/NatsBroker.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.broker.NatsBroker diff --git a/docs/docs/en/api/faststream/nats/broker/broker/NatsBroker.md b/docs/docs/en/api/faststream/nats/broker/broker/NatsBroker.md new file mode 100644 index 0000000000..7aed0de1ec --- /dev/null +++ b/docs/docs/en/api/faststream/nats/broker/broker/NatsBroker.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.broker.broker.NatsBroker diff --git a/docs/docs/en/api/faststream/nats/broker/logging/NatsParamsStorage.md b/docs/docs/en/api/faststream/nats/broker/logging/NatsParamsStorage.md new file mode 100644 index 0000000000..25b77d4331 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/broker/logging/NatsParamsStorage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.broker.logging.NatsParamsStorage diff --git a/docs/docs/en/api/faststream/nats/broker/registrator/NatsRegistrator.md b/docs/docs/en/api/faststream/nats/broker/registrator/NatsRegistrator.md new file mode 100644 index 0000000000..f7f313746a --- /dev/null +++ b/docs/docs/en/api/faststream/nats/broker/registrator/NatsRegistrator.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.broker.registrator.NatsRegistrator diff --git a/docs/docs/en/api/faststream/nats/broker/state/BrokerState.md b/docs/docs/en/api/faststream/nats/broker/state/BrokerState.md new file mode 100644 index 0000000000..ed5dc00c35 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/broker/state/BrokerState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.broker.state.BrokerState diff --git a/docs/docs/en/api/faststream/nats/broker/state/ConnectedState.md b/docs/docs/en/api/faststream/nats/broker/state/ConnectedState.md new file mode 100644 index 0000000000..b7bb106798 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/broker/state/ConnectedState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.broker.state.ConnectedState diff --git a/docs/docs/en/api/faststream/nats/broker/state/ConnectionBrokenState.md b/docs/docs/en/api/faststream/nats/broker/state/ConnectionBrokenState.md new file mode 100644 index 0000000000..66df604330 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/broker/state/ConnectionBrokenState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.broker.state.ConnectionBrokenState diff --git a/docs/docs/en/api/faststream/nats/broker/state/EmptyBrokerState.md b/docs/docs/en/api/faststream/nats/broker/state/EmptyBrokerState.md new file mode 100644 index 0000000000..88bf83710d --- /dev/null +++ b/docs/docs/en/api/faststream/nats/broker/state/EmptyBrokerState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.broker.state.EmptyBrokerState diff --git a/docs/docs/en/api/faststream/nats/fastapi/Context.md b/docs/docs/en/api/faststream/nats/fastapi/Context.md new file mode 100644 index 0000000000..99bf141f5c --- /dev/null +++ b/docs/docs/en/api/faststream/nats/fastapi/Context.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream._internal.fastapi.context.Context diff --git a/docs/docs/en/api/faststream/nats/fastapi/NatsRouter.md b/docs/docs/en/api/faststream/nats/fastapi/NatsRouter.md new file mode 100644 index 0000000000..53123192c2 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/fastapi/NatsRouter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.fastapi.NatsRouter diff --git a/docs/docs/en/api/faststream/nats/fastapi/fastapi/NatsRouter.md b/docs/docs/en/api/faststream/nats/fastapi/fastapi/NatsRouter.md new file mode 100644 index 0000000000..015f730b4f --- /dev/null +++ b/docs/docs/en/api/faststream/nats/fastapi/fastapi/NatsRouter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.fastapi.fastapi.NatsRouter diff --git a/docs/docs/en/api/faststream/nats/helpers/KVBucketDeclarer.md b/docs/docs/en/api/faststream/nats/helpers/KVBucketDeclarer.md new file mode 100644 index 0000000000..b24feaada6 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/helpers/KVBucketDeclarer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.helpers.KVBucketDeclarer diff --git a/docs/docs/en/api/faststream/nats/helpers/OSBucketDeclarer.md b/docs/docs/en/api/faststream/nats/helpers/OSBucketDeclarer.md new file mode 100644 index 0000000000..3ee16a3f24 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/helpers/OSBucketDeclarer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.helpers.OSBucketDeclarer diff --git a/docs/docs/en/api/faststream/nats/helpers/StreamBuilder.md b/docs/docs/en/api/faststream/nats/helpers/StreamBuilder.md new file mode 100644 index 0000000000..3b2a318598 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/helpers/StreamBuilder.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.helpers.StreamBuilder diff --git a/docs/docs/en/api/faststream/nats/helpers/bucket_declarer/KVBucketDeclarer.md b/docs/docs/en/api/faststream/nats/helpers/bucket_declarer/KVBucketDeclarer.md new file mode 100644 index 0000000000..fe0eaec17f --- /dev/null +++ b/docs/docs/en/api/faststream/nats/helpers/bucket_declarer/KVBucketDeclarer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.helpers.bucket_declarer.KVBucketDeclarer diff --git a/docs/docs/en/api/faststream/nats/helpers/obj_storage_declarer/OSBucketDeclarer.md b/docs/docs/en/api/faststream/nats/helpers/obj_storage_declarer/OSBucketDeclarer.md new file mode 100644 index 0000000000..b7663051c8 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/helpers/obj_storage_declarer/OSBucketDeclarer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.helpers.obj_storage_declarer.OSBucketDeclarer diff --git a/docs/docs/en/api/faststream/nats/helpers/object_builder/StreamBuilder.md b/docs/docs/en/api/faststream/nats/helpers/object_builder/StreamBuilder.md new file mode 100644 index 0000000000..024daf2d14 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/helpers/object_builder/StreamBuilder.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.helpers.object_builder.StreamBuilder diff --git a/docs/docs/en/api/faststream/nats/helpers/state/ConnectedState.md b/docs/docs/en/api/faststream/nats/helpers/state/ConnectedState.md new file mode 100644 index 0000000000..888302338b --- /dev/null +++ b/docs/docs/en/api/faststream/nats/helpers/state/ConnectedState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.helpers.state.ConnectedState diff --git a/docs/docs/en/api/faststream/nats/helpers/state/ConnectionState.md b/docs/docs/en/api/faststream/nats/helpers/state/ConnectionState.md new file mode 100644 index 0000000000..0d99fb56ed --- /dev/null +++ b/docs/docs/en/api/faststream/nats/helpers/state/ConnectionState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.helpers.state.ConnectionState diff --git a/docs/docs/en/api/faststream/nats/helpers/state/EmptyConnectionState.md b/docs/docs/en/api/faststream/nats/helpers/state/EmptyConnectionState.md new file mode 100644 index 0000000000..31a062d4ad --- /dev/null +++ b/docs/docs/en/api/faststream/nats/helpers/state/EmptyConnectionState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.helpers.state.EmptyConnectionState diff --git a/docs/docs/en/api/faststream/nats/message/NatsBatchMessage.md b/docs/docs/en/api/faststream/nats/message/NatsBatchMessage.md new file mode 100644 index 0000000000..83017107ff --- /dev/null +++ b/docs/docs/en/api/faststream/nats/message/NatsBatchMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.message.NatsBatchMessage diff --git a/docs/docs/en/api/faststream/nats/message/NatsKvMessage.md b/docs/docs/en/api/faststream/nats/message/NatsKvMessage.md new file mode 100644 index 0000000000..5ac6ed9f41 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/message/NatsKvMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.message.NatsKvMessage diff --git a/docs/docs/en/api/faststream/nats/message/NatsMessage.md b/docs/docs/en/api/faststream/nats/message/NatsMessage.md new file mode 100644 index 0000000000..22d17ceb56 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/message/NatsMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.message.NatsMessage diff --git a/docs/docs/en/api/faststream/nats/message/NatsObjMessage.md b/docs/docs/en/api/faststream/nats/message/NatsObjMessage.md new file mode 100644 index 0000000000..3671628da4 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/message/NatsObjMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.message.NatsObjMessage diff --git a/docs/docs/en/api/faststream/nats/opentelemetry/NatsTelemetryMiddleware.md b/docs/docs/en/api/faststream/nats/opentelemetry/NatsTelemetryMiddleware.md new file mode 100644 index 0000000000..e72f2de8ab --- /dev/null +++ b/docs/docs/en/api/faststream/nats/opentelemetry/NatsTelemetryMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.opentelemetry.NatsTelemetryMiddleware diff --git a/docs/docs/en/api/faststream/nats/opentelemetry/middleware/NatsTelemetryMiddleware.md b/docs/docs/en/api/faststream/nats/opentelemetry/middleware/NatsTelemetryMiddleware.md new file mode 100644 index 0000000000..b2bb226585 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/opentelemetry/middleware/NatsTelemetryMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.opentelemetry.middleware.NatsTelemetryMiddleware diff --git a/docs/docs/en/api/faststream/nats/opentelemetry/provider/BaseNatsTelemetrySettingsProvider.md b/docs/docs/en/api/faststream/nats/opentelemetry/provider/BaseNatsTelemetrySettingsProvider.md new file mode 100644 index 0000000000..d6626c537d --- /dev/null +++ b/docs/docs/en/api/faststream/nats/opentelemetry/provider/BaseNatsTelemetrySettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.opentelemetry.provider.BaseNatsTelemetrySettingsProvider diff --git a/docs/docs/en/api/faststream/nats/opentelemetry/provider/NatsBatchTelemetrySettingsProvider.md b/docs/docs/en/api/faststream/nats/opentelemetry/provider/NatsBatchTelemetrySettingsProvider.md new file mode 100644 index 0000000000..045996125a --- /dev/null +++ b/docs/docs/en/api/faststream/nats/opentelemetry/provider/NatsBatchTelemetrySettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.opentelemetry.provider.NatsBatchTelemetrySettingsProvider diff --git a/docs/docs/en/api/faststream/nats/opentelemetry/provider/NatsTelemetrySettingsProvider.md b/docs/docs/en/api/faststream/nats/opentelemetry/provider/NatsTelemetrySettingsProvider.md new file mode 100644 index 0000000000..b58590c4fa --- /dev/null +++ b/docs/docs/en/api/faststream/nats/opentelemetry/provider/NatsTelemetrySettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.opentelemetry.provider.NatsTelemetrySettingsProvider diff --git a/docs/docs/en/api/faststream/nats/opentelemetry/provider/telemetry_attributes_provider_factory.md b/docs/docs/en/api/faststream/nats/opentelemetry/provider/telemetry_attributes_provider_factory.md new file mode 100644 index 0000000000..200d333e0b --- /dev/null +++ b/docs/docs/en/api/faststream/nats/opentelemetry/provider/telemetry_attributes_provider_factory.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.opentelemetry.provider.telemetry_attributes_provider_factory diff --git a/docs/docs/en/api/faststream/nats/parser/BatchParser.md b/docs/docs/en/api/faststream/nats/parser/BatchParser.md new file mode 100644 index 0000000000..03ad25f549 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/parser/BatchParser.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.parser.BatchParser diff --git a/docs/docs/en/api/faststream/nats/parser/JsParser.md b/docs/docs/en/api/faststream/nats/parser/JsParser.md new file mode 100644 index 0000000000..0cd283d36e --- /dev/null +++ b/docs/docs/en/api/faststream/nats/parser/JsParser.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.parser.JsParser diff --git a/docs/docs/en/api/faststream/nats/parser/KvParser.md b/docs/docs/en/api/faststream/nats/parser/KvParser.md new file mode 100644 index 0000000000..acba65e133 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/parser/KvParser.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.parser.KvParser diff --git a/docs/docs/en/api/faststream/nats/parser/NatsBaseParser.md b/docs/docs/en/api/faststream/nats/parser/NatsBaseParser.md new file mode 100644 index 0000000000..00b038738d --- /dev/null +++ b/docs/docs/en/api/faststream/nats/parser/NatsBaseParser.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.parser.NatsBaseParser diff --git a/docs/docs/en/api/faststream/nats/parser/NatsParser.md b/docs/docs/en/api/faststream/nats/parser/NatsParser.md new file mode 100644 index 0000000000..ceed3d0bdf --- /dev/null +++ b/docs/docs/en/api/faststream/nats/parser/NatsParser.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.parser.NatsParser diff --git a/docs/docs/en/api/faststream/nats/parser/ObjParser.md b/docs/docs/en/api/faststream/nats/parser/ObjParser.md new file mode 100644 index 0000000000..50ff5d0e18 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/parser/ObjParser.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.parser.ObjParser diff --git a/docs/docs/en/api/faststream/nats/prometheus/NatsPrometheusMiddleware.md b/docs/docs/en/api/faststream/nats/prometheus/NatsPrometheusMiddleware.md new file mode 100644 index 0000000000..d9b179b0c4 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/prometheus/NatsPrometheusMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.prometheus.NatsPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/nats/prometheus/middleware/NatsPrometheusMiddleware.md b/docs/docs/en/api/faststream/nats/prometheus/middleware/NatsPrometheusMiddleware.md new file mode 100644 index 0000000000..7202731048 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/prometheus/middleware/NatsPrometheusMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.prometheus.middleware.NatsPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/nats/prometheus/provider/BaseNatsMetricsSettingsProvider.md b/docs/docs/en/api/faststream/nats/prometheus/provider/BaseNatsMetricsSettingsProvider.md new file mode 100644 index 0000000000..80742833bc --- /dev/null +++ b/docs/docs/en/api/faststream/nats/prometheus/provider/BaseNatsMetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.prometheus.provider.BaseNatsMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/nats/prometheus/provider/BatchNatsMetricsSettingsProvider.md b/docs/docs/en/api/faststream/nats/prometheus/provider/BatchNatsMetricsSettingsProvider.md new file mode 100644 index 0000000000..163ebb7bc6 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/prometheus/provider/BatchNatsMetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.prometheus.provider.BatchNatsMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/nats/prometheus/provider/NatsMetricsSettingsProvider.md b/docs/docs/en/api/faststream/nats/prometheus/provider/NatsMetricsSettingsProvider.md new file mode 100644 index 0000000000..e5515a4cc5 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/prometheus/provider/NatsMetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.prometheus.provider.NatsMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/nats/prometheus/provider/settings_provider_factory.md b/docs/docs/en/api/faststream/nats/prometheus/provider/settings_provider_factory.md new file mode 100644 index 0000000000..aeaa7b26e0 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/prometheus/provider/settings_provider_factory.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.prometheus.provider.settings_provider_factory diff --git a/docs/docs/en/api/faststream/nats/publisher/factory/create_publisher.md b/docs/docs/en/api/faststream/nats/publisher/factory/create_publisher.md new file mode 100644 index 0000000000..19b23b99a5 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/publisher/factory/create_publisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.publisher.factory.create_publisher diff --git a/docs/docs/en/api/faststream/nats/publisher/fake/NatsFakePublisher.md b/docs/docs/en/api/faststream/nats/publisher/fake/NatsFakePublisher.md new file mode 100644 index 0000000000..df23cc8045 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/publisher/fake/NatsFakePublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.publisher.fake.NatsFakePublisher diff --git a/docs/docs/en/api/faststream/nats/publisher/producer/NatsFastProducer.md b/docs/docs/en/api/faststream/nats/publisher/producer/NatsFastProducer.md new file mode 100644 index 0000000000..82ff491f16 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/publisher/producer/NatsFastProducer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.publisher.producer.NatsFastProducer diff --git a/docs/docs/en/api/faststream/nats/publisher/producer/NatsJSFastProducer.md b/docs/docs/en/api/faststream/nats/publisher/producer/NatsJSFastProducer.md new file mode 100644 index 0000000000..9c0e046e61 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/publisher/producer/NatsJSFastProducer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.publisher.producer.NatsJSFastProducer diff --git a/docs/docs/en/api/faststream/nats/publisher/specified/SpecificationPublisher.md b/docs/docs/en/api/faststream/nats/publisher/specified/SpecificationPublisher.md new file mode 100644 index 0000000000..3f5eec9e22 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/publisher/specified/SpecificationPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.publisher.specified.SpecificationPublisher diff --git a/docs/docs/en/api/faststream/nats/publisher/usecase/LogicPublisher.md b/docs/docs/en/api/faststream/nats/publisher/usecase/LogicPublisher.md new file mode 100644 index 0000000000..08c7794545 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/publisher/usecase/LogicPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.publisher.usecase.LogicPublisher diff --git a/docs/docs/en/api/faststream/nats/response/NatsPublishCommand.md b/docs/docs/en/api/faststream/nats/response/NatsPublishCommand.md new file mode 100644 index 0000000000..148119ba8a --- /dev/null +++ b/docs/docs/en/api/faststream/nats/response/NatsPublishCommand.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.response.NatsPublishCommand diff --git a/docs/docs/en/api/faststream/nats/response/NatsResponse.md b/docs/docs/en/api/faststream/nats/response/NatsResponse.md new file mode 100644 index 0000000000..8a7da66982 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/response/NatsResponse.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.response.NatsResponse diff --git a/docs/docs/en/api/faststream/nats/router/NatsPublisher.md b/docs/docs/en/api/faststream/nats/router/NatsPublisher.md new file mode 100644 index 0000000000..b025495e44 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/router/NatsPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.router.NatsPublisher diff --git a/docs/docs/en/api/faststream/nats/router/NatsRoute.md b/docs/docs/en/api/faststream/nats/router/NatsRoute.md new file mode 100644 index 0000000000..36df33c45e --- /dev/null +++ b/docs/docs/en/api/faststream/nats/router/NatsRoute.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.router.NatsRoute diff --git a/docs/docs/en/api/faststream/nats/router/NatsRouter.md b/docs/docs/en/api/faststream/nats/router/NatsRouter.md new file mode 100644 index 0000000000..4b6dfaaf7d --- /dev/null +++ b/docs/docs/en/api/faststream/nats/router/NatsRouter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.router.NatsRouter diff --git a/docs/docs/en/api/faststream/nats/schemas/JStream.md b/docs/docs/en/api/faststream/nats/schemas/JStream.md new file mode 100644 index 0000000000..51df9a02cc --- /dev/null +++ b/docs/docs/en/api/faststream/nats/schemas/JStream.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.schemas.JStream diff --git a/docs/docs/en/api/faststream/nats/schemas/KvWatch.md b/docs/docs/en/api/faststream/nats/schemas/KvWatch.md new file mode 100644 index 0000000000..ce99738043 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/schemas/KvWatch.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.schemas.KvWatch diff --git a/docs/docs/en/api/faststream/nats/schemas/ObjWatch.md b/docs/docs/en/api/faststream/nats/schemas/ObjWatch.md new file mode 100644 index 0000000000..51c3628e5e --- /dev/null +++ b/docs/docs/en/api/faststream/nats/schemas/ObjWatch.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.schemas.ObjWatch diff --git a/docs/docs/en/api/faststream/nats/schemas/PubAck.md b/docs/docs/en/api/faststream/nats/schemas/PubAck.md new file mode 100644 index 0000000000..697f22abe6 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/schemas/PubAck.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: nats.js.api.PubAck diff --git a/docs/docs/en/api/faststream/nats/schemas/PullSub.md b/docs/docs/en/api/faststream/nats/schemas/PullSub.md new file mode 100644 index 0000000000..cb7341340c --- /dev/null +++ b/docs/docs/en/api/faststream/nats/schemas/PullSub.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.schemas.PullSub diff --git a/docs/docs/en/api/faststream/nats/schemas/js_stream/JStream.md b/docs/docs/en/api/faststream/nats/schemas/js_stream/JStream.md new file mode 100644 index 0000000000..af375c116a --- /dev/null +++ b/docs/docs/en/api/faststream/nats/schemas/js_stream/JStream.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.schemas.js_stream.JStream diff --git a/docs/docs/en/api/faststream/nats/schemas/js_stream/compile_nats_wildcard.md b/docs/docs/en/api/faststream/nats/schemas/js_stream/compile_nats_wildcard.md new file mode 100644 index 0000000000..910f034eff --- /dev/null +++ b/docs/docs/en/api/faststream/nats/schemas/js_stream/compile_nats_wildcard.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.schemas.js_stream.compile_nats_wildcard diff --git a/docs/docs/en/api/faststream/nats/schemas/js_stream/is_subject_match_wildcard.md b/docs/docs/en/api/faststream/nats/schemas/js_stream/is_subject_match_wildcard.md new file mode 100644 index 0000000000..f9305b94e8 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/schemas/js_stream/is_subject_match_wildcard.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.schemas.js_stream.is_subject_match_wildcard diff --git a/docs/docs/en/api/faststream/nats/schemas/kv_watch/KvWatch.md b/docs/docs/en/api/faststream/nats/schemas/kv_watch/KvWatch.md new file mode 100644 index 0000000000..ce07fa305d --- /dev/null +++ b/docs/docs/en/api/faststream/nats/schemas/kv_watch/KvWatch.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.schemas.kv_watch.KvWatch diff --git a/docs/docs/en/api/faststream/nats/schemas/obj_watch/ObjWatch.md b/docs/docs/en/api/faststream/nats/schemas/obj_watch/ObjWatch.md new file mode 100644 index 0000000000..55831b8a6a --- /dev/null +++ b/docs/docs/en/api/faststream/nats/schemas/obj_watch/ObjWatch.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.schemas.obj_watch.ObjWatch diff --git a/docs/docs/en/api/faststream/nats/schemas/pull_sub/PullSub.md b/docs/docs/en/api/faststream/nats/schemas/pull_sub/PullSub.md new file mode 100644 index 0000000000..673a1e8ff6 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/schemas/pull_sub/PullSub.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.schemas.pull_sub.PullSub diff --git a/docs/docs/en/api/faststream/nats/security/parse_security.md b/docs/docs/en/api/faststream/nats/security/parse_security.md new file mode 100644 index 0000000000..d2fe5dd0c3 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/security/parse_security.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.security.parse_security diff --git a/docs/docs/en/api/faststream/nats/subscriber/adapters/UnsubscribeAdapter.md b/docs/docs/en/api/faststream/nats/subscriber/adapters/UnsubscribeAdapter.md new file mode 100644 index 0000000000..9b00a89428 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/adapters/UnsubscribeAdapter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.adapters.UnsubscribeAdapter diff --git a/docs/docs/en/api/faststream/nats/subscriber/adapters/Unsubscriptable.md b/docs/docs/en/api/faststream/nats/subscriber/adapters/Unsubscriptable.md new file mode 100644 index 0000000000..4c6c6b0abe --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/adapters/Unsubscriptable.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.adapters.Unsubscriptable diff --git a/docs/docs/en/api/faststream/nats/subscriber/adapters/Watchable.md b/docs/docs/en/api/faststream/nats/subscriber/adapters/Watchable.md new file mode 100644 index 0000000000..00dde78565 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/adapters/Watchable.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.adapters.Watchable diff --git a/docs/docs/en/api/faststream/nats/subscriber/factory/create_subscriber.md b/docs/docs/en/api/faststream/nats/subscriber/factory/create_subscriber.md new file mode 100644 index 0000000000..0e132c3394 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/factory/create_subscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.factory.create_subscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationBatchPullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationBatchPullStreamSubscriber.md new file mode 100644 index 0000000000..d663201213 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationBatchPullStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.specified.SpecificationBatchPullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationConcurrentCoreSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationConcurrentCoreSubscriber.md new file mode 100644 index 0000000000..24f1a256ce --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationConcurrentCoreSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.specified.SpecificationConcurrentCoreSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationConcurrentPullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationConcurrentPullStreamSubscriber.md new file mode 100644 index 0000000000..45d7106b98 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationConcurrentPullStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.specified.SpecificationConcurrentPullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationConcurrentPushStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationConcurrentPushStreamSubscriber.md new file mode 100644 index 0000000000..4a5bebd382 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationConcurrentPushStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.specified.SpecificationConcurrentPushStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationCoreSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationCoreSubscriber.md new file mode 100644 index 0000000000..5415ec6203 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationCoreSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.specified.SpecificationCoreSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationKeyValueWatchSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationKeyValueWatchSubscriber.md new file mode 100644 index 0000000000..bd9e10e9d2 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationKeyValueWatchSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.specified.SpecificationKeyValueWatchSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationObjStoreWatchSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationObjStoreWatchSubscriber.md new file mode 100644 index 0000000000..d2b5bfa27f --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationObjStoreWatchSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.specified.SpecificationObjStoreWatchSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationPullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationPullStreamSubscriber.md new file mode 100644 index 0000000000..c0867b195f --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationPullStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.specified.SpecificationPullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationPushStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationPushStreamSubscriber.md new file mode 100644 index 0000000000..ef20892652 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationPushStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.specified.SpecificationPushStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationSubscriber.md new file mode 100644 index 0000000000..613fdecd8a --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.specified.SpecificationSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/state/ConnectedSubscriberState.md b/docs/docs/en/api/faststream/nats/subscriber/state/ConnectedSubscriberState.md new file mode 100644 index 0000000000..3398403cb2 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/state/ConnectedSubscriberState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.state.ConnectedSubscriberState diff --git a/docs/docs/en/api/faststream/nats/subscriber/state/EmptySubscriberState.md b/docs/docs/en/api/faststream/nats/subscriber/state/EmptySubscriberState.md new file mode 100644 index 0000000000..de80057014 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/state/EmptySubscriberState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.state.EmptySubscriberState diff --git a/docs/docs/en/api/faststream/nats/subscriber/state/SubscriberState.md b/docs/docs/en/api/faststream/nats/subscriber/state/SubscriberState.md new file mode 100644 index 0000000000..a61839436a --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/state/SubscriberState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.state.SubscriberState diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/BatchPullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/BatchPullStreamSubscriber.md new file mode 100644 index 0000000000..667ff42587 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/BatchPullStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.BatchPullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentCoreSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentCoreSubscriber.md new file mode 100644 index 0000000000..bbd0895a8c --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentCoreSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.ConcurrentCoreSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentPullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentPullStreamSubscriber.md new file mode 100644 index 0000000000..7bb13db682 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentPullStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.ConcurrentPullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentPushStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentPushStreamSubscriber.md new file mode 100644 index 0000000000..c694d41369 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentPushStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.ConcurrentPushStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/CoreSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/CoreSubscriber.md new file mode 100644 index 0000000000..e35ebd3f9d --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/CoreSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.CoreSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/KeyValueWatchSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/KeyValueWatchSubscriber.md new file mode 100644 index 0000000000..507c7a33c4 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/KeyValueWatchSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.KeyValueWatchSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/LogicSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/LogicSubscriber.md new file mode 100644 index 0000000000..e97348563d --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/LogicSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.LogicSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/ObjStoreWatchSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/ObjStoreWatchSubscriber.md new file mode 100644 index 0000000000..25d1434968 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/ObjStoreWatchSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.ObjStoreWatchSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/PullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/PullStreamSubscriber.md new file mode 100644 index 0000000000..ddc3731c6e --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/PullStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.PullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/PushStreamSubscription.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/PushStreamSubscription.md new file mode 100644 index 0000000000..9ea5735afb --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/PushStreamSubscription.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.PushStreamSubscription diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/basic/DefaultSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/basic/DefaultSubscriber.md new file mode 100644 index 0000000000..f0bd5e52aa --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/basic/DefaultSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.basic.DefaultSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/basic/LogicSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/basic/LogicSubscriber.md new file mode 100644 index 0000000000..9dfc93aa9b --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/basic/LogicSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.basic.LogicSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/core_subscriber/ConcurrentCoreSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/core_subscriber/ConcurrentCoreSubscriber.md new file mode 100644 index 0000000000..a684452aa1 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/core_subscriber/ConcurrentCoreSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.core_subscriber.ConcurrentCoreSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/core_subscriber/CoreSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/core_subscriber/CoreSubscriber.md new file mode 100644 index 0000000000..cc1905f58e --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/core_subscriber/CoreSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.core_subscriber.CoreSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/key_value_subscriber/KeyValueWatchSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/key_value_subscriber/KeyValueWatchSubscriber.md new file mode 100644 index 0000000000..26e1b670d0 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/key_value_subscriber/KeyValueWatchSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.key_value_subscriber.KeyValueWatchSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/object_storage_subscriber/ObjStoreWatchSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/object_storage_subscriber/ObjStoreWatchSubscriber.md new file mode 100644 index 0000000000..b1722e57ec --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/object_storage_subscriber/ObjStoreWatchSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.object_storage_subscriber.ObjStoreWatchSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_basic/StreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_basic/StreamSubscriber.md new file mode 100644 index 0000000000..b08fd2abff --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_basic/StreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.stream_basic.StreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/BatchPullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/BatchPullStreamSubscriber.md new file mode 100644 index 0000000000..9e4973cf67 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/BatchPullStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.stream_pull_subscriber.BatchPullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/ConcurrentPullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/ConcurrentPullStreamSubscriber.md new file mode 100644 index 0000000000..6c31f93a20 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/ConcurrentPullStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.stream_pull_subscriber.ConcurrentPullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/PullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/PullStreamSubscriber.md new file mode 100644 index 0000000000..35e7de26de --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/PullStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.stream_pull_subscriber.PullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_push_subscriber/ConcurrentPushStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_push_subscriber/ConcurrentPushStreamSubscriber.md new file mode 100644 index 0000000000..78cffa0a9f --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_push_subscriber/ConcurrentPushStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.stream_push_subscriber.ConcurrentPushStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_push_subscriber/PushStreamSubscription.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_push_subscriber/PushStreamSubscription.md new file mode 100644 index 0000000000..eee1f7aeb7 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_push_subscriber/PushStreamSubscription.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.subscriber.usecases.stream_push_subscriber.PushStreamSubscription diff --git a/docs/docs/en/api/faststream/nats/testing/FakeProducer.md b/docs/docs/en/api/faststream/nats/testing/FakeProducer.md new file mode 100644 index 0000000000..f2615aeb36 --- /dev/null +++ b/docs/docs/en/api/faststream/nats/testing/FakeProducer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.testing.FakeProducer diff --git a/docs/docs/en/api/faststream/nats/testing/PatchedMessage.md b/docs/docs/en/api/faststream/nats/testing/PatchedMessage.md new file mode 100644 index 0000000000..e32802d4dd --- /dev/null +++ b/docs/docs/en/api/faststream/nats/testing/PatchedMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.testing.PatchedMessage diff --git a/docs/docs/en/api/faststream/nats/testing/TestNatsBroker.md b/docs/docs/en/api/faststream/nats/testing/TestNatsBroker.md new file mode 100644 index 0000000000..2abcf7f06d --- /dev/null +++ b/docs/docs/en/api/faststream/nats/testing/TestNatsBroker.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.testing.TestNatsBroker diff --git a/docs/docs/en/api/faststream/nats/testing/build_message.md b/docs/docs/en/api/faststream/nats/testing/build_message.md new file mode 100644 index 0000000000..160977893d --- /dev/null +++ b/docs/docs/en/api/faststream/nats/testing/build_message.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.nats.testing.build_message diff --git a/docs/docs/en/api/faststream/opentelemetry/Baggage.md b/docs/docs/en/api/faststream/opentelemetry/Baggage.md new file mode 100644 index 0000000000..a61cb56d97 --- /dev/null +++ b/docs/docs/en/api/faststream/opentelemetry/Baggage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.opentelemetry.Baggage diff --git a/docs/docs/en/api/faststream/opentelemetry/TelemetryMiddleware.md b/docs/docs/en/api/faststream/opentelemetry/TelemetryMiddleware.md new file mode 100644 index 0000000000..914f134e60 --- /dev/null +++ b/docs/docs/en/api/faststream/opentelemetry/TelemetryMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.opentelemetry.TelemetryMiddleware diff --git a/docs/docs/en/api/faststream/opentelemetry/TelemetrySettingsProvider.md b/docs/docs/en/api/faststream/opentelemetry/TelemetrySettingsProvider.md new file mode 100644 index 0000000000..7ca8b2cb6d --- /dev/null +++ b/docs/docs/en/api/faststream/opentelemetry/TelemetrySettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.opentelemetry.TelemetrySettingsProvider diff --git a/docs/docs/en/api/faststream/opentelemetry/baggage/Baggage.md b/docs/docs/en/api/faststream/opentelemetry/baggage/Baggage.md new file mode 100644 index 0000000000..c1c6e4efec --- /dev/null +++ b/docs/docs/en/api/faststream/opentelemetry/baggage/Baggage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.opentelemetry.baggage.Baggage diff --git a/docs/docs/en/api/faststream/opentelemetry/consts/MessageAction.md b/docs/docs/en/api/faststream/opentelemetry/consts/MessageAction.md new file mode 100644 index 0000000000..cd58706774 --- /dev/null +++ b/docs/docs/en/api/faststream/opentelemetry/consts/MessageAction.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.opentelemetry.consts.MessageAction diff --git a/docs/docs/en/api/faststream/opentelemetry/middleware/BaseTelemetryMiddleware.md b/docs/docs/en/api/faststream/opentelemetry/middleware/BaseTelemetryMiddleware.md new file mode 100644 index 0000000000..64a7b4a501 --- /dev/null +++ b/docs/docs/en/api/faststream/opentelemetry/middleware/BaseTelemetryMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.opentelemetry.middleware.BaseTelemetryMiddleware diff --git a/docs/docs/en/api/faststream/opentelemetry/middleware/TelemetryMiddleware.md b/docs/docs/en/api/faststream/opentelemetry/middleware/TelemetryMiddleware.md new file mode 100644 index 0000000000..f019b3ad61 --- /dev/null +++ b/docs/docs/en/api/faststream/opentelemetry/middleware/TelemetryMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.opentelemetry.middleware.TelemetryMiddleware diff --git a/docs/docs/en/api/faststream/opentelemetry/provider/TelemetrySettingsProvider.md b/docs/docs/en/api/faststream/opentelemetry/provider/TelemetrySettingsProvider.md new file mode 100644 index 0000000000..0fefe1c0ef --- /dev/null +++ b/docs/docs/en/api/faststream/opentelemetry/provider/TelemetrySettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.opentelemetry.provider.TelemetrySettingsProvider diff --git a/docs/docs/en/api/faststream/params/Context.md b/docs/docs/en/api/faststream/params/Context.md new file mode 100644 index 0000000000..8eb7fc249a --- /dev/null +++ b/docs/docs/en/api/faststream/params/Context.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.params.Context diff --git a/docs/docs/en/api/faststream/params/Depends.md b/docs/docs/en/api/faststream/params/Depends.md new file mode 100644 index 0000000000..c0704687e8 --- /dev/null +++ b/docs/docs/en/api/faststream/params/Depends.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: fast_depends.use.Depends diff --git a/docs/docs/en/api/faststream/params/Header.md b/docs/docs/en/api/faststream/params/Header.md new file mode 100644 index 0000000000..f3dd71365c --- /dev/null +++ b/docs/docs/en/api/faststream/params/Header.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.params.Header diff --git a/docs/docs/en/api/faststream/params/Path.md b/docs/docs/en/api/faststream/params/Path.md new file mode 100644 index 0000000000..ad04fdff6e --- /dev/null +++ b/docs/docs/en/api/faststream/params/Path.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.params.Path diff --git a/docs/docs/en/api/faststream/params/no_cast/NoCastField.md b/docs/docs/en/api/faststream/params/no_cast/NoCastField.md new file mode 100644 index 0000000000..56821cae8a --- /dev/null +++ b/docs/docs/en/api/faststream/params/no_cast/NoCastField.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.params.no_cast.NoCastField diff --git a/docs/docs/en/api/faststream/params/params/Context.md b/docs/docs/en/api/faststream/params/params/Context.md new file mode 100644 index 0000000000..4c3ec6b4dd --- /dev/null +++ b/docs/docs/en/api/faststream/params/params/Context.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.params.params.Context diff --git a/docs/docs/en/api/faststream/params/params/Header.md b/docs/docs/en/api/faststream/params/params/Header.md new file mode 100644 index 0000000000..6b15bd1ec1 --- /dev/null +++ b/docs/docs/en/api/faststream/params/params/Header.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.params.params.Header diff --git a/docs/docs/en/api/faststream/params/params/Path.md b/docs/docs/en/api/faststream/params/params/Path.md new file mode 100644 index 0000000000..0903f40023 --- /dev/null +++ b/docs/docs/en/api/faststream/params/params/Path.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.params.params.Path diff --git a/docs/docs/en/api/faststream/prometheus/ConsumeAttrs.md b/docs/docs/en/api/faststream/prometheus/ConsumeAttrs.md new file mode 100644 index 0000000000..ad8e536b7a --- /dev/null +++ b/docs/docs/en/api/faststream/prometheus/ConsumeAttrs.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.prometheus.ConsumeAttrs diff --git a/docs/docs/en/api/faststream/prometheus/MetricsSettingsProvider.md b/docs/docs/en/api/faststream/prometheus/MetricsSettingsProvider.md new file mode 100644 index 0000000000..0f7405e44d --- /dev/null +++ b/docs/docs/en/api/faststream/prometheus/MetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.prometheus.MetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/prometheus/PrometheusMiddleware.md b/docs/docs/en/api/faststream/prometheus/PrometheusMiddleware.md new file mode 100644 index 0000000000..c340a0cb23 --- /dev/null +++ b/docs/docs/en/api/faststream/prometheus/PrometheusMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.prometheus.PrometheusMiddleware diff --git a/docs/docs/en/api/faststream/prometheus/container/MetricsContainer.md b/docs/docs/en/api/faststream/prometheus/container/MetricsContainer.md new file mode 100644 index 0000000000..009d88d263 --- /dev/null +++ b/docs/docs/en/api/faststream/prometheus/container/MetricsContainer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.prometheus.container.MetricsContainer diff --git a/docs/docs/en/api/faststream/prometheus/manager/MetricsManager.md b/docs/docs/en/api/faststream/prometheus/manager/MetricsManager.md new file mode 100644 index 0000000000..b1a897c717 --- /dev/null +++ b/docs/docs/en/api/faststream/prometheus/manager/MetricsManager.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.prometheus.manager.MetricsManager diff --git a/docs/docs/en/api/faststream/prometheus/middleware/BasePrometheusMiddleware.md b/docs/docs/en/api/faststream/prometheus/middleware/BasePrometheusMiddleware.md new file mode 100644 index 0000000000..62bbd031ac --- /dev/null +++ b/docs/docs/en/api/faststream/prometheus/middleware/BasePrometheusMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.prometheus.middleware.BasePrometheusMiddleware diff --git a/docs/docs/en/api/faststream/prometheus/middleware/PrometheusMiddleware.md b/docs/docs/en/api/faststream/prometheus/middleware/PrometheusMiddleware.md new file mode 100644 index 0000000000..2902586e38 --- /dev/null +++ b/docs/docs/en/api/faststream/prometheus/middleware/PrometheusMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.prometheus.middleware.PrometheusMiddleware diff --git a/docs/docs/en/api/faststream/prometheus/provider/MetricsSettingsProvider.md b/docs/docs/en/api/faststream/prometheus/provider/MetricsSettingsProvider.md new file mode 100644 index 0000000000..3511a21a5b --- /dev/null +++ b/docs/docs/en/api/faststream/prometheus/provider/MetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.prometheus.provider.MetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/prometheus/types/ConsumeAttrs.md b/docs/docs/en/api/faststream/prometheus/types/ConsumeAttrs.md new file mode 100644 index 0000000000..d9196cab8d --- /dev/null +++ b/docs/docs/en/api/faststream/prometheus/types/ConsumeAttrs.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.prometheus.types.ConsumeAttrs diff --git a/docs/docs/en/api/faststream/prometheus/types/ProcessingStatus.md b/docs/docs/en/api/faststream/prometheus/types/ProcessingStatus.md new file mode 100644 index 0000000000..98b6710bcd --- /dev/null +++ b/docs/docs/en/api/faststream/prometheus/types/ProcessingStatus.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.prometheus.types.ProcessingStatus diff --git a/docs/docs/en/api/faststream/prometheus/types/PublishingStatus.md b/docs/docs/en/api/faststream/prometheus/types/PublishingStatus.md new file mode 100644 index 0000000000..4e7435fbea --- /dev/null +++ b/docs/docs/en/api/faststream/prometheus/types/PublishingStatus.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.prometheus.types.PublishingStatus diff --git a/docs/docs/en/api/faststream/rabbit/ExchangeType.md b/docs/docs/en/api/faststream/rabbit/ExchangeType.md new file mode 100644 index 0000000000..9b299b951d --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/ExchangeType.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.ExchangeType diff --git a/docs/docs/en/api/faststream/rabbit/RabbitBroker.md b/docs/docs/en/api/faststream/rabbit/RabbitBroker.md new file mode 100644 index 0000000000..f48b2b5e78 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/RabbitBroker.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.RabbitBroker diff --git a/docs/docs/en/api/faststream/rabbit/RabbitExchange.md b/docs/docs/en/api/faststream/rabbit/RabbitExchange.md new file mode 100644 index 0000000000..bbf9676e72 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/RabbitExchange.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.RabbitExchange diff --git a/docs/docs/en/api/faststream/rabbit/RabbitPublisher.md b/docs/docs/en/api/faststream/rabbit/RabbitPublisher.md new file mode 100644 index 0000000000..7e0d3f674b --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/RabbitPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.RabbitPublisher diff --git a/docs/docs/en/api/faststream/rabbit/RabbitQueue.md b/docs/docs/en/api/faststream/rabbit/RabbitQueue.md new file mode 100644 index 0000000000..97945b6408 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/RabbitQueue.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.RabbitQueue diff --git a/docs/docs/en/api/faststream/rabbit/RabbitResponse.md b/docs/docs/en/api/faststream/rabbit/RabbitResponse.md new file mode 100644 index 0000000000..4d20d82b0e --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/RabbitResponse.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.RabbitResponse diff --git a/docs/docs/en/api/faststream/rabbit/RabbitRoute.md b/docs/docs/en/api/faststream/rabbit/RabbitRoute.md new file mode 100644 index 0000000000..e11a9f058d --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/RabbitRoute.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.RabbitRoute diff --git a/docs/docs/en/api/faststream/rabbit/RabbitRouter.md b/docs/docs/en/api/faststream/rabbit/RabbitRouter.md new file mode 100644 index 0000000000..133880fc50 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/RabbitRouter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.RabbitRouter diff --git a/docs/docs/en/api/faststream/rabbit/TestApp.md b/docs/docs/en/api/faststream/rabbit/TestApp.md new file mode 100644 index 0000000000..ad101303af --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/TestApp.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream._internal.testing.app.TestApp diff --git a/docs/docs/en/api/faststream/rabbit/TestRabbitBroker.md b/docs/docs/en/api/faststream/rabbit/TestRabbitBroker.md new file mode 100644 index 0000000000..c4519d58b8 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/TestRabbitBroker.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.TestRabbitBroker diff --git a/docs/docs/en/api/faststream/rabbit/broker/RabbitBroker.md b/docs/docs/en/api/faststream/rabbit/broker/RabbitBroker.md new file mode 100644 index 0000000000..ac72ec0ae9 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/broker/RabbitBroker.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.broker.RabbitBroker diff --git a/docs/docs/en/api/faststream/rabbit/broker/broker/RabbitBroker.md b/docs/docs/en/api/faststream/rabbit/broker/broker/RabbitBroker.md new file mode 100644 index 0000000000..9ed9170ead --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/broker/broker/RabbitBroker.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.broker.broker.RabbitBroker diff --git a/docs/docs/en/api/faststream/rabbit/broker/logging/RabbitParamsStorage.md b/docs/docs/en/api/faststream/rabbit/broker/logging/RabbitParamsStorage.md new file mode 100644 index 0000000000..e9e46da6af --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/broker/logging/RabbitParamsStorage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.broker.logging.RabbitParamsStorage diff --git a/docs/docs/en/api/faststream/rabbit/broker/registrator/RabbitRegistrator.md b/docs/docs/en/api/faststream/rabbit/broker/registrator/RabbitRegistrator.md new file mode 100644 index 0000000000..f22385f512 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/broker/registrator/RabbitRegistrator.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.broker.registrator.RabbitRegistrator diff --git a/docs/docs/en/api/faststream/rabbit/fastapi/Context.md b/docs/docs/en/api/faststream/rabbit/fastapi/Context.md new file mode 100644 index 0000000000..99bf141f5c --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/fastapi/Context.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream._internal.fastapi.context.Context diff --git a/docs/docs/en/api/faststream/rabbit/fastapi/RabbitRouter.md b/docs/docs/en/api/faststream/rabbit/fastapi/RabbitRouter.md new file mode 100644 index 0000000000..72f0a90072 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/fastapi/RabbitRouter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.fastapi.RabbitRouter diff --git a/docs/docs/en/api/faststream/rabbit/fastapi/fastapi/RabbitRouter.md b/docs/docs/en/api/faststream/rabbit/fastapi/fastapi/RabbitRouter.md new file mode 100644 index 0000000000..d70c558254 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/fastapi/fastapi/RabbitRouter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.fastapi.fastapi.RabbitRouter diff --git a/docs/docs/en/api/faststream/rabbit/helpers/declarer/RabbitDeclarer.md b/docs/docs/en/api/faststream/rabbit/helpers/declarer/RabbitDeclarer.md new file mode 100644 index 0000000000..b8fc8a0ebd --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/helpers/declarer/RabbitDeclarer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.helpers.declarer.RabbitDeclarer diff --git a/docs/docs/en/api/faststream/rabbit/helpers/state/ConnectedState.md b/docs/docs/en/api/faststream/rabbit/helpers/state/ConnectedState.md new file mode 100644 index 0000000000..db97303aa3 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/helpers/state/ConnectedState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.helpers.state.ConnectedState diff --git a/docs/docs/en/api/faststream/rabbit/helpers/state/ConnectionState.md b/docs/docs/en/api/faststream/rabbit/helpers/state/ConnectionState.md new file mode 100644 index 0000000000..36b3d4d4d1 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/helpers/state/ConnectionState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.helpers.state.ConnectionState diff --git a/docs/docs/en/api/faststream/rabbit/helpers/state/EmptyConnectionState.md b/docs/docs/en/api/faststream/rabbit/helpers/state/EmptyConnectionState.md new file mode 100644 index 0000000000..7b0af42897 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/helpers/state/EmptyConnectionState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.helpers.state.EmptyConnectionState diff --git a/docs/docs/en/api/faststream/rabbit/message/RabbitMessage.md b/docs/docs/en/api/faststream/rabbit/message/RabbitMessage.md new file mode 100644 index 0000000000..598d43f818 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/message/RabbitMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.message.RabbitMessage diff --git a/docs/docs/en/api/faststream/rabbit/opentelemetry/RabbitTelemetryMiddleware.md b/docs/docs/en/api/faststream/rabbit/opentelemetry/RabbitTelemetryMiddleware.md new file mode 100644 index 0000000000..7d5ef3de27 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/opentelemetry/RabbitTelemetryMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.opentelemetry.RabbitTelemetryMiddleware diff --git a/docs/docs/en/api/faststream/rabbit/opentelemetry/middleware/RabbitTelemetryMiddleware.md b/docs/docs/en/api/faststream/rabbit/opentelemetry/middleware/RabbitTelemetryMiddleware.md new file mode 100644 index 0000000000..e86771a8ba --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/opentelemetry/middleware/RabbitTelemetryMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.opentelemetry.middleware.RabbitTelemetryMiddleware diff --git a/docs/docs/en/api/faststream/rabbit/opentelemetry/provider/RabbitTelemetrySettingsProvider.md b/docs/docs/en/api/faststream/rabbit/opentelemetry/provider/RabbitTelemetrySettingsProvider.md new file mode 100644 index 0000000000..ba6742ac90 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/opentelemetry/provider/RabbitTelemetrySettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.opentelemetry.provider.RabbitTelemetrySettingsProvider diff --git a/docs/docs/en/api/faststream/rabbit/parser/AioPikaParser.md b/docs/docs/en/api/faststream/rabbit/parser/AioPikaParser.md new file mode 100644 index 0000000000..0a02d90270 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/parser/AioPikaParser.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.parser.AioPikaParser diff --git a/docs/docs/en/api/faststream/rabbit/prometheus/RabbitPrometheusMiddleware.md b/docs/docs/en/api/faststream/rabbit/prometheus/RabbitPrometheusMiddleware.md new file mode 100644 index 0000000000..2c4308fabd --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/prometheus/RabbitPrometheusMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.prometheus.RabbitPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/rabbit/prometheus/middleware/RabbitPrometheusMiddleware.md b/docs/docs/en/api/faststream/rabbit/prometheus/middleware/RabbitPrometheusMiddleware.md new file mode 100644 index 0000000000..45163c998a --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/prometheus/middleware/RabbitPrometheusMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.prometheus.middleware.RabbitPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/rabbit/prometheus/provider/RabbitMetricsSettingsProvider.md b/docs/docs/en/api/faststream/rabbit/prometheus/provider/RabbitMetricsSettingsProvider.md new file mode 100644 index 0000000000..6d63301b34 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/prometheus/provider/RabbitMetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.prometheus.provider.RabbitMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/rabbit/publisher/factory/create_publisher.md b/docs/docs/en/api/faststream/rabbit/publisher/factory/create_publisher.md new file mode 100644 index 0000000000..bac090fa43 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/publisher/factory/create_publisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.publisher.factory.create_publisher diff --git a/docs/docs/en/api/faststream/rabbit/publisher/fake/RabbitFakePublisher.md b/docs/docs/en/api/faststream/rabbit/publisher/fake/RabbitFakePublisher.md new file mode 100644 index 0000000000..60879c8e3a --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/publisher/fake/RabbitFakePublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.publisher.fake.RabbitFakePublisher diff --git a/docs/docs/en/api/faststream/rabbit/publisher/options/MessageOptions.md b/docs/docs/en/api/faststream/rabbit/publisher/options/MessageOptions.md new file mode 100644 index 0000000000..eaa454588a --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/publisher/options/MessageOptions.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.publisher.options.MessageOptions diff --git a/docs/docs/en/api/faststream/rabbit/publisher/options/PublishOptions.md b/docs/docs/en/api/faststream/rabbit/publisher/options/PublishOptions.md new file mode 100644 index 0000000000..c80cc9e937 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/publisher/options/PublishOptions.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.publisher.options.PublishOptions diff --git a/docs/docs/en/api/faststream/rabbit/publisher/producer/AioPikaFastProducer.md b/docs/docs/en/api/faststream/rabbit/publisher/producer/AioPikaFastProducer.md new file mode 100644 index 0000000000..527cc5604c --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/publisher/producer/AioPikaFastProducer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.publisher.producer.AioPikaFastProducer diff --git a/docs/docs/en/api/faststream/rabbit/publisher/producer/LockState.md b/docs/docs/en/api/faststream/rabbit/publisher/producer/LockState.md new file mode 100644 index 0000000000..4d7b37ba46 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/publisher/producer/LockState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.publisher.producer.LockState diff --git a/docs/docs/en/api/faststream/rabbit/publisher/producer/LockUnset.md b/docs/docs/en/api/faststream/rabbit/publisher/producer/LockUnset.md new file mode 100644 index 0000000000..95df1a10e7 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/publisher/producer/LockUnset.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.publisher.producer.LockUnset diff --git a/docs/docs/en/api/faststream/rabbit/publisher/producer/RealLock.md b/docs/docs/en/api/faststream/rabbit/publisher/producer/RealLock.md new file mode 100644 index 0000000000..570a279a0a --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/publisher/producer/RealLock.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.publisher.producer.RealLock diff --git a/docs/docs/en/api/faststream/rabbit/publisher/specified/SpecificationPublisher.md b/docs/docs/en/api/faststream/rabbit/publisher/specified/SpecificationPublisher.md new file mode 100644 index 0000000000..0001c99fb7 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/publisher/specified/SpecificationPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.publisher.specified.SpecificationPublisher diff --git a/docs/docs/en/api/faststream/rabbit/publisher/usecase/LogicPublisher.md b/docs/docs/en/api/faststream/rabbit/publisher/usecase/LogicPublisher.md new file mode 100644 index 0000000000..1ef927866e --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/publisher/usecase/LogicPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.publisher.usecase.LogicPublisher diff --git a/docs/docs/en/api/faststream/rabbit/publisher/usecase/PublishKwargs.md b/docs/docs/en/api/faststream/rabbit/publisher/usecase/PublishKwargs.md new file mode 100644 index 0000000000..3d917891cd --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/publisher/usecase/PublishKwargs.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.publisher.usecase.PublishKwargs diff --git a/docs/docs/en/api/faststream/rabbit/publisher/usecase/RequestPublishKwargs.md b/docs/docs/en/api/faststream/rabbit/publisher/usecase/RequestPublishKwargs.md new file mode 100644 index 0000000000..5668633016 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/publisher/usecase/RequestPublishKwargs.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.publisher.usecase.RequestPublishKwargs diff --git a/docs/docs/en/api/faststream/rabbit/response/RabbitPublishCommand.md b/docs/docs/en/api/faststream/rabbit/response/RabbitPublishCommand.md new file mode 100644 index 0000000000..4c4bb224b6 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/response/RabbitPublishCommand.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.response.RabbitPublishCommand diff --git a/docs/docs/en/api/faststream/rabbit/response/RabbitResponse.md b/docs/docs/en/api/faststream/rabbit/response/RabbitResponse.md new file mode 100644 index 0000000000..477cfb9861 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/response/RabbitResponse.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.response.RabbitResponse diff --git a/docs/docs/en/api/faststream/rabbit/router/RabbitPublisher.md b/docs/docs/en/api/faststream/rabbit/router/RabbitPublisher.md new file mode 100644 index 0000000000..befbec9103 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/router/RabbitPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.router.RabbitPublisher diff --git a/docs/docs/en/api/faststream/rabbit/router/RabbitRoute.md b/docs/docs/en/api/faststream/rabbit/router/RabbitRoute.md new file mode 100644 index 0000000000..8e8b0fbb6c --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/router/RabbitRoute.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.router.RabbitRoute diff --git a/docs/docs/en/api/faststream/rabbit/router/RabbitRouter.md b/docs/docs/en/api/faststream/rabbit/router/RabbitRouter.md new file mode 100644 index 0000000000..eff5f6169a --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/router/RabbitRouter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.router.RabbitRouter diff --git a/docs/docs/en/api/faststream/rabbit/schemas/BaseRMQInformation.md b/docs/docs/en/api/faststream/rabbit/schemas/BaseRMQInformation.md new file mode 100644 index 0000000000..7ff32d2cd2 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/schemas/BaseRMQInformation.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.schemas.BaseRMQInformation diff --git a/docs/docs/en/api/faststream/rabbit/schemas/ExchangeType.md b/docs/docs/en/api/faststream/rabbit/schemas/ExchangeType.md new file mode 100644 index 0000000000..c6c2ef8a28 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/schemas/ExchangeType.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.schemas.ExchangeType diff --git a/docs/docs/en/api/faststream/rabbit/schemas/RabbitExchange.md b/docs/docs/en/api/faststream/rabbit/schemas/RabbitExchange.md new file mode 100644 index 0000000000..4e60ed96f5 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/schemas/RabbitExchange.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.schemas.RabbitExchange diff --git a/docs/docs/en/api/faststream/rabbit/schemas/RabbitQueue.md b/docs/docs/en/api/faststream/rabbit/schemas/RabbitQueue.md new file mode 100644 index 0000000000..947238b788 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/schemas/RabbitQueue.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.schemas.RabbitQueue diff --git a/docs/docs/en/api/faststream/rabbit/schemas/constants/ExchangeType.md b/docs/docs/en/api/faststream/rabbit/schemas/constants/ExchangeType.md new file mode 100644 index 0000000000..11705f35ac --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/schemas/constants/ExchangeType.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.schemas.constants.ExchangeType diff --git a/docs/docs/en/api/faststream/rabbit/schemas/exchange/RabbitExchange.md b/docs/docs/en/api/faststream/rabbit/schemas/exchange/RabbitExchange.md new file mode 100644 index 0000000000..ebcb211714 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/schemas/exchange/RabbitExchange.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.schemas.exchange.RabbitExchange diff --git a/docs/docs/en/api/faststream/rabbit/schemas/proto/BaseRMQInformation.md b/docs/docs/en/api/faststream/rabbit/schemas/proto/BaseRMQInformation.md new file mode 100644 index 0000000000..1eca00071b --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/schemas/proto/BaseRMQInformation.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.schemas.proto.BaseRMQInformation diff --git a/docs/docs/en/api/faststream/rabbit/schemas/queue/RabbitQueue.md b/docs/docs/en/api/faststream/rabbit/schemas/queue/RabbitQueue.md new file mode 100644 index 0000000000..83bc15e02f --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/schemas/queue/RabbitQueue.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.schemas.queue.RabbitQueue diff --git a/docs/docs/en/api/faststream/rabbit/security/parse_security.md b/docs/docs/en/api/faststream/rabbit/security/parse_security.md new file mode 100644 index 0000000000..0b19ee5ee2 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/security/parse_security.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.security.parse_security diff --git a/docs/docs/en/api/faststream/rabbit/subscriber/factory/create_subscriber.md b/docs/docs/en/api/faststream/rabbit/subscriber/factory/create_subscriber.md new file mode 100644 index 0000000000..79c7082931 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/subscriber/factory/create_subscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.subscriber.factory.create_subscriber diff --git a/docs/docs/en/api/faststream/rabbit/subscriber/specified/SpecificationSubscriber.md b/docs/docs/en/api/faststream/rabbit/subscriber/specified/SpecificationSubscriber.md new file mode 100644 index 0000000000..928876011d --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/subscriber/specified/SpecificationSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.subscriber.specified.SpecificationSubscriber diff --git a/docs/docs/en/api/faststream/rabbit/subscriber/usecase/LogicSubscriber.md b/docs/docs/en/api/faststream/rabbit/subscriber/usecase/LogicSubscriber.md new file mode 100644 index 0000000000..56ef70dd0d --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/subscriber/usecase/LogicSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.subscriber.usecase.LogicSubscriber diff --git a/docs/docs/en/api/faststream/rabbit/testing/FakeProducer.md b/docs/docs/en/api/faststream/rabbit/testing/FakeProducer.md new file mode 100644 index 0000000000..7fa3603f60 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/testing/FakeProducer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.testing.FakeProducer diff --git a/docs/docs/en/api/faststream/rabbit/testing/PatchedMessage.md b/docs/docs/en/api/faststream/rabbit/testing/PatchedMessage.md new file mode 100644 index 0000000000..f58c1140c2 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/testing/PatchedMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.testing.PatchedMessage diff --git a/docs/docs/en/api/faststream/rabbit/testing/TestRabbitBroker.md b/docs/docs/en/api/faststream/rabbit/testing/TestRabbitBroker.md new file mode 100644 index 0000000000..ab2c088b39 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/testing/TestRabbitBroker.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.testing.TestRabbitBroker diff --git a/docs/docs/en/api/faststream/rabbit/testing/apply_pattern.md b/docs/docs/en/api/faststream/rabbit/testing/apply_pattern.md new file mode 100644 index 0000000000..02ffd305ef --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/testing/apply_pattern.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.testing.apply_pattern diff --git a/docs/docs/en/api/faststream/rabbit/testing/build_message.md b/docs/docs/en/api/faststream/rabbit/testing/build_message.md new file mode 100644 index 0000000000..296715e46a --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/testing/build_message.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.testing.build_message diff --git a/docs/docs/en/api/faststream/rabbit/utils/build_url.md b/docs/docs/en/api/faststream/rabbit/utils/build_url.md new file mode 100644 index 0000000000..ffb6555837 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/utils/build_url.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.utils.build_url diff --git a/docs/docs/en/api/faststream/rabbit/utils/is_routing_exchange.md b/docs/docs/en/api/faststream/rabbit/utils/is_routing_exchange.md new file mode 100644 index 0000000000..4ef1481a69 --- /dev/null +++ b/docs/docs/en/api/faststream/rabbit/utils/is_routing_exchange.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.rabbit.utils.is_routing_exchange diff --git a/docs/docs/en/api/faststream/redis/ListSub.md b/docs/docs/en/api/faststream/redis/ListSub.md new file mode 100644 index 0000000000..9c97a0afcd --- /dev/null +++ b/docs/docs/en/api/faststream/redis/ListSub.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.ListSub diff --git a/docs/docs/en/api/faststream/redis/PubSub.md b/docs/docs/en/api/faststream/redis/PubSub.md new file mode 100644 index 0000000000..d2fba00014 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/PubSub.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.PubSub diff --git a/docs/docs/en/api/faststream/redis/RedisBroker.md b/docs/docs/en/api/faststream/redis/RedisBroker.md new file mode 100644 index 0000000000..7275bfb60a --- /dev/null +++ b/docs/docs/en/api/faststream/redis/RedisBroker.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.RedisBroker diff --git a/docs/docs/en/api/faststream/redis/RedisPublisher.md b/docs/docs/en/api/faststream/redis/RedisPublisher.md new file mode 100644 index 0000000000..565d857810 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/RedisPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.RedisPublisher diff --git a/docs/docs/en/api/faststream/redis/RedisResponse.md b/docs/docs/en/api/faststream/redis/RedisResponse.md new file mode 100644 index 0000000000..eedecf1ea3 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/RedisResponse.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.RedisResponse diff --git a/docs/docs/en/api/faststream/redis/RedisRoute.md b/docs/docs/en/api/faststream/redis/RedisRoute.md new file mode 100644 index 0000000000..14b4416ed4 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/RedisRoute.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.RedisRoute diff --git a/docs/docs/en/api/faststream/redis/RedisRouter.md b/docs/docs/en/api/faststream/redis/RedisRouter.md new file mode 100644 index 0000000000..9b7292e703 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/RedisRouter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.RedisRouter diff --git a/docs/docs/en/api/faststream/redis/StreamSub.md b/docs/docs/en/api/faststream/redis/StreamSub.md new file mode 100644 index 0000000000..d1244238b6 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/StreamSub.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.StreamSub diff --git a/docs/docs/en/api/faststream/redis/TestApp.md b/docs/docs/en/api/faststream/redis/TestApp.md new file mode 100644 index 0000000000..ad101303af --- /dev/null +++ b/docs/docs/en/api/faststream/redis/TestApp.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream._internal.testing.app.TestApp diff --git a/docs/docs/en/api/faststream/redis/TestRedisBroker.md b/docs/docs/en/api/faststream/redis/TestRedisBroker.md new file mode 100644 index 0000000000..703490c302 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/TestRedisBroker.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.TestRedisBroker diff --git a/docs/docs/en/api/faststream/redis/broker/broker/RedisBroker.md b/docs/docs/en/api/faststream/redis/broker/broker/RedisBroker.md new file mode 100644 index 0000000000..fdc177e868 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/broker/broker/RedisBroker.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.broker.broker.RedisBroker diff --git a/docs/docs/en/api/faststream/redis/broker/logging/RedisParamsStorage.md b/docs/docs/en/api/faststream/redis/broker/logging/RedisParamsStorage.md new file mode 100644 index 0000000000..b7d1bb680a --- /dev/null +++ b/docs/docs/en/api/faststream/redis/broker/logging/RedisParamsStorage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.broker.logging.RedisParamsStorage diff --git a/docs/docs/en/api/faststream/redis/broker/registrator/RedisRegistrator.md b/docs/docs/en/api/faststream/redis/broker/registrator/RedisRegistrator.md new file mode 100644 index 0000000000..8d040533d7 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/broker/registrator/RedisRegistrator.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.broker.registrator.RedisRegistrator diff --git a/docs/docs/en/api/faststream/redis/fastapi/Context.md b/docs/docs/en/api/faststream/redis/fastapi/Context.md new file mode 100644 index 0000000000..99bf141f5c --- /dev/null +++ b/docs/docs/en/api/faststream/redis/fastapi/Context.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream._internal.fastapi.context.Context diff --git a/docs/docs/en/api/faststream/redis/fastapi/RedisRouter.md b/docs/docs/en/api/faststream/redis/fastapi/RedisRouter.md new file mode 100644 index 0000000000..7894f88728 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/fastapi/RedisRouter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.fastapi.RedisRouter diff --git a/docs/docs/en/api/faststream/redis/fastapi/fastapi/RedisRouter.md b/docs/docs/en/api/faststream/redis/fastapi/fastapi/RedisRouter.md new file mode 100644 index 0000000000..858c951f61 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/fastapi/fastapi/RedisRouter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.fastapi.fastapi.RedisRouter diff --git a/docs/docs/en/api/faststream/redis/helpers/state/ConnectedState.md b/docs/docs/en/api/faststream/redis/helpers/state/ConnectedState.md new file mode 100644 index 0000000000..793fdb055e --- /dev/null +++ b/docs/docs/en/api/faststream/redis/helpers/state/ConnectedState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.helpers.state.ConnectedState diff --git a/docs/docs/en/api/faststream/redis/helpers/state/ConnectionState.md b/docs/docs/en/api/faststream/redis/helpers/state/ConnectionState.md new file mode 100644 index 0000000000..0a27d849dc --- /dev/null +++ b/docs/docs/en/api/faststream/redis/helpers/state/ConnectionState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.helpers.state.ConnectionState diff --git a/docs/docs/en/api/faststream/redis/helpers/state/EmptyConnectionState.md b/docs/docs/en/api/faststream/redis/helpers/state/EmptyConnectionState.md new file mode 100644 index 0000000000..70273722e0 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/helpers/state/EmptyConnectionState.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.helpers.state.EmptyConnectionState diff --git a/docs/docs/en/api/faststream/redis/message/BatchListMessage.md b/docs/docs/en/api/faststream/redis/message/BatchListMessage.md new file mode 100644 index 0000000000..c510fa09b9 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/message/BatchListMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.message.BatchListMessage diff --git a/docs/docs/en/api/faststream/redis/message/BatchStreamMessage.md b/docs/docs/en/api/faststream/redis/message/BatchStreamMessage.md new file mode 100644 index 0000000000..16885fd028 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/message/BatchStreamMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.message.BatchStreamMessage diff --git a/docs/docs/en/api/faststream/redis/message/DefaultListMessage.md b/docs/docs/en/api/faststream/redis/message/DefaultListMessage.md new file mode 100644 index 0000000000..8f38b34cae --- /dev/null +++ b/docs/docs/en/api/faststream/redis/message/DefaultListMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.message.DefaultListMessage diff --git a/docs/docs/en/api/faststream/redis/message/DefaultStreamMessage.md b/docs/docs/en/api/faststream/redis/message/DefaultStreamMessage.md new file mode 100644 index 0000000000..6016bb624e --- /dev/null +++ b/docs/docs/en/api/faststream/redis/message/DefaultStreamMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.message.DefaultStreamMessage diff --git a/docs/docs/en/api/faststream/redis/message/PubSubMessage.md b/docs/docs/en/api/faststream/redis/message/PubSubMessage.md new file mode 100644 index 0000000000..795cecb12e --- /dev/null +++ b/docs/docs/en/api/faststream/redis/message/PubSubMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.message.PubSubMessage diff --git a/docs/docs/en/api/faststream/redis/message/RedisBatchListMessage.md b/docs/docs/en/api/faststream/redis/message/RedisBatchListMessage.md new file mode 100644 index 0000000000..ec7d3983bd --- /dev/null +++ b/docs/docs/en/api/faststream/redis/message/RedisBatchListMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.message.RedisBatchListMessage diff --git a/docs/docs/en/api/faststream/redis/message/RedisBatchStreamMessage.md b/docs/docs/en/api/faststream/redis/message/RedisBatchStreamMessage.md new file mode 100644 index 0000000000..2c66613eb7 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/message/RedisBatchStreamMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.message.RedisBatchStreamMessage diff --git a/docs/docs/en/api/faststream/redis/message/RedisListMessage.md b/docs/docs/en/api/faststream/redis/message/RedisListMessage.md new file mode 100644 index 0000000000..8c996cb7f0 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/message/RedisListMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.message.RedisListMessage diff --git a/docs/docs/en/api/faststream/redis/message/RedisMessage.md b/docs/docs/en/api/faststream/redis/message/RedisMessage.md new file mode 100644 index 0000000000..1b0654e7ce --- /dev/null +++ b/docs/docs/en/api/faststream/redis/message/RedisMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.message.RedisMessage diff --git a/docs/docs/en/api/faststream/redis/message/RedisStreamMessage.md b/docs/docs/en/api/faststream/redis/message/RedisStreamMessage.md new file mode 100644 index 0000000000..c36385a141 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/message/RedisStreamMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.message.RedisStreamMessage diff --git a/docs/docs/en/api/faststream/redis/message/UnifyRedisDict.md b/docs/docs/en/api/faststream/redis/message/UnifyRedisDict.md new file mode 100644 index 0000000000..9485ca2848 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/message/UnifyRedisDict.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.message.UnifyRedisDict diff --git a/docs/docs/en/api/faststream/redis/message/UnifyRedisMessage.md b/docs/docs/en/api/faststream/redis/message/UnifyRedisMessage.md new file mode 100644 index 0000000000..dee09d1657 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/message/UnifyRedisMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.message.UnifyRedisMessage diff --git a/docs/docs/en/api/faststream/redis/opentelemetry/RedisTelemetryMiddleware.md b/docs/docs/en/api/faststream/redis/opentelemetry/RedisTelemetryMiddleware.md new file mode 100644 index 0000000000..537a2dc7b9 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/opentelemetry/RedisTelemetryMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.opentelemetry.RedisTelemetryMiddleware diff --git a/docs/docs/en/api/faststream/redis/opentelemetry/middleware/RedisTelemetryMiddleware.md b/docs/docs/en/api/faststream/redis/opentelemetry/middleware/RedisTelemetryMiddleware.md new file mode 100644 index 0000000000..4c0febf261 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/opentelemetry/middleware/RedisTelemetryMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.opentelemetry.middleware.RedisTelemetryMiddleware diff --git a/docs/docs/en/api/faststream/redis/opentelemetry/provider/RedisTelemetrySettingsProvider.md b/docs/docs/en/api/faststream/redis/opentelemetry/provider/RedisTelemetrySettingsProvider.md new file mode 100644 index 0000000000..26e7859c34 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/opentelemetry/provider/RedisTelemetrySettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.opentelemetry.provider.RedisTelemetrySettingsProvider diff --git a/docs/docs/en/api/faststream/redis/parser/RawMessage.md b/docs/docs/en/api/faststream/redis/parser/RawMessage.md new file mode 100644 index 0000000000..4add7b37fd --- /dev/null +++ b/docs/docs/en/api/faststream/redis/parser/RawMessage.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.parser.RawMessage diff --git a/docs/docs/en/api/faststream/redis/parser/RedisBatchListParser.md b/docs/docs/en/api/faststream/redis/parser/RedisBatchListParser.md new file mode 100644 index 0000000000..e3a583eee8 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/parser/RedisBatchListParser.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.parser.RedisBatchListParser diff --git a/docs/docs/en/api/faststream/redis/parser/RedisBatchStreamParser.md b/docs/docs/en/api/faststream/redis/parser/RedisBatchStreamParser.md new file mode 100644 index 0000000000..28ed437573 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/parser/RedisBatchStreamParser.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.parser.RedisBatchStreamParser diff --git a/docs/docs/en/api/faststream/redis/parser/RedisListParser.md b/docs/docs/en/api/faststream/redis/parser/RedisListParser.md new file mode 100644 index 0000000000..fd0cf87991 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/parser/RedisListParser.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.parser.RedisListParser diff --git a/docs/docs/en/api/faststream/redis/parser/RedisPubSubParser.md b/docs/docs/en/api/faststream/redis/parser/RedisPubSubParser.md new file mode 100644 index 0000000000..93ab92cfdb --- /dev/null +++ b/docs/docs/en/api/faststream/redis/parser/RedisPubSubParser.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.parser.RedisPubSubParser diff --git a/docs/docs/en/api/faststream/redis/parser/RedisStreamParser.md b/docs/docs/en/api/faststream/redis/parser/RedisStreamParser.md new file mode 100644 index 0000000000..79633d06ad --- /dev/null +++ b/docs/docs/en/api/faststream/redis/parser/RedisStreamParser.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.parser.RedisStreamParser diff --git a/docs/docs/en/api/faststream/redis/parser/SimpleParser.md b/docs/docs/en/api/faststream/redis/parser/SimpleParser.md new file mode 100644 index 0000000000..239d3fda25 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/parser/SimpleParser.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.parser.SimpleParser diff --git a/docs/docs/en/api/faststream/redis/prometheus/RedisPrometheusMiddleware.md b/docs/docs/en/api/faststream/redis/prometheus/RedisPrometheusMiddleware.md new file mode 100644 index 0000000000..01b23fe4f1 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/prometheus/RedisPrometheusMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.prometheus.RedisPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/redis/prometheus/middleware/RedisPrometheusMiddleware.md b/docs/docs/en/api/faststream/redis/prometheus/middleware/RedisPrometheusMiddleware.md new file mode 100644 index 0000000000..c29cc91130 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/prometheus/middleware/RedisPrometheusMiddleware.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.prometheus.middleware.RedisPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/redis/prometheus/provider/BaseRedisMetricsSettingsProvider.md b/docs/docs/en/api/faststream/redis/prometheus/provider/BaseRedisMetricsSettingsProvider.md new file mode 100644 index 0000000000..243414331b --- /dev/null +++ b/docs/docs/en/api/faststream/redis/prometheus/provider/BaseRedisMetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.prometheus.provider.BaseRedisMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/redis/prometheus/provider/BatchRedisMetricsSettingsProvider.md b/docs/docs/en/api/faststream/redis/prometheus/provider/BatchRedisMetricsSettingsProvider.md new file mode 100644 index 0000000000..33d1d2d3a1 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/prometheus/provider/BatchRedisMetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.prometheus.provider.BatchRedisMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/redis/prometheus/provider/RedisMetricsSettingsProvider.md b/docs/docs/en/api/faststream/redis/prometheus/provider/RedisMetricsSettingsProvider.md new file mode 100644 index 0000000000..a7f5f3abe8 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/prometheus/provider/RedisMetricsSettingsProvider.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.prometheus.provider.RedisMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/redis/prometheus/provider/settings_provider_factory.md b/docs/docs/en/api/faststream/redis/prometheus/provider/settings_provider_factory.md new file mode 100644 index 0000000000..aa4812f1e2 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/prometheus/provider/settings_provider_factory.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.prometheus.provider.settings_provider_factory diff --git a/docs/docs/en/api/faststream/redis/publisher/factory/create_publisher.md b/docs/docs/en/api/faststream/redis/publisher/factory/create_publisher.md new file mode 100644 index 0000000000..e568f4120a --- /dev/null +++ b/docs/docs/en/api/faststream/redis/publisher/factory/create_publisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.publisher.factory.create_publisher diff --git a/docs/docs/en/api/faststream/redis/publisher/fake/RedisFakePublisher.md b/docs/docs/en/api/faststream/redis/publisher/fake/RedisFakePublisher.md new file mode 100644 index 0000000000..eb00559657 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/publisher/fake/RedisFakePublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.publisher.fake.RedisFakePublisher diff --git a/docs/docs/en/api/faststream/redis/publisher/producer/RedisFastProducer.md b/docs/docs/en/api/faststream/redis/publisher/producer/RedisFastProducer.md new file mode 100644 index 0000000000..3bc630cc42 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/publisher/producer/RedisFastProducer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.publisher.producer.RedisFastProducer diff --git a/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationChannelPublisher.md b/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationChannelPublisher.md new file mode 100644 index 0000000000..93b88342e4 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationChannelPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.publisher.specified.SpecificationChannelPublisher diff --git a/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationListBatchPublisher.md b/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationListBatchPublisher.md new file mode 100644 index 0000000000..c3f9769199 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationListBatchPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.publisher.specified.SpecificationListBatchPublisher diff --git a/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationListPublisher.md b/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationListPublisher.md new file mode 100644 index 0000000000..a7ed630a72 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationListPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.publisher.specified.SpecificationListPublisher diff --git a/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationPublisher.md b/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationPublisher.md new file mode 100644 index 0000000000..ceb47b19f6 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.publisher.specified.SpecificationPublisher diff --git a/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationStreamPublisher.md b/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationStreamPublisher.md new file mode 100644 index 0000000000..5800dc96da --- /dev/null +++ b/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationStreamPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.publisher.specified.SpecificationStreamPublisher diff --git a/docs/docs/en/api/faststream/redis/publisher/usecase/ChannelPublisher.md b/docs/docs/en/api/faststream/redis/publisher/usecase/ChannelPublisher.md new file mode 100644 index 0000000000..8aad760800 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/publisher/usecase/ChannelPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.publisher.usecase.ChannelPublisher diff --git a/docs/docs/en/api/faststream/redis/publisher/usecase/ListBatchPublisher.md b/docs/docs/en/api/faststream/redis/publisher/usecase/ListBatchPublisher.md new file mode 100644 index 0000000000..d7a1be63e4 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/publisher/usecase/ListBatchPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.publisher.usecase.ListBatchPublisher diff --git a/docs/docs/en/api/faststream/redis/publisher/usecase/ListPublisher.md b/docs/docs/en/api/faststream/redis/publisher/usecase/ListPublisher.md new file mode 100644 index 0000000000..59895dc001 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/publisher/usecase/ListPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.publisher.usecase.ListPublisher diff --git a/docs/docs/en/api/faststream/redis/publisher/usecase/LogicPublisher.md b/docs/docs/en/api/faststream/redis/publisher/usecase/LogicPublisher.md new file mode 100644 index 0000000000..c441bcc461 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/publisher/usecase/LogicPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.publisher.usecase.LogicPublisher diff --git a/docs/docs/en/api/faststream/redis/publisher/usecase/StreamPublisher.md b/docs/docs/en/api/faststream/redis/publisher/usecase/StreamPublisher.md new file mode 100644 index 0000000000..ea56c9d699 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/publisher/usecase/StreamPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.publisher.usecase.StreamPublisher diff --git a/docs/docs/en/api/faststream/redis/response/DestinationType.md b/docs/docs/en/api/faststream/redis/response/DestinationType.md new file mode 100644 index 0000000000..4eda1ad154 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/response/DestinationType.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.response.DestinationType diff --git a/docs/docs/en/api/faststream/redis/response/RedisPublishCommand.md b/docs/docs/en/api/faststream/redis/response/RedisPublishCommand.md new file mode 100644 index 0000000000..14e21c799e --- /dev/null +++ b/docs/docs/en/api/faststream/redis/response/RedisPublishCommand.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.response.RedisPublishCommand diff --git a/docs/docs/en/api/faststream/redis/response/RedisResponse.md b/docs/docs/en/api/faststream/redis/response/RedisResponse.md new file mode 100644 index 0000000000..dd7fbe72eb --- /dev/null +++ b/docs/docs/en/api/faststream/redis/response/RedisResponse.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.response.RedisResponse diff --git a/docs/docs/en/api/faststream/redis/router/RedisPublisher.md b/docs/docs/en/api/faststream/redis/router/RedisPublisher.md new file mode 100644 index 0000000000..fd1cad4d37 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/router/RedisPublisher.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.router.RedisPublisher diff --git a/docs/docs/en/api/faststream/redis/router/RedisRoute.md b/docs/docs/en/api/faststream/redis/router/RedisRoute.md new file mode 100644 index 0000000000..d6e1f525a7 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/router/RedisRoute.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.router.RedisRoute diff --git a/docs/docs/en/api/faststream/redis/router/RedisRouter.md b/docs/docs/en/api/faststream/redis/router/RedisRouter.md new file mode 100644 index 0000000000..373ceea5a8 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/router/RedisRouter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.router.RedisRouter diff --git a/docs/docs/en/api/faststream/redis/schemas/ListSub.md b/docs/docs/en/api/faststream/redis/schemas/ListSub.md new file mode 100644 index 0000000000..3e0b448229 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/schemas/ListSub.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.schemas.ListSub diff --git a/docs/docs/en/api/faststream/redis/schemas/PubSub.md b/docs/docs/en/api/faststream/redis/schemas/PubSub.md new file mode 100644 index 0000000000..078a8e2d8e --- /dev/null +++ b/docs/docs/en/api/faststream/redis/schemas/PubSub.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.schemas.PubSub diff --git a/docs/docs/en/api/faststream/redis/schemas/StreamSub.md b/docs/docs/en/api/faststream/redis/schemas/StreamSub.md new file mode 100644 index 0000000000..396e594c0b --- /dev/null +++ b/docs/docs/en/api/faststream/redis/schemas/StreamSub.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.schemas.StreamSub diff --git a/docs/docs/en/api/faststream/redis/schemas/list_sub/ListSub.md b/docs/docs/en/api/faststream/redis/schemas/list_sub/ListSub.md new file mode 100644 index 0000000000..f4b58ff4fb --- /dev/null +++ b/docs/docs/en/api/faststream/redis/schemas/list_sub/ListSub.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.schemas.list_sub.ListSub diff --git a/docs/docs/en/api/faststream/redis/schemas/proto/RedisSpecificationProtocol.md b/docs/docs/en/api/faststream/redis/schemas/proto/RedisSpecificationProtocol.md new file mode 100644 index 0000000000..de3ab92ace --- /dev/null +++ b/docs/docs/en/api/faststream/redis/schemas/proto/RedisSpecificationProtocol.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.schemas.proto.RedisSpecificationProtocol diff --git a/docs/docs/en/api/faststream/redis/schemas/proto/validate_options.md b/docs/docs/en/api/faststream/redis/schemas/proto/validate_options.md new file mode 100644 index 0000000000..7a5381120e --- /dev/null +++ b/docs/docs/en/api/faststream/redis/schemas/proto/validate_options.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.schemas.proto.validate_options diff --git a/docs/docs/en/api/faststream/redis/schemas/pub_sub/PubSub.md b/docs/docs/en/api/faststream/redis/schemas/pub_sub/PubSub.md new file mode 100644 index 0000000000..08552c7b8c --- /dev/null +++ b/docs/docs/en/api/faststream/redis/schemas/pub_sub/PubSub.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.schemas.pub_sub.PubSub diff --git a/docs/docs/en/api/faststream/redis/schemas/stream_sub/StreamSub.md b/docs/docs/en/api/faststream/redis/schemas/stream_sub/StreamSub.md new file mode 100644 index 0000000000..e1a8d44d4e --- /dev/null +++ b/docs/docs/en/api/faststream/redis/schemas/stream_sub/StreamSub.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.schemas.stream_sub.StreamSub diff --git a/docs/docs/en/api/faststream/redis/security/parse_security.md b/docs/docs/en/api/faststream/redis/security/parse_security.md new file mode 100644 index 0000000000..d3673649db --- /dev/null +++ b/docs/docs/en/api/faststream/redis/security/parse_security.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.security.parse_security diff --git a/docs/docs/en/api/faststream/redis/subscriber/factory/create_subscriber.md b/docs/docs/en/api/faststream/redis/subscriber/factory/create_subscriber.md new file mode 100644 index 0000000000..d5cf7eadc8 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/subscriber/factory/create_subscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.subscriber.factory.create_subscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationChannelSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationChannelSubscriber.md new file mode 100644 index 0000000000..538babd05f --- /dev/null +++ b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationChannelSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.subscriber.specified.SpecificationChannelSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationListBatchSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationListBatchSubscriber.md new file mode 100644 index 0000000000..60e7fa385d --- /dev/null +++ b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationListBatchSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.subscriber.specified.SpecificationListBatchSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationListSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationListSubscriber.md new file mode 100644 index 0000000000..988ffccb3c --- /dev/null +++ b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationListSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.subscriber.specified.SpecificationListSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationStreamBatchSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationStreamBatchSubscriber.md new file mode 100644 index 0000000000..76a6aff457 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationStreamBatchSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.subscriber.specified.SpecificationStreamBatchSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationStreamSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationStreamSubscriber.md new file mode 100644 index 0000000000..f1bfe8a520 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationStreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.subscriber.specified.SpecificationStreamSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationSubscriber.md new file mode 100644 index 0000000000..90a2845dc9 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.subscriber.specified.SpecificationSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/usecase/BatchListSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/usecase/BatchListSubscriber.md new file mode 100644 index 0000000000..aee1b8aa9b --- /dev/null +++ b/docs/docs/en/api/faststream/redis/subscriber/usecase/BatchListSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.subscriber.usecase.BatchListSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/usecase/ChannelSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/usecase/ChannelSubscriber.md new file mode 100644 index 0000000000..3ab1fc045a --- /dev/null +++ b/docs/docs/en/api/faststream/redis/subscriber/usecase/ChannelSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.subscriber.usecase.ChannelSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/usecase/ListSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/usecase/ListSubscriber.md new file mode 100644 index 0000000000..f7c44e8be5 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/subscriber/usecase/ListSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.subscriber.usecase.ListSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/usecase/LogicSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/usecase/LogicSubscriber.md new file mode 100644 index 0000000000..e3531e7dcc --- /dev/null +++ b/docs/docs/en/api/faststream/redis/subscriber/usecase/LogicSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.subscriber.usecase.LogicSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/usecase/StreamBatchSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/usecase/StreamBatchSubscriber.md new file mode 100644 index 0000000000..3500cc21e2 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/subscriber/usecase/StreamBatchSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.subscriber.usecase.StreamBatchSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/usecase/StreamSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/usecase/StreamSubscriber.md new file mode 100644 index 0000000000..6e2ac31d7f --- /dev/null +++ b/docs/docs/en/api/faststream/redis/subscriber/usecase/StreamSubscriber.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.subscriber.usecase.StreamSubscriber diff --git a/docs/docs/en/api/faststream/redis/testing/ChannelVisitor.md b/docs/docs/en/api/faststream/redis/testing/ChannelVisitor.md new file mode 100644 index 0000000000..f916be2ae8 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/testing/ChannelVisitor.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.testing.ChannelVisitor diff --git a/docs/docs/en/api/faststream/redis/testing/FakeProducer.md b/docs/docs/en/api/faststream/redis/testing/FakeProducer.md new file mode 100644 index 0000000000..e05efb6448 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/testing/FakeProducer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.testing.FakeProducer diff --git a/docs/docs/en/api/faststream/redis/testing/ListVisitor.md b/docs/docs/en/api/faststream/redis/testing/ListVisitor.md new file mode 100644 index 0000000000..414b8a0400 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/testing/ListVisitor.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.testing.ListVisitor diff --git a/docs/docs/en/api/faststream/redis/testing/StreamVisitor.md b/docs/docs/en/api/faststream/redis/testing/StreamVisitor.md new file mode 100644 index 0000000000..0b72d99109 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/testing/StreamVisitor.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.testing.StreamVisitor diff --git a/docs/docs/en/api/faststream/redis/testing/TestRedisBroker.md b/docs/docs/en/api/faststream/redis/testing/TestRedisBroker.md new file mode 100644 index 0000000000..22946e09f8 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/testing/TestRedisBroker.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.testing.TestRedisBroker diff --git a/docs/docs/en/api/faststream/redis/testing/Visitor.md b/docs/docs/en/api/faststream/redis/testing/Visitor.md new file mode 100644 index 0000000000..746688710f --- /dev/null +++ b/docs/docs/en/api/faststream/redis/testing/Visitor.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.testing.Visitor diff --git a/docs/docs/en/api/faststream/redis/testing/build_message.md b/docs/docs/en/api/faststream/redis/testing/build_message.md new file mode 100644 index 0000000000..b2265905c6 --- /dev/null +++ b/docs/docs/en/api/faststream/redis/testing/build_message.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.redis.testing.build_message diff --git a/docs/docs/en/api/faststream/response/PublishCommand.md b/docs/docs/en/api/faststream/response/PublishCommand.md new file mode 100644 index 0000000000..8ca17ac376 --- /dev/null +++ b/docs/docs/en/api/faststream/response/PublishCommand.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.response.PublishCommand diff --git a/docs/docs/en/api/faststream/response/PublishType.md b/docs/docs/en/api/faststream/response/PublishType.md new file mode 100644 index 0000000000..57d3cbddd7 --- /dev/null +++ b/docs/docs/en/api/faststream/response/PublishType.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.response.PublishType diff --git a/docs/docs/en/api/faststream/response/Response.md b/docs/docs/en/api/faststream/response/Response.md new file mode 100644 index 0000000000..e96fe35896 --- /dev/null +++ b/docs/docs/en/api/faststream/response/Response.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.response.Response diff --git a/docs/docs/en/api/faststream/response/ensure_response.md b/docs/docs/en/api/faststream/response/ensure_response.md new file mode 100644 index 0000000000..e55d638acf --- /dev/null +++ b/docs/docs/en/api/faststream/response/ensure_response.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.response.ensure_response diff --git a/docs/docs/en/api/faststream/response/publish_type/PublishType.md b/docs/docs/en/api/faststream/response/publish_type/PublishType.md new file mode 100644 index 0000000000..2ac2fcd51c --- /dev/null +++ b/docs/docs/en/api/faststream/response/publish_type/PublishType.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.response.publish_type.PublishType diff --git a/docs/docs/en/api/faststream/response/response/PublishCommand.md b/docs/docs/en/api/faststream/response/response/PublishCommand.md new file mode 100644 index 0000000000..b247a7e5d8 --- /dev/null +++ b/docs/docs/en/api/faststream/response/response/PublishCommand.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.response.response.PublishCommand diff --git a/docs/docs/en/api/faststream/response/response/Response.md b/docs/docs/en/api/faststream/response/response/Response.md new file mode 100644 index 0000000000..01a68bb486 --- /dev/null +++ b/docs/docs/en/api/faststream/response/response/Response.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.response.response.Response diff --git a/docs/docs/en/api/faststream/response/utils/ensure_response.md b/docs/docs/en/api/faststream/response/utils/ensure_response.md new file mode 100644 index 0000000000..327b9ce951 --- /dev/null +++ b/docs/docs/en/api/faststream/response/utils/ensure_response.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.response.utils.ensure_response diff --git a/docs/docs/en/api/faststream/security/BaseSecurity.md b/docs/docs/en/api/faststream/security/BaseSecurity.md new file mode 100644 index 0000000000..0e5abb09ae --- /dev/null +++ b/docs/docs/en/api/faststream/security/BaseSecurity.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.security.BaseSecurity diff --git a/docs/docs/en/api/faststream/security/SASLGSSAPI.md b/docs/docs/en/api/faststream/security/SASLGSSAPI.md new file mode 100644 index 0000000000..8b6eec2741 --- /dev/null +++ b/docs/docs/en/api/faststream/security/SASLGSSAPI.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.security.SASLGSSAPI diff --git a/docs/docs/en/api/faststream/security/SASLOAuthBearer.md b/docs/docs/en/api/faststream/security/SASLOAuthBearer.md new file mode 100644 index 0000000000..9652a58840 --- /dev/null +++ b/docs/docs/en/api/faststream/security/SASLOAuthBearer.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.security.SASLOAuthBearer diff --git a/docs/docs/en/api/faststream/security/SASLPlaintext.md b/docs/docs/en/api/faststream/security/SASLPlaintext.md new file mode 100644 index 0000000000..b4b5165f27 --- /dev/null +++ b/docs/docs/en/api/faststream/security/SASLPlaintext.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.security.SASLPlaintext diff --git a/docs/docs/en/api/faststream/security/SASLScram256.md b/docs/docs/en/api/faststream/security/SASLScram256.md new file mode 100644 index 0000000000..4d50681fa9 --- /dev/null +++ b/docs/docs/en/api/faststream/security/SASLScram256.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.security.SASLScram256 diff --git a/docs/docs/en/api/faststream/security/SASLScram512.md b/docs/docs/en/api/faststream/security/SASLScram512.md new file mode 100644 index 0000000000..115645cc8c --- /dev/null +++ b/docs/docs/en/api/faststream/security/SASLScram512.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.security.SASLScram512 diff --git a/docs/docs/en/api/faststream/specification/AsyncAPI.md b/docs/docs/en/api/faststream/specification/AsyncAPI.md new file mode 100644 index 0000000000..4b23e3fa4a --- /dev/null +++ b/docs/docs/en/api/faststream/specification/AsyncAPI.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.AsyncAPI diff --git a/docs/docs/en/api/faststream/specification/Contact.md b/docs/docs/en/api/faststream/specification/Contact.md new file mode 100644 index 0000000000..aa8ac012ea --- /dev/null +++ b/docs/docs/en/api/faststream/specification/Contact.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.Contact diff --git a/docs/docs/en/api/faststream/specification/ExternalDocs.md b/docs/docs/en/api/faststream/specification/ExternalDocs.md new file mode 100644 index 0000000000..52e0432c94 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/ExternalDocs.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.ExternalDocs diff --git a/docs/docs/en/api/faststream/specification/License.md b/docs/docs/en/api/faststream/specification/License.md new file mode 100644 index 0000000000..ac2365f82b --- /dev/null +++ b/docs/docs/en/api/faststream/specification/License.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.License diff --git a/docs/docs/en/api/faststream/specification/Tag.md b/docs/docs/en/api/faststream/specification/Tag.md new file mode 100644 index 0000000000..ae4f1202a1 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/Tag.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.Tag diff --git a/docs/docs/en/api/faststream/specification/asyncapi/AsyncAPI.md b/docs/docs/en/api/faststream/specification/asyncapi/AsyncAPI.md new file mode 100644 index 0000000000..f6c0b2de09 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/AsyncAPI.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.AsyncAPI diff --git a/docs/docs/en/api/faststream/specification/asyncapi/factory/AsyncAPI.md b/docs/docs/en/api/faststream/specification/asyncapi/factory/AsyncAPI.md new file mode 100644 index 0000000000..9e68cc1f6c --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/factory/AsyncAPI.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.factory.AsyncAPI diff --git a/docs/docs/en/api/faststream/specification/asyncapi/get_asyncapi_html.md b/docs/docs/en/api/faststream/specification/asyncapi/get_asyncapi_html.md new file mode 100644 index 0000000000..02a5bf12cb --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/get_asyncapi_html.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.get_asyncapi_html diff --git a/docs/docs/en/api/faststream/specification/asyncapi/message/get_model_schema.md b/docs/docs/en/api/faststream/specification/asyncapi/message/get_model_schema.md new file mode 100644 index 0000000000..83b5c9026e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/message/get_model_schema.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.message.get_model_schema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/message/get_response_schema.md b/docs/docs/en/api/faststream/specification/asyncapi/message/get_response_schema.md new file mode 100644 index 0000000000..d283b28902 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/message/get_response_schema.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.message.get_response_schema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/message/parse_handler_params.md b/docs/docs/en/api/faststream/specification/asyncapi/message/parse_handler_params.md new file mode 100644 index 0000000000..cb6c4416f8 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/message/parse_handler_params.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.message.parse_handler_params diff --git a/docs/docs/en/api/faststream/specification/asyncapi/site/get_asyncapi_html.md b/docs/docs/en/api/faststream/specification/asyncapi/site/get_asyncapi_html.md new file mode 100644 index 0000000000..837b931af7 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/site/get_asyncapi_html.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.site.get_asyncapi_html diff --git a/docs/docs/en/api/faststream/specification/asyncapi/site/serve_app.md b/docs/docs/en/api/faststream/specification/asyncapi/site/serve_app.md new file mode 100644 index 0000000000..279e9eb8e0 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/site/serve_app.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.site.serve_app diff --git a/docs/docs/en/api/faststream/specification/asyncapi/utils/clear_key.md b/docs/docs/en/api/faststream/specification/asyncapi/utils/clear_key.md new file mode 100644 index 0000000000..cf6103d19a --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/utils/clear_key.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.utils.clear_key diff --git a/docs/docs/en/api/faststream/specification/asyncapi/utils/move_pydantic_refs.md b/docs/docs/en/api/faststream/specification/asyncapi/utils/move_pydantic_refs.md new file mode 100644 index 0000000000..445472f96d --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/utils/move_pydantic_refs.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.utils.move_pydantic_refs diff --git a/docs/docs/en/api/faststream/specification/asyncapi/utils/resolve_payloads.md b/docs/docs/en/api/faststream/specification/asyncapi/utils/resolve_payloads.md new file mode 100644 index 0000000000..d92d1850f3 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/utils/resolve_payloads.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.utils.resolve_payloads diff --git a/docs/docs/en/api/faststream/specification/asyncapi/utils/to_camelcase.md b/docs/docs/en/api/faststream/specification/asyncapi/utils/to_camelcase.md new file mode 100644 index 0000000000..5a260c9cca --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/utils/to_camelcase.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.utils.to_camelcase diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/AsyncAPI2.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/AsyncAPI2.md new file mode 100644 index 0000000000..b6ca4b870a --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/AsyncAPI2.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.AsyncAPI2 diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/facade/AsyncAPI2.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/facade/AsyncAPI2.md new file mode 100644 index 0000000000..1807a92056 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/facade/AsyncAPI2.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.facade.AsyncAPI2 diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_app_schema.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_app_schema.md new file mode 100644 index 0000000000..ef0e191d3d --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_app_schema.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.generate.get_app_schema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_channels.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_channels.md new file mode 100644 index 0000000000..03fc069dc1 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_channels.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.generate.get_broker_channels diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_server.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_server.md new file mode 100644 index 0000000000..c7b9007c14 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_server.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.generate.get_broker_server diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/resolve_channel_messages.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/resolve_channel_messages.md new file mode 100644 index 0000000000..91abb99b8b --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/resolve_channel_messages.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.generate.resolve_channel_messages diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/get_app_schema.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/get_app_schema.md new file mode 100644 index 0000000000..234b4b8bda --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/get_app_schema.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.get_app_schema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ApplicationInfo.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ApplicationInfo.md new file mode 100644 index 0000000000..b7aaf16515 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ApplicationInfo.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.ApplicationInfo diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ApplicationSchema.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ApplicationSchema.md new file mode 100644 index 0000000000..614fed94e1 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ApplicationSchema.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.ApplicationSchema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Channel.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Channel.md new file mode 100644 index 0000000000..76da65a973 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Channel.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.Channel diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Components.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Components.md new file mode 100644 index 0000000000..12ba1a0a30 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Components.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.Components diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Contact.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Contact.md new file mode 100644 index 0000000000..7eba14d8b1 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Contact.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.Contact diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/CorrelationId.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/CorrelationId.md new file mode 100644 index 0000000000..3173309f51 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/CorrelationId.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.CorrelationId diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ExternalDocs.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ExternalDocs.md new file mode 100644 index 0000000000..2df43d1016 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ExternalDocs.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.ExternalDocs diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/License.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/License.md new file mode 100644 index 0000000000..3f17b11448 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/License.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.License diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Message.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Message.md new file mode 100644 index 0000000000..f6247931d4 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Message.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.Message diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Operation.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Operation.md new file mode 100644 index 0000000000..e25d0e8ff2 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Operation.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.Operation diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Parameter.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Parameter.md new file mode 100644 index 0000000000..fac8aa5ee7 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Parameter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.Parameter diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Reference.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Reference.md new file mode 100644 index 0000000000..c469faf891 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Reference.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.Reference diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Server.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Server.md new file mode 100644 index 0000000000..82bc1ddb32 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Server.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.Server diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ServerVariable.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ServerVariable.md new file mode 100644 index 0000000000..06639f3ec5 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ServerVariable.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.ServerVariable diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Tag.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Tag.md new file mode 100644 index 0000000000..35baa89db7 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Tag.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.Tag diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/ChannelBinding.md new file mode 100644 index 0000000000..36874fc37c --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/OperationBinding.md new file mode 100644 index 0000000000..eb11d6b550 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/ChannelBinding.md new file mode 100644 index 0000000000..263e89f51b --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/OperationBinding.md new file mode 100644 index 0000000000..350a96b413 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/ChannelBinding.md new file mode 100644 index 0000000000..6b4f8d6d93 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Exchange.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Exchange.md new file mode 100644 index 0000000000..dbd3288b64 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Exchange.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.channel.Exchange diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Queue.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Queue.md new file mode 100644 index 0000000000..31de312529 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Queue.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.channel.Queue diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/OperationBinding.md new file mode 100644 index 0000000000..937cda8820 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/ChannelBinding.md new file mode 100644 index 0000000000..7792a2bef7 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/OperationBinding.md new file mode 100644 index 0000000000..21c35af99f --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel/ChannelBinding.md new file mode 100644 index 0000000000..82b2556711 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/OperationBinding.md new file mode 100644 index 0000000000..49e28f86ef --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/ChannelBinding.md new file mode 100644 index 0000000000..a044af926c --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.main.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/OperationBinding.md new file mode 100644 index 0000000000..9cf2d46f59 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.main.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/ChannelBinding.md new file mode 100644 index 0000000000..c7d4ecef03 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.main.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/OperationBinding.md new file mode 100644 index 0000000000..b464bbb356 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.main.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/ChannelBinding.md new file mode 100644 index 0000000000..8380c4571d --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.nats.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/OperationBinding.md new file mode 100644 index 0000000000..c48ff3bad7 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.nats.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel/ChannelBinding.md new file mode 100644 index 0000000000..ebc06a51b8 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.nats.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/OperationBinding.md new file mode 100644 index 0000000000..10ebc684ce --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.nats.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/ChannelBinding.md new file mode 100644 index 0000000000..49402a3533 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.redis.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/OperationBinding.md new file mode 100644 index 0000000000..4a41fede12 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.redis.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel/ChannelBinding.md new file mode 100644 index 0000000000..4c859b133e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.redis.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/OperationBinding.md new file mode 100644 index 0000000000..5e7ef90817 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.redis.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/ChannelBinding.md new file mode 100644 index 0000000000..efd54e587e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/OperationBinding.md new file mode 100644 index 0000000000..4f3babf6a5 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/ChannelBinding.md new file mode 100644 index 0000000000..274f800ea8 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/from_spec.md new file mode 100644 index 0000000000..6890ca0373 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.channel.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/OperationBinding.md new file mode 100644 index 0000000000..931067bfef --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/from_spec.md new file mode 100644 index 0000000000..b8a69ffcc0 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/from_spec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.operation.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channels/Channel.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channels/Channel.md new file mode 100644 index 0000000000..520d156b96 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channels/Channel.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.channels.Channel diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/components/Components.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/components/Components.md new file mode 100644 index 0000000000..215edc3e69 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/components/Components.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.components.Components diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact/Contact.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact/Contact.md new file mode 100644 index 0000000000..14b7574d92 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact/Contact.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.contact.Contact diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs/ExternalDocs.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs/ExternalDocs.md new file mode 100644 index 0000000000..8b66a2c5f3 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs/ExternalDocs.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.docs.ExternalDocs diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/info/ApplicationInfo.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/info/ApplicationInfo.md new file mode 100644 index 0000000000..db377ddd61 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/info/ApplicationInfo.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.info.ApplicationInfo diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license/License.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license/License.md new file mode 100644 index 0000000000..d9d4102522 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license/License.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.license.License diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/CorrelationId.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/CorrelationId.md new file mode 100644 index 0000000000..bbfc2f40d8 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/CorrelationId.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.message.CorrelationId diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/Message.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/Message.md new file mode 100644 index 0000000000..9667e77e8e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/Message.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.message.Message diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operations/Operation.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operations/Operation.md new file mode 100644 index 0000000000..3d750e5f3e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operations/Operation.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.operations.Operation diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/schema/ApplicationSchema.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/schema/ApplicationSchema.md new file mode 100644 index 0000000000..2a380a8e4d --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/schema/ApplicationSchema.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.schema.ApplicationSchema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/servers/Server.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/servers/Server.md new file mode 100644 index 0000000000..a50c1a5cf1 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/servers/Server.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.servers.Server diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/servers/ServerVariable.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/servers/ServerVariable.md new file mode 100644 index 0000000000..8606288a32 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/servers/ServerVariable.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.servers.ServerVariable diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag/Tag.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag/Tag.md new file mode 100644 index 0000000000..c3d9025966 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag/Tag.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.tag.Tag diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/utils/Parameter.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/utils/Parameter.md new file mode 100644 index 0000000000..c2971d5485 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/utils/Parameter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.utils.Parameter diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/utils/Reference.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/utils/Reference.md new file mode 100644 index 0000000000..2737907b0e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/utils/Reference.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.utils.Reference diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/AsyncAPI3.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/AsyncAPI3.md new file mode 100644 index 0000000000..4eb400a450 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/AsyncAPI3.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.AsyncAPI3 diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/facade/AsyncAPI3.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/facade/AsyncAPI3.md new file mode 100644 index 0000000000..5216f86a02 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/facade/AsyncAPI3.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.facade.AsyncAPI3 diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_app_schema.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_app_schema.md new file mode 100644 index 0000000000..0faa97ba94 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_app_schema.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.generate.get_app_schema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_channels.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_channels.md new file mode 100644 index 0000000000..d43691125d --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_channels.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.generate.get_broker_channels diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_server.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_server.md new file mode 100644 index 0000000000..1c71db1292 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_server.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.generate.get_broker_server diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/get_app_schema.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/get_app_schema.md new file mode 100644 index 0000000000..977c46289d --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/get_app_schema.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.get_app_schema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationInfo.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationInfo.md new file mode 100644 index 0000000000..be7a85513c --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationInfo.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.ApplicationInfo diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationSchema.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationSchema.md new file mode 100644 index 0000000000..0f3fa28a38 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationSchema.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.ApplicationSchema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Channel.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Channel.md new file mode 100644 index 0000000000..f213110586 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Channel.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.Channel diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Components.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Components.md new file mode 100644 index 0000000000..bce8d6e93e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Components.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.Components diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Contact.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Contact.md new file mode 100644 index 0000000000..14b7574d92 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Contact.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.contact.Contact diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/CorrelationId.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/CorrelationId.md new file mode 100644 index 0000000000..bbfc2f40d8 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/CorrelationId.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.message.CorrelationId diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ExternalDocs.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ExternalDocs.md new file mode 100644 index 0000000000..8b66a2c5f3 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ExternalDocs.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.docs.ExternalDocs diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/License.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/License.md new file mode 100644 index 0000000000..d9d4102522 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/License.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.license.License diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Message.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Message.md new file mode 100644 index 0000000000..9667e77e8e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Message.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.message.Message diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Operation.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Operation.md new file mode 100644 index 0000000000..a46ecefb8d --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Operation.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.Operation diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Parameter.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Parameter.md new file mode 100644 index 0000000000..c2971d5485 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Parameter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.utils.Parameter diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Reference.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Reference.md new file mode 100644 index 0000000000..2737907b0e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Reference.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.utils.Reference diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Server.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Server.md new file mode 100644 index 0000000000..d41ebe84c3 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Server.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.Server diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ServerVariable.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ServerVariable.md new file mode 100644 index 0000000000..8606288a32 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ServerVariable.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.servers.ServerVariable diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Tag.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Tag.md new file mode 100644 index 0000000000..c3d9025966 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Tag.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.tag.Tag diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/ChannelBinding.md new file mode 100644 index 0000000000..ca8431218b --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/OperationBinding.md new file mode 100644 index 0000000000..876f866f35 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/ChannelBinding.md new file mode 100644 index 0000000000..2777001c4d --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.amqp.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/OperationBinding.md new file mode 100644 index 0000000000..325bba3f9e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.amqp.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel/ChannelBinding.md new file mode 100644 index 0000000000..74c10098ac --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.amqp.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation/OperationBinding.md new file mode 100644 index 0000000000..51c5024cc7 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.amqp.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka/ChannelBinding.md new file mode 100644 index 0000000000..82b2556711 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka/OperationBinding.md new file mode 100644 index 0000000000..49e28f86ef --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/ChannelBinding.md new file mode 100644 index 0000000000..07977ed15f --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.main.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/OperationBinding.md new file mode 100644 index 0000000000..c897790951 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.main.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel/ChannelBinding.md new file mode 100644 index 0000000000..409e449a27 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.main.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation/OperationBinding.md new file mode 100644 index 0000000000..4e85a7f5e4 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.bindings.main.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats/ChannelBinding.md new file mode 100644 index 0000000000..ebc06a51b8 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.nats.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats/OperationBinding.md new file mode 100644 index 0000000000..10ebc684ce --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.nats.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis/ChannelBinding.md new file mode 100644 index 0000000000..4c859b133e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.redis.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis/OperationBinding.md new file mode 100644 index 0000000000..5e7ef90817 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.redis.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs/ChannelBinding.md new file mode 100644 index 0000000000..274f800ea8 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs/OperationBinding.md new file mode 100644 index 0000000000..931067bfef --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channels/Channel.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channels/Channel.md new file mode 100644 index 0000000000..b3b425a350 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channels/Channel.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.channels.Channel diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/components/Components.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/components/Components.md new file mode 100644 index 0000000000..db5c489f43 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/components/Components.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.components.Components diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/contact/Contact.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/contact/Contact.md new file mode 100644 index 0000000000..14b7574d92 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/contact/Contact.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.contact.Contact diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/docs/ExternalDocs.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/docs/ExternalDocs.md new file mode 100644 index 0000000000..8b66a2c5f3 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/docs/ExternalDocs.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.docs.ExternalDocs diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/info/ApplicationInfo.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/info/ApplicationInfo.md new file mode 100644 index 0000000000..f0c2b0f95d --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/info/ApplicationInfo.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.info.ApplicationInfo diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/license/License.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/license/License.md new file mode 100644 index 0000000000..d9d4102522 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/license/License.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.license.License diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/message/CorrelationId.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/message/CorrelationId.md new file mode 100644 index 0000000000..bbfc2f40d8 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/message/CorrelationId.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.message.CorrelationId diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/message/Message.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/message/Message.md new file mode 100644 index 0000000000..9667e77e8e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/message/Message.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.message.Message diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/Action.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/Action.md new file mode 100644 index 0000000000..c5a9956348 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/Action.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.operations.Action diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/Operation.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/Operation.md new file mode 100644 index 0000000000..1ac73f73da --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/Operation.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.operations.Operation diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/schema/ApplicationSchema.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/schema/ApplicationSchema.md new file mode 100644 index 0000000000..57fc00568a --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/schema/ApplicationSchema.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.schema.ApplicationSchema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/servers/Server.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/servers/Server.md new file mode 100644 index 0000000000..1d9f1168d9 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/servers/Server.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v3_0_0.schema.servers.Server diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/tag/Tag.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/tag/Tag.md new file mode 100644 index 0000000000..c3d9025966 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/tag/Tag.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.tag.Tag diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/utils/Parameter.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/utils/Parameter.md new file mode 100644 index 0000000000..c2971d5485 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/utils/Parameter.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.utils.Parameter diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/utils/Reference.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/utils/Reference.md new file mode 100644 index 0000000000..2737907b0e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/utils/Reference.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.asyncapi.v2_6_0.schema.utils.Reference diff --git a/docs/docs/en/api/faststream/specification/base/info/BaseApplicationInfo.md b/docs/docs/en/api/faststream/specification/base/info/BaseApplicationInfo.md new file mode 100644 index 0000000000..324bbbcec9 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/base/info/BaseApplicationInfo.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.base.info.BaseApplicationInfo diff --git a/docs/docs/en/api/faststream/specification/base/schema/BaseApplicationSchema.md b/docs/docs/en/api/faststream/specification/base/schema/BaseApplicationSchema.md new file mode 100644 index 0000000000..8d9291322c --- /dev/null +++ b/docs/docs/en/api/faststream/specification/base/schema/BaseApplicationSchema.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.base.schema.BaseApplicationSchema diff --git a/docs/docs/en/api/faststream/specification/base/specification/Specification.md b/docs/docs/en/api/faststream/specification/base/specification/Specification.md new file mode 100644 index 0000000000..0b3f07b9f7 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/base/specification/Specification.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.base.specification.Specification diff --git a/docs/docs/en/api/faststream/specification/proto/EndpointSpecification.md b/docs/docs/en/api/faststream/specification/proto/EndpointSpecification.md new file mode 100644 index 0000000000..3d6dcee882 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/proto/EndpointSpecification.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.proto.EndpointSpecification diff --git a/docs/docs/en/api/faststream/specification/proto/ServerSpecification.md b/docs/docs/en/api/faststream/specification/proto/ServerSpecification.md new file mode 100644 index 0000000000..d49b60e512 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/proto/ServerSpecification.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.proto.ServerSpecification diff --git a/docs/docs/en/api/faststream/specification/proto/broker/ServerSpecification.md b/docs/docs/en/api/faststream/specification/proto/broker/ServerSpecification.md new file mode 100644 index 0000000000..6bb667f707 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/proto/broker/ServerSpecification.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.proto.broker.ServerSpecification diff --git a/docs/docs/en/api/faststream/specification/proto/endpoint/EndpointSpecification.md b/docs/docs/en/api/faststream/specification/proto/endpoint/EndpointSpecification.md new file mode 100644 index 0000000000..491c5e3e87 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/proto/endpoint/EndpointSpecification.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.proto.endpoint.EndpointSpecification diff --git a/docs/docs/en/api/faststream/specification/schema/Contact.md b/docs/docs/en/api/faststream/specification/schema/Contact.md new file mode 100644 index 0000000000..5c95b1d99b --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/Contact.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.Contact diff --git a/docs/docs/en/api/faststream/specification/schema/ContactDict.md b/docs/docs/en/api/faststream/specification/schema/ContactDict.md new file mode 100644 index 0000000000..79d9ca5fb2 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/ContactDict.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.ContactDict diff --git a/docs/docs/en/api/faststream/specification/schema/ExternalDocs.md b/docs/docs/en/api/faststream/specification/schema/ExternalDocs.md new file mode 100644 index 0000000000..242418f578 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/ExternalDocs.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.ExternalDocs diff --git a/docs/docs/en/api/faststream/specification/schema/ExternalDocsDict.md b/docs/docs/en/api/faststream/specification/schema/ExternalDocsDict.md new file mode 100644 index 0000000000..788848b13a --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/ExternalDocsDict.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.ExternalDocsDict diff --git a/docs/docs/en/api/faststream/specification/schema/License.md b/docs/docs/en/api/faststream/specification/schema/License.md new file mode 100644 index 0000000000..4e321c7aab --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/License.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.License diff --git a/docs/docs/en/api/faststream/specification/schema/LicenseDict.md b/docs/docs/en/api/faststream/specification/schema/LicenseDict.md new file mode 100644 index 0000000000..16204a3fc8 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/LicenseDict.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.LicenseDict diff --git a/docs/docs/en/api/faststream/specification/schema/Message.md b/docs/docs/en/api/faststream/specification/schema/Message.md new file mode 100644 index 0000000000..d1baee52f5 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/Message.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.Message diff --git a/docs/docs/en/api/faststream/specification/schema/Operation.md b/docs/docs/en/api/faststream/specification/schema/Operation.md new file mode 100644 index 0000000000..cde09d402f --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/Operation.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.Operation diff --git a/docs/docs/en/api/faststream/specification/schema/PublisherSpec.md b/docs/docs/en/api/faststream/specification/schema/PublisherSpec.md new file mode 100644 index 0000000000..5b3e7f23e5 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/PublisherSpec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.PublisherSpec diff --git a/docs/docs/en/api/faststream/specification/schema/SubscriberSpec.md b/docs/docs/en/api/faststream/specification/schema/SubscriberSpec.md new file mode 100644 index 0000000000..7ec1f6964b --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/SubscriberSpec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.SubscriberSpec diff --git a/docs/docs/en/api/faststream/specification/schema/Tag.md b/docs/docs/en/api/faststream/specification/schema/Tag.md new file mode 100644 index 0000000000..03071c314f --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/Tag.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.Tag diff --git a/docs/docs/en/api/faststream/specification/schema/TagDict.md b/docs/docs/en/api/faststream/specification/schema/TagDict.md new file mode 100644 index 0000000000..02f4de9c05 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/TagDict.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.TagDict diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/ChannelBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/ChannelBinding.md new file mode 100644 index 0000000000..cb7f566dc1 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/bindings/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.bindings.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/OperationBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/OperationBinding.md new file mode 100644 index 0000000000..6fcad5ea7e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/bindings/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.bindings.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/amqp/ChannelBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/amqp/ChannelBinding.md new file mode 100644 index 0000000000..194c68f536 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/bindings/amqp/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.bindings.amqp.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/amqp/Exchange.md b/docs/docs/en/api/faststream/specification/schema/bindings/amqp/Exchange.md new file mode 100644 index 0000000000..355222c2bb --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/bindings/amqp/Exchange.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.bindings.amqp.Exchange diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/amqp/OperationBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/amqp/OperationBinding.md new file mode 100644 index 0000000000..6bb90ca8ae --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/bindings/amqp/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.bindings.amqp.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/amqp/Queue.md b/docs/docs/en/api/faststream/specification/schema/bindings/amqp/Queue.md new file mode 100644 index 0000000000..54c9493d0e --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/bindings/amqp/Queue.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.bindings.amqp.Queue diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/kafka/ChannelBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/kafka/ChannelBinding.md new file mode 100644 index 0000000000..2561bf2e72 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/bindings/kafka/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.bindings.kafka.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/kafka/OperationBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/kafka/OperationBinding.md new file mode 100644 index 0000000000..0746cedd33 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/bindings/kafka/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.bindings.kafka.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/main/ChannelBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/main/ChannelBinding.md new file mode 100644 index 0000000000..73bfc4bb40 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/bindings/main/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.bindings.main.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/main/OperationBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/main/OperationBinding.md new file mode 100644 index 0000000000..f4ebb70b9c --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/bindings/main/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.bindings.main.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/nats/ChannelBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/nats/ChannelBinding.md new file mode 100644 index 0000000000..4495e21ac2 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/bindings/nats/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.bindings.nats.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/nats/OperationBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/nats/OperationBinding.md new file mode 100644 index 0000000000..fde8061b86 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/bindings/nats/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.bindings.nats.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/redis/ChannelBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/redis/ChannelBinding.md new file mode 100644 index 0000000000..0f991824da --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/bindings/redis/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.bindings.redis.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/redis/OperationBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/redis/OperationBinding.md new file mode 100644 index 0000000000..95e3ca446a --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/bindings/redis/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.bindings.redis.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/sqs/ChannelBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/sqs/ChannelBinding.md new file mode 100644 index 0000000000..521a6f5560 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/bindings/sqs/ChannelBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.bindings.sqs.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/sqs/OperationBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/sqs/OperationBinding.md new file mode 100644 index 0000000000..a70995cb7f --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/bindings/sqs/OperationBinding.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.bindings.sqs.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/schema/extra/Contact.md b/docs/docs/en/api/faststream/specification/schema/extra/Contact.md new file mode 100644 index 0000000000..f89be2dc65 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/extra/Contact.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.extra.Contact diff --git a/docs/docs/en/api/faststream/specification/schema/extra/ContactDict.md b/docs/docs/en/api/faststream/specification/schema/extra/ContactDict.md new file mode 100644 index 0000000000..8f20fd396d --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/extra/ContactDict.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.extra.ContactDict diff --git a/docs/docs/en/api/faststream/specification/schema/extra/ExternalDocs.md b/docs/docs/en/api/faststream/specification/schema/extra/ExternalDocs.md new file mode 100644 index 0000000000..a745e15910 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/extra/ExternalDocs.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.extra.ExternalDocs diff --git a/docs/docs/en/api/faststream/specification/schema/extra/ExternalDocsDict.md b/docs/docs/en/api/faststream/specification/schema/extra/ExternalDocsDict.md new file mode 100644 index 0000000000..1110d88070 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/extra/ExternalDocsDict.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.extra.ExternalDocsDict diff --git a/docs/docs/en/api/faststream/specification/schema/extra/License.md b/docs/docs/en/api/faststream/specification/schema/extra/License.md new file mode 100644 index 0000000000..033374ed25 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/extra/License.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.extra.License diff --git a/docs/docs/en/api/faststream/specification/schema/extra/LicenseDict.md b/docs/docs/en/api/faststream/specification/schema/extra/LicenseDict.md new file mode 100644 index 0000000000..e2994e1d88 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/extra/LicenseDict.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.extra.LicenseDict diff --git a/docs/docs/en/api/faststream/specification/schema/extra/Tag.md b/docs/docs/en/api/faststream/specification/schema/extra/Tag.md new file mode 100644 index 0000000000..cc373f1528 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/extra/Tag.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.extra.Tag diff --git a/docs/docs/en/api/faststream/specification/schema/extra/TagDict.md b/docs/docs/en/api/faststream/specification/schema/extra/TagDict.md new file mode 100644 index 0000000000..c2455e5c4f --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/extra/TagDict.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.extra.TagDict diff --git a/docs/docs/en/api/faststream/specification/schema/extra/contact/Contact.md b/docs/docs/en/api/faststream/specification/schema/extra/contact/Contact.md new file mode 100644 index 0000000000..f34ea777d3 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/extra/contact/Contact.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.extra.contact.Contact diff --git a/docs/docs/en/api/faststream/specification/schema/extra/contact/ContactDict.md b/docs/docs/en/api/faststream/specification/schema/extra/contact/ContactDict.md new file mode 100644 index 0000000000..17d0d774eb --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/extra/contact/ContactDict.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.extra.contact.ContactDict diff --git a/docs/docs/en/api/faststream/specification/schema/extra/external_docs/ExternalDocs.md b/docs/docs/en/api/faststream/specification/schema/extra/external_docs/ExternalDocs.md new file mode 100644 index 0000000000..bf06e4b97c --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/extra/external_docs/ExternalDocs.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.extra.external_docs.ExternalDocs diff --git a/docs/docs/en/api/faststream/specification/schema/extra/external_docs/ExternalDocsDict.md b/docs/docs/en/api/faststream/specification/schema/extra/external_docs/ExternalDocsDict.md new file mode 100644 index 0000000000..cf1c76bc2b --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/extra/external_docs/ExternalDocsDict.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.extra.external_docs.ExternalDocsDict diff --git a/docs/docs/en/api/faststream/specification/schema/extra/license/License.md b/docs/docs/en/api/faststream/specification/schema/extra/license/License.md new file mode 100644 index 0000000000..58cb3821e7 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/extra/license/License.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.extra.license.License diff --git a/docs/docs/en/api/faststream/specification/schema/extra/license/LicenseDict.md b/docs/docs/en/api/faststream/specification/schema/extra/license/LicenseDict.md new file mode 100644 index 0000000000..fb8779aa39 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/extra/license/LicenseDict.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.extra.license.LicenseDict diff --git a/docs/docs/en/api/faststream/specification/schema/extra/tag/Tag.md b/docs/docs/en/api/faststream/specification/schema/extra/tag/Tag.md new file mode 100644 index 0000000000..b25a4d5cb1 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/extra/tag/Tag.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.extra.tag.Tag diff --git a/docs/docs/en/api/faststream/specification/schema/extra/tag/TagDict.md b/docs/docs/en/api/faststream/specification/schema/extra/tag/TagDict.md new file mode 100644 index 0000000000..92500cc5b2 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/extra/tag/TagDict.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.extra.tag.TagDict diff --git a/docs/docs/en/api/faststream/specification/schema/message/Message.md b/docs/docs/en/api/faststream/specification/schema/message/Message.md new file mode 100644 index 0000000000..1c2fd0ceb8 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/message/Message.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.message.Message diff --git a/docs/docs/en/api/faststream/specification/schema/message/model/Message.md b/docs/docs/en/api/faststream/specification/schema/message/model/Message.md new file mode 100644 index 0000000000..f057a4e898 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/message/model/Message.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.message.model.Message diff --git a/docs/docs/en/api/faststream/specification/schema/operation/Operation.md b/docs/docs/en/api/faststream/specification/schema/operation/Operation.md new file mode 100644 index 0000000000..23088a80f0 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/operation/Operation.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.operation.Operation diff --git a/docs/docs/en/api/faststream/specification/schema/operation/model/Operation.md b/docs/docs/en/api/faststream/specification/schema/operation/model/Operation.md new file mode 100644 index 0000000000..17c306a8ab --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/operation/model/Operation.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.operation.model.Operation diff --git a/docs/docs/en/api/faststream/specification/schema/publisher/PublisherSpec.md b/docs/docs/en/api/faststream/specification/schema/publisher/PublisherSpec.md new file mode 100644 index 0000000000..002bc1ecb8 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/publisher/PublisherSpec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.publisher.PublisherSpec diff --git a/docs/docs/en/api/faststream/specification/schema/subscriber/SubscriberSpec.md b/docs/docs/en/api/faststream/specification/schema/subscriber/SubscriberSpec.md new file mode 100644 index 0000000000..5a4e4515e2 --- /dev/null +++ b/docs/docs/en/api/faststream/specification/schema/subscriber/SubscriberSpec.md @@ -0,0 +1,11 @@ +--- +# 0.5 - API +# 2 - Release +# 3 - Contributing +# 5 - Template Page +# 10 - Default +search: + boost: 0.5 +--- + +::: faststream.specification.schema.subscriber.SubscriberSpec diff --git a/faststream/_internal/broker/abc_broker.py b/faststream/_internal/broker/abc_broker.py index 93d62accf0..97ace30b81 100644 --- a/faststream/_internal/broker/abc_broker.py +++ b/faststream/_internal/broker/abc_broker.py @@ -46,6 +46,7 @@ def __init__( decoder: Optional["CustomCallable"], include_in_schema: Optional[bool], state: "BrokerState", + routers: Sequence["ABCBroker[Any]"], ) -> None: self.prefix = prefix self.include_in_schema = include_in_schema @@ -60,6 +61,8 @@ def __init__( self._state = Pointer(state) + self.include_routers(*routers) + def add_middleware(self, middleware: "BrokerMiddleware[MsgType]") -> None: """Append BrokerMiddleware to the end of middlewares list. diff --git a/faststream/_internal/broker/broker.py b/faststream/_internal/broker/broker.py index db0d81e839..fa59569e30 100644 --- a/faststream/_internal/broker/broker.py +++ b/faststream/_internal/broker/broker.py @@ -93,6 +93,10 @@ def __init__( "Graceful shutdown timeout. Broker waits for all running subscribers completion before shut down.", ), ], + routers: Annotated[ + Sequence["ABCBroker[Any]"], + Doc("Routers to apply to broker."), + ], # Logging args logger_state: LoggerState, # FastDepends args @@ -163,6 +167,7 @@ def __init__( Optional["AsyncCustomCallable"], to_async(parser) if parser else None, ), + routers=routers, # Broker is a root router include_in_schema=True, prefix="", diff --git a/faststream/_internal/broker/router.py b/faststream/_internal/broker/router.py index ee2f28602a..81f4a2998a 100644 --- a/faststream/_internal/broker/router.py +++ b/faststream/_internal/broker/router.py @@ -74,6 +74,7 @@ def __init__( parser: Optional["CustomCallable"], decoder: Optional["CustomCallable"], include_in_schema: Optional[bool], + routers: Sequence["ABCBroker[Any]"], ) -> None: super().__init__( prefix=prefix, @@ -83,6 +84,7 @@ def __init__( decoder=decoder, include_in_schema=include_in_schema, state=EmptyBrokerState("You should include router to any broker."), + routers=routers ) for h in handlers: diff --git a/faststream/confluent/broker/broker.py b/faststream/confluent/broker/broker.py index 8a930fea91..1b96a46126 100644 --- a/faststream/confluent/broker/broker.py +++ b/faststream/confluent/broker/broker.py @@ -46,6 +46,7 @@ LoggerProto, SendableMessage, ) + from faststream._internal.broker.abc_broker import ABCBroker from faststream._internal.types import ( BrokerMiddleware, CustomCallable, @@ -280,6 +281,10 @@ def __init__( ], Doc("Middlewares to apply to all broker publishers/subscribers."), ] = (), + routers: Annotated[ + Sequence["ABCBroker[Any]"], + Doc("Routers to apply to broker."), + ] = (), # AsyncAPI args security: Annotated[ Optional["BaseSecurity"], @@ -379,6 +384,7 @@ def __init__( decoder=decoder, parser=parser, middlewares=middlewares, + routers=routers, # AsyncAPI args description=description, specification_url=specification_url, diff --git a/faststream/confluent/router.py b/faststream/confluent/router.py index 53a3d97426..ed6ca3bce8 100644 --- a/faststream/confluent/router.py +++ b/faststream/confluent/router.py @@ -25,6 +25,7 @@ from fast_depends.dependencies import Dependant from faststream._internal.basic_types import SendableMessage + from faststream._internal.broker.abc_broker import ABCBroker from faststream._internal.types import ( BrokerMiddleware, CustomCallable, @@ -508,6 +509,10 @@ def __init__( ], Doc("Router middlewares to apply to all routers' publishers/subscribers."), ] = (), + routers: Annotated[ + Sequence["ABCBroker[Any]"], + Doc("Routers to apply to broker."), + ] = (), parser: Annotated[ Optional["CustomCallable"], Doc("Parser to map original **Message** object to FastStream one."), @@ -527,6 +532,7 @@ def __init__( prefix=prefix, dependencies=dependencies, middlewares=middlewares, # type: ignore[arg-type] + routers=routers, parser=parser, decoder=decoder, include_in_schema=include_in_schema, diff --git a/faststream/kafka/broker/broker.py b/faststream/kafka/broker/broker.py index 5b4f74b8a8..292f3a566b 100644 --- a/faststream/kafka/broker/broker.py +++ b/faststream/kafka/broker/broker.py @@ -51,6 +51,7 @@ LoggerProto, SendableMessage, ) + from faststream._internal.broker.abc_broker import ABCBroker from faststream._internal.types import ( BrokerMiddleware, CustomCallable, @@ -453,6 +454,10 @@ def __init__( ], Doc("Middlewares to apply to all broker publishers/subscribers."), ] = (), + routers: Annotated[ + Sequence["ABCBroker[Any]"], + Doc("Routers to apply to broker."), + ] = (), # AsyncAPI args security: Annotated[ Optional["BaseSecurity"], @@ -559,6 +564,7 @@ def __init__( decoder=decoder, parser=parser, middlewares=middlewares, + routers=routers, # AsyncAPI args description=description, specification_url=specification_url, diff --git a/faststream/kafka/router.py b/faststream/kafka/router.py index 31b21fccf0..a9d51af57f 100644 --- a/faststream/kafka/router.py +++ b/faststream/kafka/router.py @@ -28,6 +28,7 @@ from fast_depends.dependencies import Dependant from faststream._internal.basic_types import SendableMessage + from faststream._internal.broker.abc_broker import ABCBroker from faststream._internal.types import ( BrokerMiddleware, CustomCallable, @@ -618,6 +619,10 @@ def __init__( ], Doc("Router middlewares to apply to all routers' publishers/subscribers."), ] = (), + routers: Annotated[ + Sequence["ABCBroker[Any]"], + Doc("Routers to apply to broker."), + ] = (), parser: Annotated[ Optional["CustomCallable"], Doc("Parser to map original **ConsumerRecord** object to FastStream one."), @@ -637,6 +642,7 @@ def __init__( prefix=prefix, dependencies=dependencies, middlewares=middlewares, + routers=routers, parser=parser, decoder=decoder, include_in_schema=include_in_schema, diff --git a/faststream/nats/broker/broker.py b/faststream/nats/broker/broker.py index 1055f4f60d..0940225a29 100644 --- a/faststream/nats/broker/broker.py +++ b/faststream/nats/broker/broker.py @@ -66,6 +66,7 @@ LoggerProto, SendableMessage, ) + from faststream._internal.broker.abc_broker import ABCBroker from faststream._internal.types import ( BrokerMiddleware, CustomCallable, @@ -376,6 +377,10 @@ def __init__( Sequence["BrokerMiddleware[Msg]"], Doc("Middlewares to apply to all broker publishers/subscribers."), ] = (), + routers: Annotated[ + Sequence["ABCBroker[Any]"], + Doc("Routers to apply to broker."), + ] = (), # AsyncAPI args security: Annotated[ Optional["BaseSecurity"], @@ -485,6 +490,7 @@ def __init__( decoder=decoder, parser=parser, middlewares=middlewares, + routers=routers, # AsyncAPI description=description, specification_url=specification_url, diff --git a/faststream/nats/router.py b/faststream/nats/router.py index 556bfb7f66..101026e00b 100644 --- a/faststream/nats/router.py +++ b/faststream/nats/router.py @@ -25,6 +25,7 @@ from nats.aio.msg import Msg from faststream._internal.basic_types import SendableMessage + from faststream._internal.broker.abc_broker import ABCBroker from faststream._internal.types import ( BrokerMiddleware, CustomCallable, @@ -360,6 +361,10 @@ def __init__( Sequence["BrokerMiddleware[Msg]"], Doc("Router middlewares to apply to all routers' publishers/subscribers."), ] = (), + routers: Annotated[ + Sequence["ABCBroker[Any]"], + Doc("Routers to apply to broker."), + ] = (), parser: Annotated[ Optional["CustomCallable"], Doc("Parser to map original **IncomingMessage** Msg to FastStream one."), @@ -379,6 +384,7 @@ def __init__( prefix=prefix, dependencies=dependencies, middlewares=middlewares, + routers=routers, parser=parser, decoder=decoder, include_in_schema=include_in_schema, diff --git a/faststream/rabbit/broker/broker.py b/faststream/rabbit/broker/broker.py index 789ac5b931..a171755cf1 100644 --- a/faststream/rabbit/broker/broker.py +++ b/faststream/rabbit/broker/broker.py @@ -172,6 +172,10 @@ def __init__( Sequence["BrokerMiddleware[IncomingMessage]"], Doc("Middlewares to apply to all broker publishers/subscribers."), ] = (), + routers: Annotated[ + Sequence["ABCBroker[Any]"], + Doc("Routers to apply to broker."), + ] = (), # AsyncAPI args security: Annotated[ Optional["BaseSecurity"], @@ -266,6 +270,7 @@ def __init__( decoder=decoder, parser=parser, middlewares=middlewares, + routers=routers, # AsyncAPI args description=description, specification_url=specification_url, diff --git a/faststream/rabbit/router.py b/faststream/rabbit/router.py index d272dd0ae8..59aac51eb0 100644 --- a/faststream/rabbit/router.py +++ b/faststream/rabbit/router.py @@ -18,6 +18,7 @@ from fast_depends.dependencies import Dependant from faststream._internal.basic_types import AnyDict + from faststream._internal.broker.abc_broker import ABCBroker from faststream._internal.types import ( BrokerMiddleware, CustomCallable, @@ -314,6 +315,10 @@ def __init__( Sequence["BrokerMiddleware[IncomingMessage]"], Doc("Router middlewares to apply to all routers' publishers/subscribers."), ] = (), + routers: Annotated[ + Sequence["ABCBroker[Any]"], + Doc("Routers to apply to broker."), + ] = (), parser: Annotated[ Optional["CustomCallable"], Doc("Parser to map original **IncomingMessage** Msg to FastStream one."), @@ -333,6 +338,7 @@ def __init__( prefix=prefix, dependencies=dependencies, middlewares=middlewares, + routers=routers, parser=parser, decoder=decoder, include_in_schema=include_in_schema, diff --git a/faststream/redis/broker/broker.py b/faststream/redis/broker/broker.py index c0e0f89192..b47845e296 100644 --- a/faststream/redis/broker/broker.py +++ b/faststream/redis/broker/broker.py @@ -50,6 +50,7 @@ LoggerProto, SendableMessage, ) + from faststream._internal.broker.abc_broker import ABCBroker from faststream._internal.types import ( BrokerMiddleware, CustomCallable, @@ -138,6 +139,10 @@ def __init__( Sequence["BrokerMiddleware[BaseMessage]"], Doc("Middlewares to apply to all broker publishers/subscribers."), ] = (), + routers: Annotated[ + Sequence["ABCBroker[Any]"], + Doc("Routers to apply to broker."), + ] = (), # AsyncAPI args security: Annotated[ Optional["BaseSecurity"], @@ -228,6 +233,7 @@ def __init__( decoder=decoder, parser=parser, middlewares=middlewares, + routers=routers, # AsyncAPI description=description, specification_url=specification_url, diff --git a/faststream/redis/router.py b/faststream/redis/router.py index 0c048b4e2e..a7c33875dc 100644 --- a/faststream/redis/router.py +++ b/faststream/redis/router.py @@ -17,6 +17,7 @@ from fast_depends.dependencies import Dependant from faststream._internal.basic_types import AnyDict, SendableMessage + from faststream._internal.broker.abc_broker import ABCBroker from faststream._internal.types import ( BrokerMiddleware, CustomCallable, @@ -232,6 +233,10 @@ def __init__( Sequence["BrokerMiddleware[BaseMessage]"], Doc("Router middlewares to apply to all routers' publishers/subscribers."), ] = (), + routers: Annotated[ + Sequence["ABCBroker[Any]"], + Doc("Routers to apply to broker."), + ] = (), parser: Annotated[ Optional["CustomCallable"], Doc("Parser to map original **IncomingMessage** Msg to FastStream one."), @@ -251,6 +256,7 @@ def __init__( prefix=prefix, dependencies=dependencies, middlewares=middlewares, + routers=routers, parser=parser, decoder=decoder, include_in_schema=include_in_schema, diff --git a/tests/brokers/base/router.py b/tests/brokers/base/router.py index 382f54dc0c..a29c8e63ec 100644 --- a/tests/brokers/base/router.py +++ b/tests/brokers/base/router.py @@ -593,6 +593,34 @@ def subscriber(s) -> None: mock.parser.assert_called_once() mock.decoder.assert_called_once() + async def test_router_in_init( + self, + router: BrokerRouter, + queue: str, + ) -> None: + event = asyncio.Event() + + args, kwargs = self.get_subscriber_params(queue) + + @router.subscriber(*args, **kwargs) + def subscriber(m) -> None: + event.set() + + pub_broker = self.get_broker(routers=[router]) + + async with self.patch_broker(pub_broker) as br: + await br.start() + + await asyncio.wait( + ( + asyncio.create_task(br.publish("hello", queue)), + asyncio.create_task(event.wait()), + ), + timeout=self.timeout, + ) + + assert event.is_set() + @pytest.mark.asyncio() class RouterLocalTestcase(RouterTestcase): From 5f4c9f462694ad5a4854946572e5f8cd44f99f70 Mon Sep 17 00:00:00 2001 From: Flosckow <66554425+Flosckow@users.noreply.github.com> Date: Wed, 11 Dec 2024 02:29:14 +0700 Subject: [PATCH 220/245] Fix: return logger (#1982) * Fix: return logger, typing * Fix: lint * chore: fix tests --------- Co-authored-by: Daniil Dumchenko Co-authored-by: Nikita Pastukhov --- faststream/_internal/broker/router.py | 2 +- faststream/confluent/broker/broker.py | 1 + faststream/confluent/client.py | 7 +++++-- faststream/rabbit/broker/broker.py | 2 +- .../asyncapi/v3_0_0/schema/bindings/amqp/channel.py | 4 +++- tests/brokers/kafka/test_consume.py | 8 ++++++-- tests/prometheus/confluent/basic.py | 4 ---- tests/prometheus/kafka/basic.py | 4 ---- tests/prometheus/nats/basic.py | 3 ++- tests/prometheus/nats/test_nats.py | 4 +++- tests/prometheus/nats/test_provider.py | 3 ++- tests/prometheus/rabbit/basic.py | 4 ---- tests/prometheus/rabbit/test_provider.py | 6 +----- tests/prometheus/redis/basic.py | 4 ---- 14 files changed, 25 insertions(+), 31 deletions(-) diff --git a/faststream/_internal/broker/router.py b/faststream/_internal/broker/router.py index 81f4a2998a..8c02459095 100644 --- a/faststream/_internal/broker/router.py +++ b/faststream/_internal/broker/router.py @@ -84,7 +84,7 @@ def __init__( decoder=decoder, include_in_schema=include_in_schema, state=EmptyBrokerState("You should include router to any broker."), - routers=routers + routers=routers, ) for h in handlers: diff --git a/faststream/confluent/broker/broker.py b/faststream/confluent/broker/broker.py index 1b96a46126..0262dbd9c3 100644 --- a/faststream/confluent/broker/broker.py +++ b/faststream/confluent/broker/broker.py @@ -454,6 +454,7 @@ async def _connect( # type: ignore[override] **kwargs, client_id=client_id, config=self.config, + logger=self._state.get().logger_state, ) self._producer.connect(native_producer) diff --git a/faststream/confluent/client.py b/faststream/confluent/client.py index 05a0210a6a..385a1b4389 100644 --- a/faststream/confluent/client.py +++ b/faststream/confluent/client.py @@ -43,6 +43,7 @@ class AsyncConfluentProducer: def __init__( self, *, + logger: "LoggerState", config: config_module.ConfluentFastConfig, bootstrap_servers: Union[str, list[str]] = "localhost", client_id: Optional[str] = None, @@ -64,6 +65,8 @@ def __init__( sasl_plain_password: Optional[str] = None, sasl_plain_username: Optional[str] = None, ) -> None: + self.logger_state = logger + if isinstance(bootstrap_servers, Iterable) and not isinstance( bootstrap_servers, str, @@ -107,7 +110,7 @@ def __init__( }, ) - self.producer = Producer(final_config, logger=self.logger) # type: ignore[call-arg] + self.producer = Producer(final_config, logger=self.logger_state.logger.logger) # type: ignore[call-arg] self.__running = True self._poll_task = asyncio.create_task(self._poll_loop()) @@ -309,7 +312,7 @@ def __init__( ) self.config = final_config - self.consumer = Consumer(final_config, logger=self.logger) # type: ignore[call-arg] + self.consumer = Consumer(final_config, logger=self.logger_state.logger.logger) # type: ignore[call-arg] # We shouldn't read messages and close consumer concurrently # https://github.com/airtai/faststream/issues/1904#issuecomment-2506990895 diff --git a/faststream/rabbit/broker/broker.py b/faststream/rabbit/broker/broker.py index a171755cf1..04d2c2cd4f 100644 --- a/faststream/rabbit/broker/broker.py +++ b/faststream/rabbit/broker/broker.py @@ -16,7 +16,7 @@ from typing_extensions import Doc, override from faststream.__about__ import SERVICE_NAME -from faststream._internal.broker.broker import BrokerUsecase +from faststream._internal.broker.broker import ABCBroker, BrokerUsecase from faststream._internal.constants import EMPTY from faststream._internal.publisher.proto import PublisherProto from faststream.message import gen_cor_id diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel.py index 3d2bcc23ad..bfadb4c0f4 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel.py @@ -1,4 +1,6 @@ -from typing import Optional, Self +from typing import Optional + +from typing_extensions import Self from faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp import ( ChannelBinding as V2Binding, diff --git a/tests/brokers/kafka/test_consume.py b/tests/brokers/kafka/test_consume.py index 3c9bd4ca90..1c8ee55f99 100644 --- a/tests/brokers/kafka/test_consume.py +++ b/tests/brokers/kafka/test_consume.py @@ -399,7 +399,9 @@ async def handler(msg): await asyncio.wait( ( - asyncio.create_task(br._producer._producer.producer.send(queue, key=b"")), + asyncio.create_task( + br._producer._producer.producer.send(queue, key=b"") + ), asyncio.create_task(event.wait()), ), timeout=3, @@ -426,7 +428,9 @@ async def handler(msg): await asyncio.wait( ( - asyncio.create_task(br._producer._producer.producer.send(queue, key=b"")), + asyncio.create_task( + br._producer._producer.producer.send(queue, key=b"") + ), asyncio.create_task(event.wait()), ), timeout=3, diff --git a/tests/prometheus/confluent/basic.py b/tests/prometheus/confluent/basic.py index 92df8e38f4..facea2efec 100644 --- a/tests/prometheus/confluent/basic.py +++ b/tests/prometheus/confluent/basic.py @@ -1,7 +1,6 @@ from typing import Any from faststream import AckPolicy -from faststream.confluent import KafkaBroker from faststream.confluent.prometheus import KafkaPrometheusMiddleware from tests.brokers.confluent.basic import ConfluentTestcaseConfig @@ -9,9 +8,6 @@ class KafkaPrometheusSettings(ConfluentTestcaseConfig): messaging_system = "kafka" - def get_broker(self, apply_types=False, **kwargs: Any) -> KafkaBroker: - return KafkaBroker(apply_types=apply_types, **kwargs) - def get_middleware(self, **kwargs: Any) -> KafkaPrometheusMiddleware: return KafkaPrometheusMiddleware(**kwargs) diff --git a/tests/prometheus/kafka/basic.py b/tests/prometheus/kafka/basic.py index 0225f7053a..9fdd8795dc 100644 --- a/tests/prometheus/kafka/basic.py +++ b/tests/prometheus/kafka/basic.py @@ -1,7 +1,6 @@ from typing import Any from faststream import AckPolicy -from faststream.kafka import KafkaBroker from faststream.kafka.prometheus import KafkaPrometheusMiddleware from tests.brokers.kafka.basic import KafkaTestcaseConfig @@ -9,9 +8,6 @@ class KafkaPrometheusSettings(KafkaTestcaseConfig): messaging_system = "kafka" - def get_broker(self, apply_types=False, **kwargs: Any) -> KafkaBroker: - return KafkaBroker(apply_types=apply_types, **kwargs) - def get_middleware(self, **kwargs: Any) -> KafkaPrometheusMiddleware: return KafkaPrometheusMiddleware(**kwargs) diff --git a/tests/prometheus/nats/basic.py b/tests/prometheus/nats/basic.py index 2bb3abbad9..5199ee84ef 100644 --- a/tests/prometheus/nats/basic.py +++ b/tests/prometheus/nats/basic.py @@ -2,9 +2,10 @@ from faststream.nats import NatsBroker from faststream.nats.prometheus import NatsPrometheusMiddleware +from tests.brokers.nats.basic import NatsTestcaseConfig -class NatsPrometheusSettings: +class NatsPrometheusSettings(NatsTestcaseConfig): messaging_system = "nats" def get_broker(self, apply_types=False, **kwargs: Any) -> NatsBroker: diff --git a/tests/prometheus/nats/test_nats.py b/tests/prometheus/nats/test_nats.py index a3bdbed2e0..edb07ad20b 100644 --- a/tests/prometheus/nats/test_nats.py +++ b/tests/prometheus/nats/test_nats.py @@ -22,7 +22,9 @@ def stream(queue): @pytest.mark.nats() class TestPrometheus( - NatsPrometheusSettings, LocalPrometheusTestcase, LocalRPCPrometheusTestcase + NatsPrometheusSettings, + LocalPrometheusTestcase, + LocalRPCPrometheusTestcase, ): async def test_metrics_batch( self, diff --git a/tests/prometheus/nats/test_provider.py b/tests/prometheus/nats/test_provider.py index c8ce53dc72..10410b95f8 100644 --- a/tests/prometheus/nats/test_provider.py +++ b/tests/prometheus/nats/test_provider.py @@ -16,7 +16,8 @@ class LocalBaseNatsMetricsSettingsProviderTestcase( - NatsPrometheusSettings, LocalMetricsSettingsProviderTestcase + NatsPrometheusSettings, + LocalMetricsSettingsProviderTestcase, ): def test_get_publish_destination_name_from_cmd(self, queue: str) -> None: expected_destination_name = queue diff --git a/tests/prometheus/rabbit/basic.py b/tests/prometheus/rabbit/basic.py index d1d192e459..a489fcb2e8 100644 --- a/tests/prometheus/rabbit/basic.py +++ b/tests/prometheus/rabbit/basic.py @@ -1,6 +1,5 @@ from typing import Any -from faststream.rabbit import RabbitBroker from faststream.rabbit.prometheus import RabbitPrometheusMiddleware from tests.brokers.rabbit.basic import RabbitTestcaseConfig @@ -8,8 +7,5 @@ class RabbitPrometheusSettings(RabbitTestcaseConfig): messaging_system = "rabbitmq" - def get_broker(self, apply_types=False, **kwargs: Any) -> RabbitBroker: - return RabbitBroker(apply_types=apply_types, **kwargs) - def get_middleware(self, **kwargs: Any) -> RabbitPrometheusMiddleware: return RabbitPrometheusMiddleware(**kwargs) diff --git a/tests/prometheus/rabbit/test_provider.py b/tests/prometheus/rabbit/test_provider.py index 9b6eb0b7bf..88f4c506bb 100644 --- a/tests/prometheus/rabbit/test_provider.py +++ b/tests/prometheus/rabbit/test_provider.py @@ -5,10 +5,7 @@ from faststream.prometheus import MetricsSettingsProvider from faststream.rabbit.prometheus.provider import RabbitMetricsSettingsProvider -from tests.prometheus.basic import ( - LocalMetricsSettingsProviderTestcase, - LocalRPCPrometheusTestcase, -) +from tests.prometheus.basic import LocalMetricsSettingsProviderTestcase from .basic import RabbitPrometheusSettings @@ -16,7 +13,6 @@ class TestRabbitMetricsSettingsProvider( RabbitPrometheusSettings, LocalMetricsSettingsProviderTestcase, - LocalRPCPrometheusTestcase, ): @staticmethod def get_provider() -> MetricsSettingsProvider: diff --git a/tests/prometheus/redis/basic.py b/tests/prometheus/redis/basic.py index 1a6ed6cfeb..a1f89f3ead 100644 --- a/tests/prometheus/redis/basic.py +++ b/tests/prometheus/redis/basic.py @@ -1,6 +1,5 @@ from typing import Any -from faststream.redis import RedisBroker from faststream.redis.prometheus import RedisPrometheusMiddleware from tests.brokers.redis.basic import RedisTestcaseConfig @@ -8,8 +7,5 @@ class RedisPrometheusSettings(RedisTestcaseConfig): messaging_system = "redis" - def get_broker(self, apply_types=False, **kwargs: Any) -> RedisBroker: - return RedisBroker(apply_types=apply_types, **kwargs) - def get_middleware(self, **kwargs: Any) -> RedisPrometheusMiddleware: return RedisPrometheusMiddleware(**kwargs) From b9c7dd442d1a015bc0aff92450aefd675e2e52f0 Mon Sep 17 00:00:00 2001 From: Flosckow <66554425+Flosckow@users.noreply.github.com> Date: Wed, 11 Dec 2024 02:41:00 +0700 Subject: [PATCH 221/245] Feat: replace subscribers (#1976) * Feat: replace subscribers * Fix: lint * Fix: add mixin * Fix: lint * Fix: add markers * chore: fix tests --------- Co-authored-by: Daniil Dumchenko Co-authored-by: Pastukhov Nikita Co-authored-by: Nikita Pastukhov --- faststream/redis/subscriber/specified.py | 8 +- faststream/redis/subscriber/usecase.py | 771 ------------------ .../redis/subscriber/usecases/__init__.py | 19 + faststream/redis/subscriber/usecases/basic.py | 155 ++++ .../subscriber/usecases/channel_subscriber.py | 155 ++++ .../subscriber/usecases/list_subscriber.py | 221 +++++ .../subscriber/usecases/stream_subscriber.py | 336 ++++++++ faststream/redis/testing.py | 10 +- 8 files changed, 896 insertions(+), 779 deletions(-) delete mode 100644 faststream/redis/subscriber/usecase.py create mode 100644 faststream/redis/subscriber/usecases/__init__.py create mode 100644 faststream/redis/subscriber/usecases/basic.py create mode 100644 faststream/redis/subscriber/usecases/channel_subscriber.py create mode 100644 faststream/redis/subscriber/usecases/list_subscriber.py create mode 100644 faststream/redis/subscriber/usecases/stream_subscriber.py diff --git a/faststream/redis/subscriber/specified.py b/faststream/redis/subscriber/specified.py index e943a80aeb..30591233db 100644 --- a/faststream/redis/subscriber/specified.py +++ b/faststream/redis/subscriber/specified.py @@ -3,10 +3,14 @@ ) from faststream.redis.schemas import ListSub, StreamSub from faststream.redis.schemas.proto import RedisSpecificationProtocol -from faststream.redis.subscriber.usecase import ( - BatchListSubscriber, +from faststream.redis.subscriber.usecases.channel_subscriber import ( ChannelSubscriber, +) +from faststream.redis.subscriber.usecases.list_subscriber import ( + BatchListSubscriber, ListSubscriber, +) +from faststream.redis.subscriber.usecases.stream_subscriber import ( StreamBatchSubscriber, StreamSubscriber, ) diff --git a/faststream/redis/subscriber/usecase.py b/faststream/redis/subscriber/usecase.py deleted file mode 100644 index f1c9bb880f..0000000000 --- a/faststream/redis/subscriber/usecase.py +++ /dev/null @@ -1,771 +0,0 @@ -import math -from abc import abstractmethod -from collections.abc import Awaitable, Iterable, Sequence -from contextlib import suppress -from copy import deepcopy -from typing import ( - TYPE_CHECKING, - Any, - Callable, - Optional, -) - -import anyio -from redis.asyncio.client import ( - PubSub as RPubSub, - Redis, -) -from redis.exceptions import ResponseError -from typing_extensions import TypeAlias, override - -from faststream._internal.subscriber.mixins import TasksMixin -from faststream._internal.subscriber.usecase import SubscriberUsecase -from faststream._internal.subscriber.utils import process_msg -from faststream.middlewares import AckPolicy -from faststream.redis.message import ( - BatchListMessage, - BatchStreamMessage, - DefaultListMessage, - DefaultStreamMessage, - PubSubMessage, - RedisListMessage, - RedisMessage, - RedisStreamMessage, - UnifyRedisDict, -) -from faststream.redis.parser import ( - RedisBatchListParser, - RedisBatchStreamParser, - RedisListParser, - RedisPubSubParser, - RedisStreamParser, -) -from faststream.redis.publisher.fake import RedisFakePublisher -from faststream.redis.schemas import ListSub, PubSub, StreamSub - -if TYPE_CHECKING: - from fast_depends.dependencies import Dependant - - from faststream._internal.basic_types import AnyDict - from faststream._internal.publisher.proto import BasePublisherProto - from faststream._internal.state import BrokerState - from faststream._internal.types import ( - AsyncCallable, - BrokerMiddleware, - CustomCallable, - ) - from faststream.message import StreamMessage as BrokerStreamMessage - - -TopicName: TypeAlias = bytes -Offset: TypeAlias = bytes - - -class LogicSubscriber(TasksMixin, SubscriberUsecase[UnifyRedisDict]): - """A class to represent a Redis handler.""" - - _client: Optional["Redis[bytes]"] - - def __init__( - self, - *, - default_parser: "AsyncCallable", - default_decoder: "AsyncCallable", - # Subscriber args - ack_policy: "AckPolicy", - no_reply: bool, - broker_dependencies: Iterable["Dependant"], - broker_middlewares: Sequence["BrokerMiddleware[UnifyRedisDict]"], - ) -> None: - super().__init__( - default_parser=default_parser, - default_decoder=default_decoder, - # Propagated options - ack_policy=ack_policy, - no_reply=no_reply, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - ) - - self._client = None - - @override - def _setup( # type: ignore[override] - self, - *, - connection: Optional["Redis[bytes]"], - # basic args - extra_context: "AnyDict", - # broker options - broker_parser: Optional["CustomCallable"], - broker_decoder: Optional["CustomCallable"], - # dependant args - state: "BrokerState", - ) -> None: - self._client = connection - - super()._setup( - extra_context=extra_context, - broker_parser=broker_parser, - broker_decoder=broker_decoder, - state=state, - ) - - def _make_response_publisher( - self, - message: "BrokerStreamMessage[UnifyRedisDict]", - ) -> Sequence["BasePublisherProto"]: - return ( - RedisFakePublisher( - self._state.get().producer, - channel=message.reply_to, - ), - ) - - @override - async def start( - self, - *args: Any, - ) -> None: - if self.tasks: - return - - await super().start() - - start_signal = anyio.Event() - - if self.calls: - self.add_task(self._consume(*args, start_signal=start_signal)) - - with anyio.fail_after(3.0): - await start_signal.wait() - - else: - start_signal.set() - - async def _consume(self, *args: Any, start_signal: anyio.Event) -> None: - connected = True - - while self.running: - try: - await self._get_msgs(*args) - - except Exception: # noqa: PERF203 - if connected: - connected = False - await anyio.sleep(5) - - else: - if not connected: - connected = True - - finally: - if not start_signal.is_set(): - with suppress(Exception): - start_signal.set() - - @abstractmethod - async def _get_msgs(self, *args: Any) -> None: - raise NotImplementedError - - @staticmethod - def build_log_context( - message: Optional["BrokerStreamMessage[Any]"], - channel: str = "", - ) -> dict[str, str]: - return { - "channel": channel, - "message_id": getattr(message, "message_id", ""), - } - - -class ChannelSubscriber(LogicSubscriber): - subscription: Optional[RPubSub] - - def __init__( - self, - *, - channel: "PubSub", - # Subscriber args - no_reply: bool, - broker_dependencies: Iterable["Dependant"], - broker_middlewares: Sequence["BrokerMiddleware[UnifyRedisDict]"], - ) -> None: - parser = RedisPubSubParser(pattern=channel.path_regex) - super().__init__( - default_parser=parser.parse_message, - default_decoder=parser.decode_message, - # Propagated options - ack_policy=AckPolicy.DO_NOTHING, - no_reply=no_reply, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - ) - - self.channel = channel - self.subscription = None - - def get_log_context( - self, - message: Optional["BrokerStreamMessage[Any]"], - ) -> dict[str, str]: - return self.build_log_context( - message=message, - channel=self.channel.name, - ) - - @override - async def start(self) -> None: - if self.subscription: - return - - assert self._client, "You should setup subscriber at first." # nosec B101 - - self.subscription = psub = self._client.pubsub() - - if self.channel.pattern: - await psub.psubscribe(self.channel.name) - else: - await psub.subscribe(self.channel.name) - - await super().start(psub) - - async def close(self) -> None: - if self.subscription is not None: - await self.subscription.unsubscribe() - await self.subscription.aclose() # type: ignore[attr-defined] - self.subscription = None - - await super().close() - - @override - async def get_one( # type: ignore[override] - self, - *, - timeout: float = 5.0, - ) -> "Optional[RedisMessage]": - assert self.subscription, "You should start subscriber at first." # nosec B101 - assert ( # nosec B101 - not self.calls - ), "You can't use `get_one` method if subscriber has registered handlers." - - sleep_interval = timeout / 10 - - raw_message: Optional[PubSubMessage] = None - - with anyio.move_on_after(timeout): - while (raw_message := await self._get_message(self.subscription)) is None: # noqa: ASYNC110 - await anyio.sleep(sleep_interval) - - context = self._state.get().di_state.context - - msg: Optional[RedisMessage] = await process_msg( # type: ignore[assignment] - msg=raw_message, - middlewares=( - m(raw_message, context=context) for m in self._broker_middlewares - ), - parser=self._parser, - decoder=self._decoder, - ) - return msg - - async def _get_message(self, psub: RPubSub) -> Optional[PubSubMessage]: - raw_msg = await psub.get_message( - ignore_subscribe_messages=True, - timeout=self.channel.polling_interval, - ) - - if raw_msg: - return PubSubMessage( - type=raw_msg["type"], - data=raw_msg["data"], - channel=raw_msg["channel"].decode(), - pattern=raw_msg["pattern"], - ) - - return None - - async def _get_msgs(self, psub: RPubSub) -> None: - if msg := await self._get_message(psub): - await self.consume(msg) # type: ignore[arg-type] - - def add_prefix(self, prefix: str) -> None: - new_ch = deepcopy(self.channel) - new_ch.name = f"{prefix}{new_ch.name}" - self.channel = new_ch - - -class _ListHandlerMixin(LogicSubscriber): - def __init__( - self, - *, - list: ListSub, - default_parser: "AsyncCallable", - default_decoder: "AsyncCallable", - # Subscriber args - ack_policy: "AckPolicy", - no_reply: bool, - broker_dependencies: Iterable["Dependant"], - broker_middlewares: Sequence["BrokerMiddleware[UnifyRedisDict]"], - ) -> None: - super().__init__( - default_parser=default_parser, - default_decoder=default_decoder, - # Propagated options - ack_policy=ack_policy, - no_reply=no_reply, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - ) - - self.list_sub = list - - def get_log_context( - self, - message: Optional["BrokerStreamMessage[Any]"], - ) -> dict[str, str]: - return self.build_log_context( - message=message, - channel=self.list_sub.name, - ) - - @override - async def _consume( # type: ignore[override] - self, - client: "Redis[bytes]", - *, - start_signal: "anyio.Event", - ) -> None: - start_signal.set() - await super()._consume(client, start_signal=start_signal) - - @override - async def start(self) -> None: - if self.tasks: - return - - assert self._client, "You should setup subscriber at first." # nosec B101 - - await super().start(self._client) - - @override - async def get_one( # type: ignore[override] - self, - *, - timeout: float = 5.0, - ) -> "Optional[RedisListMessage]": - assert self._client, "You should start subscriber at first." # nosec B101 - assert ( # nosec B101 - not self.calls - ), "You can't use `get_one` method if subscriber has registered handlers." - - sleep_interval = timeout / 10 - raw_message = None - - with anyio.move_on_after(timeout): - while ( # noqa: ASYNC110 - raw_message := await self._client.lpop(name=self.list_sub.name) - ) is None: - await anyio.sleep(sleep_interval) - - if not raw_message: - return None - - redis_incoming_msg = DefaultListMessage( - type="list", - data=raw_message, - channel=self.list_sub.name, - ) - - context = self._state.get().di_state.context - - msg: RedisListMessage = await process_msg( # type: ignore[assignment] - msg=redis_incoming_msg, - middlewares=( - m(redis_incoming_msg, context=context) for m in self._broker_middlewares - ), - parser=self._parser, - decoder=self._decoder, - ) - return msg - - def add_prefix(self, prefix: str) -> None: - new_list = deepcopy(self.list_sub) - new_list.name = f"{prefix}{new_list.name}" - self.list_sub = new_list - - -class ListSubscriber(_ListHandlerMixin): - def __init__( - self, - *, - list: ListSub, - # Subscriber args - no_reply: bool, - broker_dependencies: Iterable["Dependant"], - broker_middlewares: Sequence["BrokerMiddleware[UnifyRedisDict]"], - ) -> None: - parser = RedisListParser() - super().__init__( - list=list, - default_parser=parser.parse_message, - default_decoder=parser.decode_message, - # Propagated options - ack_policy=AckPolicy.DO_NOTHING, - no_reply=no_reply, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - ) - - async def _get_msgs(self, client: "Redis[bytes]") -> None: - raw_msg = await client.blpop( - self.list_sub.name, - timeout=self.list_sub.polling_interval, - ) - - if raw_msg: - _, msg_data = raw_msg - - msg = DefaultListMessage( - type="list", - data=msg_data, - channel=self.list_sub.name, - ) - - await self.consume(msg) - - -class BatchListSubscriber(_ListHandlerMixin): - def __init__( - self, - *, - list: ListSub, - # Subscriber args - no_reply: bool, - broker_dependencies: Iterable["Dependant"], - broker_middlewares: Sequence["BrokerMiddleware[UnifyRedisDict]"], - ) -> None: - parser = RedisBatchListParser() - super().__init__( - list=list, - default_parser=parser.parse_message, - default_decoder=parser.decode_message, - # Propagated options - ack_policy=AckPolicy.DO_NOTHING, - no_reply=no_reply, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - ) - - async def _get_msgs(self, client: "Redis[bytes]") -> None: - raw_msgs = await client.lpop( - name=self.list_sub.name, - count=self.list_sub.max_records, - ) - - if raw_msgs: - msg = BatchListMessage( - type="blist", - channel=self.list_sub.name, - data=raw_msgs, - ) - - await self.consume(msg) # type: ignore[arg-type] - - else: - await anyio.sleep(self.list_sub.polling_interval) - - -class _StreamHandlerMixin(LogicSubscriber): - def __init__( - self, - *, - stream: StreamSub, - default_parser: "AsyncCallable", - default_decoder: "AsyncCallable", - # Subscriber args - ack_policy: "AckPolicy", - no_reply: bool, - broker_dependencies: Iterable["Dependant"], - broker_middlewares: Sequence["BrokerMiddleware[UnifyRedisDict]"], - ) -> None: - super().__init__( - default_parser=default_parser, - default_decoder=default_decoder, - # Propagated options - ack_policy=ack_policy, - no_reply=no_reply, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - ) - - self.stream_sub = stream - self.last_id = stream.last_id - - def get_log_context( - self, - message: Optional["BrokerStreamMessage[Any]"], - ) -> dict[str, str]: - return self.build_log_context( - message=message, - channel=self.stream_sub.name, - ) - - @override - async def start(self) -> None: - if self.tasks: - return - - assert self._client, "You should setup subscriber at first." # nosec B101 - - client = self._client - - self.extra_watcher_options.update( - redis=client, - group=self.stream_sub.group, - ) - - stream = self.stream_sub - - read: Callable[ - [str], - Awaitable[ - tuple[ - tuple[ - TopicName, - tuple[ - tuple[ - Offset, - dict[bytes, bytes], - ], - ..., - ], - ], - ..., - ], - ], - ] - - if stream.group and stream.consumer: - try: - await client.xgroup_create( - name=stream.name, - id=self.last_id, - groupname=stream.group, - mkstream=True, - ) - except ResponseError as e: - if "already exists" not in str(e): - raise - - def read( - _: str, - ) -> Awaitable[ - tuple[ - tuple[ - TopicName, - tuple[ - tuple[ - Offset, - dict[bytes, bytes], - ], - ..., - ], - ], - ..., - ], - ]: - return client.xreadgroup( - groupname=stream.group, - consumername=stream.consumer, - streams={stream.name: ">"}, - count=stream.max_records, - block=stream.polling_interval, - noack=stream.no_ack, - ) - - else: - - def read( - last_id: str, - ) -> Awaitable[ - tuple[ - tuple[ - TopicName, - tuple[ - tuple[ - Offset, - dict[bytes, bytes], - ], - ..., - ], - ], - ..., - ], - ]: - return client.xread( - {stream.name: last_id}, - block=stream.polling_interval, - count=stream.max_records, - ) - - await super().start(read) - - @override - async def get_one( # type: ignore[override] - self, - *, - timeout: float = 5.0, - ) -> "Optional[RedisStreamMessage]": - assert self._client, "You should start subscriber at first." # nosec B101 - assert ( # nosec B101 - not self.calls - ), "You can't use `get_one` method if subscriber has registered handlers." - - stream_message = await self._client.xread( - {self.stream_sub.name: self.last_id}, - block=math.ceil(timeout * 1000), - count=1, - ) - - if not stream_message: - return None - - ((stream_name, ((message_id, raw_message),)),) = stream_message - - self.last_id = message_id.decode() - - redis_incoming_msg = DefaultStreamMessage( - type="stream", - channel=stream_name.decode(), - message_ids=[message_id], - data=raw_message, - ) - - context = self._state.get().di_state.context - - msg: RedisStreamMessage = await process_msg( # type: ignore[assignment] - msg=redis_incoming_msg, - middlewares=( - m(redis_incoming_msg, context=context) for m in self._broker_middlewares - ), - parser=self._parser, - decoder=self._decoder, - ) - return msg - - def add_prefix(self, prefix: str) -> None: - new_stream = deepcopy(self.stream_sub) - new_stream.name = f"{prefix}{new_stream.name}" - self.stream_sub = new_stream - - -class StreamSubscriber(_StreamHandlerMixin): - def __init__( - self, - *, - stream: StreamSub, - # Subscriber args - ack_policy: "AckPolicy", - no_reply: bool, - broker_dependencies: Iterable["Dependant"], - broker_middlewares: Sequence["BrokerMiddleware[UnifyRedisDict]"], - ) -> None: - parser = RedisStreamParser() - super().__init__( - stream=stream, - default_parser=parser.parse_message, - default_decoder=parser.decode_message, - # Propagated options - ack_policy=ack_policy, - no_reply=no_reply, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - ) - - async def _get_msgs( - self, - read: Callable[ - [str], - Awaitable[ - tuple[ - tuple[ - TopicName, - tuple[ - tuple[ - Offset, - dict[bytes, bytes], - ], - ..., - ], - ], - ..., - ], - ], - ], - ) -> None: - for stream_name, msgs in await read(self.last_id): - if msgs: - self.last_id = msgs[-1][0].decode() - - for message_id, raw_msg in msgs: - msg = DefaultStreamMessage( - type="stream", - channel=stream_name.decode(), - message_ids=[message_id], - data=raw_msg, - ) - - await self.consume(msg) # type: ignore[arg-type] - - -class StreamBatchSubscriber(_StreamHandlerMixin): - def __init__( - self, - *, - stream: StreamSub, - # Subscriber args - ack_policy: "AckPolicy", - no_reply: bool, - broker_dependencies: Iterable["Dependant"], - broker_middlewares: Sequence["BrokerMiddleware[UnifyRedisDict]"], - ) -> None: - parser = RedisBatchStreamParser() - super().__init__( - stream=stream, - default_parser=parser.parse_message, - default_decoder=parser.decode_message, - # Propagated options - ack_policy=ack_policy, - no_reply=no_reply, - broker_middlewares=broker_middlewares, - broker_dependencies=broker_dependencies, - ) - - async def _get_msgs( - self, - read: Callable[ - [str], - Awaitable[ - tuple[tuple[bytes, tuple[tuple[bytes, dict[bytes, bytes]], ...]], ...], - ], - ], - ) -> None: - for stream_name, msgs in await read(self.last_id): - if msgs: - self.last_id = msgs[-1][0].decode() - - data: list[dict[bytes, bytes]] = [] - ids: list[bytes] = [] - for message_id, i in msgs: - data.append(i) - ids.append(message_id) - - msg = BatchStreamMessage( - type="bstream", - channel=stream_name.decode(), - data=data, - message_ids=ids, - ) - - await self.consume(msg) # type: ignore[arg-type] diff --git a/faststream/redis/subscriber/usecases/__init__.py b/faststream/redis/subscriber/usecases/__init__.py new file mode 100644 index 0000000000..32ad97f400 --- /dev/null +++ b/faststream/redis/subscriber/usecases/__init__.py @@ -0,0 +1,19 @@ +from .basic import LogicSubscriber +from .channel_subscriber import ChannelSubscriber +from .list_subscriber import BatchListSubscriber, ListSubscriber, _ListHandlerMixin +from .stream_subscriber import ( + StreamBatchSubscriber, + StreamSubscriber, + _StreamHandlerMixin, +) + +__all__ = ( + "BatchListSubscriber", + "ChannelSubscriber", + "ListSubscriber", + "LogicSubscriber", + "StreamBatchSubscriber", + "StreamSubscriber", + "_ListHandlerMixin", + "_StreamHandlerMixin", +) diff --git a/faststream/redis/subscriber/usecases/basic.py b/faststream/redis/subscriber/usecases/basic.py new file mode 100644 index 0000000000..a5592f3730 --- /dev/null +++ b/faststream/redis/subscriber/usecases/basic.py @@ -0,0 +1,155 @@ +from abc import abstractmethod +from collections.abc import Iterable, Sequence +from contextlib import suppress +from typing import ( + TYPE_CHECKING, + Any, + Optional, +) + +import anyio +from typing_extensions import TypeAlias, override + +from faststream._internal.subscriber.mixins import TasksMixin +from faststream._internal.subscriber.usecase import SubscriberUsecase +from faststream.redis.message import ( + UnifyRedisDict, +) +from faststream.redis.publisher.fake import RedisFakePublisher + +if TYPE_CHECKING: + from fast_depends.dependencies import Dependant + from redis.asyncio.client import Redis + + from faststream._internal.basic_types import AnyDict + from faststream._internal.publisher.proto import BasePublisherProto + from faststream._internal.state import BrokerState, Pointer + from faststream._internal.types import ( + AsyncCallable, + BrokerMiddleware, + CustomCallable, + ) + from faststream.message import StreamMessage as BrokerStreamMessage + from faststream.middlewares import AckPolicy + + +TopicName: TypeAlias = bytes +Offset: TypeAlias = bytes + + +class LogicSubscriber(TasksMixin, SubscriberUsecase[UnifyRedisDict]): + """A class to represent a Redis handler.""" + + _client: Optional["Redis[bytes]"] + + def __init__( + self, + *, + default_parser: "AsyncCallable", + default_decoder: "AsyncCallable", + # Subscriber args + ack_policy: "AckPolicy", + no_reply: bool, + broker_dependencies: Iterable["Dependant"], + broker_middlewares: Sequence["BrokerMiddleware[UnifyRedisDict]"], + ) -> None: + super().__init__( + default_parser=default_parser, + default_decoder=default_decoder, + # Propagated options + ack_policy=ack_policy, + no_reply=no_reply, + broker_middlewares=broker_middlewares, + broker_dependencies=broker_dependencies, + ) + + self._client = None + + @override + def _setup( # type: ignore[override] + self, + *, + connection: Optional["Redis[bytes]"], + # basic args + extra_context: "AnyDict", + # broker options + broker_parser: Optional["CustomCallable"], + broker_decoder: Optional["CustomCallable"], + # dependant args + state: "Pointer[BrokerState]", + ) -> None: + self._client = connection + + super()._setup( + extra_context=extra_context, + broker_parser=broker_parser, + broker_decoder=broker_decoder, + state=state, + ) + + def _make_response_publisher( + self, + message: "BrokerStreamMessage[UnifyRedisDict]", + ) -> Sequence["BasePublisherProto"]: + return ( + RedisFakePublisher( + self._state.get().producer, + channel=message.reply_to, + ), + ) + + @override + async def start( + self, + *args: Any, + ) -> None: + if self.tasks: + return + + await super().start() + + start_signal = anyio.Event() + + if self.calls: + self.add_task(self._consume(*args, start_signal=start_signal)) + + with anyio.fail_after(3.0): + await start_signal.wait() + + else: + start_signal.set() + + async def _consume(self, *args: Any, start_signal: anyio.Event) -> None: + connected = True + + while self.running: + try: + await self._get_msgs(*args) + + except Exception: # noqa: PERF203 + if connected: + connected = False + await anyio.sleep(5) + + else: + if not connected: + connected = True + + finally: + if not start_signal.is_set(): + with suppress(Exception): + start_signal.set() + + @abstractmethod + async def _get_msgs(self, *args: Any) -> None: + raise NotImplementedError + + @staticmethod + def build_log_context( + message: Optional["BrokerStreamMessage[Any]"], + channel: str = "", + ) -> dict[str, str]: + return { + "channel": channel, + "message_id": getattr(message, "message_id", ""), + } diff --git a/faststream/redis/subscriber/usecases/channel_subscriber.py b/faststream/redis/subscriber/usecases/channel_subscriber.py new file mode 100644 index 0000000000..e7c261ad07 --- /dev/null +++ b/faststream/redis/subscriber/usecases/channel_subscriber.py @@ -0,0 +1,155 @@ +from collections.abc import Iterable, Sequence +from copy import deepcopy +from typing import ( + TYPE_CHECKING, + Any, + Optional, +) + +import anyio +from redis.asyncio.client import ( + PubSub as RPubSub, +) +from typing_extensions import TypeAlias, override + +from faststream._internal.subscriber.utils import process_msg +from faststream.middlewares import AckPolicy +from faststream.redis.message import ( + PubSubMessage, + RedisMessage, + UnifyRedisDict, +) +from faststream.redis.parser import ( + RedisPubSubParser, +) + +from .basic import LogicSubscriber + +if TYPE_CHECKING: + from fast_depends.dependencies import Dependant + + from faststream._internal.types import ( + BrokerMiddleware, + ) + from faststream.message import StreamMessage as BrokerStreamMessage + from faststream.redis.schemas import PubSub + + +TopicName: TypeAlias = bytes +Offset: TypeAlias = bytes + + +class ChannelSubscriber(LogicSubscriber): + subscription: Optional[RPubSub] + + def __init__( + self, + *, + channel: "PubSub", + # Subscriber args + no_reply: bool, + broker_dependencies: Iterable["Dependant"], + broker_middlewares: Sequence["BrokerMiddleware[UnifyRedisDict]"], + ) -> None: + parser = RedisPubSubParser(pattern=channel.path_regex) + super().__init__( + default_parser=parser.parse_message, + default_decoder=parser.decode_message, + # Propagated options + ack_policy=AckPolicy.DO_NOTHING, + no_reply=no_reply, + broker_middlewares=broker_middlewares, + broker_dependencies=broker_dependencies, + ) + + self.channel = channel + self.subscription = None + + def get_log_context( + self, + message: Optional["BrokerStreamMessage[Any]"], + ) -> dict[str, str]: + return self.build_log_context( + message=message, + channel=self.channel.name, + ) + + @override + async def start(self) -> None: + if self.subscription: + return + + assert self._client, "You should setup subscriber at first." # nosec B101 + + self.subscription = psub = self._client.pubsub() + + if self.channel.pattern: + await psub.psubscribe(self.channel.name) + else: + await psub.subscribe(self.channel.name) + + await super().start(psub) + + async def close(self) -> None: + if self.subscription is not None: + await self.subscription.unsubscribe() + await self.subscription.aclose() # type: ignore[attr-defined] + self.subscription = None + + await super().close() + + @override + async def get_one( + self, + *, + timeout: float = 5.0, + ) -> "Optional[RedisMessage]": + assert self.subscription, "You should start subscriber at first." # nosec B101 + assert ( # nosec B101 + not self.calls + ), "You can't use `get_one` method if subscriber has registered handlers." + + sleep_interval = timeout / 10 + + raw_message: Optional[PubSubMessage] = None + + with anyio.move_on_after(timeout): + while (raw_message := await self._get_message(self.subscription)) is None: # noqa: ASYNC110 + await anyio.sleep(sleep_interval) + + context = self._state.get().di_state.context + + msg: Optional[RedisMessage] = await process_msg( # type: ignore[assignment] + msg=raw_message, + middlewares=( + m(raw_message, context=context) for m in self._broker_middlewares + ), + parser=self._parser, + decoder=self._decoder, + ) + return msg + + async def _get_message(self, psub: RPubSub) -> Optional[PubSubMessage]: + raw_msg = await psub.get_message( + ignore_subscribe_messages=True, + timeout=self.channel.polling_interval, + ) + + if raw_msg: + return PubSubMessage( + type=raw_msg["type"], + data=raw_msg["data"], + channel=raw_msg["channel"].decode(), + pattern=raw_msg["pattern"], + ) + + return None + + async def _get_msgs(self, psub: RPubSub) -> None: + if msg := await self._get_message(psub): + await self.consume(msg) + + def add_prefix(self, prefix: str) -> None: + new_ch = deepcopy(self.channel) + new_ch.name = f"{prefix}{new_ch.name}" + self.channel = new_ch diff --git a/faststream/redis/subscriber/usecases/list_subscriber.py b/faststream/redis/subscriber/usecases/list_subscriber.py new file mode 100644 index 0000000000..8c6558398f --- /dev/null +++ b/faststream/redis/subscriber/usecases/list_subscriber.py @@ -0,0 +1,221 @@ +from collections.abc import Iterable, Sequence +from copy import deepcopy +from typing import ( + TYPE_CHECKING, + Any, + Optional, +) + +import anyio +from typing_extensions import TypeAlias, override + +from faststream._internal.subscriber.utils import process_msg +from faststream.middlewares import AckPolicy +from faststream.redis.message import ( + BatchListMessage, + DefaultListMessage, + RedisListMessage, + UnifyRedisDict, +) +from faststream.redis.parser import ( + RedisBatchListParser, + RedisListParser, +) +from faststream.redis.schemas import ListSub + +from .basic import LogicSubscriber + +if TYPE_CHECKING: + from fast_depends.dependencies import Dependant + from redis.asyncio.client import Redis + + from faststream._internal.types import ( + AsyncCallable, + BrokerMiddleware, + ) + from faststream.message import StreamMessage as BrokerStreamMessage + + +TopicName: TypeAlias = bytes +Offset: TypeAlias = bytes + + +class _ListHandlerMixin(LogicSubscriber): + def __init__( + self, + *, + list: ListSub, + default_parser: "AsyncCallable", + default_decoder: "AsyncCallable", + # Subscriber args + ack_policy: "AckPolicy", + no_reply: bool, + broker_dependencies: Iterable["Dependant"], + broker_middlewares: Sequence["BrokerMiddleware[UnifyRedisDict]"], + ) -> None: + super().__init__( + default_parser=default_parser, + default_decoder=default_decoder, + # Propagated options + ack_policy=ack_policy, + no_reply=no_reply, + broker_middlewares=broker_middlewares, + broker_dependencies=broker_dependencies, + ) + + self.list_sub = list + + def get_log_context( + self, + message: Optional["BrokerStreamMessage[Any]"], + ) -> dict[str, str]: + return self.build_log_context( + message=message, + channel=self.list_sub.name, + ) + + @override + async def _consume( # type: ignore[override] + self, + client: "Redis[bytes]", + *, + start_signal: "anyio.Event", + ) -> None: + start_signal.set() + await super()._consume(client, start_signal=start_signal) + + @override + async def start(self) -> None: + if self.tasks: + return + + assert self._client, "You should setup subscriber at first." # nosec B101 + + await super().start(self._client) + + @override + async def get_one( + self, + *, + timeout: float = 5.0, + ) -> "Optional[RedisListMessage]": + assert self._client, "You should start subscriber at first." # nosec B101 + assert ( # nosec B101 + not self.calls + ), "You can't use `get_one` method if subscriber has registered handlers." + + sleep_interval = timeout / 10 + raw_message = None + + with anyio.move_on_after(timeout): + while ( # noqa: ASYNC110 + raw_message := await self._client.lpop(name=self.list_sub.name) + ) is None: + await anyio.sleep(sleep_interval) + + if not raw_message: + return None + + redis_incoming_msg = DefaultListMessage( + type="list", + data=raw_message, + channel=self.list_sub.name, + ) + + context = self._state.get().di_state.context + + msg: RedisListMessage = await process_msg( # type: ignore[assignment] + msg=redis_incoming_msg, + middlewares=( + m(redis_incoming_msg, context=context) for m in self._broker_middlewares + ), + parser=self._parser, + decoder=self._decoder, + ) + return msg + + def add_prefix(self, prefix: str) -> None: + new_list = deepcopy(self.list_sub) + new_list.name = f"{prefix}{new_list.name}" + self.list_sub = new_list + + +class ListSubscriber(_ListHandlerMixin): + def __init__( + self, + *, + list: ListSub, + # Subscriber args + no_reply: bool, + broker_dependencies: Iterable["Dependant"], + broker_middlewares: Sequence["BrokerMiddleware[UnifyRedisDict]"], + ) -> None: + parser = RedisListParser() + super().__init__( + list=list, + default_parser=parser.parse_message, + default_decoder=parser.decode_message, + # Propagated options + ack_policy=AckPolicy.DO_NOTHING, + no_reply=no_reply, + broker_middlewares=broker_middlewares, + broker_dependencies=broker_dependencies, + ) + + async def _get_msgs(self, client: "Redis[bytes]") -> None: + raw_msg = await client.blpop( + self.list_sub.name, + timeout=self.list_sub.polling_interval, + ) + + if raw_msg: + _, msg_data = raw_msg + + msg = DefaultListMessage( + type="list", + data=msg_data, + channel=self.list_sub.name, + ) + + await self.consume(msg) + + +class BatchListSubscriber(_ListHandlerMixin): + def __init__( + self, + *, + list: ListSub, + # Subscriber args + no_reply: bool, + broker_dependencies: Iterable["Dependant"], + broker_middlewares: Sequence["BrokerMiddleware[UnifyRedisDict]"], + ) -> None: + parser = RedisBatchListParser() + super().__init__( + list=list, + default_parser=parser.parse_message, + default_decoder=parser.decode_message, + # Propagated options + ack_policy=AckPolicy.DO_NOTHING, + no_reply=no_reply, + broker_middlewares=broker_middlewares, + broker_dependencies=broker_dependencies, + ) + + async def _get_msgs(self, client: "Redis[bytes]") -> None: + raw_msgs = await client.lpop( + name=self.list_sub.name, + count=self.list_sub.max_records, + ) + + if raw_msgs: + msg = BatchListMessage( + type="blist", + channel=self.list_sub.name, + data=raw_msgs, + ) + + await self.consume(msg) + + else: + await anyio.sleep(self.list_sub.polling_interval) diff --git a/faststream/redis/subscriber/usecases/stream_subscriber.py b/faststream/redis/subscriber/usecases/stream_subscriber.py new file mode 100644 index 0000000000..44c3a0c28b --- /dev/null +++ b/faststream/redis/subscriber/usecases/stream_subscriber.py @@ -0,0 +1,336 @@ +import math +from collections.abc import Awaitable, Iterable, Sequence +from copy import deepcopy +from typing import ( + TYPE_CHECKING, + Any, + Callable, + Optional, +) + +from redis.exceptions import ResponseError +from typing_extensions import TypeAlias, override + +from faststream._internal.subscriber.utils import process_msg +from faststream.redis.message import ( + BatchStreamMessage, + DefaultStreamMessage, + RedisStreamMessage, + UnifyRedisDict, +) +from faststream.redis.parser import ( + RedisBatchStreamParser, + RedisStreamParser, +) +from faststream.redis.schemas import StreamSub + +from .basic import LogicSubscriber + +if TYPE_CHECKING: + from fast_depends.dependencies import Dependant + + from faststream._internal.types import ( + AsyncCallable, + BrokerMiddleware, + ) + from faststream.message import StreamMessage as BrokerStreamMessage + from faststream.middlewares import AckPolicy + + +TopicName: TypeAlias = bytes +Offset: TypeAlias = bytes + + +class _StreamHandlerMixin(LogicSubscriber): + def __init__( + self, + *, + stream: StreamSub, + default_parser: "AsyncCallable", + default_decoder: "AsyncCallable", + # Subscriber args + ack_policy: "AckPolicy", + no_reply: bool, + broker_dependencies: Iterable["Dependant"], + broker_middlewares: Sequence["BrokerMiddleware[UnifyRedisDict]"], + ) -> None: + super().__init__( + default_parser=default_parser, + default_decoder=default_decoder, + # Propagated options + ack_policy=ack_policy, + no_reply=no_reply, + broker_middlewares=broker_middlewares, + broker_dependencies=broker_dependencies, + ) + + self.stream_sub = stream + self.last_id = stream.last_id + + def get_log_context( + self, + message: Optional["BrokerStreamMessage[Any]"], + ) -> dict[str, str]: + return self.build_log_context( + message=message, + channel=self.stream_sub.name, + ) + + @override + async def start(self) -> None: + if self.tasks: + return + + assert self._client, "You should setup subscriber at first." # nosec B101 + + client = self._client + + self.extra_watcher_options.update( + redis=client, + group=self.stream_sub.group, + ) + + stream = self.stream_sub + + read: Callable[ + [str], + Awaitable[ + tuple[ + tuple[ + TopicName, + tuple[ + tuple[ + Offset, + dict[bytes, bytes], + ], + ..., + ], + ], + ..., + ], + ], + ] + + if stream.group and stream.consumer: + try: + await client.xgroup_create( + name=stream.name, + id=self.last_id, + groupname=stream.group, + mkstream=True, + ) + except ResponseError as e: + if "already exists" not in str(e): + raise + + def read( + _: str, + ) -> Awaitable[ + tuple[ + tuple[ + TopicName, + tuple[ + tuple[ + Offset, + dict[bytes, bytes], + ], + ..., + ], + ], + ..., + ], + ]: + return client.xreadgroup( + groupname=stream.group, + consumername=stream.consumer, + streams={stream.name: ">"}, + count=stream.max_records, + block=stream.polling_interval, + noack=stream.no_ack, + ) + + else: + + def read( + last_id: str, + ) -> Awaitable[ + tuple[ + tuple[ + TopicName, + tuple[ + tuple[ + Offset, + dict[bytes, bytes], + ], + ..., + ], + ], + ..., + ], + ]: + return client.xread( + {stream.name: last_id}, + block=stream.polling_interval, + count=stream.max_records, + ) + + await super().start(read) + + @override + async def get_one( + self, + *, + timeout: float = 5.0, + ) -> "Optional[RedisStreamMessage]": + assert self._client, "You should start subscriber at first." # nosec B101 + assert ( # nosec B101 + not self.calls + ), "You can't use `get_one` method if subscriber has registered handlers." + + stream_message = await self._client.xread( + {self.stream_sub.name: self.last_id}, + block=math.ceil(timeout * 1000), + count=1, + ) + + if not stream_message: + return None + + ((stream_name, ((message_id, raw_message),)),) = stream_message + + self.last_id = message_id.decode() + + redis_incoming_msg = DefaultStreamMessage( + type="stream", + channel=stream_name.decode(), + message_ids=[message_id], + data=raw_message, + ) + + context = self._state.get().di_state.context + + msg: RedisStreamMessage = await process_msg( # type: ignore[assignment] + msg=redis_incoming_msg, + middlewares=( + m(redis_incoming_msg, context=context) for m in self._broker_middlewares + ), + parser=self._parser, + decoder=self._decoder, + ) + return msg + + def add_prefix(self, prefix: str) -> None: + new_stream = deepcopy(self.stream_sub) + new_stream.name = f"{prefix}{new_stream.name}" + self.stream_sub = new_stream + + +class StreamSubscriber(_StreamHandlerMixin): + def __init__( + self, + *, + stream: StreamSub, + # Subscriber args + ack_policy: "AckPolicy", + no_reply: bool, + broker_dependencies: Iterable["Dependant"], + broker_middlewares: Sequence["BrokerMiddleware[UnifyRedisDict]"], + ) -> None: + parser = RedisStreamParser() + super().__init__( + stream=stream, + default_parser=parser.parse_message, + default_decoder=parser.decode_message, + # Propagated options + ack_policy=ack_policy, + no_reply=no_reply, + broker_middlewares=broker_middlewares, + broker_dependencies=broker_dependencies, + ) + + async def _get_msgs( + self, + read: Callable[ + [str], + Awaitable[ + tuple[ + tuple[ + TopicName, + tuple[ + tuple[ + Offset, + dict[bytes, bytes], + ], + ..., + ], + ], + ..., + ], + ], + ], + ) -> None: + for stream_name, msgs in await read(self.last_id): + if msgs: + self.last_id = msgs[-1][0].decode() + + for message_id, raw_msg in msgs: + msg = DefaultStreamMessage( + type="stream", + channel=stream_name.decode(), + message_ids=[message_id], + data=raw_msg, + ) + + await self.consume(msg) + + +class StreamBatchSubscriber(_StreamHandlerMixin): + def __init__( + self, + *, + stream: StreamSub, + # Subscriber args + ack_policy: "AckPolicy", + no_reply: bool, + broker_dependencies: Iterable["Dependant"], + broker_middlewares: Sequence["BrokerMiddleware[UnifyRedisDict]"], + ) -> None: + parser = RedisBatchStreamParser() + super().__init__( + stream=stream, + default_parser=parser.parse_message, + default_decoder=parser.decode_message, + # Propagated options + ack_policy=ack_policy, + no_reply=no_reply, + broker_middlewares=broker_middlewares, + broker_dependencies=broker_dependencies, + ) + + async def _get_msgs( + self, + read: Callable[ + [str], + Awaitable[ + tuple[tuple[bytes, tuple[tuple[bytes, dict[bytes, bytes]], ...]], ...], + ], + ], + ) -> None: + for stream_name, msgs in await read(self.last_id): + if msgs: + self.last_id = msgs[-1][0].decode() + + data: list[dict[bytes, bytes]] = [] + ids: list[bytes] = [] + for message_id, i in msgs: + data.append(i) + ids.append(message_id) + + msg = BatchStreamMessage( + type="bstream", + channel=stream_name.decode(), + data=data, + message_ids=ids, + ) + + await self.consume(msg) diff --git a/faststream/redis/testing.py b/faststream/redis/testing.py index 558a0fd5ae..26537284da 100644 --- a/faststream/redis/testing.py +++ b/faststream/redis/testing.py @@ -31,16 +31,14 @@ from faststream.redis.publisher.producer import RedisFastProducer from faststream.redis.response import DestinationType, RedisPublishCommand from faststream.redis.schemas import INCORRECT_SETUP_MSG -from faststream.redis.subscriber.usecase import ( - ChannelSubscriber, - LogicSubscriber, - _ListHandlerMixin, - _StreamHandlerMixin, -) +from faststream.redis.subscriber.usecases.channel_subscriber import ChannelSubscriber +from faststream.redis.subscriber.usecases.list_subscriber import _ListHandlerMixin +from faststream.redis.subscriber.usecases.stream_subscriber import _StreamHandlerMixin if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict, SendableMessage from faststream.redis.publisher.specified import SpecificationPublisher + from faststream.redis.subscriber.usecases.basic import LogicSubscriber __all__ = ("TestRedisBroker",) From a456e94c3d3c3677d2d73737c007be2f6aadd8ee Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Wed, 11 Dec 2024 22:20:50 +0300 Subject: [PATCH 222/245] lint: fix routers types --- faststream/_internal/broker/abc_broker.py | 2 +- faststream/_internal/broker/broker.py | 2 +- faststream/_internal/broker/router.py | 2 +- faststream/confluent/broker/broker.py | 2 +- faststream/confluent/router.py | 2 +- faststream/kafka/broker/broker.py | 2 +- faststream/kafka/router.py | 2 +- faststream/nats/broker/broker.py | 2 +- faststream/nats/router.py | 2 +- faststream/rabbit/broker/broker.py | 2 +- faststream/rabbit/router.py | 2 +- faststream/redis/broker/broker.py | 2 +- faststream/redis/broker/registrator.py | 10 ++++++---- faststream/redis/router.py | 2 +- 14 files changed, 19 insertions(+), 17 deletions(-) diff --git a/faststream/_internal/broker/abc_broker.py b/faststream/_internal/broker/abc_broker.py index 97ace30b81..28d52976e4 100644 --- a/faststream/_internal/broker/abc_broker.py +++ b/faststream/_internal/broker/abc_broker.py @@ -46,7 +46,7 @@ def __init__( decoder: Optional["CustomCallable"], include_in_schema: Optional[bool], state: "BrokerState", - routers: Sequence["ABCBroker[Any]"], + routers: Sequence["ABCBroker[MsgType]"], ) -> None: self.prefix = prefix self.include_in_schema = include_in_schema diff --git a/faststream/_internal/broker/broker.py b/faststream/_internal/broker/broker.py index fa59569e30..6442c6b09b 100644 --- a/faststream/_internal/broker/broker.py +++ b/faststream/_internal/broker/broker.py @@ -94,7 +94,7 @@ def __init__( ), ], routers: Annotated[ - Sequence["ABCBroker[Any]"], + Sequence["ABCBroker[MsgType]"], Doc("Routers to apply to broker."), ], # Logging args diff --git a/faststream/_internal/broker/router.py b/faststream/_internal/broker/router.py index 8c02459095..7c0c8c2410 100644 --- a/faststream/_internal/broker/router.py +++ b/faststream/_internal/broker/router.py @@ -74,7 +74,7 @@ def __init__( parser: Optional["CustomCallable"], decoder: Optional["CustomCallable"], include_in_schema: Optional[bool], - routers: Sequence["ABCBroker[Any]"], + routers: Sequence["ABCBroker[MsgType]"], ) -> None: super().__init__( prefix=prefix, diff --git a/faststream/confluent/broker/broker.py b/faststream/confluent/broker/broker.py index 0262dbd9c3..63d729786e 100644 --- a/faststream/confluent/broker/broker.py +++ b/faststream/confluent/broker/broker.py @@ -282,7 +282,7 @@ def __init__( Doc("Middlewares to apply to all broker publishers/subscribers."), ] = (), routers: Annotated[ - Sequence["ABCBroker[Any]"], + Sequence["ABCBroker[Message]"], Doc("Routers to apply to broker."), ] = (), # AsyncAPI args diff --git a/faststream/confluent/router.py b/faststream/confluent/router.py index ed6ca3bce8..4eb663b5a0 100644 --- a/faststream/confluent/router.py +++ b/faststream/confluent/router.py @@ -510,7 +510,7 @@ def __init__( Doc("Router middlewares to apply to all routers' publishers/subscribers."), ] = (), routers: Annotated[ - Sequence["ABCBroker[Any]"], + Sequence["ABCBroker[Message]"], Doc("Routers to apply to broker."), ] = (), parser: Annotated[ diff --git a/faststream/kafka/broker/broker.py b/faststream/kafka/broker/broker.py index 292f3a566b..752ca5c52d 100644 --- a/faststream/kafka/broker/broker.py +++ b/faststream/kafka/broker/broker.py @@ -455,7 +455,7 @@ def __init__( Doc("Middlewares to apply to all broker publishers/subscribers."), ] = (), routers: Annotated[ - Sequence["ABCBroker[Any]"], + Sequence["ABCBroker[ConsumerRecord]"], Doc("Routers to apply to broker."), ] = (), # AsyncAPI args diff --git a/faststream/kafka/router.py b/faststream/kafka/router.py index a9d51af57f..0846da624a 100644 --- a/faststream/kafka/router.py +++ b/faststream/kafka/router.py @@ -620,7 +620,7 @@ def __init__( Doc("Router middlewares to apply to all routers' publishers/subscribers."), ] = (), routers: Annotated[ - Sequence["ABCBroker[Any]"], + Sequence["ABCBroker[ConsumerRecord]"], Doc("Routers to apply to broker."), ] = (), parser: Annotated[ diff --git a/faststream/nats/broker/broker.py b/faststream/nats/broker/broker.py index 0940225a29..ef75a4768e 100644 --- a/faststream/nats/broker/broker.py +++ b/faststream/nats/broker/broker.py @@ -378,7 +378,7 @@ def __init__( Doc("Middlewares to apply to all broker publishers/subscribers."), ] = (), routers: Annotated[ - Sequence["ABCBroker[Any]"], + Sequence["ABCBroker[Msg]"], Doc("Routers to apply to broker."), ] = (), # AsyncAPI args diff --git a/faststream/nats/router.py b/faststream/nats/router.py index 101026e00b..6d5b85cc9c 100644 --- a/faststream/nats/router.py +++ b/faststream/nats/router.py @@ -362,7 +362,7 @@ def __init__( Doc("Router middlewares to apply to all routers' publishers/subscribers."), ] = (), routers: Annotated[ - Sequence["ABCBroker[Any]"], + Sequence["ABCBroker[Msg]"], Doc("Routers to apply to broker."), ] = (), parser: Annotated[ diff --git a/faststream/rabbit/broker/broker.py b/faststream/rabbit/broker/broker.py index 04d2c2cd4f..084758401d 100644 --- a/faststream/rabbit/broker/broker.py +++ b/faststream/rabbit/broker/broker.py @@ -173,7 +173,7 @@ def __init__( Doc("Middlewares to apply to all broker publishers/subscribers."), ] = (), routers: Annotated[ - Sequence["ABCBroker[Any]"], + Sequence["ABCBroker[IncomingMessage]"], Doc("Routers to apply to broker."), ] = (), # AsyncAPI args diff --git a/faststream/rabbit/router.py b/faststream/rabbit/router.py index 59aac51eb0..8a2c6cc62f 100644 --- a/faststream/rabbit/router.py +++ b/faststream/rabbit/router.py @@ -316,7 +316,7 @@ def __init__( Doc("Router middlewares to apply to all routers' publishers/subscribers."), ] = (), routers: Annotated[ - Sequence["ABCBroker[Any]"], + Sequence["ABCBroker[IncomingMessage]"], Doc("Routers to apply to broker."), ] = (), parser: Annotated[ diff --git a/faststream/redis/broker/broker.py b/faststream/redis/broker/broker.py index b47845e296..aa90c1d5ca 100644 --- a/faststream/redis/broker/broker.py +++ b/faststream/redis/broker/broker.py @@ -140,7 +140,7 @@ def __init__( Doc("Middlewares to apply to all broker publishers/subscribers."), ] = (), routers: Annotated[ - Sequence["ABCBroker[Any]"], + Sequence["ABCBroker[BaseMessage]"], Doc("Routers to apply to broker."), ] = (), # AsyncAPI args diff --git a/faststream/redis/broker/registrator.py b/faststream/redis/broker/registrator.py index 9b1556b0c1..39567dd835 100644 --- a/faststream/redis/broker/registrator.py +++ b/faststream/redis/broker/registrator.py @@ -8,7 +8,6 @@ from faststream.middlewares import AckPolicy from faststream.redis.message import UnifyRedisDict from faststream.redis.publisher.factory import create_publisher -from faststream.redis.publisher.specified import SpecificationPublisher from faststream.redis.subscriber.factory import SubsciberType, create_subscriber from faststream.redis.subscriber.specified import SpecificationSubscriber @@ -22,7 +21,10 @@ SubscriberMiddleware, ) from faststream.redis.message import UnifyRedisMessage - from faststream.redis.publisher.specified import PublisherType + from faststream.redis.publisher.specified import ( + PublisherType, + SpecificationPublisher, + ) from faststream.redis.schemas import ListSub, PubSub, StreamSub @@ -104,7 +106,7 @@ def subscriber( # type: ignore[override] ] = True, ) -> SpecificationSubscriber: subscriber = cast( - SpecificationSubscriber, + "SpecificationSubscriber", super().subscriber( create_subscriber( channel=channel, @@ -195,7 +197,7 @@ def publisher( # type: ignore[override] Or you can create a publisher object to call it lately - `broker.publisher(...).publish(...)`. """ return cast( - SpecificationPublisher, + "SpecificationPublisher", super().publisher( create_publisher( channel=channel, diff --git a/faststream/redis/router.py b/faststream/redis/router.py index a7c33875dc..d6d4e67cfe 100644 --- a/faststream/redis/router.py +++ b/faststream/redis/router.py @@ -234,7 +234,7 @@ def __init__( Doc("Router middlewares to apply to all routers' publishers/subscribers."), ] = (), routers: Annotated[ - Sequence["ABCBroker[Any]"], + Sequence["ABCBroker[BaseMessage]"], Doc("Routers to apply to broker."), ] = (), parser: Annotated[ From a10d9b5932de4410af54eb21fb3f431216902a79 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Wed, 11 Dec 2024 22:48:42 +0300 Subject: [PATCH 223/245] lint: fix internal broker types --- faststream/_internal/broker/abc_broker.py | 5 ++++- faststream/_internal/broker/broker.py | 21 +++++++++++---------- faststream/_internal/broker/pub_base.py | 6 +++++- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/faststream/_internal/broker/abc_broker.py b/faststream/_internal/broker/abc_broker.py index 28d52976e4..bd3a993e7a 100644 --- a/faststream/_internal/broker/abc_broker.py +++ b/faststream/_internal/broker/abc_broker.py @@ -22,7 +22,10 @@ class FinalSubscriber( EndpointSpecification[MsgType, SubscriberSpec], SubscriberProto[MsgType], ): - pass + @property + @abstractmethod + def call_name(self) -> str: + raise NotImplementedError class FinalPublisher( diff --git a/faststream/_internal/broker/broker.py b/faststream/_internal/broker/broker.py index 6442c6b09b..7c92788054 100644 --- a/faststream/_internal/broker/broker.py +++ b/faststream/_internal/broker/broker.py @@ -37,7 +37,7 @@ from faststream._internal.utils.functions import to_async from faststream.specification.proto import ServerSpecification -from .abc_broker import ABCBroker +from .abc_broker import ABCBroker, FinalPublisher from .pub_base import BrokerPublishMixin if TYPE_CHECKING: @@ -47,10 +47,7 @@ from fast_depends.library.serializer import SerializerProto from faststream._internal.basic_types import AnyDict, Decorator - from faststream._internal.publisher.proto import ( - ProducerProto, - PublisherProto, - ) + from faststream._internal.publisher.proto import ProducerProto from faststream.security import BaseSecurity from faststream.specification.schema.extra import Tag, TagDict @@ -64,9 +61,9 @@ class BrokerUsecase( ): """A class representing a broker async use case.""" - url: Union[str, Sequence[str]] + url: Union[str, list[str]] _connection: Optional[ConnectionType] - _producer: "ProducerProto" + middlewares: Sequence["BrokerMiddleware[MsgType]"] def __init__( self, @@ -110,7 +107,7 @@ def __init__( Doc("Custom library dependant generator callback."), ], _call_decorators: Annotated[ - Iterable["Decorator"], + Sequence["Decorator"], Doc("Any custom decorator to apply to wrapped functions."), ], # AsyncAPI kwargs @@ -311,8 +308,12 @@ def _subscriber_setup_extra(self) -> "AnyDict": "broker_decoder": self._decoder, } - def publisher(self, *args: Any, **kwargs: Any) -> "PublisherProto[MsgType]": - pub = super().publisher(*args, **kwargs, is_running=self.running) + def publisher( + self, + publisher: "FinalPublisher[MsgType]", + is_running: bool = False, + ) -> "FinalPublisher[MsgType]": + pub = super().publisher(publisher, is_running=self.running) self.setup_publisher(pub) return pub diff --git a/faststream/_internal/broker/pub_base.py b/faststream/_internal/broker/pub_base.py index e0938adf3a..d4d8563f57 100644 --- a/faststream/_internal/broker/pub_base.py +++ b/faststream/_internal/broker/pub_base.py @@ -17,7 +17,11 @@ class BrokerPublishMixin(Generic[MsgType]): middlewares: Sequence["BrokerMiddleware[MsgType]"] - context: "ContextRepo" + + @property + @abstractmethod + def context(self) -> "ContextRepo": + raise NotImplementedError @abstractmethod async def publish( From 4bf0e3392fd744e37139b6f22c5dd4293b54333c Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Wed, 11 Dec 2024 23:03:01 +0300 Subject: [PATCH 224/245] lint: fix ruff TC006 --- faststream/_internal/broker/broker.py | 4 ++-- faststream/_internal/cli/main.py | 4 ++-- faststream/_internal/cli/utils/parser.py | 2 +- faststream/_internal/fastapi/get_dependant.py | 4 ++-- faststream/_internal/fastapi/router.py | 4 ++-- faststream/_internal/subscriber/call_item.py | 4 ++-- faststream/_internal/subscriber/utils.py | 2 +- faststream/_internal/testing/ast.py | 4 ++-- faststream/_internal/utils/functions.py | 4 ++-- .../confluent/opentelemetry/provider.py | 6 ++--- faststream/confluent/prometheus/provider.py | 6 ++--- faststream/confluent/publisher/factory.py | 4 ++-- faststream/confluent/subscriber/factory.py | 6 ++--- faststream/kafka/opentelemetry/provider.py | 6 ++--- faststream/kafka/parser.py | 2 +- faststream/kafka/prometheus/provider.py | 2 +- faststream/message/utils.py | 2 +- faststream/middlewares/exception.py | 2 +- faststream/nats/broker/registrator.py | 6 ++--- faststream/nats/fastapi/fastapi.py | 4 ++-- .../usecases/key_value_subscriber.py | 2 +- .../usecases/object_storage_subscriber.py | 5 ++-- .../usecases/stream_pull_subscriber.py | 4 ++-- faststream/opentelemetry/middleware.py | 2 +- faststream/prometheus/container.py | 23 +++++++++++-------- faststream/rabbit/broker/registrator.py | 6 ++--- faststream/rabbit/fastapi/fastapi.py | 2 +- faststream/redis/fastapi/fastapi.py | 2 +- faststream/redis/opentelemetry/provider.py | 2 +- faststream/redis/testing.py | 2 +- tests/opentelemetry/basic.py | 6 ++--- 31 files changed, 69 insertions(+), 65 deletions(-) diff --git a/faststream/_internal/broker/broker.py b/faststream/_internal/broker/broker.py index 7c92788054..c68ae0aa82 100644 --- a/faststream/_internal/broker/broker.py +++ b/faststream/_internal/broker/broker.py @@ -157,11 +157,11 @@ def __init__( middlewares=middlewares, dependencies=dependencies, decoder=cast( - Optional["AsyncCustomCallable"], + "Optional[AsyncCustomCallable]", to_async(decoder) if decoder else None, ), parser=cast( - Optional["AsyncCustomCallable"], + "Optional[AsyncCustomCallable]", to_async(parser) if parser else None, ), routers=routers, diff --git a/faststream/_internal/cli/main.py b/faststream/_internal/cli/main.py index ec7ece0112..e9efba45ea 100644 --- a/faststream/_internal/cli/main.py +++ b/faststream/_internal/cli/main.py @@ -125,7 +125,7 @@ def run( # Should be imported after sys.path changes module_path, app_obj = import_from_string(app, is_factory=is_factory) - app_obj = cast(Application, app_obj) + app_obj = cast("Application", app_obj) args = (app, extra, is_factory, casted_log_level) @@ -197,7 +197,7 @@ def _run( ) -> None: """Runs the specified application.""" _, app_obj = import_from_string(app, is_factory=is_factory) - app_obj = cast(Application, app_obj) + app_obj = cast("Application", app_obj) _run_imported_app( app_obj, extra_options=extra_options, diff --git a/faststream/_internal/cli/utils/parser.py b/faststream/_internal/cli/utils/parser.py index 8ee5ff3b21..72ecff5251 100644 --- a/faststream/_internal/cli/utils/parser.py +++ b/faststream/_internal/cli/utils/parser.py @@ -29,7 +29,7 @@ def parse_cli_args(*args: str) -> tuple[str, dict[str, "SettingField"]]: *reduce( lambda acc, x: acc + x.split("="), args, - cast(list[str], []), + cast("list[str]", []), ), "-", ]: diff --git a/faststream/_internal/fastapi/get_dependant.py b/faststream/_internal/fastapi/get_dependant.py index 7e26cb51f4..172059c807 100644 --- a/faststream/_internal/fastapi/get_dependant.py +++ b/faststream/_internal/fastapi/get_dependant.py @@ -68,7 +68,7 @@ def _patch_fastapi_dependent(dependant: "Dependant") -> "Dependant": if PYDANTIC_V2: from pydantic.fields import FieldInfo - info = cast(FieldInfo, info) + info = cast("FieldInfo", info) field_data.update( { @@ -95,7 +95,7 @@ def _patch_fastapi_dependent(dependant: "Dependant") -> "Dependant": else: from pydantic.fields import ModelField # type: ignore[attr-defined] - info = cast(ModelField, info) + info = cast("ModelField", info) field_data.update( { diff --git a/faststream/_internal/fastapi/router.py b/faststream/_internal/fastapi/router.py index 7d99dae680..8b2c8432fc 100644 --- a/faststream/_internal/fastapi/router.py +++ b/faststream/_internal/fastapi/router.py @@ -16,7 +16,6 @@ ) from weakref import WeakSet -from fastapi.background import BackgroundTasks from fastapi.datastructures import Default from fastapi.responses import HTMLResponse from fastapi.routing import APIRoute, APIRouter @@ -43,6 +42,7 @@ from types import TracebackType from fastapi import FastAPI, params + from fastapi.background import BackgroundTasks from fastapi.types import IncEx from starlette import routing from starlette.types import ASGIApp, AppType, Lifespan @@ -67,7 +67,7 @@ async def __aexit__( ) -> Optional[bool]: if not exc_type and ( background := cast( - Optional[BackgroundTasks], + "Optional[BackgroundTasks]", getattr(self.context.get_local("message"), "background", None), ) ): diff --git a/faststream/_internal/subscriber/call_item.py b/faststream/_internal/subscriber/call_item.py index bd8c7a4e49..9858e833cd 100644 --- a/faststream/_internal/subscriber/call_item.py +++ b/faststream/_internal/subscriber/call_item.py @@ -125,8 +125,8 @@ async def is_suitable( cache: dict[Any, Any], ) -> Optional["StreamMessage[MsgType]"]: """Check is message suite for current filter.""" - if not (parser := cast(Optional["AsyncCallable"], self.item_parser)) or not ( - decoder := cast(Optional["AsyncCallable"], self.item_decoder) + if not (parser := cast("Optional[AsyncCallable]", self.item_parser)) or not ( + decoder := cast("Optional[AsyncCallable]", self.item_decoder) ): error_msg = "You should setup `HandlerItem` at first." raise SetupError(error_msg) diff --git a/faststream/_internal/subscriber/utils.py b/faststream/_internal/subscriber/utils.py index 9195087e2f..67c22f793d 100644 --- a/faststream/_internal/subscriber/utils.py +++ b/faststream/_internal/subscriber/utils.py @@ -131,7 +131,7 @@ def resolve_custom_func( original_params = inspect.signature(custom_func).parameters if len(original_params) == 1: - return to_async(cast(Union["SyncCallable", "AsyncCallable"], custom_func)) + return to_async(cast("Union[SyncCallable, AsyncCallable]", custom_func)) name = tuple(original_params.items())[1][0] return partial(to_async(custom_func), **{name: default_func}) diff --git a/faststream/_internal/testing/ast.py b/faststream/_internal/testing/ast.py index 495819fc38..880e895a66 100644 --- a/faststream/_internal/testing/ast.py +++ b/faststream/_internal/testing/ast.py @@ -9,7 +9,7 @@ def is_contains_context_name(scip_name: str, name: str) -> bool: stack = traceback.extract_stack()[-3] tree = _read_source_ast(stack.filename) - node = cast(Union[ast.With, ast.AsyncWith], _find_ast_node(tree, stack.lineno)) + node = cast("Union[ast.With, ast.AsyncWith]", _find_ast_node(tree, stack.lineno)) context_calls = _get_withitem_calls(node) try: @@ -29,7 +29,7 @@ def _find_ast_node(module: ast.Module, lineno: Optional[int]) -> Optional[ast.AS if lineno is not None: # pragma: no branch for i in getattr(module, "body", ()): if i.lineno == lineno: - return cast(ast.AST, i) + return cast("ast.AST", i) r = _find_ast_node(i, lineno) if r is not None: diff --git a/faststream/_internal/utils/functions.py b/faststream/_internal/utils/functions.py index d81201fcf0..e8cb60d696 100644 --- a/faststream/_internal/utils/functions.py +++ b/faststream/_internal/utils/functions.py @@ -51,9 +51,9 @@ def to_async( ) -> Callable[F_Spec, Awaitable[F_Return]]: """Converts a synchronous function to an asynchronous function.""" if is_coroutine_callable(func): - return cast(Callable[F_Spec, Awaitable[F_Return]], func) + return cast("Callable[F_Spec, Awaitable[F_Return]]", func) - func = cast(Callable[F_Spec, F_Return], func) + func = cast("Callable[F_Spec, F_Return]", func) @wraps(func) async def to_async_wrapper(*args: F_Spec.args, **kwargs: F_Spec.kwargs) -> F_Return: diff --git a/faststream/confluent/opentelemetry/provider.py b/faststream/confluent/opentelemetry/provider.py index cf7445520b..73bd7ead3c 100644 --- a/faststream/confluent/opentelemetry/provider.py +++ b/faststream/confluent/opentelemetry/provider.py @@ -73,7 +73,7 @@ def get_consume_destination_name( self, msg: "StreamMessage[Message]", ) -> str: - return cast(str, msg.raw_message.topic()) + return cast("str", msg.raw_message.topic()) class BatchConfluentTelemetrySettingsProvider( @@ -90,7 +90,7 @@ def get_consume_attrs_from_message( SpanAttributes.MESSAGING_MESSAGE_CONVERSATION_ID: msg.correlation_id, SpanAttributes.MESSAGING_BATCH_MESSAGE_COUNT: len(msg.raw_message), SpanAttributes.MESSAGING_MESSAGE_PAYLOAD_SIZE_BYTES: len( - bytearray().join(cast(Sequence[bytes], msg.body)), + bytearray().join(cast("Sequence[bytes]", msg.body)), ), SpanAttributes.MESSAGING_KAFKA_DESTINATION_PARTITION: raw_message.partition(), MESSAGING_DESTINATION_PUBLISH_NAME: raw_message.topic(), @@ -100,7 +100,7 @@ def get_consume_destination_name( self, msg: "StreamMessage[tuple[Message, ...]]", ) -> str: - return cast(str, msg.raw_message[0].topic()) + return cast("str", msg.raw_message[0].topic()) def telemetry_attributes_provider_factory( diff --git a/faststream/confluent/prometheus/provider.py b/faststream/confluent/prometheus/provider.py index a242bc2092..c5b2814687 100644 --- a/faststream/confluent/prometheus/provider.py +++ b/faststream/confluent/prometheus/provider.py @@ -32,7 +32,7 @@ def get_consume_attrs_from_message( msg: "StreamMessage[Message]", ) -> ConsumeAttrs: return { - "destination_name": cast(str, msg.raw_message.topic()), + "destination_name": cast("str", msg.raw_message.topic()), "message_size": len(msg.body), "messages_count": 1, } @@ -47,8 +47,8 @@ def get_consume_attrs_from_message( ) -> ConsumeAttrs: raw_message = msg.raw_message[0] return { - "destination_name": cast(str, raw_message.topic()), - "message_size": len(bytearray().join(cast(Sequence[bytes], msg.body))), + "destination_name": cast("str", raw_message.topic()), + "message_size": len(bytearray().join(cast("Sequence[bytes]", msg.body))), "messages_count": len(msg.raw_message), } diff --git a/faststream/confluent/publisher/factory.py b/faststream/confluent/publisher/factory.py index 9bcd5da08f..e5e68dc049 100644 --- a/faststream/confluent/publisher/factory.py +++ b/faststream/confluent/publisher/factory.py @@ -119,7 +119,7 @@ def create_publisher( headers=headers, reply_to=reply_to, broker_middlewares=cast( - Sequence["BrokerMiddleware[tuple[ConfluentMsg, ...]]"], + "Sequence[BrokerMiddleware[tuple[ConfluentMsg, ...]]]", broker_middlewares, ), middlewares=middlewares, @@ -137,7 +137,7 @@ def create_publisher( headers=headers, reply_to=reply_to, broker_middlewares=cast( - Sequence["BrokerMiddleware[ConfluentMsg]"], + "Sequence[BrokerMiddleware[ConfluentMsg]]", broker_middlewares, ), middlewares=middlewares, diff --git a/faststream/confluent/subscriber/factory.py b/faststream/confluent/subscriber/factory.py index 1954c3a40d..5f9803fe63 100644 --- a/faststream/confluent/subscriber/factory.py +++ b/faststream/confluent/subscriber/factory.py @@ -176,7 +176,7 @@ def create_subscriber( no_reply=no_reply, broker_dependencies=broker_dependencies, broker_middlewares=cast( - Sequence["BrokerMiddleware[tuple[ConfluentMsg, ...]]"], + "Sequence[BrokerMiddleware[tuple[ConfluentMsg, ...]]]", broker_middlewares, ), title_=title_, @@ -195,7 +195,7 @@ def create_subscriber( no_reply=no_reply, broker_dependencies=broker_dependencies, broker_middlewares=cast( - Sequence["BrokerMiddleware[ConfluentMsg]"], + "Sequence[BrokerMiddleware[ConfluentMsg]]", broker_middlewares, ), title_=title_, @@ -215,7 +215,7 @@ def create_subscriber( no_reply=no_reply, broker_dependencies=broker_dependencies, broker_middlewares=cast( - Sequence["BrokerMiddleware[ConfluentMsg]"], + "Sequence[BrokerMiddleware[ConfluentMsg]]", broker_middlewares, ), title_=title_, diff --git a/faststream/kafka/opentelemetry/provider.py b/faststream/kafka/opentelemetry/provider.py index 7e0c6434fa..6eedfafdf7 100644 --- a/faststream/kafka/opentelemetry/provider.py +++ b/faststream/kafka/opentelemetry/provider.py @@ -73,7 +73,7 @@ def get_consume_destination_name( self, msg: "StreamMessage[ConsumerRecord]", ) -> str: - return cast(str, msg.raw_message.topic) + return cast("str", msg.raw_message.topic) class BatchKafkaTelemetrySettingsProvider( @@ -90,7 +90,7 @@ def get_consume_attrs_from_message( SpanAttributes.MESSAGING_MESSAGE_ID: msg.message_id, SpanAttributes.MESSAGING_MESSAGE_CONVERSATION_ID: msg.correlation_id, SpanAttributes.MESSAGING_MESSAGE_PAYLOAD_SIZE_BYTES: len( - bytearray().join(cast(Sequence[bytes], msg.body)), + bytearray().join(cast("Sequence[bytes]", msg.body)), ), SpanAttributes.MESSAGING_BATCH_MESSAGE_COUNT: len(msg.raw_message), SpanAttributes.MESSAGING_KAFKA_DESTINATION_PARTITION: raw_message.partition, @@ -101,7 +101,7 @@ def get_consume_destination_name( self, msg: "StreamMessage[tuple[ConsumerRecord, ...]]", ) -> str: - return cast(str, msg.raw_message[0].topic) + return cast("str", msg.raw_message[0].topic) def telemetry_attributes_provider_factory( diff --git a/faststream/kafka/parser.py b/faststream/kafka/parser.py index 294aab87e8..936abbc7b0 100644 --- a/faststream/kafka/parser.py +++ b/faststream/kafka/parser.py @@ -97,7 +97,7 @@ async def decode_message( ) -> "DecodedMessage": """Decode a batch of messages.""" # super() should be here due python can't find it in comprehension - super_obj = cast(AioKafkaParser, super()) + super_obj = cast("AioKafkaParser", super()) return [ decode_message(await super_obj.parse_message(m)) for m in msg.raw_message diff --git a/faststream/kafka/prometheus/provider.py b/faststream/kafka/prometheus/provider.py index 1d9d19fe40..25f324decb 100644 --- a/faststream/kafka/prometheus/provider.py +++ b/faststream/kafka/prometheus/provider.py @@ -46,7 +46,7 @@ def get_consume_attrs_from_message( raw_message = msg.raw_message[0] return { "destination_name": raw_message.topic, - "message_size": len(bytearray().join(cast(Sequence[bytes], msg.body))), + "message_size": len(bytearray().join(cast("Sequence[bytes]", msg.body))), "messages_count": len(msg.raw_message), } diff --git a/faststream/message/utils.py b/faststream/message/utils.py index 715c336bd1..c06750f813 100644 --- a/faststream/message/utils.py +++ b/faststream/message/utils.py @@ -30,7 +30,7 @@ def decode_message(message: "StreamMessage[Any]") -> "DecodedMessage": m: DecodedMessage = body if content_type := getattr(message, "content_type", False): - content_type = ContentTypes(cast(str, content_type)) + content_type = ContentTypes(cast("str", content_type)) if content_type is ContentTypes.TEXT: m = body.decode() diff --git a/faststream/middlewares/exception.py b/faststream/middlewares/exception.py index eb18aa4f24..4172fb41bb 100644 --- a/faststream/middlewares/exception.py +++ b/faststream/middlewares/exception.py @@ -75,7 +75,7 @@ def __init__( ( exc_type, apply_types( - cast(Callable[..., Awaitable[None]], to_async(handler)), + cast("Callable[..., Awaitable[None]]", to_async(handler)), ), ) for exc_type, handler in (handlers or {}).items() diff --git a/faststream/nats/broker/registrator.py b/faststream/nats/broker/registrator.py index 4dddc88bad..6e385ae119 100644 --- a/faststream/nats/broker/registrator.py +++ b/faststream/nats/broker/registrator.py @@ -9,7 +9,6 @@ from faststream.middlewares import AckPolicy from faststream.nats.helpers import StreamBuilder from faststream.nats.publisher.factory import create_publisher -from faststream.nats.publisher.specified import SpecificationPublisher from faststream.nats.schemas import JStream, KvWatch, ObjWatch, PullSub from faststream.nats.subscriber.factory import create_subscriber from faststream.nats.subscriber.specified import SpecificationSubscriber @@ -25,6 +24,7 @@ SubscriberMiddleware, ) from faststream.nats.message import NatsMessage + from faststream.nats.publisher.specified import SpecificationPublisher class NatsRegistrator(ABCBroker["Msg"]): @@ -211,7 +211,7 @@ def subscriber( # type: ignore[override] stream = self._stream_builder.create(stream) subscriber = cast( - SpecificationSubscriber, + "SpecificationSubscriber", super().subscriber( create_subscriber( subject=subject, @@ -330,7 +330,7 @@ def publisher( # type: ignore[override] stream = self._stream_builder.create(stream) publisher = cast( - SpecificationPublisher, + "SpecificationPublisher", super().publisher( publisher=create_publisher( subject=subject, diff --git a/faststream/nats/fastapi/fastapi.py b/faststream/nats/fastapi/fastapi.py index a967a2e692..179a838290 100644 --- a/faststream/nats/fastapi/fastapi.py +++ b/faststream/nats/fastapi/fastapi.py @@ -34,7 +34,6 @@ from faststream._internal.fastapi.router import StreamRouter from faststream.middlewares import AckPolicy from faststream.nats.broker import NatsBroker -from faststream.nats.subscriber.specified import SpecificationSubscriber if TYPE_CHECKING: from enum import Enum @@ -62,6 +61,7 @@ from faststream.nats.message import NatsMessage from faststream.nats.publisher.specified import SpecificationPublisher from faststream.nats.schemas import JStream, KvWatch, ObjWatch, PullSub + from faststream.nats.subscriber.specified import SpecificationSubscriber from faststream.security import BaseSecurity from faststream.specification.schema.extra import Tag, TagDict @@ -848,7 +848,7 @@ def subscriber( # type: ignore[override] ] = False, ) -> "SpecificationSubscriber": return cast( - SpecificationSubscriber, + "SpecificationSubscriber", super().subscriber( subject=subject, queue=queue, diff --git a/faststream/nats/subscriber/usecases/key_value_subscriber.py b/faststream/nats/subscriber/usecases/key_value_subscriber.py index 9b3f27c494..20827bd6bf 100644 --- a/faststream/nats/subscriber/usecases/key_value_subscriber.py +++ b/faststream/nats/subscriber/usecases/key_value_subscriber.py @@ -147,7 +147,7 @@ async def __consume_watch(self) -> None: while self.running: with suppress(ConnectionClosedError, TimeoutError): message = cast( - Optional["KeyValue.Entry"], + "Optional[KeyValue.Entry]", # type: ignore[no-untyped-call] await key_watcher.updates(self.kv_watch.timeout), ) diff --git a/faststream/nats/subscriber/usecases/object_storage_subscriber.py b/faststream/nats/subscriber/usecases/object_storage_subscriber.py index 0e6332ce3e..326d8fe2a6 100644 --- a/faststream/nats/subscriber/usecases/object_storage_subscriber.py +++ b/faststream/nats/subscriber/usecases/object_storage_subscriber.py @@ -151,9 +151,8 @@ async def __consume_watch(self) -> None: while self.running: with suppress(TimeoutError): message = cast( - Optional["ObjectInfo"], - # type: ignore[no-untyped-call] - await obj_watch.updates(self.obj_watch.timeout), + "Optional[ObjectInfo]", + await obj_watch.updates(self.obj_watch.timeout), # type: ignore[no-untyped-call] ) if message: diff --git a/faststream/nats/subscriber/usecases/stream_pull_subscriber.py b/faststream/nats/subscriber/usecases/stream_pull_subscriber.py index 6dd7693edc..04ed7f5377 100644 --- a/faststream/nats/subscriber/usecases/stream_pull_subscriber.py +++ b/faststream/nats/subscriber/usecases/stream_pull_subscriber.py @@ -13,7 +13,6 @@ from faststream._internal.subscriber.mixins import ConcurrentMixin, TasksMixin from faststream._internal.subscriber.utils import process_msg -from faststream.nats.message import NatsMessage from faststream.nats.parser import ( BatchParser, ) @@ -35,6 +34,7 @@ BrokerMiddleware, ) from faststream.middlewares import AckPolicy + from faststream.nats.message import NatsMessage from faststream.nats.schemas import JStream, PullSub @@ -201,7 +201,7 @@ async def get_one( context = self._state.get().di_state.context return cast( - NatsMessage, + "NatsMessage", await process_msg( msg=raw_message, middlewares=( diff --git a/faststream/opentelemetry/middleware.py b/faststream/opentelemetry/middleware.py index 0bbe97aa86..247bd4ff75 100644 --- a/faststream/opentelemetry/middleware.py +++ b/faststream/opentelemetry/middleware.py @@ -409,7 +409,7 @@ def _get_span_from_headers(headers: "AnyDict") -> Optional[Span]: return None return cast( - Optional[Span], + "Optional[Span]", next(iter(trace_context.values())), ) diff --git a/faststream/prometheus/container.py b/faststream/prometheus/container.py index ed7ee8bc5f..6ef46499b1 100644 --- a/faststream/prometheus/container.py +++ b/faststream/prometheus/container.py @@ -50,7 +50,8 @@ def __init__( received_messages_total_name = f"{metrics_prefix}_received_messages_total" self.received_messages_total = cast( - Counter, self._get_registered_metric(received_messages_total_name) + "Counter", + self._get_registered_metric(received_messages_total_name), ) or Counter( name=received_messages_total_name, documentation="Count of received messages by broker and handler", @@ -62,7 +63,8 @@ def __init__( f"{metrics_prefix}_received_messages_size_bytes" ) self.received_messages_size_bytes = cast( - Histogram, self._get_registered_metric(received_messages_size_bytes_name) + "Histogram", + self._get_registered_metric(received_messages_size_bytes_name), ) or Histogram( name=received_messages_size_bytes_name, documentation="Histogram of received messages size in bytes by broker and handler", @@ -75,7 +77,8 @@ def __init__( f"{metrics_prefix}_received_messages_in_process" ) self.received_messages_in_process = cast( - Gauge, self._get_registered_metric(received_messages_in_process_name) + "Gauge", + self._get_registered_metric(received_messages_in_process_name), ) or Gauge( name=received_messages_in_process_name, documentation="Gauge of received messages in process by broker and handler", @@ -87,7 +90,8 @@ def __init__( f"{metrics_prefix}_received_processed_messages_total" ) self.received_processed_messages_total = cast( - Counter, self._get_registered_metric(received_processed_messages_total_name) + "Counter", + self._get_registered_metric(received_processed_messages_total_name), ) or Counter( name=received_processed_messages_total_name, documentation="Count of received processed messages by broker, handler and status", @@ -99,7 +103,7 @@ def __init__( f"{metrics_prefix}_received_processed_messages_duration_seconds" ) self.received_processed_messages_duration_seconds = cast( - Histogram, + "Histogram", self._get_registered_metric( received_processed_messages_duration_seconds_name ), @@ -114,7 +118,7 @@ def __init__( f"{metrics_prefix}_received_processed_messages_exceptions_total" ) self.received_processed_messages_exceptions_total = cast( - Counter, + "Counter", self._get_registered_metric( received_processed_messages_exceptions_total_name ), @@ -127,7 +131,8 @@ def __init__( published_messages_total_name = f"{metrics_prefix}_published_messages_total" self.published_messages_total = cast( - Counter, self._get_registered_metric(published_messages_total_name) + "Counter", + self._get_registered_metric(published_messages_total_name), ) or Counter( name=published_messages_total_name, documentation="Count of published messages by destination and status", @@ -139,7 +144,7 @@ def __init__( f"{metrics_prefix}_published_messages_duration_seconds" ) self.published_messages_duration_seconds = cast( - Histogram, + "Histogram", self._get_registered_metric(published_messages_duration_seconds_name), ) or Histogram( name=published_messages_duration_seconds_name, @@ -152,7 +157,7 @@ def __init__( f"{metrics_prefix}_published_messages_exceptions_total" ) self.published_messages_exceptions_total = cast( - Counter, + "Counter", self._get_registered_metric(published_messages_exceptions_total_name), ) or Counter( name=published_messages_exceptions_total_name, diff --git a/faststream/rabbit/broker/registrator.py b/faststream/rabbit/broker/registrator.py index 371c80d708..21d94004ad 100644 --- a/faststream/rabbit/broker/registrator.py +++ b/faststream/rabbit/broker/registrator.py @@ -7,7 +7,6 @@ from faststream._internal.constants import EMPTY from faststream.middlewares import AckPolicy from faststream.rabbit.publisher.factory import create_publisher -from faststream.rabbit.publisher.specified import SpecificationPublisher from faststream.rabbit.publisher.usecase import PublishKwargs from faststream.rabbit.schemas import ( RabbitExchange, @@ -28,6 +27,7 @@ SubscriberMiddleware, ) from faststream.rabbit.message import RabbitMessage + from faststream.rabbit.publisher.specified import SpecificationPublisher class RabbitRegistrator(ABCBroker["IncomingMessage"]): @@ -113,7 +113,7 @@ def subscriber( # type: ignore[override] ] = True, ) -> SpecificationSubscriber: subscriber = cast( - SpecificationSubscriber, + "SpecificationSubscriber", super().subscriber( create_subscriber( queue=RabbitQueue.validate(queue), @@ -276,7 +276,7 @@ def publisher( # type: ignore[override] ) return cast( - SpecificationPublisher, + "SpecificationPublisher", super().publisher( create_publisher( routing_key=routing_key, diff --git a/faststream/rabbit/fastapi/fastapi.py b/faststream/rabbit/fastapi/fastapi.py index d5d2631f2f..00c23f2cdb 100644 --- a/faststream/rabbit/fastapi/fastapi.py +++ b/faststream/rabbit/fastapi/fastapi.py @@ -672,7 +672,7 @@ def subscriber( # type: ignore[override] ] = False, ) -> SpecificationSubscriber: return cast( - SpecificationSubscriber, + "SpecificationSubscriber", super().subscriber( queue=queue, exchange=exchange, diff --git a/faststream/redis/fastapi/fastapi.py b/faststream/redis/fastapi/fastapi.py index f544eb2363..f05b7987af 100644 --- a/faststream/redis/fastapi/fastapi.py +++ b/faststream/redis/fastapi/fastapi.py @@ -622,7 +622,7 @@ def subscriber( # type: ignore[override] ] = False, ) -> SpecificationSubscriber: return cast( - SpecificationSubscriber, + "SpecificationSubscriber", super().subscriber( channel=channel, list=list, diff --git a/faststream/redis/opentelemetry/provider.py b/faststream/redis/opentelemetry/provider.py index 799e68f803..334cc2f564 100644 --- a/faststream/redis/opentelemetry/provider.py +++ b/faststream/redis/opentelemetry/provider.py @@ -29,7 +29,7 @@ def get_consume_attrs_from_message( MESSAGING_DESTINATION_PUBLISH_NAME: msg.raw_message["channel"], } - if cast(str, msg.raw_message.get("type", "")).startswith("b"): + if cast("str", msg.raw_message.get("type", "")).startswith("b"): attrs[SpanAttributes.MESSAGING_BATCH_MESSAGE_COUNT] = len( msg.raw_message["data"] ) diff --git a/faststream/redis/testing.py b/faststream/redis/testing.py index 26537284da..088115f97c 100644 --- a/faststream/redis/testing.py +++ b/faststream/redis/testing.py @@ -181,7 +181,7 @@ async def publish_batch( visitor = ListVisitor() for handler in self.broker._subscribers: # pragma: no branch if visitor.visit(list=cmd.destination, sub=handler): - casted_handler = cast(_ListHandlerMixin, handler) + casted_handler = cast("_ListHandlerMixin", handler) if casted_handler.list_sub.batch: msg = visitor.get_message( diff --git a/tests/opentelemetry/basic.py b/tests/opentelemetry/basic.py index 9a8f4dd176..2b0396b8f7 100644 --- a/tests/opentelemetry/basic.py +++ b/tests/opentelemetry/basic.py @@ -55,8 +55,8 @@ def destination_name(self, queue: str) -> str: @staticmethod def get_spans(exporter: InMemorySpanExporter) -> list[Span]: - spans = cast(tuple[Span, ...], exporter.get_finished_spans()) - return sorted(spans, key=lambda s: s.start_time) + spans = cast("tuple[Span, ...]", exporter.get_finished_spans()) + return sorted(spans, key=lambda s: s.start_time or 0) @staticmethod def get_metrics( @@ -73,7 +73,7 @@ def get_metrics( metrics = reader.get_metrics_data() metrics = metrics.resource_metrics[0].scope_metrics[0].metrics metrics = sorted(metrics, key=lambda m: m.name) - return cast(list[Metric], metrics) + return cast("list[Metric]", metrics) @pytest.fixture() def tracer_provider(self) -> TracerProvider: From 7025d86a809951ffee2e8f52bd19a60619ccd46c Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Thu, 12 Dec 2024 00:00:08 +0300 Subject: [PATCH 225/245] lint: fix internal mypy --- faststream/_internal/_compat.py | 19 +++++++++---------- .../cli/supervisors/asgi_multiprocess.py | 9 ++++++++- faststream/_internal/fastapi/get_dependant.py | 4 ++-- faststream/_internal/state/broker.py | 14 +++++++++++++- .../_internal/state/logger/params_storage.py | 2 +- faststream/_internal/state/logger/state.py | 14 +++++++++++--- faststream/_internal/state/producer.py | 8 ++++++++ faststream/_internal/testing/broker.py | 2 +- 8 files changed, 53 insertions(+), 19 deletions(-) diff --git a/faststream/_internal/_compat.py b/faststream/_internal/_compat.py index 4dd403e02b..b515aaface 100644 --- a/faststream/_internal/_compat.py +++ b/faststream/_internal/_compat.py @@ -22,14 +22,6 @@ sys.platform == "win32" or sys.platform == "cygwin" or sys.platform == "msys" ) - -ModelVar = TypeVar("ModelVar", bound=BaseModel) - - -json_dumps: Callable[..., bytes] -orjson: Any -ujson: Any - __all__ = ( "HAS_TYPER", "PYDANTIC_V2", @@ -38,6 +30,7 @@ "EmailStr", "ExceptionGroup", "GetJsonSchemaHandler", + "PydanticUndefined", "json_dumps", "json_loads", "with_info_plain_validator_function", @@ -49,8 +42,12 @@ HAS_TYPER = False +json_dumps: Callable[..., bytes] +orjson: Any +ujson: Any + try: - import orjson + import orjson # type: ignore[no-redef] except ImportError: orjson = None @@ -76,6 +73,8 @@ def json_dumps(*a: Any, **kw: Any) -> bytes: return json.dumps(*a, **kw).encode() +ModelVar = TypeVar("ModelVar", bound=BaseModel) + JsonSchemaValue = Mapping[str, Any] major, minor, *_ = PYDANTIC_VERSION.split(".") _PYDANTCI_MAJOR, _PYDANTIC_MINOR = int(major), int(minor) @@ -113,7 +112,7 @@ def dump_json(data: Any) -> bytes: return json_dumps(model_to_jsonable(data)) def get_model_fields(model: type[BaseModel]) -> AnyDict: - return model.model_fields + return model.model_fields # type: ignore[return-value] def model_to_json(model: BaseModel, **kwargs: Any) -> str: return model.model_dump_json(**kwargs) diff --git a/faststream/_internal/cli/supervisors/asgi_multiprocess.py b/faststream/_internal/cli/supervisors/asgi_multiprocess.py index ac3a3e32aa..bcfba99010 100644 --- a/faststream/_internal/cli/supervisors/asgi_multiprocess.py +++ b/faststream/_internal/cli/supervisors/asgi_multiprocess.py @@ -1,11 +1,18 @@ import inspect +from typing import TYPE_CHECKING from faststream.asgi.app import cast_uvicorn_params +if TYPE_CHECKING: + from faststream._internal.basic_types import SettingField + class ASGIMultiprocess: def __init__( - self, target: str, args: tuple[str, dict[str, str], bool, int], workers: int + self, + target: str, + args: tuple[str, dict[str, "SettingField"], bool, int], + workers: int, ) -> None: _, uvicorn_kwargs, is_factory, log_level = args self._target = target diff --git a/faststream/_internal/fastapi/get_dependant.py b/faststream/_internal/fastapi/get_dependant.py index 172059c807..a53f33affd 100644 --- a/faststream/_internal/fastapi/get_dependant.py +++ b/faststream/_internal/fastapi/get_dependant.py @@ -121,9 +121,9 @@ def _patch_fastapi_dependent(dependant: "Dependant") -> "Dependant": ) dependant.custom_fields = {} # type: ignore[attr-defined] - dependant.flat_params = [ + dependant.flat_params = [ # type: ignore[attr-defined] OptionItem(field_name=name, field_type=type_, default_value=default) for name, (type_, default) in params_unique.items() - ] # type: ignore[attr-defined] + ] return dependant diff --git a/faststream/_internal/state/broker.py b/faststream/_internal/state/broker.py index 374b0e8c3b..c108beb037 100644 --- a/faststream/_internal/state/broker.py +++ b/faststream/_internal/state/broker.py @@ -32,13 +32,21 @@ def __init__(self, error_msg: str) -> None: self.producer = ProducerUnset() @property - def logger_state(self) -> "DIState": + def logger_state(self) -> "LoggerState": + raise IncorrectState(self.error_msg) + + @logger_state.setter + def logger_state(self, value: "LoggerState", /) -> None: raise IncorrectState(self.error_msg) @property def graceful_timeout(self) -> Optional[float]: raise IncorrectState(self.error_msg) + @graceful_timeout.setter + def graceful_timeout(self, value: Optional[float], /) -> None: + raise IncorrectState(self.error_msg) + def _setup(self) -> None: pass @@ -54,6 +62,10 @@ class EmptyBrokerState(_EmptyBrokerState): def di_state(self) -> "DIState": raise IncorrectState(self.error_msg) + @di_state.setter + def di_state(self, value: "DIState", /) -> None: + raise IncorrectState(self.error_msg) + class OuterBrokerState(_EmptyBrokerState): def __init__(self, *, di_state: "DIState") -> None: diff --git a/faststream/_internal/state/logger/params_storage.py b/faststream/_internal/state/logger/params_storage.py index ee12344a7a..c63e0b8e99 100644 --- a/faststream/_internal/state/logger/params_storage.py +++ b/faststream/_internal/state/logger/params_storage.py @@ -12,7 +12,7 @@ def make_logger_storage( logger: Optional["LoggerProto"], log_fmt: Optional[str], - default_storage_cls: type["LoggerParamsStorage"], + default_storage_cls: type["DefaultLoggerStorage"], ) -> "LoggerParamsStorage": if logger is EMPTY: return default_storage_cls(log_fmt) diff --git a/faststream/_internal/state/logger/state.py b/faststream/_internal/state/logger/state.py index 5cec93320a..7fd495e020 100644 --- a/faststream/_internal/state/logger/state.py +++ b/faststream/_internal/state/logger/state.py @@ -8,7 +8,11 @@ NotSetLoggerObject, RealLoggerObject, ) -from .params_storage import LoggerParamsStorage, make_logger_storage +from .params_storage import ( + DefaultLoggerStorage, + LoggerParamsStorage, + make_logger_storage, +) if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict, LoggerProto @@ -19,7 +23,7 @@ def make_logger_state( logger: Optional["LoggerProto"], log_level: int, log_fmt: Optional[str], - default_storage_cls: type["LoggerParamsStorage"], + default_storage_cls: type["DefaultLoggerStorage"], ) -> "LoggerState": storage = make_logger_storage( logger=logger, @@ -64,7 +68,11 @@ def log( exc_info=exc_info, ) - def _setup(self, *, context: "ContextRepo") -> None: + def _setup( # type: ignore[override] + self, + *, + context: "ContextRepo", + ) -> None: if not self.logger: if logger := self.params_storage.get_logger(context=context): self.logger = RealLoggerObject(logger) diff --git a/faststream/_internal/state/producer.py b/faststream/_internal/state/producer.py index d65cd4f205..30e6e6cf12 100644 --- a/faststream/_internal/state/producer.py +++ b/faststream/_internal/state/producer.py @@ -15,10 +15,18 @@ class ProducerUnset(ProducerProto): def _decoder(self) -> "AsyncCallable": raise IncorrectState(self.msg) + @_decoder.setter + def _decoder(self, value: "AsyncCallable", /) -> None: + raise IncorrectState(self.msg) + @property def _parser(self) -> "AsyncCallable": raise IncorrectState(self.msg) + @_parser.setter + def _parser(self, value: "AsyncCallable", /) -> None: + raise IncorrectState(self.msg) + async def publish(self, cmd: "PublishCommand") -> Optional[Any]: raise IncorrectState(self.msg) diff --git a/faststream/_internal/testing/broker.py b/faststream/_internal/testing/broker.py index ac57846c80..9994274f68 100644 --- a/faststream/_internal/testing/broker.py +++ b/faststream/_internal/testing/broker.py @@ -181,7 +181,7 @@ async def publisher_response_subscriber(msg: Any) -> None: for subscriber in broker._subscribers: subscriber.running = True - subscriber.lock = MultiLock() + subscriber.lock = MultiLock() # type: ignore[attr-defined] def _fake_close( self, From b84c032be03e383637a3df4c7898b897c906664f Mon Sep 17 00:00:00 2001 From: Artem-Safronov <140204604+Artem-Safronov@users.noreply.github.com> Date: Thu, 12 Dec 2024 07:21:06 +0300 Subject: [PATCH 226/245] feat: add application states (#1974) * feat: add application state * docs: generate API References --------- Co-authored-by: Artem-Safronov --- faststream/_internal/application.py | 32 ++++++++++++++++------- faststream/_internal/state/__init__.py | 3 +++ faststream/_internal/state/application.py | 28 ++++++++++++++++++++ tests/cli/test_app_state.py | 31 ++++++++++++++++++++++ 4 files changed, 85 insertions(+), 9 deletions(-) create mode 100644 faststream/_internal/state/application.py create mode 100644 tests/cli/test_app_state.py diff --git a/faststream/_internal/application.py b/faststream/_internal/application.py index 85e0ba43d0..5f9c523797 100644 --- a/faststream/_internal/application.py +++ b/faststream/_internal/application.py @@ -16,7 +16,11 @@ from faststream._internal.constants import EMPTY from faststream._internal.context import ContextRepo from faststream._internal.log import logger -from faststream._internal.state import DIState +from faststream._internal.state import ( + BasicApplicationState, + DIState, + RunningApplicationState, +) from faststream._internal.state.broker import OuterBrokerState from faststream._internal.utils import apply_types from faststream._internal.utils.functions import ( @@ -99,13 +103,15 @@ def _init_setupable_( # noqa: PLW3201 serializer = PydanticSerializer() - self._state = DIState( - use_fastdepends=True, - get_dependent=None, - call_decorators=(), - serializer=serializer, - provider=self.provider, - context=self.context, + self._state = BasicApplicationState( + di_state=DIState( + use_fastdepends=True, + get_dependent=None, + call_decorators=(), + serializer=serializer, + provider=self.provider, + context=self.context, + ) ) self.broker = broker @@ -113,7 +119,7 @@ def _init_setupable_( # noqa: PLW3201 self._setup() def _setup(self) -> None: - self.broker._setup(OuterBrokerState(di_state=self._state)) + self.broker._setup(OuterBrokerState(di_state=self._state.di_state)) async def _start_broker(self) -> None: await self.broker.start() @@ -188,6 +194,8 @@ async def _startup( async with self._startup_logging(log_level=log_level): await self.start(**(run_extra_options or {})) + self._state = RunningApplicationState(di_state=self._state.di_state) + async def start( self, **run_extra_options: "SettingField", @@ -235,6 +243,8 @@ async def _shutdown(self, log_level: int = logging.INFO) -> None: async with self._shutdown_logging(log_level=log_level): await self.stop() + self._state = BasicApplicationState(di_state=self._state.di_state) + async def stop(self) -> None: """Executes shutdown hooks and stop broker.""" async with self._shutdown_hooks_context(): @@ -318,3 +328,7 @@ def after_shutdown( apply_types(to_async(func), context__=self.context) ) return func + + @property + def running(self) -> bool: + return self._state.running diff --git a/faststream/_internal/state/__init__.py b/faststream/_internal/state/__init__.py index f65fc1cb63..47975c762b 100644 --- a/faststream/_internal/state/__init__.py +++ b/faststream/_internal/state/__init__.py @@ -1,3 +1,4 @@ +from .application import BasicApplicationState, RunningApplicationState from .broker import BrokerState, EmptyBrokerState from .fast_depends import DIState from .logger import LoggerParamsStorage, LoggerState @@ -6,6 +7,7 @@ __all__ = ( # state + "BasicApplicationState", "BrokerState", # FastDepend "DIState", @@ -14,6 +16,7 @@ # logging "LoggerState", "Pointer", + "RunningApplicationState", # proto "SetupAble", ) diff --git a/faststream/_internal/state/application.py b/faststream/_internal/state/application.py new file mode 100644 index 0000000000..e63aa3be29 --- /dev/null +++ b/faststream/_internal/state/application.py @@ -0,0 +1,28 @@ +from abc import ABC, abstractmethod + +from faststream._internal.state.fast_depends import DIState + + +class ApplicationState(ABC): + def __init__(self, di_state: DIState) -> None: + self._di_state = di_state + + @property + @abstractmethod + def running(self) -> bool: ... + + @property + def di_state(self) -> DIState: + return self._di_state + + +class BasicApplicationState(ApplicationState): + @property + def running(self) -> bool: + return False + + +class RunningApplicationState(ApplicationState): + @property + def running(self) -> bool: + return True diff --git a/tests/cli/test_app_state.py b/tests/cli/test_app_state.py new file mode 100644 index 0000000000..9896b8839a --- /dev/null +++ b/tests/cli/test_app_state.py @@ -0,0 +1,31 @@ +from unittest.mock import AsyncMock, patch + +import pytest + +from faststream import FastStream + + +@pytest.mark.asyncio() +async def test_state_running(app: FastStream) -> None: + with patch( + "faststream._internal.application.Application.start", new_callable=AsyncMock + ): + await app._startup() + + assert app.running + + +@pytest.mark.asyncio() +async def test_state_stopped(app: FastStream) -> None: + with ( + patch( + "faststream._internal.application.Application.start", new_callable=AsyncMock + ), + patch( + "faststream._internal.application.Application.stop", new_callable=AsyncMock + ), + ): + await app._startup() + await app._shutdown() + + assert not app.running From cddf8de1af84694d339b2f1408eb122f3ee91d2c Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Thu, 12 Dec 2024 07:26:39 +0300 Subject: [PATCH 227/245] fix: correct FastAPI with new state --- faststream/_internal/application.py | 17 +++++++++-------- faststream/_internal/fastapi/router.py | 2 +- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/faststream/_internal/application.py b/faststream/_internal/application.py index 5f9c523797..4f670ffd85 100644 --- a/faststream/_internal/application.py +++ b/faststream/_internal/application.py @@ -16,9 +16,10 @@ from faststream._internal.constants import EMPTY from faststream._internal.context import ContextRepo from faststream._internal.log import logger -from faststream._internal.state import ( +from faststream._internal.state import DIState +from faststream._internal.state.application import ( + ApplicationState, BasicApplicationState, - DIState, RunningApplicationState, ) from faststream._internal.state.broker import OuterBrokerState @@ -103,7 +104,7 @@ def _init_setupable_( # noqa: PLW3201 serializer = PydanticSerializer() - self._state = BasicApplicationState( + self._state: ApplicationState = BasicApplicationState( di_state=DIState( use_fastdepends=True, get_dependent=None, @@ -171,6 +172,10 @@ def __init__( else: self.lifespan_context = fake_context + @property + def running(self) -> bool: + return self._state.running + @abstractmethod def exit(self) -> None: """Stop application manually.""" @@ -278,7 +283,7 @@ async def _shutdown_logging( "FastStream app shut down gracefully.", ) - # Setvice methods + # Service methods def _log(self, level: int, message: str) -> None: if self.logger is not None: @@ -328,7 +333,3 @@ def after_shutdown( apply_types(to_async(func), context__=self.context) ) return func - - @property - def running(self) -> bool: - return self._state.running diff --git a/faststream/_internal/fastapi/router.py b/faststream/_internal/fastapi/router.py index 8b2c8432fc..9451503045 100644 --- a/faststream/_internal/fastapi/router.py +++ b/faststream/_internal/fastapi/router.py @@ -235,7 +235,7 @@ def wrapper( response_model_exclude_defaults=response_model_exclude_defaults, response_model_exclude_none=response_model_exclude_none, provider_factory=self._get_dependencies_overides_provider, - state=self._state, + state=self._state.di_state, ) return wrapper From c032ecfebd5ab3981af4b35c646d49a63673e5a2 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Fri, 13 Dec 2024 18:52:18 +0300 Subject: [PATCH 228/245] tests: refactor publish js frame test --- tests/brokers/nats/test_consume.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/tests/brokers/nats/test_consume.py b/tests/brokers/nats/test_consume.py index 18fb87c818..f03daaec4c 100644 --- a/tests/brokers/nats/test_consume.py +++ b/tests/brokers/nats/test_consume.py @@ -75,22 +75,17 @@ def subscriber(m) -> None: async with self.patch_broker(consume_broker) as br: await br.start() - completed, _ = await asyncio.wait( - ( - asyncio.create_task(br.publish("hello", queue, stream=stream.name)), - asyncio.create_task(event.wait()), - ), + + result = await br.publish("hello", queue, stream=stream.name) + + await asyncio.wait( + (asyncio.create_task(event.wait()),), timeout=3, ) - publish_with_stream_returns_ack_frame = False - for task in completed: - if isinstance(task.result(), PubAck): - publish_with_stream_returns_ack_frame = True - break + assert isinstance(result, PubAck), result assert event.is_set() - assert publish_with_stream_returns_ack_frame async def test_consume_with_filter( self, From acf1d8c436030a0b524751bc4f974b73e215f747 Mon Sep 17 00:00:00 2001 From: Spataphore <93342746+spataphore1337@users.noreply.github.com> Date: Sat, 14 Dec 2024 13:35:02 +0300 Subject: [PATCH 229/245] feat: make return RecordMetada if not no_confirm, change annotations and convert Doc to doc string. (#1983) * feat: change returns kafka publish, change annotation and convert Doc to doc string * docs: generate API References * delete docs * change annotations on broker publish and publish_batch * add tests and use lint.sh --------- Co-authored-by: spataphore1337 --- docs/docs/en/api/faststream/AckPolicy.md | 11 - docs/docs/en/api/faststream/BaseMiddleware.md | 11 - docs/docs/en/api/faststream/Context.md | 11 - docs/docs/en/api/faststream/Depends.md | 11 - .../en/api/faststream/ExceptionMiddleware.md | 11 - docs/docs/en/api/faststream/FastStream.md | 11 - docs/docs/en/api/faststream/Header.md | 11 - docs/docs/en/api/faststream/Path.md | 11 - docs/docs/en/api/faststream/Response.md | 11 - docs/docs/en/api/faststream/TestApp.md | 11 - docs/docs/en/api/faststream/app/FastStream.md | 11 - docs/docs/en/api/faststream/apply_types.md | 11 - .../en/api/faststream/asgi/AsgiFastStream.md | 11 - .../en/api/faststream/asgi/AsgiResponse.md | 11 - .../api/faststream/asgi/app/AsgiFastStream.md | 11 - .../en/api/faststream/asgi/app/CliRunState.md | 11 - .../api/faststream/asgi/app/OuterRunState.md | 11 - .../en/api/faststream/asgi/app/ServerState.md | 11 - .../asgi/app/cast_uvicorn_params.md | 11 - .../asgi/factories/make_asyncapi_asgi.md | 11 - .../asgi/factories/make_ping_asgi.md | 11 - docs/docs/en/api/faststream/asgi/get.md | 11 - .../en/api/faststream/asgi/handlers/get.md | 11 - .../api/faststream/asgi/make_asyncapi_asgi.md | 11 - .../en/api/faststream/asgi/make_ping_asgi.md | 11 - .../faststream/asgi/response/AsgiResponse.md | 11 - .../asgi/websocket/WebSocketClose.md | 11 - .../api/faststream/confluent/KafkaBroker.md | 11 - .../faststream/confluent/KafkaPublisher.md | 11 - .../api/faststream/confluent/KafkaResponse.md | 11 - .../en/api/faststream/confluent/KafkaRoute.md | 11 - .../api/faststream/confluent/KafkaRouter.md | 11 - .../en/api/faststream/confluent/TestApp.md | 11 - .../faststream/confluent/TestKafkaBroker.md | 11 - .../faststream/confluent/TopicPartition.md | 11 - .../confluent/broker/KafkaBroker.md | 11 - .../confluent/broker/broker/KafkaBroker.md | 11 - .../broker/logging/KafkaParamsStorage.md | 11 - .../broker/registrator/KafkaRegistrator.md | 11 - .../client/AsyncConfluentConsumer.md | 11 - .../client/AsyncConfluentProducer.md | 11 - .../confluent/client/BatchBuilder.md | 11 - .../confluent/client/check_msg_error.md | 11 - .../confluent/client/create_topics.md | 11 - .../confluent/config/BrokerAddressFamily.md | 11 - .../confluent/config/BuiltinFeatures.md | 11 - .../confluent/config/ClientDNSLookup.md | 11 - .../confluent/config/CompressionCodec.md | 11 - .../confluent/config/CompressionType.md | 11 - .../confluent/config/ConfluentConfig.md | 11 - .../confluent/config/ConfluentFastConfig.md | 11 - .../api/faststream/confluent/config/Debug.md | 11 - .../confluent/config/GroupProtocol.md | 11 - .../confluent/config/IsolationLevel.md | 11 - .../confluent/config/OffsetStoreMethod.md | 11 - .../confluent/config/SASLOAUTHBearerMethod.md | 11 - .../confluent/config/SecurityProtocol.md | 11 - .../faststream/confluent/fastapi/Context.md | 11 - .../confluent/fastapi/KafkaRouter.md | 11 - .../confluent/fastapi/fastapi/KafkaRouter.md | 11 - .../confluent/message/ConsumerProtocol.md | 11 - .../confluent/message/FakeConsumer.md | 11 - .../confluent/message/KafkaMessage.md | 11 - .../opentelemetry/KafkaTelemetryMiddleware.md | 11 - .../middleware/KafkaTelemetryMiddleware.md | 11 - .../BaseConfluentTelemetrySettingsProvider.md | 11 - ...BatchConfluentTelemetrySettingsProvider.md | 11 - .../ConfluentTelemetrySettingsProvider.md | 11 - .../telemetry_attributes_provider_factory.md | 11 - .../confluent/parser/AsyncConfluentParser.md | 11 - .../prometheus/KafkaPrometheusMiddleware.md | 11 - .../middleware/KafkaPrometheusMiddleware.md | 11 - .../BaseConfluentMetricsSettingsProvider.md | 11 - .../BatchConfluentMetricsSettingsProvider.md | 11 - .../ConfluentMetricsSettingsProvider.md | 11 - .../provider/settings_provider_factory.md | 11 - .../publisher/factory/create_publisher.md | 11 - .../publisher/fake/KafkaFakePublisher.md | 11 - .../producer/AsyncConfluentFastProducer.md | 11 - .../specified/SpecificationBatchPublisher.md | 11 - .../SpecificationDefaultPublisher.md | 11 - .../specified/SpecificationPublisher.md | 11 - .../publisher/state/EmptyProducerState.md | 11 - .../publisher/state/ProducerState.md | 11 - .../confluent/publisher/state/RealProducer.md | 11 - .../publisher/usecase/BatchPublisher.md | 11 - .../publisher/usecase/DefaultPublisher.md | 11 - .../publisher/usecase/LogicPublisher.md | 11 - .../confluent/response/KafkaPublishCommand.md | 11 - .../confluent/response/KafkaResponse.md | 11 - .../confluent/router/KafkaPublisher.md | 11 - .../faststream/confluent/router/KafkaRoute.md | 11 - .../confluent/router/KafkaRouter.md | 11 - .../confluent/schemas/TopicPartition.md | 11 - .../params/ConsumerConnectionParams.md | 11 - .../schemas/partition/TopicPartition.md | 11 - .../confluent/security/parse_security.md | 11 - .../subscriber/factory/create_subscriber.md | 11 - .../specified/SpecificationBatchSubscriber.md | 11 - ...pecificationConcurrentDefaultSubscriber.md | 11 - .../SpecificationDefaultSubscriber.md | 11 - .../specified/SpecificationSubscriber.md | 11 - .../subscriber/usecase/BatchSubscriber.md | 11 - .../usecase/ConcurrentDefaultSubscriber.md | 11 - .../subscriber/usecase/DefaultSubscriber.md | 11 - .../subscriber/usecase/LogicSubscriber.md | 11 - .../confluent/testing/FakeProducer.md | 11 - .../confluent/testing/MockConfluentMessage.md | 11 - .../confluent/testing/TestKafkaBroker.md | 11 - .../confluent/testing/build_message.md | 11 - .../api/faststream/exceptions/AckMessage.md | 11 - .../api/faststream/exceptions/ContextError.md | 11 - .../exceptions/FastStreamException.md | 11 - .../FeatureNotSupportedException.md | 11 - .../faststream/exceptions/HandlerException.md | 11 - .../faststream/exceptions/IgnoredException.md | 11 - .../faststream/exceptions/IncorrectState.md | 11 - .../api/faststream/exceptions/NackMessage.md | 11 - .../faststream/exceptions/RejectMessage.md | 11 - .../api/faststream/exceptions/SetupError.md | 11 - .../api/faststream/exceptions/SkipMessage.md | 11 - .../exceptions/StartupValidationError.md | 11 - .../faststream/exceptions/StopApplication.md | 11 - .../api/faststream/exceptions/StopConsume.md | 11 - .../exceptions/SubscriberNotFound.md | 11 - .../en/api/faststream/kafka/KafkaBroker.md | 11 - .../en/api/faststream/kafka/KafkaPublisher.md | 11 - .../en/api/faststream/kafka/KafkaResponse.md | 11 - .../en/api/faststream/kafka/KafkaRoute.md | 11 - .../en/api/faststream/kafka/KafkaRouter.md | 11 - docs/docs/en/api/faststream/kafka/TestApp.md | 11 - .../api/faststream/kafka/TestKafkaBroker.md | 11 - .../en/api/faststream/kafka/TopicPartition.md | 11 - .../faststream/kafka/broker/KafkaBroker.md | 11 - .../kafka/broker/broker/KafkaBroker.md | 11 - .../broker/logging/KafkaParamsStorage.md | 11 - .../broker/registrator/KafkaRegistrator.md | 11 - .../api/faststream/kafka/fastapi/Context.md | 11 - .../faststream/kafka/fastapi/KafkaRouter.md | 11 - .../kafka/fastapi/fastapi/KafkaRouter.md | 11 - .../kafka/message/ConsumerProtocol.md | 11 - .../faststream/kafka/message/FakeConsumer.md | 11 - .../kafka/message/KafkaAckableMessage.md | 11 - .../faststream/kafka/message/KafkaMessage.md | 11 - .../opentelemetry/KafkaTelemetryMiddleware.md | 11 - .../middleware/KafkaTelemetryMiddleware.md | 11 - .../BaseKafkaTelemetrySettingsProvider.md | 11 - .../BatchKafkaTelemetrySettingsProvider.md | 11 - .../KafkaTelemetrySettingsProvider.md | 11 - .../telemetry_attributes_provider_factory.md | 11 - .../kafka/parser/AioKafkaBatchParser.md | 11 - .../faststream/kafka/parser/AioKafkaParser.md | 11 - .../prometheus/KafkaPrometheusMiddleware.md | 11 - .../middleware/KafkaPrometheusMiddleware.md | 11 - .../BaseKafkaMetricsSettingsProvider.md | 11 - .../BatchKafkaMetricsSettingsProvider.md | 11 - .../provider/KafkaMetricsSettingsProvider.md | 11 - .../provider/settings_provider_factory.md | 11 - .../publisher/factory/create_publisher.md | 11 - .../publisher/fake/KafkaFakePublisher.md | 11 - .../producer/AioKafkaFastProducer.md | 11 - .../specified/SpecificationBatchPublisher.md | 11 - .../SpecificationDefaultPublisher.md | 11 - .../specified/SpecificationPublisher.md | 11 - .../publisher/state/EmptyProducerState.md | 11 - .../kafka/publisher/state/ProducerState.md | 11 - .../kafka/publisher/state/RealProducer.md | 11 - .../kafka/publisher/usecase/BatchPublisher.md | 11 - .../publisher/usecase/DefaultPublisher.md | 11 - .../kafka/publisher/usecase/LogicPublisher.md | 11 - .../kafka/response/KafkaPublishCommand.md | 11 - .../kafka/response/KafkaResponse.md | 11 - .../faststream/kafka/router/KafkaPublisher.md | 11 - .../api/faststream/kafka/router/KafkaRoute.md | 11 - .../faststream/kafka/router/KafkaRouter.md | 11 - .../params/ConsumerConnectionParams.md | 11 - .../kafka/security/parse_security.md | 11 - .../subscriber/factory/create_subscriber.md | 11 - .../specified/SpecificationBatchSubscriber.md | 11 - ...pecificationConcurrentDefaultSubscriber.md | 11 - .../SpecificationDefaultSubscriber.md | 11 - .../specified/SpecificationSubscriber.md | 11 - .../subscriber/usecase/BatchSubscriber.md | 11 - .../usecase/ConcurrentDefaultSubscriber.md | 11 - .../subscriber/usecase/DefaultSubscriber.md | 11 - .../subscriber/usecase/LogicSubscriber.md | 11 - .../faststream/kafka/testing/FakeProducer.md | 11 - .../kafka/testing/TestKafkaBroker.md | 11 - .../faststream/kafka/testing/build_message.md | 11 - .../en/api/faststream/message/AckStatus.md | 11 - .../en/api/faststream/message/SourceType.md | 11 - .../api/faststream/message/StreamMessage.md | 11 - .../api/faststream/message/decode_message.md | 11 - .../api/faststream/message/encode_message.md | 11 - .../en/api/faststream/message/gen_cor_id.md | 11 - .../faststream/message/message/AckStatus.md | 11 - .../message/message/StreamMessage.md | 11 - .../message/source_type/SourceType.md | 11 - .../message/utils/decode_message.md | 11 - .../message/utils/encode_message.md | 11 - .../faststream/message/utils/gen_cor_id.md | 11 - .../api/faststream/middlewares/AckPolicy.md | 11 - .../middlewares/AcknowledgementMiddleware.md | 11 - .../faststream/middlewares/BaseMiddleware.md | 11 - .../middlewares/ExceptionMiddleware.md | 11 - .../acknowledgement/conf/AckPolicy.md | 11 - .../middleware/AcknowledgementMiddleware.md | 11 - .../middlewares/base/BaseMiddleware.md | 11 - .../exception/ExceptionMiddleware.md | 11 - .../middlewares/exception/ignore_handler.md | 11 - .../logging/CriticalLogMiddleware.md | 11 - docs/docs/en/api/faststream/nats/AckPolicy.md | 11 - .../en/api/faststream/nats/ConsumerConfig.md | 11 - .../en/api/faststream/nats/DeliverPolicy.md | 11 - .../en/api/faststream/nats/DiscardPolicy.md | 11 - .../en/api/faststream/nats/ExternalStream.md | 11 - docs/docs/en/api/faststream/nats/JStream.md | 11 - docs/docs/en/api/faststream/nats/KvWatch.md | 11 - .../docs/en/api/faststream/nats/NatsBroker.md | 11 - .../en/api/faststream/nats/NatsPublisher.md | 11 - .../en/api/faststream/nats/NatsResponse.md | 11 - docs/docs/en/api/faststream/nats/NatsRoute.md | 11 - .../docs/en/api/faststream/nats/NatsRouter.md | 11 - docs/docs/en/api/faststream/nats/ObjWatch.md | 11 - docs/docs/en/api/faststream/nats/Placement.md | 11 - docs/docs/en/api/faststream/nats/PubAck.md | 11 - docs/docs/en/api/faststream/nats/PullSub.md | 11 - docs/docs/en/api/faststream/nats/RePublish.md | 11 - .../en/api/faststream/nats/ReplayPolicy.md | 11 - .../en/api/faststream/nats/RetentionPolicy.md | 11 - .../en/api/faststream/nats/StorageType.md | 11 - .../en/api/faststream/nats/StreamConfig.md | 11 - .../en/api/faststream/nats/StreamSource.md | 11 - docs/docs/en/api/faststream/nats/TestApp.md | 11 - .../en/api/faststream/nats/TestNatsBroker.md | 11 - .../api/faststream/nats/broker/NatsBroker.md | 11 - .../nats/broker/broker/NatsBroker.md | 11 - .../nats/broker/logging/NatsParamsStorage.md | 11 - .../broker/registrator/NatsRegistrator.md | 11 - .../nats/broker/state/BrokerState.md | 11 - .../nats/broker/state/ConnectedState.md | 11 - .../broker/state/ConnectionBrokenState.md | 11 - .../nats/broker/state/EmptyBrokerState.md | 11 - .../en/api/faststream/nats/fastapi/Context.md | 11 - .../api/faststream/nats/fastapi/NatsRouter.md | 11 - .../nats/fastapi/fastapi/NatsRouter.md | 11 - .../nats/helpers/KVBucketDeclarer.md | 11 - .../nats/helpers/OSBucketDeclarer.md | 11 - .../faststream/nats/helpers/StreamBuilder.md | 11 - .../bucket_declarer/KVBucketDeclarer.md | 11 - .../obj_storage_declarer/OSBucketDeclarer.md | 11 - .../helpers/object_builder/StreamBuilder.md | 11 - .../nats/helpers/state/ConnectedState.md | 11 - .../nats/helpers/state/ConnectionState.md | 11 - .../helpers/state/EmptyConnectionState.md | 11 - .../nats/message/NatsBatchMessage.md | 11 - .../faststream/nats/message/NatsKvMessage.md | 11 - .../faststream/nats/message/NatsMessage.md | 11 - .../faststream/nats/message/NatsObjMessage.md | 11 - .../opentelemetry/NatsTelemetryMiddleware.md | 11 - .../middleware/NatsTelemetryMiddleware.md | 11 - .../BaseNatsTelemetrySettingsProvider.md | 11 - .../NatsBatchTelemetrySettingsProvider.md | 11 - .../provider/NatsTelemetrySettingsProvider.md | 11 - .../telemetry_attributes_provider_factory.md | 11 - .../api/faststream/nats/parser/BatchParser.md | 11 - .../en/api/faststream/nats/parser/JsParser.md | 11 - .../en/api/faststream/nats/parser/KvParser.md | 11 - .../faststream/nats/parser/NatsBaseParser.md | 11 - .../api/faststream/nats/parser/NatsParser.md | 11 - .../api/faststream/nats/parser/ObjParser.md | 11 - .../prometheus/NatsPrometheusMiddleware.md | 11 - .../middleware/NatsPrometheusMiddleware.md | 11 - .../BaseNatsMetricsSettingsProvider.md | 11 - .../BatchNatsMetricsSettingsProvider.md | 11 - .../provider/NatsMetricsSettingsProvider.md | 11 - .../provider/settings_provider_factory.md | 11 - .../publisher/factory/create_publisher.md | 11 - .../nats/publisher/fake/NatsFakePublisher.md | 11 - .../publisher/producer/NatsFastProducer.md | 11 - .../publisher/producer/NatsJSFastProducer.md | 11 - .../specified/SpecificationPublisher.md | 11 - .../nats/publisher/usecase/LogicPublisher.md | 11 - .../nats/response/NatsPublishCommand.md | 11 - .../faststream/nats/response/NatsResponse.md | 11 - .../faststream/nats/router/NatsPublisher.md | 11 - .../api/faststream/nats/router/NatsRoute.md | 11 - .../api/faststream/nats/router/NatsRouter.md | 11 - .../en/api/faststream/nats/schemas/JStream.md | 11 - .../en/api/faststream/nats/schemas/KvWatch.md | 11 - .../api/faststream/nats/schemas/ObjWatch.md | 11 - .../en/api/faststream/nats/schemas/PubAck.md | 11 - .../en/api/faststream/nats/schemas/PullSub.md | 11 - .../nats/schemas/js_stream/JStream.md | 11 - .../js_stream/compile_nats_wildcard.md | 11 - .../js_stream/is_subject_match_wildcard.md | 11 - .../nats/schemas/kv_watch/KvWatch.md | 11 - .../nats/schemas/obj_watch/ObjWatch.md | 11 - .../nats/schemas/pull_sub/PullSub.md | 11 - .../nats/security/parse_security.md | 11 - .../subscriber/adapters/UnsubscribeAdapter.md | 11 - .../subscriber/adapters/Unsubscriptable.md | 11 - .../nats/subscriber/adapters/Watchable.md | 11 - .../subscriber/factory/create_subscriber.md | 11 - .../SpecificationBatchPullStreamSubscriber.md | 11 - .../SpecificationConcurrentCoreSubscriber.md | 11 - ...ificationConcurrentPullStreamSubscriber.md | 11 - ...ificationConcurrentPushStreamSubscriber.md | 11 - .../specified/SpecificationCoreSubscriber.md | 11 - .../SpecificationKeyValueWatchSubscriber.md | 11 - .../SpecificationObjStoreWatchSubscriber.md | 11 - .../SpecificationPullStreamSubscriber.md | 11 - .../SpecificationPushStreamSubscriber.md | 11 - .../specified/SpecificationSubscriber.md | 11 - .../state/ConnectedSubscriberState.md | 11 - .../subscriber/state/EmptySubscriberState.md | 11 - .../nats/subscriber/state/SubscriberState.md | 11 - .../usecases/BatchPullStreamSubscriber.md | 11 - .../usecases/ConcurrentCoreSubscriber.md | 11 - .../ConcurrentPullStreamSubscriber.md | 11 - .../ConcurrentPushStreamSubscriber.md | 11 - .../subscriber/usecases/CoreSubscriber.md | 11 - .../usecases/KeyValueWatchSubscriber.md | 11 - .../subscriber/usecases/LogicSubscriber.md | 11 - .../usecases/ObjStoreWatchSubscriber.md | 11 - .../usecases/PullStreamSubscriber.md | 11 - .../usecases/PushStreamSubscription.md | 11 - .../usecases/basic/DefaultSubscriber.md | 11 - .../usecases/basic/LogicSubscriber.md | 11 - .../ConcurrentCoreSubscriber.md | 11 - .../core_subscriber/CoreSubscriber.md | 11 - .../KeyValueWatchSubscriber.md | 11 - .../ObjStoreWatchSubscriber.md | 11 - .../usecases/stream_basic/StreamSubscriber.md | 11 - .../BatchPullStreamSubscriber.md | 11 - .../ConcurrentPullStreamSubscriber.md | 11 - .../PullStreamSubscriber.md | 11 - .../ConcurrentPushStreamSubscriber.md | 11 - .../PushStreamSubscription.md | 11 - .../faststream/nats/testing/FakeProducer.md | 11 - .../faststream/nats/testing/PatchedMessage.md | 11 - .../faststream/nats/testing/TestNatsBroker.md | 11 - .../faststream/nats/testing/build_message.md | 11 - .../api/faststream/opentelemetry/Baggage.md | 11 - .../opentelemetry/TelemetryMiddleware.md | 11 - .../TelemetrySettingsProvider.md | 11 - .../opentelemetry/baggage/Baggage.md | 11 - .../opentelemetry/consts/MessageAction.md | 11 - .../middleware/BaseTelemetryMiddleware.md | 11 - .../middleware/TelemetryMiddleware.md | 11 - .../provider/TelemetrySettingsProvider.md | 11 - docs/docs/en/api/faststream/params/Context.md | 11 - docs/docs/en/api/faststream/params/Depends.md | 11 - docs/docs/en/api/faststream/params/Header.md | 11 - docs/docs/en/api/faststream/params/Path.md | 11 - .../faststream/params/no_cast/NoCastField.md | 11 - .../api/faststream/params/params/Context.md | 11 - .../en/api/faststream/params/params/Header.md | 11 - .../en/api/faststream/params/params/Path.md | 11 - .../api/faststream/prometheus/ConsumeAttrs.md | 11 - .../prometheus/MetricsSettingsProvider.md | 11 - .../prometheus/PrometheusMiddleware.md | 11 - .../prometheus/container/MetricsContainer.md | 11 - .../prometheus/manager/MetricsManager.md | 11 - .../middleware/BasePrometheusMiddleware.md | 11 - .../middleware/PrometheusMiddleware.md | 11 - .../provider/MetricsSettingsProvider.md | 11 - .../prometheus/types/ConsumeAttrs.md | 11 - .../prometheus/types/ProcessingStatus.md | 11 - .../prometheus/types/PublishingStatus.md | 11 - .../en/api/faststream/rabbit/ExchangeType.md | 11 - .../en/api/faststream/rabbit/RabbitBroker.md | 11 - .../api/faststream/rabbit/RabbitExchange.md | 11 - .../api/faststream/rabbit/RabbitPublisher.md | 11 - .../en/api/faststream/rabbit/RabbitQueue.md | 11 - .../api/faststream/rabbit/RabbitResponse.md | 11 - .../en/api/faststream/rabbit/RabbitRoute.md | 11 - .../en/api/faststream/rabbit/RabbitRouter.md | 11 - docs/docs/en/api/faststream/rabbit/TestApp.md | 11 - .../api/faststream/rabbit/TestRabbitBroker.md | 11 - .../faststream/rabbit/broker/RabbitBroker.md | 11 - .../rabbit/broker/broker/RabbitBroker.md | 11 - .../broker/logging/RabbitParamsStorage.md | 11 - .../broker/registrator/RabbitRegistrator.md | 11 - .../api/faststream/rabbit/fastapi/Context.md | 11 - .../faststream/rabbit/fastapi/RabbitRouter.md | 11 - .../rabbit/fastapi/fastapi/RabbitRouter.md | 11 - .../rabbit/helpers/declarer/RabbitDeclarer.md | 11 - .../rabbit/helpers/state/ConnectedState.md | 11 - .../rabbit/helpers/state/ConnectionState.md | 11 - .../helpers/state/EmptyConnectionState.md | 11 - .../rabbit/message/RabbitMessage.md | 11 - .../RabbitTelemetryMiddleware.md | 11 - .../middleware/RabbitTelemetryMiddleware.md | 11 - .../RabbitTelemetrySettingsProvider.md | 11 - .../faststream/rabbit/parser/AioPikaParser.md | 11 - .../prometheus/RabbitPrometheusMiddleware.md | 11 - .../middleware/RabbitPrometheusMiddleware.md | 11 - .../provider/RabbitMetricsSettingsProvider.md | 11 - .../publisher/factory/create_publisher.md | 11 - .../publisher/fake/RabbitFakePublisher.md | 11 - .../publisher/options/MessageOptions.md | 11 - .../publisher/options/PublishOptions.md | 11 - .../publisher/producer/AioPikaFastProducer.md | 11 - .../rabbit/publisher/producer/LockState.md | 11 - .../rabbit/publisher/producer/LockUnset.md | 11 - .../rabbit/publisher/producer/RealLock.md | 11 - .../specified/SpecificationPublisher.md | 11 - .../publisher/usecase/LogicPublisher.md | 11 - .../rabbit/publisher/usecase/PublishKwargs.md | 11 - .../publisher/usecase/RequestPublishKwargs.md | 11 - .../rabbit/response/RabbitPublishCommand.md | 11 - .../rabbit/response/RabbitResponse.md | 11 - .../rabbit/router/RabbitPublisher.md | 11 - .../faststream/rabbit/router/RabbitRoute.md | 11 - .../faststream/rabbit/router/RabbitRouter.md | 11 - .../rabbit/schemas/BaseRMQInformation.md | 11 - .../faststream/rabbit/schemas/ExchangeType.md | 11 - .../rabbit/schemas/RabbitExchange.md | 11 - .../faststream/rabbit/schemas/RabbitQueue.md | 11 - .../rabbit/schemas/constants/ExchangeType.md | 11 - .../rabbit/schemas/exchange/RabbitExchange.md | 11 - .../schemas/proto/BaseRMQInformation.md | 11 - .../rabbit/schemas/queue/RabbitQueue.md | 11 - .../rabbit/security/parse_security.md | 11 - .../subscriber/factory/create_subscriber.md | 11 - .../specified/SpecificationSubscriber.md | 11 - .../subscriber/usecase/LogicSubscriber.md | 11 - .../faststream/rabbit/testing/FakeProducer.md | 11 - .../rabbit/testing/PatchedMessage.md | 11 - .../rabbit/testing/TestRabbitBroker.md | 11 - .../rabbit/testing/apply_pattern.md | 11 - .../rabbit/testing/build_message.md | 11 - .../api/faststream/rabbit/utils/build_url.md | 11 - .../rabbit/utils/is_routing_exchange.md | 11 - docs/docs/en/api/faststream/redis/ListSub.md | 11 - docs/docs/en/api/faststream/redis/PubSub.md | 11 - .../en/api/faststream/redis/RedisBroker.md | 11 - .../en/api/faststream/redis/RedisPublisher.md | 11 - .../en/api/faststream/redis/RedisResponse.md | 11 - .../en/api/faststream/redis/RedisRoute.md | 11 - .../en/api/faststream/redis/RedisRouter.md | 11 - .../docs/en/api/faststream/redis/StreamSub.md | 11 - docs/docs/en/api/faststream/redis/TestApp.md | 11 - .../api/faststream/redis/TestRedisBroker.md | 11 - .../redis/broker/broker/RedisBroker.md | 11 - .../broker/logging/RedisParamsStorage.md | 11 - .../broker/registrator/RedisRegistrator.md | 11 - .../api/faststream/redis/fastapi/Context.md | 11 - .../faststream/redis/fastapi/RedisRouter.md | 11 - .../redis/fastapi/fastapi/RedisRouter.md | 11 - .../redis/helpers/state/ConnectedState.md | 11 - .../redis/helpers/state/ConnectionState.md | 11 - .../helpers/state/EmptyConnectionState.md | 11 - .../redis/message/BatchListMessage.md | 11 - .../redis/message/BatchStreamMessage.md | 11 - .../redis/message/DefaultListMessage.md | 11 - .../redis/message/DefaultStreamMessage.md | 11 - .../faststream/redis/message/PubSubMessage.md | 11 - .../redis/message/RedisBatchListMessage.md | 11 - .../redis/message/RedisBatchStreamMessage.md | 11 - .../redis/message/RedisListMessage.md | 11 - .../faststream/redis/message/RedisMessage.md | 11 - .../redis/message/RedisStreamMessage.md | 11 - .../redis/message/UnifyRedisDict.md | 11 - .../redis/message/UnifyRedisMessage.md | 11 - .../opentelemetry/RedisTelemetryMiddleware.md | 11 - .../middleware/RedisTelemetryMiddleware.md | 11 - .../RedisTelemetrySettingsProvider.md | 11 - .../api/faststream/redis/parser/RawMessage.md | 11 - .../redis/parser/RedisBatchListParser.md | 11 - .../redis/parser/RedisBatchStreamParser.md | 11 - .../redis/parser/RedisListParser.md | 11 - .../redis/parser/RedisPubSubParser.md | 11 - .../redis/parser/RedisStreamParser.md | 11 - .../faststream/redis/parser/SimpleParser.md | 11 - .../prometheus/RedisPrometheusMiddleware.md | 11 - .../middleware/RedisPrometheusMiddleware.md | 11 - .../BaseRedisMetricsSettingsProvider.md | 11 - .../BatchRedisMetricsSettingsProvider.md | 11 - .../provider/RedisMetricsSettingsProvider.md | 11 - .../provider/settings_provider_factory.md | 11 - .../publisher/factory/create_publisher.md | 11 - .../publisher/fake/RedisFakePublisher.md | 11 - .../publisher/producer/RedisFastProducer.md | 11 - .../SpecificationChannelPublisher.md | 11 - .../SpecificationListBatchPublisher.md | 11 - .../specified/SpecificationListPublisher.md | 11 - .../specified/SpecificationPublisher.md | 11 - .../specified/SpecificationStreamPublisher.md | 11 - .../publisher/usecase/ChannelPublisher.md | 11 - .../publisher/usecase/ListBatchPublisher.md | 11 - .../redis/publisher/usecase/ListPublisher.md | 11 - .../redis/publisher/usecase/LogicPublisher.md | 11 - .../publisher/usecase/StreamPublisher.md | 11 - .../redis/response/DestinationType.md | 11 - .../redis/response/RedisPublishCommand.md | 11 - .../redis/response/RedisResponse.md | 11 - .../faststream/redis/router/RedisPublisher.md | 11 - .../api/faststream/redis/router/RedisRoute.md | 11 - .../faststream/redis/router/RedisRouter.md | 11 - .../api/faststream/redis/schemas/ListSub.md | 11 - .../en/api/faststream/redis/schemas/PubSub.md | 11 - .../api/faststream/redis/schemas/StreamSub.md | 11 - .../redis/schemas/list_sub/ListSub.md | 11 - .../proto/RedisSpecificationProtocol.md | 11 - .../redis/schemas/proto/validate_options.md | 11 - .../redis/schemas/pub_sub/PubSub.md | 11 - .../redis/schemas/stream_sub/StreamSub.md | 11 - .../redis/security/parse_security.md | 11 - .../subscriber/factory/create_subscriber.md | 11 - .../SpecificationChannelSubscriber.md | 11 - .../SpecificationListBatchSubscriber.md | 11 - .../specified/SpecificationListSubscriber.md | 11 - .../SpecificationStreamBatchSubscriber.md | 11 - .../SpecificationStreamSubscriber.md | 11 - .../specified/SpecificationSubscriber.md | 11 - .../subscriber/usecase/BatchListSubscriber.md | 11 - .../subscriber/usecase/ChannelSubscriber.md | 11 - .../subscriber/usecase/ListSubscriber.md | 11 - .../subscriber/usecase/LogicSubscriber.md | 11 - .../usecase/StreamBatchSubscriber.md | 11 - .../subscriber/usecase/StreamSubscriber.md | 11 - .../redis/testing/ChannelVisitor.md | 11 - .../faststream/redis/testing/FakeProducer.md | 11 - .../faststream/redis/testing/ListVisitor.md | 11 - .../faststream/redis/testing/StreamVisitor.md | 11 - .../redis/testing/TestRedisBroker.md | 11 - .../api/faststream/redis/testing/Visitor.md | 11 - .../faststream/redis/testing/build_message.md | 11 - .../api/faststream/response/PublishCommand.md | 11 - .../en/api/faststream/response/PublishType.md | 11 - .../en/api/faststream/response/Response.md | 11 - .../faststream/response/ensure_response.md | 11 - .../response/publish_type/PublishType.md | 11 - .../response/response/PublishCommand.md | 11 - .../faststream/response/response/Response.md | 11 - .../response/utils/ensure_response.md | 11 - .../api/faststream/security/BaseSecurity.md | 11 - .../en/api/faststream/security/SASLGSSAPI.md | 11 - .../faststream/security/SASLOAuthBearer.md | 11 - .../api/faststream/security/SASLPlaintext.md | 11 - .../api/faststream/security/SASLScram256.md | 11 - .../api/faststream/security/SASLScram512.md | 11 - .../api/faststream/specification/AsyncAPI.md | 11 - .../api/faststream/specification/Contact.md | 11 - .../faststream/specification/ExternalDocs.md | 11 - .../api/faststream/specification/License.md | 11 - .../en/api/faststream/specification/Tag.md | 11 - .../specification/asyncapi/AsyncAPI.md | 11 - .../asyncapi/factory/AsyncAPI.md | 11 - .../asyncapi/get_asyncapi_html.md | 11 - .../asyncapi/message/get_model_schema.md | 11 - .../asyncapi/message/get_response_schema.md | 11 - .../asyncapi/message/parse_handler_params.md | 11 - .../asyncapi/site/get_asyncapi_html.md | 11 - .../specification/asyncapi/site/serve_app.md | 11 - .../specification/asyncapi/utils/clear_key.md | 11 - .../asyncapi/utils/move_pydantic_refs.md | 11 - .../asyncapi/utils/resolve_payloads.md | 11 - .../asyncapi/utils/to_camelcase.md | 11 - .../asyncapi/v2_6_0/AsyncAPI2.md | 11 - .../asyncapi/v2_6_0/facade/AsyncAPI2.md | 11 - .../v2_6_0/generate/get_app_schema.md | 11 - .../v2_6_0/generate/get_broker_channels.md | 11 - .../v2_6_0/generate/get_broker_server.md | 11 - .../generate/resolve_channel_messages.md | 11 - .../asyncapi/v2_6_0/get_app_schema.md | 11 - .../asyncapi/v2_6_0/schema/ApplicationInfo.md | 11 - .../v2_6_0/schema/ApplicationSchema.md | 11 - .../asyncapi/v2_6_0/schema/Channel.md | 11 - .../asyncapi/v2_6_0/schema/Components.md | 11 - .../asyncapi/v2_6_0/schema/Contact.md | 11 - .../asyncapi/v2_6_0/schema/CorrelationId.md | 11 - .../asyncapi/v2_6_0/schema/ExternalDocs.md | 11 - .../asyncapi/v2_6_0/schema/License.md | 11 - .../asyncapi/v2_6_0/schema/Message.md | 11 - .../asyncapi/v2_6_0/schema/Operation.md | 11 - .../asyncapi/v2_6_0/schema/Parameter.md | 11 - .../asyncapi/v2_6_0/schema/Reference.md | 11 - .../asyncapi/v2_6_0/schema/Server.md | 11 - .../asyncapi/v2_6_0/schema/ServerVariable.md | 11 - .../asyncapi/v2_6_0/schema/Tag.md | 11 - .../v2_6_0/schema/bindings/ChannelBinding.md | 11 - .../schema/bindings/OperationBinding.md | 11 - .../schema/bindings/amqp/ChannelBinding.md | 11 - .../schema/bindings/amqp/OperationBinding.md | 11 - .../bindings/amqp/channel/ChannelBinding.md | 11 - .../schema/bindings/amqp/channel/Exchange.md | 11 - .../schema/bindings/amqp/channel/Queue.md | 11 - .../amqp/operation/OperationBinding.md | 11 - .../schema/bindings/kafka/ChannelBinding.md | 11 - .../schema/bindings/kafka/OperationBinding.md | 11 - .../bindings/kafka/channel/ChannelBinding.md | 11 - .../kafka/operation/OperationBinding.md | 11 - .../schema/bindings/main/ChannelBinding.md | 11 - .../schema/bindings/main/OperationBinding.md | 11 - .../bindings/main/channel/ChannelBinding.md | 11 - .../main/operation/OperationBinding.md | 11 - .../schema/bindings/nats/ChannelBinding.md | 11 - .../schema/bindings/nats/OperationBinding.md | 11 - .../bindings/nats/channel/ChannelBinding.md | 11 - .../nats/operation/OperationBinding.md | 11 - .../schema/bindings/redis/ChannelBinding.md | 11 - .../schema/bindings/redis/OperationBinding.md | 11 - .../bindings/redis/channel/ChannelBinding.md | 11 - .../redis/operation/OperationBinding.md | 11 - .../schema/bindings/sqs/ChannelBinding.md | 11 - .../schema/bindings/sqs/OperationBinding.md | 11 - .../bindings/sqs/channel/ChannelBinding.md | 11 - .../schema/bindings/sqs/channel/from_spec.md | 11 - .../sqs/operation/OperationBinding.md | 11 - .../bindings/sqs/operation/from_spec.md | 11 - .../v2_6_0/schema/channels/Channel.md | 11 - .../v2_6_0/schema/components/Components.md | 11 - .../asyncapi/v2_6_0/schema/contact/Contact.md | 11 - .../v2_6_0/schema/docs/ExternalDocs.md | 11 - .../v2_6_0/schema/info/ApplicationInfo.md | 11 - .../asyncapi/v2_6_0/schema/license/License.md | 11 - .../v2_6_0/schema/message/CorrelationId.md | 11 - .../asyncapi/v2_6_0/schema/message/Message.md | 11 - .../v2_6_0/schema/operations/Operation.md | 11 - .../v2_6_0/schema/schema/ApplicationSchema.md | 11 - .../asyncapi/v2_6_0/schema/servers/Server.md | 11 - .../v2_6_0/schema/servers/ServerVariable.md | 11 - .../asyncapi/v2_6_0/schema/tag/Tag.md | 11 - .../asyncapi/v2_6_0/schema/utils/Parameter.md | 11 - .../asyncapi/v2_6_0/schema/utils/Reference.md | 11 - .../asyncapi/v3_0_0/AsyncAPI3.md | 11 - .../asyncapi/v3_0_0/facade/AsyncAPI3.md | 11 - .../v3_0_0/generate/get_app_schema.md | 11 - .../v3_0_0/generate/get_broker_channels.md | 11 - .../v3_0_0/generate/get_broker_server.md | 11 - .../asyncapi/v3_0_0/get_app_schema.md | 11 - .../asyncapi/v3_0_0/schema/ApplicationInfo.md | 11 - .../v3_0_0/schema/ApplicationSchema.md | 11 - .../asyncapi/v3_0_0/schema/Channel.md | 11 - .../asyncapi/v3_0_0/schema/Components.md | 11 - .../asyncapi/v3_0_0/schema/Contact.md | 11 - .../asyncapi/v3_0_0/schema/CorrelationId.md | 11 - .../asyncapi/v3_0_0/schema/ExternalDocs.md | 11 - .../asyncapi/v3_0_0/schema/License.md | 11 - .../asyncapi/v3_0_0/schema/Message.md | 11 - .../asyncapi/v3_0_0/schema/Operation.md | 11 - .../asyncapi/v3_0_0/schema/Parameter.md | 11 - .../asyncapi/v3_0_0/schema/Reference.md | 11 - .../asyncapi/v3_0_0/schema/Server.md | 11 - .../asyncapi/v3_0_0/schema/ServerVariable.md | 11 - .../asyncapi/v3_0_0/schema/Tag.md | 11 - .../v3_0_0/schema/bindings/ChannelBinding.md | 11 - .../schema/bindings/OperationBinding.md | 11 - .../schema/bindings/amqp/ChannelBinding.md | 11 - .../schema/bindings/amqp/OperationBinding.md | 11 - .../bindings/amqp/channel/ChannelBinding.md | 11 - .../amqp/operation/OperationBinding.md | 11 - .../schema/bindings/kafka/ChannelBinding.md | 11 - .../schema/bindings/kafka/OperationBinding.md | 11 - .../schema/bindings/main/ChannelBinding.md | 11 - .../schema/bindings/main/OperationBinding.md | 11 - .../bindings/main/channel/ChannelBinding.md | 11 - .../main/operation/OperationBinding.md | 11 - .../schema/bindings/nats/ChannelBinding.md | 11 - .../schema/bindings/nats/OperationBinding.md | 11 - .../schema/bindings/redis/ChannelBinding.md | 11 - .../schema/bindings/redis/OperationBinding.md | 11 - .../schema/bindings/sqs/ChannelBinding.md | 11 - .../schema/bindings/sqs/OperationBinding.md | 11 - .../v3_0_0/schema/channels/Channel.md | 11 - .../v3_0_0/schema/components/Components.md | 11 - .../asyncapi/v3_0_0/schema/contact/Contact.md | 11 - .../v3_0_0/schema/docs/ExternalDocs.md | 11 - .../v3_0_0/schema/info/ApplicationInfo.md | 11 - .../asyncapi/v3_0_0/schema/license/License.md | 11 - .../v3_0_0/schema/message/CorrelationId.md | 11 - .../asyncapi/v3_0_0/schema/message/Message.md | 11 - .../v3_0_0/schema/operations/Action.md | 11 - .../v3_0_0/schema/operations/Operation.md | 11 - .../v3_0_0/schema/schema/ApplicationSchema.md | 11 - .../asyncapi/v3_0_0/schema/servers/Server.md | 11 - .../asyncapi/v3_0_0/schema/tag/Tag.md | 11 - .../asyncapi/v3_0_0/schema/utils/Parameter.md | 11 - .../asyncapi/v3_0_0/schema/utils/Reference.md | 11 - .../base/info/BaseApplicationInfo.md | 11 - .../base/schema/BaseApplicationSchema.md | 11 - .../base/specification/Specification.md | 11 - .../proto/EndpointSpecification.md | 11 - .../proto/ServerSpecification.md | 11 - .../proto/broker/ServerSpecification.md | 11 - .../proto/endpoint/EndpointSpecification.md | 11 - .../specification/schema/Contact.md | 11 - .../specification/schema/ContactDict.md | 11 - .../specification/schema/ExternalDocs.md | 11 - .../specification/schema/ExternalDocsDict.md | 11 - .../specification/schema/License.md | 11 - .../specification/schema/LicenseDict.md | 11 - .../specification/schema/Message.md | 11 - .../specification/schema/Operation.md | 11 - .../specification/schema/PublisherSpec.md | 11 - .../specification/schema/SubscriberSpec.md | 11 - .../faststream/specification/schema/Tag.md | 11 - .../specification/schema/TagDict.md | 11 - .../schema/bindings/ChannelBinding.md | 11 - .../schema/bindings/OperationBinding.md | 11 - .../schema/bindings/amqp/ChannelBinding.md | 11 - .../schema/bindings/amqp/Exchange.md | 11 - .../schema/bindings/amqp/OperationBinding.md | 11 - .../schema/bindings/amqp/Queue.md | 11 - .../schema/bindings/kafka/ChannelBinding.md | 11 - .../schema/bindings/kafka/OperationBinding.md | 11 - .../schema/bindings/main/ChannelBinding.md | 11 - .../schema/bindings/main/OperationBinding.md | 11 - .../schema/bindings/nats/ChannelBinding.md | 11 - .../schema/bindings/nats/OperationBinding.md | 11 - .../schema/bindings/redis/ChannelBinding.md | 11 - .../schema/bindings/redis/OperationBinding.md | 11 - .../schema/bindings/sqs/ChannelBinding.md | 11 - .../schema/bindings/sqs/OperationBinding.md | 11 - .../specification/schema/extra/Contact.md | 11 - .../specification/schema/extra/ContactDict.md | 11 - .../schema/extra/ExternalDocs.md | 11 - .../schema/extra/ExternalDocsDict.md | 11 - .../specification/schema/extra/License.md | 11 - .../specification/schema/extra/LicenseDict.md | 11 - .../specification/schema/extra/Tag.md | 11 - .../specification/schema/extra/TagDict.md | 11 - .../schema/extra/contact/Contact.md | 11 - .../schema/extra/contact/ContactDict.md | 11 - .../extra/external_docs/ExternalDocs.md | 11 - .../extra/external_docs/ExternalDocsDict.md | 11 - .../schema/extra/license/License.md | 11 - .../schema/extra/license/LicenseDict.md | 11 - .../specification/schema/extra/tag/Tag.md | 11 - .../specification/schema/extra/tag/TagDict.md | 11 - .../specification/schema/message/Message.md | 11 - .../schema/message/model/Message.md | 11 - .../schema/operation/Operation.md | 11 - .../schema/operation/model/Operation.md | 11 - .../schema/publisher/PublisherSpec.md | 11 - .../schema/subscriber/SubscriberSpec.md | 11 - docs/docs/en/release.md | 2 +- faststream/kafka/broker/broker.py | 251 ++++++++++-------- faststream/kafka/publisher/producer.py | 11 +- faststream/kafka/publisher/usecase.py | 244 +++++++++-------- tests/brokers/kafka/test_publish.py | 28 +- 744 files changed, 310 insertions(+), 8355 deletions(-) delete mode 100644 docs/docs/en/api/faststream/AckPolicy.md delete mode 100644 docs/docs/en/api/faststream/BaseMiddleware.md delete mode 100644 docs/docs/en/api/faststream/Context.md delete mode 100644 docs/docs/en/api/faststream/Depends.md delete mode 100644 docs/docs/en/api/faststream/ExceptionMiddleware.md delete mode 100644 docs/docs/en/api/faststream/FastStream.md delete mode 100644 docs/docs/en/api/faststream/Header.md delete mode 100644 docs/docs/en/api/faststream/Path.md delete mode 100644 docs/docs/en/api/faststream/Response.md delete mode 100644 docs/docs/en/api/faststream/TestApp.md delete mode 100644 docs/docs/en/api/faststream/app/FastStream.md delete mode 100644 docs/docs/en/api/faststream/apply_types.md delete mode 100644 docs/docs/en/api/faststream/asgi/AsgiFastStream.md delete mode 100644 docs/docs/en/api/faststream/asgi/AsgiResponse.md delete mode 100644 docs/docs/en/api/faststream/asgi/app/AsgiFastStream.md delete mode 100644 docs/docs/en/api/faststream/asgi/app/CliRunState.md delete mode 100644 docs/docs/en/api/faststream/asgi/app/OuterRunState.md delete mode 100644 docs/docs/en/api/faststream/asgi/app/ServerState.md delete mode 100644 docs/docs/en/api/faststream/asgi/app/cast_uvicorn_params.md delete mode 100644 docs/docs/en/api/faststream/asgi/factories/make_asyncapi_asgi.md delete mode 100644 docs/docs/en/api/faststream/asgi/factories/make_ping_asgi.md delete mode 100644 docs/docs/en/api/faststream/asgi/get.md delete mode 100644 docs/docs/en/api/faststream/asgi/handlers/get.md delete mode 100644 docs/docs/en/api/faststream/asgi/make_asyncapi_asgi.md delete mode 100644 docs/docs/en/api/faststream/asgi/make_ping_asgi.md delete mode 100644 docs/docs/en/api/faststream/asgi/response/AsgiResponse.md delete mode 100644 docs/docs/en/api/faststream/asgi/websocket/WebSocketClose.md delete mode 100644 docs/docs/en/api/faststream/confluent/KafkaBroker.md delete mode 100644 docs/docs/en/api/faststream/confluent/KafkaPublisher.md delete mode 100644 docs/docs/en/api/faststream/confluent/KafkaResponse.md delete mode 100644 docs/docs/en/api/faststream/confluent/KafkaRoute.md delete mode 100644 docs/docs/en/api/faststream/confluent/KafkaRouter.md delete mode 100644 docs/docs/en/api/faststream/confluent/TestApp.md delete mode 100644 docs/docs/en/api/faststream/confluent/TestKafkaBroker.md delete mode 100644 docs/docs/en/api/faststream/confluent/TopicPartition.md delete mode 100644 docs/docs/en/api/faststream/confluent/broker/KafkaBroker.md delete mode 100644 docs/docs/en/api/faststream/confluent/broker/broker/KafkaBroker.md delete mode 100644 docs/docs/en/api/faststream/confluent/broker/logging/KafkaParamsStorage.md delete mode 100644 docs/docs/en/api/faststream/confluent/broker/registrator/KafkaRegistrator.md delete mode 100644 docs/docs/en/api/faststream/confluent/client/AsyncConfluentConsumer.md delete mode 100644 docs/docs/en/api/faststream/confluent/client/AsyncConfluentProducer.md delete mode 100644 docs/docs/en/api/faststream/confluent/client/BatchBuilder.md delete mode 100644 docs/docs/en/api/faststream/confluent/client/check_msg_error.md delete mode 100644 docs/docs/en/api/faststream/confluent/client/create_topics.md delete mode 100644 docs/docs/en/api/faststream/confluent/config/BrokerAddressFamily.md delete mode 100644 docs/docs/en/api/faststream/confluent/config/BuiltinFeatures.md delete mode 100644 docs/docs/en/api/faststream/confluent/config/ClientDNSLookup.md delete mode 100644 docs/docs/en/api/faststream/confluent/config/CompressionCodec.md delete mode 100644 docs/docs/en/api/faststream/confluent/config/CompressionType.md delete mode 100644 docs/docs/en/api/faststream/confluent/config/ConfluentConfig.md delete mode 100644 docs/docs/en/api/faststream/confluent/config/ConfluentFastConfig.md delete mode 100644 docs/docs/en/api/faststream/confluent/config/Debug.md delete mode 100644 docs/docs/en/api/faststream/confluent/config/GroupProtocol.md delete mode 100644 docs/docs/en/api/faststream/confluent/config/IsolationLevel.md delete mode 100644 docs/docs/en/api/faststream/confluent/config/OffsetStoreMethod.md delete mode 100644 docs/docs/en/api/faststream/confluent/config/SASLOAUTHBearerMethod.md delete mode 100644 docs/docs/en/api/faststream/confluent/config/SecurityProtocol.md delete mode 100644 docs/docs/en/api/faststream/confluent/fastapi/Context.md delete mode 100644 docs/docs/en/api/faststream/confluent/fastapi/KafkaRouter.md delete mode 100644 docs/docs/en/api/faststream/confluent/fastapi/fastapi/KafkaRouter.md delete mode 100644 docs/docs/en/api/faststream/confluent/message/ConsumerProtocol.md delete mode 100644 docs/docs/en/api/faststream/confluent/message/FakeConsumer.md delete mode 100644 docs/docs/en/api/faststream/confluent/message/KafkaMessage.md delete mode 100644 docs/docs/en/api/faststream/confluent/opentelemetry/KafkaTelemetryMiddleware.md delete mode 100644 docs/docs/en/api/faststream/confluent/opentelemetry/middleware/KafkaTelemetryMiddleware.md delete mode 100644 docs/docs/en/api/faststream/confluent/opentelemetry/provider/BaseConfluentTelemetrySettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/confluent/opentelemetry/provider/BatchConfluentTelemetrySettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/confluent/opentelemetry/provider/ConfluentTelemetrySettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/confluent/opentelemetry/provider/telemetry_attributes_provider_factory.md delete mode 100644 docs/docs/en/api/faststream/confluent/parser/AsyncConfluentParser.md delete mode 100644 docs/docs/en/api/faststream/confluent/prometheus/KafkaPrometheusMiddleware.md delete mode 100644 docs/docs/en/api/faststream/confluent/prometheus/middleware/KafkaPrometheusMiddleware.md delete mode 100644 docs/docs/en/api/faststream/confluent/prometheus/provider/BaseConfluentMetricsSettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/confluent/prometheus/provider/BatchConfluentMetricsSettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/confluent/prometheus/provider/ConfluentMetricsSettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/confluent/prometheus/provider/settings_provider_factory.md delete mode 100644 docs/docs/en/api/faststream/confluent/publisher/factory/create_publisher.md delete mode 100644 docs/docs/en/api/faststream/confluent/publisher/fake/KafkaFakePublisher.md delete mode 100644 docs/docs/en/api/faststream/confluent/publisher/producer/AsyncConfluentFastProducer.md delete mode 100644 docs/docs/en/api/faststream/confluent/publisher/specified/SpecificationBatchPublisher.md delete mode 100644 docs/docs/en/api/faststream/confluent/publisher/specified/SpecificationDefaultPublisher.md delete mode 100644 docs/docs/en/api/faststream/confluent/publisher/specified/SpecificationPublisher.md delete mode 100644 docs/docs/en/api/faststream/confluent/publisher/state/EmptyProducerState.md delete mode 100644 docs/docs/en/api/faststream/confluent/publisher/state/ProducerState.md delete mode 100644 docs/docs/en/api/faststream/confluent/publisher/state/RealProducer.md delete mode 100644 docs/docs/en/api/faststream/confluent/publisher/usecase/BatchPublisher.md delete mode 100644 docs/docs/en/api/faststream/confluent/publisher/usecase/DefaultPublisher.md delete mode 100644 docs/docs/en/api/faststream/confluent/publisher/usecase/LogicPublisher.md delete mode 100644 docs/docs/en/api/faststream/confluent/response/KafkaPublishCommand.md delete mode 100644 docs/docs/en/api/faststream/confluent/response/KafkaResponse.md delete mode 100644 docs/docs/en/api/faststream/confluent/router/KafkaPublisher.md delete mode 100644 docs/docs/en/api/faststream/confluent/router/KafkaRoute.md delete mode 100644 docs/docs/en/api/faststream/confluent/router/KafkaRouter.md delete mode 100644 docs/docs/en/api/faststream/confluent/schemas/TopicPartition.md delete mode 100644 docs/docs/en/api/faststream/confluent/schemas/params/ConsumerConnectionParams.md delete mode 100644 docs/docs/en/api/faststream/confluent/schemas/partition/TopicPartition.md delete mode 100644 docs/docs/en/api/faststream/confluent/security/parse_security.md delete mode 100644 docs/docs/en/api/faststream/confluent/subscriber/factory/create_subscriber.md delete mode 100644 docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationBatchSubscriber.md delete mode 100644 docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationConcurrentDefaultSubscriber.md delete mode 100644 docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationDefaultSubscriber.md delete mode 100644 docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationSubscriber.md delete mode 100644 docs/docs/en/api/faststream/confluent/subscriber/usecase/BatchSubscriber.md delete mode 100644 docs/docs/en/api/faststream/confluent/subscriber/usecase/ConcurrentDefaultSubscriber.md delete mode 100644 docs/docs/en/api/faststream/confluent/subscriber/usecase/DefaultSubscriber.md delete mode 100644 docs/docs/en/api/faststream/confluent/subscriber/usecase/LogicSubscriber.md delete mode 100644 docs/docs/en/api/faststream/confluent/testing/FakeProducer.md delete mode 100644 docs/docs/en/api/faststream/confluent/testing/MockConfluentMessage.md delete mode 100644 docs/docs/en/api/faststream/confluent/testing/TestKafkaBroker.md delete mode 100644 docs/docs/en/api/faststream/confluent/testing/build_message.md delete mode 100644 docs/docs/en/api/faststream/exceptions/AckMessage.md delete mode 100644 docs/docs/en/api/faststream/exceptions/ContextError.md delete mode 100644 docs/docs/en/api/faststream/exceptions/FastStreamException.md delete mode 100644 docs/docs/en/api/faststream/exceptions/FeatureNotSupportedException.md delete mode 100644 docs/docs/en/api/faststream/exceptions/HandlerException.md delete mode 100644 docs/docs/en/api/faststream/exceptions/IgnoredException.md delete mode 100644 docs/docs/en/api/faststream/exceptions/IncorrectState.md delete mode 100644 docs/docs/en/api/faststream/exceptions/NackMessage.md delete mode 100644 docs/docs/en/api/faststream/exceptions/RejectMessage.md delete mode 100644 docs/docs/en/api/faststream/exceptions/SetupError.md delete mode 100644 docs/docs/en/api/faststream/exceptions/SkipMessage.md delete mode 100644 docs/docs/en/api/faststream/exceptions/StartupValidationError.md delete mode 100644 docs/docs/en/api/faststream/exceptions/StopApplication.md delete mode 100644 docs/docs/en/api/faststream/exceptions/StopConsume.md delete mode 100644 docs/docs/en/api/faststream/exceptions/SubscriberNotFound.md delete mode 100644 docs/docs/en/api/faststream/kafka/KafkaBroker.md delete mode 100644 docs/docs/en/api/faststream/kafka/KafkaPublisher.md delete mode 100644 docs/docs/en/api/faststream/kafka/KafkaResponse.md delete mode 100644 docs/docs/en/api/faststream/kafka/KafkaRoute.md delete mode 100644 docs/docs/en/api/faststream/kafka/KafkaRouter.md delete mode 100644 docs/docs/en/api/faststream/kafka/TestApp.md delete mode 100644 docs/docs/en/api/faststream/kafka/TestKafkaBroker.md delete mode 100644 docs/docs/en/api/faststream/kafka/TopicPartition.md delete mode 100644 docs/docs/en/api/faststream/kafka/broker/KafkaBroker.md delete mode 100644 docs/docs/en/api/faststream/kafka/broker/broker/KafkaBroker.md delete mode 100644 docs/docs/en/api/faststream/kafka/broker/logging/KafkaParamsStorage.md delete mode 100644 docs/docs/en/api/faststream/kafka/broker/registrator/KafkaRegistrator.md delete mode 100644 docs/docs/en/api/faststream/kafka/fastapi/Context.md delete mode 100644 docs/docs/en/api/faststream/kafka/fastapi/KafkaRouter.md delete mode 100644 docs/docs/en/api/faststream/kafka/fastapi/fastapi/KafkaRouter.md delete mode 100644 docs/docs/en/api/faststream/kafka/message/ConsumerProtocol.md delete mode 100644 docs/docs/en/api/faststream/kafka/message/FakeConsumer.md delete mode 100644 docs/docs/en/api/faststream/kafka/message/KafkaAckableMessage.md delete mode 100644 docs/docs/en/api/faststream/kafka/message/KafkaMessage.md delete mode 100644 docs/docs/en/api/faststream/kafka/opentelemetry/KafkaTelemetryMiddleware.md delete mode 100644 docs/docs/en/api/faststream/kafka/opentelemetry/middleware/KafkaTelemetryMiddleware.md delete mode 100644 docs/docs/en/api/faststream/kafka/opentelemetry/provider/BaseKafkaTelemetrySettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/kafka/opentelemetry/provider/BatchKafkaTelemetrySettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/kafka/opentelemetry/provider/KafkaTelemetrySettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/kafka/opentelemetry/provider/telemetry_attributes_provider_factory.md delete mode 100644 docs/docs/en/api/faststream/kafka/parser/AioKafkaBatchParser.md delete mode 100644 docs/docs/en/api/faststream/kafka/parser/AioKafkaParser.md delete mode 100644 docs/docs/en/api/faststream/kafka/prometheus/KafkaPrometheusMiddleware.md delete mode 100644 docs/docs/en/api/faststream/kafka/prometheus/middleware/KafkaPrometheusMiddleware.md delete mode 100644 docs/docs/en/api/faststream/kafka/prometheus/provider/BaseKafkaMetricsSettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/kafka/prometheus/provider/BatchKafkaMetricsSettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/kafka/prometheus/provider/KafkaMetricsSettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/kafka/prometheus/provider/settings_provider_factory.md delete mode 100644 docs/docs/en/api/faststream/kafka/publisher/factory/create_publisher.md delete mode 100644 docs/docs/en/api/faststream/kafka/publisher/fake/KafkaFakePublisher.md delete mode 100644 docs/docs/en/api/faststream/kafka/publisher/producer/AioKafkaFastProducer.md delete mode 100644 docs/docs/en/api/faststream/kafka/publisher/specified/SpecificationBatchPublisher.md delete mode 100644 docs/docs/en/api/faststream/kafka/publisher/specified/SpecificationDefaultPublisher.md delete mode 100644 docs/docs/en/api/faststream/kafka/publisher/specified/SpecificationPublisher.md delete mode 100644 docs/docs/en/api/faststream/kafka/publisher/state/EmptyProducerState.md delete mode 100644 docs/docs/en/api/faststream/kafka/publisher/state/ProducerState.md delete mode 100644 docs/docs/en/api/faststream/kafka/publisher/state/RealProducer.md delete mode 100644 docs/docs/en/api/faststream/kafka/publisher/usecase/BatchPublisher.md delete mode 100644 docs/docs/en/api/faststream/kafka/publisher/usecase/DefaultPublisher.md delete mode 100644 docs/docs/en/api/faststream/kafka/publisher/usecase/LogicPublisher.md delete mode 100644 docs/docs/en/api/faststream/kafka/response/KafkaPublishCommand.md delete mode 100644 docs/docs/en/api/faststream/kafka/response/KafkaResponse.md delete mode 100644 docs/docs/en/api/faststream/kafka/router/KafkaPublisher.md delete mode 100644 docs/docs/en/api/faststream/kafka/router/KafkaRoute.md delete mode 100644 docs/docs/en/api/faststream/kafka/router/KafkaRouter.md delete mode 100644 docs/docs/en/api/faststream/kafka/schemas/params/ConsumerConnectionParams.md delete mode 100644 docs/docs/en/api/faststream/kafka/security/parse_security.md delete mode 100644 docs/docs/en/api/faststream/kafka/subscriber/factory/create_subscriber.md delete mode 100644 docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationBatchSubscriber.md delete mode 100644 docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationConcurrentDefaultSubscriber.md delete mode 100644 docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationDefaultSubscriber.md delete mode 100644 docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationSubscriber.md delete mode 100644 docs/docs/en/api/faststream/kafka/subscriber/usecase/BatchSubscriber.md delete mode 100644 docs/docs/en/api/faststream/kafka/subscriber/usecase/ConcurrentDefaultSubscriber.md delete mode 100644 docs/docs/en/api/faststream/kafka/subscriber/usecase/DefaultSubscriber.md delete mode 100644 docs/docs/en/api/faststream/kafka/subscriber/usecase/LogicSubscriber.md delete mode 100644 docs/docs/en/api/faststream/kafka/testing/FakeProducer.md delete mode 100644 docs/docs/en/api/faststream/kafka/testing/TestKafkaBroker.md delete mode 100644 docs/docs/en/api/faststream/kafka/testing/build_message.md delete mode 100644 docs/docs/en/api/faststream/message/AckStatus.md delete mode 100644 docs/docs/en/api/faststream/message/SourceType.md delete mode 100644 docs/docs/en/api/faststream/message/StreamMessage.md delete mode 100644 docs/docs/en/api/faststream/message/decode_message.md delete mode 100644 docs/docs/en/api/faststream/message/encode_message.md delete mode 100644 docs/docs/en/api/faststream/message/gen_cor_id.md delete mode 100644 docs/docs/en/api/faststream/message/message/AckStatus.md delete mode 100644 docs/docs/en/api/faststream/message/message/StreamMessage.md delete mode 100644 docs/docs/en/api/faststream/message/source_type/SourceType.md delete mode 100644 docs/docs/en/api/faststream/message/utils/decode_message.md delete mode 100644 docs/docs/en/api/faststream/message/utils/encode_message.md delete mode 100644 docs/docs/en/api/faststream/message/utils/gen_cor_id.md delete mode 100644 docs/docs/en/api/faststream/middlewares/AckPolicy.md delete mode 100644 docs/docs/en/api/faststream/middlewares/AcknowledgementMiddleware.md delete mode 100644 docs/docs/en/api/faststream/middlewares/BaseMiddleware.md delete mode 100644 docs/docs/en/api/faststream/middlewares/ExceptionMiddleware.md delete mode 100644 docs/docs/en/api/faststream/middlewares/acknowledgement/conf/AckPolicy.md delete mode 100644 docs/docs/en/api/faststream/middlewares/acknowledgement/middleware/AcknowledgementMiddleware.md delete mode 100644 docs/docs/en/api/faststream/middlewares/base/BaseMiddleware.md delete mode 100644 docs/docs/en/api/faststream/middlewares/exception/ExceptionMiddleware.md delete mode 100644 docs/docs/en/api/faststream/middlewares/exception/ignore_handler.md delete mode 100644 docs/docs/en/api/faststream/middlewares/logging/CriticalLogMiddleware.md delete mode 100644 docs/docs/en/api/faststream/nats/AckPolicy.md delete mode 100644 docs/docs/en/api/faststream/nats/ConsumerConfig.md delete mode 100644 docs/docs/en/api/faststream/nats/DeliverPolicy.md delete mode 100644 docs/docs/en/api/faststream/nats/DiscardPolicy.md delete mode 100644 docs/docs/en/api/faststream/nats/ExternalStream.md delete mode 100644 docs/docs/en/api/faststream/nats/JStream.md delete mode 100644 docs/docs/en/api/faststream/nats/KvWatch.md delete mode 100644 docs/docs/en/api/faststream/nats/NatsBroker.md delete mode 100644 docs/docs/en/api/faststream/nats/NatsPublisher.md delete mode 100644 docs/docs/en/api/faststream/nats/NatsResponse.md delete mode 100644 docs/docs/en/api/faststream/nats/NatsRoute.md delete mode 100644 docs/docs/en/api/faststream/nats/NatsRouter.md delete mode 100644 docs/docs/en/api/faststream/nats/ObjWatch.md delete mode 100644 docs/docs/en/api/faststream/nats/Placement.md delete mode 100644 docs/docs/en/api/faststream/nats/PubAck.md delete mode 100644 docs/docs/en/api/faststream/nats/PullSub.md delete mode 100644 docs/docs/en/api/faststream/nats/RePublish.md delete mode 100644 docs/docs/en/api/faststream/nats/ReplayPolicy.md delete mode 100644 docs/docs/en/api/faststream/nats/RetentionPolicy.md delete mode 100644 docs/docs/en/api/faststream/nats/StorageType.md delete mode 100644 docs/docs/en/api/faststream/nats/StreamConfig.md delete mode 100644 docs/docs/en/api/faststream/nats/StreamSource.md delete mode 100644 docs/docs/en/api/faststream/nats/TestApp.md delete mode 100644 docs/docs/en/api/faststream/nats/TestNatsBroker.md delete mode 100644 docs/docs/en/api/faststream/nats/broker/NatsBroker.md delete mode 100644 docs/docs/en/api/faststream/nats/broker/broker/NatsBroker.md delete mode 100644 docs/docs/en/api/faststream/nats/broker/logging/NatsParamsStorage.md delete mode 100644 docs/docs/en/api/faststream/nats/broker/registrator/NatsRegistrator.md delete mode 100644 docs/docs/en/api/faststream/nats/broker/state/BrokerState.md delete mode 100644 docs/docs/en/api/faststream/nats/broker/state/ConnectedState.md delete mode 100644 docs/docs/en/api/faststream/nats/broker/state/ConnectionBrokenState.md delete mode 100644 docs/docs/en/api/faststream/nats/broker/state/EmptyBrokerState.md delete mode 100644 docs/docs/en/api/faststream/nats/fastapi/Context.md delete mode 100644 docs/docs/en/api/faststream/nats/fastapi/NatsRouter.md delete mode 100644 docs/docs/en/api/faststream/nats/fastapi/fastapi/NatsRouter.md delete mode 100644 docs/docs/en/api/faststream/nats/helpers/KVBucketDeclarer.md delete mode 100644 docs/docs/en/api/faststream/nats/helpers/OSBucketDeclarer.md delete mode 100644 docs/docs/en/api/faststream/nats/helpers/StreamBuilder.md delete mode 100644 docs/docs/en/api/faststream/nats/helpers/bucket_declarer/KVBucketDeclarer.md delete mode 100644 docs/docs/en/api/faststream/nats/helpers/obj_storage_declarer/OSBucketDeclarer.md delete mode 100644 docs/docs/en/api/faststream/nats/helpers/object_builder/StreamBuilder.md delete mode 100644 docs/docs/en/api/faststream/nats/helpers/state/ConnectedState.md delete mode 100644 docs/docs/en/api/faststream/nats/helpers/state/ConnectionState.md delete mode 100644 docs/docs/en/api/faststream/nats/helpers/state/EmptyConnectionState.md delete mode 100644 docs/docs/en/api/faststream/nats/message/NatsBatchMessage.md delete mode 100644 docs/docs/en/api/faststream/nats/message/NatsKvMessage.md delete mode 100644 docs/docs/en/api/faststream/nats/message/NatsMessage.md delete mode 100644 docs/docs/en/api/faststream/nats/message/NatsObjMessage.md delete mode 100644 docs/docs/en/api/faststream/nats/opentelemetry/NatsTelemetryMiddleware.md delete mode 100644 docs/docs/en/api/faststream/nats/opentelemetry/middleware/NatsTelemetryMiddleware.md delete mode 100644 docs/docs/en/api/faststream/nats/opentelemetry/provider/BaseNatsTelemetrySettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/nats/opentelemetry/provider/NatsBatchTelemetrySettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/nats/opentelemetry/provider/NatsTelemetrySettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/nats/opentelemetry/provider/telemetry_attributes_provider_factory.md delete mode 100644 docs/docs/en/api/faststream/nats/parser/BatchParser.md delete mode 100644 docs/docs/en/api/faststream/nats/parser/JsParser.md delete mode 100644 docs/docs/en/api/faststream/nats/parser/KvParser.md delete mode 100644 docs/docs/en/api/faststream/nats/parser/NatsBaseParser.md delete mode 100644 docs/docs/en/api/faststream/nats/parser/NatsParser.md delete mode 100644 docs/docs/en/api/faststream/nats/parser/ObjParser.md delete mode 100644 docs/docs/en/api/faststream/nats/prometheus/NatsPrometheusMiddleware.md delete mode 100644 docs/docs/en/api/faststream/nats/prometheus/middleware/NatsPrometheusMiddleware.md delete mode 100644 docs/docs/en/api/faststream/nats/prometheus/provider/BaseNatsMetricsSettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/nats/prometheus/provider/BatchNatsMetricsSettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/nats/prometheus/provider/NatsMetricsSettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/nats/prometheus/provider/settings_provider_factory.md delete mode 100644 docs/docs/en/api/faststream/nats/publisher/factory/create_publisher.md delete mode 100644 docs/docs/en/api/faststream/nats/publisher/fake/NatsFakePublisher.md delete mode 100644 docs/docs/en/api/faststream/nats/publisher/producer/NatsFastProducer.md delete mode 100644 docs/docs/en/api/faststream/nats/publisher/producer/NatsJSFastProducer.md delete mode 100644 docs/docs/en/api/faststream/nats/publisher/specified/SpecificationPublisher.md delete mode 100644 docs/docs/en/api/faststream/nats/publisher/usecase/LogicPublisher.md delete mode 100644 docs/docs/en/api/faststream/nats/response/NatsPublishCommand.md delete mode 100644 docs/docs/en/api/faststream/nats/response/NatsResponse.md delete mode 100644 docs/docs/en/api/faststream/nats/router/NatsPublisher.md delete mode 100644 docs/docs/en/api/faststream/nats/router/NatsRoute.md delete mode 100644 docs/docs/en/api/faststream/nats/router/NatsRouter.md delete mode 100644 docs/docs/en/api/faststream/nats/schemas/JStream.md delete mode 100644 docs/docs/en/api/faststream/nats/schemas/KvWatch.md delete mode 100644 docs/docs/en/api/faststream/nats/schemas/ObjWatch.md delete mode 100644 docs/docs/en/api/faststream/nats/schemas/PubAck.md delete mode 100644 docs/docs/en/api/faststream/nats/schemas/PullSub.md delete mode 100644 docs/docs/en/api/faststream/nats/schemas/js_stream/JStream.md delete mode 100644 docs/docs/en/api/faststream/nats/schemas/js_stream/compile_nats_wildcard.md delete mode 100644 docs/docs/en/api/faststream/nats/schemas/js_stream/is_subject_match_wildcard.md delete mode 100644 docs/docs/en/api/faststream/nats/schemas/kv_watch/KvWatch.md delete mode 100644 docs/docs/en/api/faststream/nats/schemas/obj_watch/ObjWatch.md delete mode 100644 docs/docs/en/api/faststream/nats/schemas/pull_sub/PullSub.md delete mode 100644 docs/docs/en/api/faststream/nats/security/parse_security.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/adapters/UnsubscribeAdapter.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/adapters/Unsubscriptable.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/adapters/Watchable.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/factory/create_subscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationBatchPullStreamSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationConcurrentCoreSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationConcurrentPullStreamSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationConcurrentPushStreamSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationCoreSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationKeyValueWatchSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationObjStoreWatchSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationPullStreamSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationPushStreamSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/state/ConnectedSubscriberState.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/state/EmptySubscriberState.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/state/SubscriberState.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/BatchPullStreamSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentCoreSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentPullStreamSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentPushStreamSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/CoreSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/KeyValueWatchSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/LogicSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/ObjStoreWatchSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/PullStreamSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/PushStreamSubscription.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/basic/DefaultSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/basic/LogicSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/core_subscriber/ConcurrentCoreSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/core_subscriber/CoreSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/key_value_subscriber/KeyValueWatchSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/object_storage_subscriber/ObjStoreWatchSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/stream_basic/StreamSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/BatchPullStreamSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/ConcurrentPullStreamSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/PullStreamSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/stream_push_subscriber/ConcurrentPushStreamSubscriber.md delete mode 100644 docs/docs/en/api/faststream/nats/subscriber/usecases/stream_push_subscriber/PushStreamSubscription.md delete mode 100644 docs/docs/en/api/faststream/nats/testing/FakeProducer.md delete mode 100644 docs/docs/en/api/faststream/nats/testing/PatchedMessage.md delete mode 100644 docs/docs/en/api/faststream/nats/testing/TestNatsBroker.md delete mode 100644 docs/docs/en/api/faststream/nats/testing/build_message.md delete mode 100644 docs/docs/en/api/faststream/opentelemetry/Baggage.md delete mode 100644 docs/docs/en/api/faststream/opentelemetry/TelemetryMiddleware.md delete mode 100644 docs/docs/en/api/faststream/opentelemetry/TelemetrySettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/opentelemetry/baggage/Baggage.md delete mode 100644 docs/docs/en/api/faststream/opentelemetry/consts/MessageAction.md delete mode 100644 docs/docs/en/api/faststream/opentelemetry/middleware/BaseTelemetryMiddleware.md delete mode 100644 docs/docs/en/api/faststream/opentelemetry/middleware/TelemetryMiddleware.md delete mode 100644 docs/docs/en/api/faststream/opentelemetry/provider/TelemetrySettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/params/Context.md delete mode 100644 docs/docs/en/api/faststream/params/Depends.md delete mode 100644 docs/docs/en/api/faststream/params/Header.md delete mode 100644 docs/docs/en/api/faststream/params/Path.md delete mode 100644 docs/docs/en/api/faststream/params/no_cast/NoCastField.md delete mode 100644 docs/docs/en/api/faststream/params/params/Context.md delete mode 100644 docs/docs/en/api/faststream/params/params/Header.md delete mode 100644 docs/docs/en/api/faststream/params/params/Path.md delete mode 100644 docs/docs/en/api/faststream/prometheus/ConsumeAttrs.md delete mode 100644 docs/docs/en/api/faststream/prometheus/MetricsSettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/prometheus/PrometheusMiddleware.md delete mode 100644 docs/docs/en/api/faststream/prometheus/container/MetricsContainer.md delete mode 100644 docs/docs/en/api/faststream/prometheus/manager/MetricsManager.md delete mode 100644 docs/docs/en/api/faststream/prometheus/middleware/BasePrometheusMiddleware.md delete mode 100644 docs/docs/en/api/faststream/prometheus/middleware/PrometheusMiddleware.md delete mode 100644 docs/docs/en/api/faststream/prometheus/provider/MetricsSettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/prometheus/types/ConsumeAttrs.md delete mode 100644 docs/docs/en/api/faststream/prometheus/types/ProcessingStatus.md delete mode 100644 docs/docs/en/api/faststream/prometheus/types/PublishingStatus.md delete mode 100644 docs/docs/en/api/faststream/rabbit/ExchangeType.md delete mode 100644 docs/docs/en/api/faststream/rabbit/RabbitBroker.md delete mode 100644 docs/docs/en/api/faststream/rabbit/RabbitExchange.md delete mode 100644 docs/docs/en/api/faststream/rabbit/RabbitPublisher.md delete mode 100644 docs/docs/en/api/faststream/rabbit/RabbitQueue.md delete mode 100644 docs/docs/en/api/faststream/rabbit/RabbitResponse.md delete mode 100644 docs/docs/en/api/faststream/rabbit/RabbitRoute.md delete mode 100644 docs/docs/en/api/faststream/rabbit/RabbitRouter.md delete mode 100644 docs/docs/en/api/faststream/rabbit/TestApp.md delete mode 100644 docs/docs/en/api/faststream/rabbit/TestRabbitBroker.md delete mode 100644 docs/docs/en/api/faststream/rabbit/broker/RabbitBroker.md delete mode 100644 docs/docs/en/api/faststream/rabbit/broker/broker/RabbitBroker.md delete mode 100644 docs/docs/en/api/faststream/rabbit/broker/logging/RabbitParamsStorage.md delete mode 100644 docs/docs/en/api/faststream/rabbit/broker/registrator/RabbitRegistrator.md delete mode 100644 docs/docs/en/api/faststream/rabbit/fastapi/Context.md delete mode 100644 docs/docs/en/api/faststream/rabbit/fastapi/RabbitRouter.md delete mode 100644 docs/docs/en/api/faststream/rabbit/fastapi/fastapi/RabbitRouter.md delete mode 100644 docs/docs/en/api/faststream/rabbit/helpers/declarer/RabbitDeclarer.md delete mode 100644 docs/docs/en/api/faststream/rabbit/helpers/state/ConnectedState.md delete mode 100644 docs/docs/en/api/faststream/rabbit/helpers/state/ConnectionState.md delete mode 100644 docs/docs/en/api/faststream/rabbit/helpers/state/EmptyConnectionState.md delete mode 100644 docs/docs/en/api/faststream/rabbit/message/RabbitMessage.md delete mode 100644 docs/docs/en/api/faststream/rabbit/opentelemetry/RabbitTelemetryMiddleware.md delete mode 100644 docs/docs/en/api/faststream/rabbit/opentelemetry/middleware/RabbitTelemetryMiddleware.md delete mode 100644 docs/docs/en/api/faststream/rabbit/opentelemetry/provider/RabbitTelemetrySettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/rabbit/parser/AioPikaParser.md delete mode 100644 docs/docs/en/api/faststream/rabbit/prometheus/RabbitPrometheusMiddleware.md delete mode 100644 docs/docs/en/api/faststream/rabbit/prometheus/middleware/RabbitPrometheusMiddleware.md delete mode 100644 docs/docs/en/api/faststream/rabbit/prometheus/provider/RabbitMetricsSettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/rabbit/publisher/factory/create_publisher.md delete mode 100644 docs/docs/en/api/faststream/rabbit/publisher/fake/RabbitFakePublisher.md delete mode 100644 docs/docs/en/api/faststream/rabbit/publisher/options/MessageOptions.md delete mode 100644 docs/docs/en/api/faststream/rabbit/publisher/options/PublishOptions.md delete mode 100644 docs/docs/en/api/faststream/rabbit/publisher/producer/AioPikaFastProducer.md delete mode 100644 docs/docs/en/api/faststream/rabbit/publisher/producer/LockState.md delete mode 100644 docs/docs/en/api/faststream/rabbit/publisher/producer/LockUnset.md delete mode 100644 docs/docs/en/api/faststream/rabbit/publisher/producer/RealLock.md delete mode 100644 docs/docs/en/api/faststream/rabbit/publisher/specified/SpecificationPublisher.md delete mode 100644 docs/docs/en/api/faststream/rabbit/publisher/usecase/LogicPublisher.md delete mode 100644 docs/docs/en/api/faststream/rabbit/publisher/usecase/PublishKwargs.md delete mode 100644 docs/docs/en/api/faststream/rabbit/publisher/usecase/RequestPublishKwargs.md delete mode 100644 docs/docs/en/api/faststream/rabbit/response/RabbitPublishCommand.md delete mode 100644 docs/docs/en/api/faststream/rabbit/response/RabbitResponse.md delete mode 100644 docs/docs/en/api/faststream/rabbit/router/RabbitPublisher.md delete mode 100644 docs/docs/en/api/faststream/rabbit/router/RabbitRoute.md delete mode 100644 docs/docs/en/api/faststream/rabbit/router/RabbitRouter.md delete mode 100644 docs/docs/en/api/faststream/rabbit/schemas/BaseRMQInformation.md delete mode 100644 docs/docs/en/api/faststream/rabbit/schemas/ExchangeType.md delete mode 100644 docs/docs/en/api/faststream/rabbit/schemas/RabbitExchange.md delete mode 100644 docs/docs/en/api/faststream/rabbit/schemas/RabbitQueue.md delete mode 100644 docs/docs/en/api/faststream/rabbit/schemas/constants/ExchangeType.md delete mode 100644 docs/docs/en/api/faststream/rabbit/schemas/exchange/RabbitExchange.md delete mode 100644 docs/docs/en/api/faststream/rabbit/schemas/proto/BaseRMQInformation.md delete mode 100644 docs/docs/en/api/faststream/rabbit/schemas/queue/RabbitQueue.md delete mode 100644 docs/docs/en/api/faststream/rabbit/security/parse_security.md delete mode 100644 docs/docs/en/api/faststream/rabbit/subscriber/factory/create_subscriber.md delete mode 100644 docs/docs/en/api/faststream/rabbit/subscriber/specified/SpecificationSubscriber.md delete mode 100644 docs/docs/en/api/faststream/rabbit/subscriber/usecase/LogicSubscriber.md delete mode 100644 docs/docs/en/api/faststream/rabbit/testing/FakeProducer.md delete mode 100644 docs/docs/en/api/faststream/rabbit/testing/PatchedMessage.md delete mode 100644 docs/docs/en/api/faststream/rabbit/testing/TestRabbitBroker.md delete mode 100644 docs/docs/en/api/faststream/rabbit/testing/apply_pattern.md delete mode 100644 docs/docs/en/api/faststream/rabbit/testing/build_message.md delete mode 100644 docs/docs/en/api/faststream/rabbit/utils/build_url.md delete mode 100644 docs/docs/en/api/faststream/rabbit/utils/is_routing_exchange.md delete mode 100644 docs/docs/en/api/faststream/redis/ListSub.md delete mode 100644 docs/docs/en/api/faststream/redis/PubSub.md delete mode 100644 docs/docs/en/api/faststream/redis/RedisBroker.md delete mode 100644 docs/docs/en/api/faststream/redis/RedisPublisher.md delete mode 100644 docs/docs/en/api/faststream/redis/RedisResponse.md delete mode 100644 docs/docs/en/api/faststream/redis/RedisRoute.md delete mode 100644 docs/docs/en/api/faststream/redis/RedisRouter.md delete mode 100644 docs/docs/en/api/faststream/redis/StreamSub.md delete mode 100644 docs/docs/en/api/faststream/redis/TestApp.md delete mode 100644 docs/docs/en/api/faststream/redis/TestRedisBroker.md delete mode 100644 docs/docs/en/api/faststream/redis/broker/broker/RedisBroker.md delete mode 100644 docs/docs/en/api/faststream/redis/broker/logging/RedisParamsStorage.md delete mode 100644 docs/docs/en/api/faststream/redis/broker/registrator/RedisRegistrator.md delete mode 100644 docs/docs/en/api/faststream/redis/fastapi/Context.md delete mode 100644 docs/docs/en/api/faststream/redis/fastapi/RedisRouter.md delete mode 100644 docs/docs/en/api/faststream/redis/fastapi/fastapi/RedisRouter.md delete mode 100644 docs/docs/en/api/faststream/redis/helpers/state/ConnectedState.md delete mode 100644 docs/docs/en/api/faststream/redis/helpers/state/ConnectionState.md delete mode 100644 docs/docs/en/api/faststream/redis/helpers/state/EmptyConnectionState.md delete mode 100644 docs/docs/en/api/faststream/redis/message/BatchListMessage.md delete mode 100644 docs/docs/en/api/faststream/redis/message/BatchStreamMessage.md delete mode 100644 docs/docs/en/api/faststream/redis/message/DefaultListMessage.md delete mode 100644 docs/docs/en/api/faststream/redis/message/DefaultStreamMessage.md delete mode 100644 docs/docs/en/api/faststream/redis/message/PubSubMessage.md delete mode 100644 docs/docs/en/api/faststream/redis/message/RedisBatchListMessage.md delete mode 100644 docs/docs/en/api/faststream/redis/message/RedisBatchStreamMessage.md delete mode 100644 docs/docs/en/api/faststream/redis/message/RedisListMessage.md delete mode 100644 docs/docs/en/api/faststream/redis/message/RedisMessage.md delete mode 100644 docs/docs/en/api/faststream/redis/message/RedisStreamMessage.md delete mode 100644 docs/docs/en/api/faststream/redis/message/UnifyRedisDict.md delete mode 100644 docs/docs/en/api/faststream/redis/message/UnifyRedisMessage.md delete mode 100644 docs/docs/en/api/faststream/redis/opentelemetry/RedisTelemetryMiddleware.md delete mode 100644 docs/docs/en/api/faststream/redis/opentelemetry/middleware/RedisTelemetryMiddleware.md delete mode 100644 docs/docs/en/api/faststream/redis/opentelemetry/provider/RedisTelemetrySettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/redis/parser/RawMessage.md delete mode 100644 docs/docs/en/api/faststream/redis/parser/RedisBatchListParser.md delete mode 100644 docs/docs/en/api/faststream/redis/parser/RedisBatchStreamParser.md delete mode 100644 docs/docs/en/api/faststream/redis/parser/RedisListParser.md delete mode 100644 docs/docs/en/api/faststream/redis/parser/RedisPubSubParser.md delete mode 100644 docs/docs/en/api/faststream/redis/parser/RedisStreamParser.md delete mode 100644 docs/docs/en/api/faststream/redis/parser/SimpleParser.md delete mode 100644 docs/docs/en/api/faststream/redis/prometheus/RedisPrometheusMiddleware.md delete mode 100644 docs/docs/en/api/faststream/redis/prometheus/middleware/RedisPrometheusMiddleware.md delete mode 100644 docs/docs/en/api/faststream/redis/prometheus/provider/BaseRedisMetricsSettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/redis/prometheus/provider/BatchRedisMetricsSettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/redis/prometheus/provider/RedisMetricsSettingsProvider.md delete mode 100644 docs/docs/en/api/faststream/redis/prometheus/provider/settings_provider_factory.md delete mode 100644 docs/docs/en/api/faststream/redis/publisher/factory/create_publisher.md delete mode 100644 docs/docs/en/api/faststream/redis/publisher/fake/RedisFakePublisher.md delete mode 100644 docs/docs/en/api/faststream/redis/publisher/producer/RedisFastProducer.md delete mode 100644 docs/docs/en/api/faststream/redis/publisher/specified/SpecificationChannelPublisher.md delete mode 100644 docs/docs/en/api/faststream/redis/publisher/specified/SpecificationListBatchPublisher.md delete mode 100644 docs/docs/en/api/faststream/redis/publisher/specified/SpecificationListPublisher.md delete mode 100644 docs/docs/en/api/faststream/redis/publisher/specified/SpecificationPublisher.md delete mode 100644 docs/docs/en/api/faststream/redis/publisher/specified/SpecificationStreamPublisher.md delete mode 100644 docs/docs/en/api/faststream/redis/publisher/usecase/ChannelPublisher.md delete mode 100644 docs/docs/en/api/faststream/redis/publisher/usecase/ListBatchPublisher.md delete mode 100644 docs/docs/en/api/faststream/redis/publisher/usecase/ListPublisher.md delete mode 100644 docs/docs/en/api/faststream/redis/publisher/usecase/LogicPublisher.md delete mode 100644 docs/docs/en/api/faststream/redis/publisher/usecase/StreamPublisher.md delete mode 100644 docs/docs/en/api/faststream/redis/response/DestinationType.md delete mode 100644 docs/docs/en/api/faststream/redis/response/RedisPublishCommand.md delete mode 100644 docs/docs/en/api/faststream/redis/response/RedisResponse.md delete mode 100644 docs/docs/en/api/faststream/redis/router/RedisPublisher.md delete mode 100644 docs/docs/en/api/faststream/redis/router/RedisRoute.md delete mode 100644 docs/docs/en/api/faststream/redis/router/RedisRouter.md delete mode 100644 docs/docs/en/api/faststream/redis/schemas/ListSub.md delete mode 100644 docs/docs/en/api/faststream/redis/schemas/PubSub.md delete mode 100644 docs/docs/en/api/faststream/redis/schemas/StreamSub.md delete mode 100644 docs/docs/en/api/faststream/redis/schemas/list_sub/ListSub.md delete mode 100644 docs/docs/en/api/faststream/redis/schemas/proto/RedisSpecificationProtocol.md delete mode 100644 docs/docs/en/api/faststream/redis/schemas/proto/validate_options.md delete mode 100644 docs/docs/en/api/faststream/redis/schemas/pub_sub/PubSub.md delete mode 100644 docs/docs/en/api/faststream/redis/schemas/stream_sub/StreamSub.md delete mode 100644 docs/docs/en/api/faststream/redis/security/parse_security.md delete mode 100644 docs/docs/en/api/faststream/redis/subscriber/factory/create_subscriber.md delete mode 100644 docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationChannelSubscriber.md delete mode 100644 docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationListBatchSubscriber.md delete mode 100644 docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationListSubscriber.md delete mode 100644 docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationStreamBatchSubscriber.md delete mode 100644 docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationStreamSubscriber.md delete mode 100644 docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationSubscriber.md delete mode 100644 docs/docs/en/api/faststream/redis/subscriber/usecase/BatchListSubscriber.md delete mode 100644 docs/docs/en/api/faststream/redis/subscriber/usecase/ChannelSubscriber.md delete mode 100644 docs/docs/en/api/faststream/redis/subscriber/usecase/ListSubscriber.md delete mode 100644 docs/docs/en/api/faststream/redis/subscriber/usecase/LogicSubscriber.md delete mode 100644 docs/docs/en/api/faststream/redis/subscriber/usecase/StreamBatchSubscriber.md delete mode 100644 docs/docs/en/api/faststream/redis/subscriber/usecase/StreamSubscriber.md delete mode 100644 docs/docs/en/api/faststream/redis/testing/ChannelVisitor.md delete mode 100644 docs/docs/en/api/faststream/redis/testing/FakeProducer.md delete mode 100644 docs/docs/en/api/faststream/redis/testing/ListVisitor.md delete mode 100644 docs/docs/en/api/faststream/redis/testing/StreamVisitor.md delete mode 100644 docs/docs/en/api/faststream/redis/testing/TestRedisBroker.md delete mode 100644 docs/docs/en/api/faststream/redis/testing/Visitor.md delete mode 100644 docs/docs/en/api/faststream/redis/testing/build_message.md delete mode 100644 docs/docs/en/api/faststream/response/PublishCommand.md delete mode 100644 docs/docs/en/api/faststream/response/PublishType.md delete mode 100644 docs/docs/en/api/faststream/response/Response.md delete mode 100644 docs/docs/en/api/faststream/response/ensure_response.md delete mode 100644 docs/docs/en/api/faststream/response/publish_type/PublishType.md delete mode 100644 docs/docs/en/api/faststream/response/response/PublishCommand.md delete mode 100644 docs/docs/en/api/faststream/response/response/Response.md delete mode 100644 docs/docs/en/api/faststream/response/utils/ensure_response.md delete mode 100644 docs/docs/en/api/faststream/security/BaseSecurity.md delete mode 100644 docs/docs/en/api/faststream/security/SASLGSSAPI.md delete mode 100644 docs/docs/en/api/faststream/security/SASLOAuthBearer.md delete mode 100644 docs/docs/en/api/faststream/security/SASLPlaintext.md delete mode 100644 docs/docs/en/api/faststream/security/SASLScram256.md delete mode 100644 docs/docs/en/api/faststream/security/SASLScram512.md delete mode 100644 docs/docs/en/api/faststream/specification/AsyncAPI.md delete mode 100644 docs/docs/en/api/faststream/specification/Contact.md delete mode 100644 docs/docs/en/api/faststream/specification/ExternalDocs.md delete mode 100644 docs/docs/en/api/faststream/specification/License.md delete mode 100644 docs/docs/en/api/faststream/specification/Tag.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/AsyncAPI.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/factory/AsyncAPI.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/get_asyncapi_html.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/message/get_model_schema.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/message/get_response_schema.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/message/parse_handler_params.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/site/get_asyncapi_html.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/site/serve_app.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/utils/clear_key.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/utils/move_pydantic_refs.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/utils/resolve_payloads.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/utils/to_camelcase.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/AsyncAPI2.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/facade/AsyncAPI2.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_app_schema.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_channels.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_server.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/resolve_channel_messages.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/get_app_schema.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ApplicationInfo.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ApplicationSchema.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Channel.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Components.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Contact.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/CorrelationId.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ExternalDocs.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/License.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Message.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Operation.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Parameter.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Reference.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Server.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ServerVariable.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Tag.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Exchange.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Queue.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/from_spec.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channels/Channel.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/components/Components.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact/Contact.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs/ExternalDocs.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/info/ApplicationInfo.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license/License.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/CorrelationId.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/Message.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operations/Operation.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/schema/ApplicationSchema.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/servers/Server.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/servers/ServerVariable.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag/Tag.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/utils/Parameter.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/utils/Reference.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/AsyncAPI3.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/facade/AsyncAPI3.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_app_schema.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_channels.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_server.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/get_app_schema.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationInfo.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationSchema.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Channel.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Components.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Contact.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/CorrelationId.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ExternalDocs.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/License.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Message.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Operation.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Parameter.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Reference.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Server.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ServerVariable.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Tag.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channels/Channel.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/components/Components.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/contact/Contact.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/docs/ExternalDocs.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/info/ApplicationInfo.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/license/License.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/message/CorrelationId.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/message/Message.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/Action.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/Operation.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/schema/ApplicationSchema.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/servers/Server.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/tag/Tag.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/utils/Parameter.md delete mode 100644 docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/utils/Reference.md delete mode 100644 docs/docs/en/api/faststream/specification/base/info/BaseApplicationInfo.md delete mode 100644 docs/docs/en/api/faststream/specification/base/schema/BaseApplicationSchema.md delete mode 100644 docs/docs/en/api/faststream/specification/base/specification/Specification.md delete mode 100644 docs/docs/en/api/faststream/specification/proto/EndpointSpecification.md delete mode 100644 docs/docs/en/api/faststream/specification/proto/ServerSpecification.md delete mode 100644 docs/docs/en/api/faststream/specification/proto/broker/ServerSpecification.md delete mode 100644 docs/docs/en/api/faststream/specification/proto/endpoint/EndpointSpecification.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/Contact.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/ContactDict.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/ExternalDocs.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/ExternalDocsDict.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/License.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/LicenseDict.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/Message.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/Operation.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/PublisherSpec.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/SubscriberSpec.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/Tag.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/TagDict.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/amqp/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/amqp/Exchange.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/amqp/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/amqp/Queue.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/kafka/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/kafka/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/main/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/main/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/nats/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/nats/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/redis/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/redis/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/sqs/ChannelBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/bindings/sqs/OperationBinding.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/extra/Contact.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/extra/ContactDict.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/extra/ExternalDocs.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/extra/ExternalDocsDict.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/extra/License.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/extra/LicenseDict.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/extra/Tag.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/extra/TagDict.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/extra/contact/Contact.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/extra/contact/ContactDict.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/extra/external_docs/ExternalDocs.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/extra/external_docs/ExternalDocsDict.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/extra/license/License.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/extra/license/LicenseDict.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/extra/tag/Tag.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/extra/tag/TagDict.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/message/Message.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/message/model/Message.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/operation/Operation.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/operation/model/Operation.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/publisher/PublisherSpec.md delete mode 100644 docs/docs/en/api/faststream/specification/schema/subscriber/SubscriberSpec.md diff --git a/docs/docs/en/api/faststream/AckPolicy.md b/docs/docs/en/api/faststream/AckPolicy.md deleted file mode 100644 index 4d7218c81b..0000000000 --- a/docs/docs/en/api/faststream/AckPolicy.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.AckPolicy diff --git a/docs/docs/en/api/faststream/BaseMiddleware.md b/docs/docs/en/api/faststream/BaseMiddleware.md deleted file mode 100644 index 21145bf983..0000000000 --- a/docs/docs/en/api/faststream/BaseMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.BaseMiddleware diff --git a/docs/docs/en/api/faststream/Context.md b/docs/docs/en/api/faststream/Context.md deleted file mode 100644 index c6400b1e56..0000000000 --- a/docs/docs/en/api/faststream/Context.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.Context diff --git a/docs/docs/en/api/faststream/Depends.md b/docs/docs/en/api/faststream/Depends.md deleted file mode 100644 index c0704687e8..0000000000 --- a/docs/docs/en/api/faststream/Depends.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: fast_depends.use.Depends diff --git a/docs/docs/en/api/faststream/ExceptionMiddleware.md b/docs/docs/en/api/faststream/ExceptionMiddleware.md deleted file mode 100644 index a5e2038f22..0000000000 --- a/docs/docs/en/api/faststream/ExceptionMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.ExceptionMiddleware diff --git a/docs/docs/en/api/faststream/FastStream.md b/docs/docs/en/api/faststream/FastStream.md deleted file mode 100644 index 8d79ba3921..0000000000 --- a/docs/docs/en/api/faststream/FastStream.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.FastStream diff --git a/docs/docs/en/api/faststream/Header.md b/docs/docs/en/api/faststream/Header.md deleted file mode 100644 index 98bdb592a7..0000000000 --- a/docs/docs/en/api/faststream/Header.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.Header diff --git a/docs/docs/en/api/faststream/Path.md b/docs/docs/en/api/faststream/Path.md deleted file mode 100644 index 7716f47c23..0000000000 --- a/docs/docs/en/api/faststream/Path.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.Path diff --git a/docs/docs/en/api/faststream/Response.md b/docs/docs/en/api/faststream/Response.md deleted file mode 100644 index 3475e3f584..0000000000 --- a/docs/docs/en/api/faststream/Response.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.Response diff --git a/docs/docs/en/api/faststream/TestApp.md b/docs/docs/en/api/faststream/TestApp.md deleted file mode 100644 index 2301790c21..0000000000 --- a/docs/docs/en/api/faststream/TestApp.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.TestApp diff --git a/docs/docs/en/api/faststream/app/FastStream.md b/docs/docs/en/api/faststream/app/FastStream.md deleted file mode 100644 index 24235253c2..0000000000 --- a/docs/docs/en/api/faststream/app/FastStream.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.app.FastStream diff --git a/docs/docs/en/api/faststream/apply_types.md b/docs/docs/en/api/faststream/apply_types.md deleted file mode 100644 index 9dc4603bd2..0000000000 --- a/docs/docs/en/api/faststream/apply_types.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: fast_depends.use.inject diff --git a/docs/docs/en/api/faststream/asgi/AsgiFastStream.md b/docs/docs/en/api/faststream/asgi/AsgiFastStream.md deleted file mode 100644 index 49a94bd574..0000000000 --- a/docs/docs/en/api/faststream/asgi/AsgiFastStream.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asgi.AsgiFastStream diff --git a/docs/docs/en/api/faststream/asgi/AsgiResponse.md b/docs/docs/en/api/faststream/asgi/AsgiResponse.md deleted file mode 100644 index 4814f18557..0000000000 --- a/docs/docs/en/api/faststream/asgi/AsgiResponse.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asgi.AsgiResponse diff --git a/docs/docs/en/api/faststream/asgi/app/AsgiFastStream.md b/docs/docs/en/api/faststream/asgi/app/AsgiFastStream.md deleted file mode 100644 index 9d58b9576c..0000000000 --- a/docs/docs/en/api/faststream/asgi/app/AsgiFastStream.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asgi.app.AsgiFastStream diff --git a/docs/docs/en/api/faststream/asgi/app/CliRunState.md b/docs/docs/en/api/faststream/asgi/app/CliRunState.md deleted file mode 100644 index 1124f2d50b..0000000000 --- a/docs/docs/en/api/faststream/asgi/app/CliRunState.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asgi.app.CliRunState diff --git a/docs/docs/en/api/faststream/asgi/app/OuterRunState.md b/docs/docs/en/api/faststream/asgi/app/OuterRunState.md deleted file mode 100644 index 3789ea0461..0000000000 --- a/docs/docs/en/api/faststream/asgi/app/OuterRunState.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asgi.app.OuterRunState diff --git a/docs/docs/en/api/faststream/asgi/app/ServerState.md b/docs/docs/en/api/faststream/asgi/app/ServerState.md deleted file mode 100644 index 6d5e2c20c6..0000000000 --- a/docs/docs/en/api/faststream/asgi/app/ServerState.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asgi.app.ServerState diff --git a/docs/docs/en/api/faststream/asgi/app/cast_uvicorn_params.md b/docs/docs/en/api/faststream/asgi/app/cast_uvicorn_params.md deleted file mode 100644 index 1431e2c833..0000000000 --- a/docs/docs/en/api/faststream/asgi/app/cast_uvicorn_params.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asgi.app.cast_uvicorn_params diff --git a/docs/docs/en/api/faststream/asgi/factories/make_asyncapi_asgi.md b/docs/docs/en/api/faststream/asgi/factories/make_asyncapi_asgi.md deleted file mode 100644 index e96de51b01..0000000000 --- a/docs/docs/en/api/faststream/asgi/factories/make_asyncapi_asgi.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asgi.factories.make_asyncapi_asgi diff --git a/docs/docs/en/api/faststream/asgi/factories/make_ping_asgi.md b/docs/docs/en/api/faststream/asgi/factories/make_ping_asgi.md deleted file mode 100644 index fb163d02a1..0000000000 --- a/docs/docs/en/api/faststream/asgi/factories/make_ping_asgi.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asgi.factories.make_ping_asgi diff --git a/docs/docs/en/api/faststream/asgi/get.md b/docs/docs/en/api/faststream/asgi/get.md deleted file mode 100644 index 044c05ed81..0000000000 --- a/docs/docs/en/api/faststream/asgi/get.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asgi.get diff --git a/docs/docs/en/api/faststream/asgi/handlers/get.md b/docs/docs/en/api/faststream/asgi/handlers/get.md deleted file mode 100644 index 8f3c04a050..0000000000 --- a/docs/docs/en/api/faststream/asgi/handlers/get.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asgi.handlers.get diff --git a/docs/docs/en/api/faststream/asgi/make_asyncapi_asgi.md b/docs/docs/en/api/faststream/asgi/make_asyncapi_asgi.md deleted file mode 100644 index 5e57a1a2db..0000000000 --- a/docs/docs/en/api/faststream/asgi/make_asyncapi_asgi.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asgi.make_asyncapi_asgi diff --git a/docs/docs/en/api/faststream/asgi/make_ping_asgi.md b/docs/docs/en/api/faststream/asgi/make_ping_asgi.md deleted file mode 100644 index 5c24aaef19..0000000000 --- a/docs/docs/en/api/faststream/asgi/make_ping_asgi.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asgi.make_ping_asgi diff --git a/docs/docs/en/api/faststream/asgi/response/AsgiResponse.md b/docs/docs/en/api/faststream/asgi/response/AsgiResponse.md deleted file mode 100644 index 037739b09d..0000000000 --- a/docs/docs/en/api/faststream/asgi/response/AsgiResponse.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asgi.response.AsgiResponse diff --git a/docs/docs/en/api/faststream/asgi/websocket/WebSocketClose.md b/docs/docs/en/api/faststream/asgi/websocket/WebSocketClose.md deleted file mode 100644 index 130ee9a59a..0000000000 --- a/docs/docs/en/api/faststream/asgi/websocket/WebSocketClose.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.asgi.websocket.WebSocketClose diff --git a/docs/docs/en/api/faststream/confluent/KafkaBroker.md b/docs/docs/en/api/faststream/confluent/KafkaBroker.md deleted file mode 100644 index 99fd644946..0000000000 --- a/docs/docs/en/api/faststream/confluent/KafkaBroker.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.KafkaBroker diff --git a/docs/docs/en/api/faststream/confluent/KafkaPublisher.md b/docs/docs/en/api/faststream/confluent/KafkaPublisher.md deleted file mode 100644 index 73e485fcc5..0000000000 --- a/docs/docs/en/api/faststream/confluent/KafkaPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.KafkaPublisher diff --git a/docs/docs/en/api/faststream/confluent/KafkaResponse.md b/docs/docs/en/api/faststream/confluent/KafkaResponse.md deleted file mode 100644 index eb0eab479c..0000000000 --- a/docs/docs/en/api/faststream/confluent/KafkaResponse.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.KafkaResponse diff --git a/docs/docs/en/api/faststream/confluent/KafkaRoute.md b/docs/docs/en/api/faststream/confluent/KafkaRoute.md deleted file mode 100644 index 723012794f..0000000000 --- a/docs/docs/en/api/faststream/confluent/KafkaRoute.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.KafkaRoute diff --git a/docs/docs/en/api/faststream/confluent/KafkaRouter.md b/docs/docs/en/api/faststream/confluent/KafkaRouter.md deleted file mode 100644 index b9e7b0d991..0000000000 --- a/docs/docs/en/api/faststream/confluent/KafkaRouter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.KafkaRouter diff --git a/docs/docs/en/api/faststream/confluent/TestApp.md b/docs/docs/en/api/faststream/confluent/TestApp.md deleted file mode 100644 index ad101303af..0000000000 --- a/docs/docs/en/api/faststream/confluent/TestApp.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream._internal.testing.app.TestApp diff --git a/docs/docs/en/api/faststream/confluent/TestKafkaBroker.md b/docs/docs/en/api/faststream/confluent/TestKafkaBroker.md deleted file mode 100644 index 0a24384f69..0000000000 --- a/docs/docs/en/api/faststream/confluent/TestKafkaBroker.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.TestKafkaBroker diff --git a/docs/docs/en/api/faststream/confluent/TopicPartition.md b/docs/docs/en/api/faststream/confluent/TopicPartition.md deleted file mode 100644 index 9b5e09bdf9..0000000000 --- a/docs/docs/en/api/faststream/confluent/TopicPartition.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.TopicPartition diff --git a/docs/docs/en/api/faststream/confluent/broker/KafkaBroker.md b/docs/docs/en/api/faststream/confluent/broker/KafkaBroker.md deleted file mode 100644 index cdfdbc6ef1..0000000000 --- a/docs/docs/en/api/faststream/confluent/broker/KafkaBroker.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.broker.KafkaBroker diff --git a/docs/docs/en/api/faststream/confluent/broker/broker/KafkaBroker.md b/docs/docs/en/api/faststream/confluent/broker/broker/KafkaBroker.md deleted file mode 100644 index 05c8356f26..0000000000 --- a/docs/docs/en/api/faststream/confluent/broker/broker/KafkaBroker.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.broker.broker.KafkaBroker diff --git a/docs/docs/en/api/faststream/confluent/broker/logging/KafkaParamsStorage.md b/docs/docs/en/api/faststream/confluent/broker/logging/KafkaParamsStorage.md deleted file mode 100644 index 900f945037..0000000000 --- a/docs/docs/en/api/faststream/confluent/broker/logging/KafkaParamsStorage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.broker.logging.KafkaParamsStorage diff --git a/docs/docs/en/api/faststream/confluent/broker/registrator/KafkaRegistrator.md b/docs/docs/en/api/faststream/confluent/broker/registrator/KafkaRegistrator.md deleted file mode 100644 index 80068d2349..0000000000 --- a/docs/docs/en/api/faststream/confluent/broker/registrator/KafkaRegistrator.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.broker.registrator.KafkaRegistrator diff --git a/docs/docs/en/api/faststream/confluent/client/AsyncConfluentConsumer.md b/docs/docs/en/api/faststream/confluent/client/AsyncConfluentConsumer.md deleted file mode 100644 index 25374c405d..0000000000 --- a/docs/docs/en/api/faststream/confluent/client/AsyncConfluentConsumer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.client.AsyncConfluentConsumer diff --git a/docs/docs/en/api/faststream/confluent/client/AsyncConfluentProducer.md b/docs/docs/en/api/faststream/confluent/client/AsyncConfluentProducer.md deleted file mode 100644 index 29bfac283f..0000000000 --- a/docs/docs/en/api/faststream/confluent/client/AsyncConfluentProducer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.client.AsyncConfluentProducer diff --git a/docs/docs/en/api/faststream/confluent/client/BatchBuilder.md b/docs/docs/en/api/faststream/confluent/client/BatchBuilder.md deleted file mode 100644 index 232f9ecdf2..0000000000 --- a/docs/docs/en/api/faststream/confluent/client/BatchBuilder.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.client.BatchBuilder diff --git a/docs/docs/en/api/faststream/confluent/client/check_msg_error.md b/docs/docs/en/api/faststream/confluent/client/check_msg_error.md deleted file mode 100644 index 71ac291b6e..0000000000 --- a/docs/docs/en/api/faststream/confluent/client/check_msg_error.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.client.check_msg_error diff --git a/docs/docs/en/api/faststream/confluent/client/create_topics.md b/docs/docs/en/api/faststream/confluent/client/create_topics.md deleted file mode 100644 index 8efc1a80c4..0000000000 --- a/docs/docs/en/api/faststream/confluent/client/create_topics.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.client.create_topics diff --git a/docs/docs/en/api/faststream/confluent/config/BrokerAddressFamily.md b/docs/docs/en/api/faststream/confluent/config/BrokerAddressFamily.md deleted file mode 100644 index bf5cfbaca7..0000000000 --- a/docs/docs/en/api/faststream/confluent/config/BrokerAddressFamily.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.config.BrokerAddressFamily diff --git a/docs/docs/en/api/faststream/confluent/config/BuiltinFeatures.md b/docs/docs/en/api/faststream/confluent/config/BuiltinFeatures.md deleted file mode 100644 index 41e324305d..0000000000 --- a/docs/docs/en/api/faststream/confluent/config/BuiltinFeatures.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.config.BuiltinFeatures diff --git a/docs/docs/en/api/faststream/confluent/config/ClientDNSLookup.md b/docs/docs/en/api/faststream/confluent/config/ClientDNSLookup.md deleted file mode 100644 index 15f67688f1..0000000000 --- a/docs/docs/en/api/faststream/confluent/config/ClientDNSLookup.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.config.ClientDNSLookup diff --git a/docs/docs/en/api/faststream/confluent/config/CompressionCodec.md b/docs/docs/en/api/faststream/confluent/config/CompressionCodec.md deleted file mode 100644 index dd9640afd4..0000000000 --- a/docs/docs/en/api/faststream/confluent/config/CompressionCodec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.config.CompressionCodec diff --git a/docs/docs/en/api/faststream/confluent/config/CompressionType.md b/docs/docs/en/api/faststream/confluent/config/CompressionType.md deleted file mode 100644 index 8139bfcdda..0000000000 --- a/docs/docs/en/api/faststream/confluent/config/CompressionType.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.config.CompressionType diff --git a/docs/docs/en/api/faststream/confluent/config/ConfluentConfig.md b/docs/docs/en/api/faststream/confluent/config/ConfluentConfig.md deleted file mode 100644 index 9ebd97c1ff..0000000000 --- a/docs/docs/en/api/faststream/confluent/config/ConfluentConfig.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.config.ConfluentConfig diff --git a/docs/docs/en/api/faststream/confluent/config/ConfluentFastConfig.md b/docs/docs/en/api/faststream/confluent/config/ConfluentFastConfig.md deleted file mode 100644 index 27861ffd5b..0000000000 --- a/docs/docs/en/api/faststream/confluent/config/ConfluentFastConfig.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.config.ConfluentFastConfig diff --git a/docs/docs/en/api/faststream/confluent/config/Debug.md b/docs/docs/en/api/faststream/confluent/config/Debug.md deleted file mode 100644 index 2036046f5d..0000000000 --- a/docs/docs/en/api/faststream/confluent/config/Debug.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.config.Debug diff --git a/docs/docs/en/api/faststream/confluent/config/GroupProtocol.md b/docs/docs/en/api/faststream/confluent/config/GroupProtocol.md deleted file mode 100644 index a5cab4b1d9..0000000000 --- a/docs/docs/en/api/faststream/confluent/config/GroupProtocol.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.config.GroupProtocol diff --git a/docs/docs/en/api/faststream/confluent/config/IsolationLevel.md b/docs/docs/en/api/faststream/confluent/config/IsolationLevel.md deleted file mode 100644 index d122261f0f..0000000000 --- a/docs/docs/en/api/faststream/confluent/config/IsolationLevel.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.config.IsolationLevel diff --git a/docs/docs/en/api/faststream/confluent/config/OffsetStoreMethod.md b/docs/docs/en/api/faststream/confluent/config/OffsetStoreMethod.md deleted file mode 100644 index 4b203e65e9..0000000000 --- a/docs/docs/en/api/faststream/confluent/config/OffsetStoreMethod.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.config.OffsetStoreMethod diff --git a/docs/docs/en/api/faststream/confluent/config/SASLOAUTHBearerMethod.md b/docs/docs/en/api/faststream/confluent/config/SASLOAUTHBearerMethod.md deleted file mode 100644 index 2cb635c6b0..0000000000 --- a/docs/docs/en/api/faststream/confluent/config/SASLOAUTHBearerMethod.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.config.SASLOAUTHBearerMethod diff --git a/docs/docs/en/api/faststream/confluent/config/SecurityProtocol.md b/docs/docs/en/api/faststream/confluent/config/SecurityProtocol.md deleted file mode 100644 index 8415d3214e..0000000000 --- a/docs/docs/en/api/faststream/confluent/config/SecurityProtocol.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.config.SecurityProtocol diff --git a/docs/docs/en/api/faststream/confluent/fastapi/Context.md b/docs/docs/en/api/faststream/confluent/fastapi/Context.md deleted file mode 100644 index 99bf141f5c..0000000000 --- a/docs/docs/en/api/faststream/confluent/fastapi/Context.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream._internal.fastapi.context.Context diff --git a/docs/docs/en/api/faststream/confluent/fastapi/KafkaRouter.md b/docs/docs/en/api/faststream/confluent/fastapi/KafkaRouter.md deleted file mode 100644 index 034203e103..0000000000 --- a/docs/docs/en/api/faststream/confluent/fastapi/KafkaRouter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.fastapi.KafkaRouter diff --git a/docs/docs/en/api/faststream/confluent/fastapi/fastapi/KafkaRouter.md b/docs/docs/en/api/faststream/confluent/fastapi/fastapi/KafkaRouter.md deleted file mode 100644 index 87edcc2c3d..0000000000 --- a/docs/docs/en/api/faststream/confluent/fastapi/fastapi/KafkaRouter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.fastapi.fastapi.KafkaRouter diff --git a/docs/docs/en/api/faststream/confluent/message/ConsumerProtocol.md b/docs/docs/en/api/faststream/confluent/message/ConsumerProtocol.md deleted file mode 100644 index 18971d0829..0000000000 --- a/docs/docs/en/api/faststream/confluent/message/ConsumerProtocol.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.message.ConsumerProtocol diff --git a/docs/docs/en/api/faststream/confluent/message/FakeConsumer.md b/docs/docs/en/api/faststream/confluent/message/FakeConsumer.md deleted file mode 100644 index 19e60bb461..0000000000 --- a/docs/docs/en/api/faststream/confluent/message/FakeConsumer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.message.FakeConsumer diff --git a/docs/docs/en/api/faststream/confluent/message/KafkaMessage.md b/docs/docs/en/api/faststream/confluent/message/KafkaMessage.md deleted file mode 100644 index 02004c7d37..0000000000 --- a/docs/docs/en/api/faststream/confluent/message/KafkaMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.message.KafkaMessage diff --git a/docs/docs/en/api/faststream/confluent/opentelemetry/KafkaTelemetryMiddleware.md b/docs/docs/en/api/faststream/confluent/opentelemetry/KafkaTelemetryMiddleware.md deleted file mode 100644 index 743c494591..0000000000 --- a/docs/docs/en/api/faststream/confluent/opentelemetry/KafkaTelemetryMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.opentelemetry.KafkaTelemetryMiddleware diff --git a/docs/docs/en/api/faststream/confluent/opentelemetry/middleware/KafkaTelemetryMiddleware.md b/docs/docs/en/api/faststream/confluent/opentelemetry/middleware/KafkaTelemetryMiddleware.md deleted file mode 100644 index b34265dfbb..0000000000 --- a/docs/docs/en/api/faststream/confluent/opentelemetry/middleware/KafkaTelemetryMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.opentelemetry.middleware.KafkaTelemetryMiddleware diff --git a/docs/docs/en/api/faststream/confluent/opentelemetry/provider/BaseConfluentTelemetrySettingsProvider.md b/docs/docs/en/api/faststream/confluent/opentelemetry/provider/BaseConfluentTelemetrySettingsProvider.md deleted file mode 100644 index 730662fae5..0000000000 --- a/docs/docs/en/api/faststream/confluent/opentelemetry/provider/BaseConfluentTelemetrySettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.opentelemetry.provider.BaseConfluentTelemetrySettingsProvider diff --git a/docs/docs/en/api/faststream/confluent/opentelemetry/provider/BatchConfluentTelemetrySettingsProvider.md b/docs/docs/en/api/faststream/confluent/opentelemetry/provider/BatchConfluentTelemetrySettingsProvider.md deleted file mode 100644 index a6db133484..0000000000 --- a/docs/docs/en/api/faststream/confluent/opentelemetry/provider/BatchConfluentTelemetrySettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.opentelemetry.provider.BatchConfluentTelemetrySettingsProvider diff --git a/docs/docs/en/api/faststream/confluent/opentelemetry/provider/ConfluentTelemetrySettingsProvider.md b/docs/docs/en/api/faststream/confluent/opentelemetry/provider/ConfluentTelemetrySettingsProvider.md deleted file mode 100644 index 2c5242e6e5..0000000000 --- a/docs/docs/en/api/faststream/confluent/opentelemetry/provider/ConfluentTelemetrySettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.opentelemetry.provider.ConfluentTelemetrySettingsProvider diff --git a/docs/docs/en/api/faststream/confluent/opentelemetry/provider/telemetry_attributes_provider_factory.md b/docs/docs/en/api/faststream/confluent/opentelemetry/provider/telemetry_attributes_provider_factory.md deleted file mode 100644 index 7dd0e1d0fd..0000000000 --- a/docs/docs/en/api/faststream/confluent/opentelemetry/provider/telemetry_attributes_provider_factory.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.opentelemetry.provider.telemetry_attributes_provider_factory diff --git a/docs/docs/en/api/faststream/confluent/parser/AsyncConfluentParser.md b/docs/docs/en/api/faststream/confluent/parser/AsyncConfluentParser.md deleted file mode 100644 index e5029a60d1..0000000000 --- a/docs/docs/en/api/faststream/confluent/parser/AsyncConfluentParser.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.parser.AsyncConfluentParser diff --git a/docs/docs/en/api/faststream/confluent/prometheus/KafkaPrometheusMiddleware.md b/docs/docs/en/api/faststream/confluent/prometheus/KafkaPrometheusMiddleware.md deleted file mode 100644 index e84e84acc3..0000000000 --- a/docs/docs/en/api/faststream/confluent/prometheus/KafkaPrometheusMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.prometheus.KafkaPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/confluent/prometheus/middleware/KafkaPrometheusMiddleware.md b/docs/docs/en/api/faststream/confluent/prometheus/middleware/KafkaPrometheusMiddleware.md deleted file mode 100644 index 6603893f74..0000000000 --- a/docs/docs/en/api/faststream/confluent/prometheus/middleware/KafkaPrometheusMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.prometheus.middleware.KafkaPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/confluent/prometheus/provider/BaseConfluentMetricsSettingsProvider.md b/docs/docs/en/api/faststream/confluent/prometheus/provider/BaseConfluentMetricsSettingsProvider.md deleted file mode 100644 index 27c186c098..0000000000 --- a/docs/docs/en/api/faststream/confluent/prometheus/provider/BaseConfluentMetricsSettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.prometheus.provider.BaseConfluentMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/confluent/prometheus/provider/BatchConfluentMetricsSettingsProvider.md b/docs/docs/en/api/faststream/confluent/prometheus/provider/BatchConfluentMetricsSettingsProvider.md deleted file mode 100644 index f784a64e9f..0000000000 --- a/docs/docs/en/api/faststream/confluent/prometheus/provider/BatchConfluentMetricsSettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.prometheus.provider.BatchConfluentMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/confluent/prometheus/provider/ConfluentMetricsSettingsProvider.md b/docs/docs/en/api/faststream/confluent/prometheus/provider/ConfluentMetricsSettingsProvider.md deleted file mode 100644 index 65f0a8348e..0000000000 --- a/docs/docs/en/api/faststream/confluent/prometheus/provider/ConfluentMetricsSettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.prometheus.provider.ConfluentMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/confluent/prometheus/provider/settings_provider_factory.md b/docs/docs/en/api/faststream/confluent/prometheus/provider/settings_provider_factory.md deleted file mode 100644 index 78358f46e3..0000000000 --- a/docs/docs/en/api/faststream/confluent/prometheus/provider/settings_provider_factory.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.prometheus.provider.settings_provider_factory diff --git a/docs/docs/en/api/faststream/confluent/publisher/factory/create_publisher.md b/docs/docs/en/api/faststream/confluent/publisher/factory/create_publisher.md deleted file mode 100644 index 60e9664052..0000000000 --- a/docs/docs/en/api/faststream/confluent/publisher/factory/create_publisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.publisher.factory.create_publisher diff --git a/docs/docs/en/api/faststream/confluent/publisher/fake/KafkaFakePublisher.md b/docs/docs/en/api/faststream/confluent/publisher/fake/KafkaFakePublisher.md deleted file mode 100644 index 019fbf855f..0000000000 --- a/docs/docs/en/api/faststream/confluent/publisher/fake/KafkaFakePublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.publisher.fake.KafkaFakePublisher diff --git a/docs/docs/en/api/faststream/confluent/publisher/producer/AsyncConfluentFastProducer.md b/docs/docs/en/api/faststream/confluent/publisher/producer/AsyncConfluentFastProducer.md deleted file mode 100644 index fd614d1593..0000000000 --- a/docs/docs/en/api/faststream/confluent/publisher/producer/AsyncConfluentFastProducer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.publisher.producer.AsyncConfluentFastProducer diff --git a/docs/docs/en/api/faststream/confluent/publisher/specified/SpecificationBatchPublisher.md b/docs/docs/en/api/faststream/confluent/publisher/specified/SpecificationBatchPublisher.md deleted file mode 100644 index 2879b0d6c3..0000000000 --- a/docs/docs/en/api/faststream/confluent/publisher/specified/SpecificationBatchPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.publisher.specified.SpecificationBatchPublisher diff --git a/docs/docs/en/api/faststream/confluent/publisher/specified/SpecificationDefaultPublisher.md b/docs/docs/en/api/faststream/confluent/publisher/specified/SpecificationDefaultPublisher.md deleted file mode 100644 index 581ae19fd8..0000000000 --- a/docs/docs/en/api/faststream/confluent/publisher/specified/SpecificationDefaultPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.publisher.specified.SpecificationDefaultPublisher diff --git a/docs/docs/en/api/faststream/confluent/publisher/specified/SpecificationPublisher.md b/docs/docs/en/api/faststream/confluent/publisher/specified/SpecificationPublisher.md deleted file mode 100644 index 55ed49caf5..0000000000 --- a/docs/docs/en/api/faststream/confluent/publisher/specified/SpecificationPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.publisher.specified.SpecificationPublisher diff --git a/docs/docs/en/api/faststream/confluent/publisher/state/EmptyProducerState.md b/docs/docs/en/api/faststream/confluent/publisher/state/EmptyProducerState.md deleted file mode 100644 index a72476a6d3..0000000000 --- a/docs/docs/en/api/faststream/confluent/publisher/state/EmptyProducerState.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.publisher.state.EmptyProducerState diff --git a/docs/docs/en/api/faststream/confluent/publisher/state/ProducerState.md b/docs/docs/en/api/faststream/confluent/publisher/state/ProducerState.md deleted file mode 100644 index 5a5a35dddd..0000000000 --- a/docs/docs/en/api/faststream/confluent/publisher/state/ProducerState.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.publisher.state.ProducerState diff --git a/docs/docs/en/api/faststream/confluent/publisher/state/RealProducer.md b/docs/docs/en/api/faststream/confluent/publisher/state/RealProducer.md deleted file mode 100644 index 52143d1596..0000000000 --- a/docs/docs/en/api/faststream/confluent/publisher/state/RealProducer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.publisher.state.RealProducer diff --git a/docs/docs/en/api/faststream/confluent/publisher/usecase/BatchPublisher.md b/docs/docs/en/api/faststream/confluent/publisher/usecase/BatchPublisher.md deleted file mode 100644 index 23e8baeed9..0000000000 --- a/docs/docs/en/api/faststream/confluent/publisher/usecase/BatchPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.publisher.usecase.BatchPublisher diff --git a/docs/docs/en/api/faststream/confluent/publisher/usecase/DefaultPublisher.md b/docs/docs/en/api/faststream/confluent/publisher/usecase/DefaultPublisher.md deleted file mode 100644 index faa20eaa11..0000000000 --- a/docs/docs/en/api/faststream/confluent/publisher/usecase/DefaultPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.publisher.usecase.DefaultPublisher diff --git a/docs/docs/en/api/faststream/confluent/publisher/usecase/LogicPublisher.md b/docs/docs/en/api/faststream/confluent/publisher/usecase/LogicPublisher.md deleted file mode 100644 index d9a8594d12..0000000000 --- a/docs/docs/en/api/faststream/confluent/publisher/usecase/LogicPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.publisher.usecase.LogicPublisher diff --git a/docs/docs/en/api/faststream/confluent/response/KafkaPublishCommand.md b/docs/docs/en/api/faststream/confluent/response/KafkaPublishCommand.md deleted file mode 100644 index 2a4efcf180..0000000000 --- a/docs/docs/en/api/faststream/confluent/response/KafkaPublishCommand.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.response.KafkaPublishCommand diff --git a/docs/docs/en/api/faststream/confluent/response/KafkaResponse.md b/docs/docs/en/api/faststream/confluent/response/KafkaResponse.md deleted file mode 100644 index 7fa5542613..0000000000 --- a/docs/docs/en/api/faststream/confluent/response/KafkaResponse.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.response.KafkaResponse diff --git a/docs/docs/en/api/faststream/confluent/router/KafkaPublisher.md b/docs/docs/en/api/faststream/confluent/router/KafkaPublisher.md deleted file mode 100644 index ee1c818707..0000000000 --- a/docs/docs/en/api/faststream/confluent/router/KafkaPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.router.KafkaPublisher diff --git a/docs/docs/en/api/faststream/confluent/router/KafkaRoute.md b/docs/docs/en/api/faststream/confluent/router/KafkaRoute.md deleted file mode 100644 index 60d7bb1c99..0000000000 --- a/docs/docs/en/api/faststream/confluent/router/KafkaRoute.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.router.KafkaRoute diff --git a/docs/docs/en/api/faststream/confluent/router/KafkaRouter.md b/docs/docs/en/api/faststream/confluent/router/KafkaRouter.md deleted file mode 100644 index dac6c1a646..0000000000 --- a/docs/docs/en/api/faststream/confluent/router/KafkaRouter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.router.KafkaRouter diff --git a/docs/docs/en/api/faststream/confluent/schemas/TopicPartition.md b/docs/docs/en/api/faststream/confluent/schemas/TopicPartition.md deleted file mode 100644 index 0c52345b4e..0000000000 --- a/docs/docs/en/api/faststream/confluent/schemas/TopicPartition.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.schemas.TopicPartition diff --git a/docs/docs/en/api/faststream/confluent/schemas/params/ConsumerConnectionParams.md b/docs/docs/en/api/faststream/confluent/schemas/params/ConsumerConnectionParams.md deleted file mode 100644 index f4ed5b2004..0000000000 --- a/docs/docs/en/api/faststream/confluent/schemas/params/ConsumerConnectionParams.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.schemas.params.ConsumerConnectionParams diff --git a/docs/docs/en/api/faststream/confluent/schemas/partition/TopicPartition.md b/docs/docs/en/api/faststream/confluent/schemas/partition/TopicPartition.md deleted file mode 100644 index 11e0bc2b3c..0000000000 --- a/docs/docs/en/api/faststream/confluent/schemas/partition/TopicPartition.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.schemas.partition.TopicPartition diff --git a/docs/docs/en/api/faststream/confluent/security/parse_security.md b/docs/docs/en/api/faststream/confluent/security/parse_security.md deleted file mode 100644 index 1eb84ceed6..0000000000 --- a/docs/docs/en/api/faststream/confluent/security/parse_security.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.security.parse_security diff --git a/docs/docs/en/api/faststream/confluent/subscriber/factory/create_subscriber.md b/docs/docs/en/api/faststream/confluent/subscriber/factory/create_subscriber.md deleted file mode 100644 index ce811a99d9..0000000000 --- a/docs/docs/en/api/faststream/confluent/subscriber/factory/create_subscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.subscriber.factory.create_subscriber diff --git a/docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationBatchSubscriber.md b/docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationBatchSubscriber.md deleted file mode 100644 index ae9e9f42e8..0000000000 --- a/docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationBatchSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.subscriber.specified.SpecificationBatchSubscriber diff --git a/docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationConcurrentDefaultSubscriber.md b/docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationConcurrentDefaultSubscriber.md deleted file mode 100644 index a42a4cb21b..0000000000 --- a/docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationConcurrentDefaultSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.subscriber.specified.SpecificationConcurrentDefaultSubscriber diff --git a/docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationDefaultSubscriber.md b/docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationDefaultSubscriber.md deleted file mode 100644 index d4dd2d304e..0000000000 --- a/docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationDefaultSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.subscriber.specified.SpecificationDefaultSubscriber diff --git a/docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationSubscriber.md b/docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationSubscriber.md deleted file mode 100644 index 8887278921..0000000000 --- a/docs/docs/en/api/faststream/confluent/subscriber/specified/SpecificationSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.subscriber.specified.SpecificationSubscriber diff --git a/docs/docs/en/api/faststream/confluent/subscriber/usecase/BatchSubscriber.md b/docs/docs/en/api/faststream/confluent/subscriber/usecase/BatchSubscriber.md deleted file mode 100644 index 4642abd4a8..0000000000 --- a/docs/docs/en/api/faststream/confluent/subscriber/usecase/BatchSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.subscriber.usecase.BatchSubscriber diff --git a/docs/docs/en/api/faststream/confluent/subscriber/usecase/ConcurrentDefaultSubscriber.md b/docs/docs/en/api/faststream/confluent/subscriber/usecase/ConcurrentDefaultSubscriber.md deleted file mode 100644 index 13d0f308c1..0000000000 --- a/docs/docs/en/api/faststream/confluent/subscriber/usecase/ConcurrentDefaultSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.subscriber.usecase.ConcurrentDefaultSubscriber diff --git a/docs/docs/en/api/faststream/confluent/subscriber/usecase/DefaultSubscriber.md b/docs/docs/en/api/faststream/confluent/subscriber/usecase/DefaultSubscriber.md deleted file mode 100644 index c2d7ed227e..0000000000 --- a/docs/docs/en/api/faststream/confluent/subscriber/usecase/DefaultSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.subscriber.usecase.DefaultSubscriber diff --git a/docs/docs/en/api/faststream/confluent/subscriber/usecase/LogicSubscriber.md b/docs/docs/en/api/faststream/confluent/subscriber/usecase/LogicSubscriber.md deleted file mode 100644 index c47daf891f..0000000000 --- a/docs/docs/en/api/faststream/confluent/subscriber/usecase/LogicSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.subscriber.usecase.LogicSubscriber diff --git a/docs/docs/en/api/faststream/confluent/testing/FakeProducer.md b/docs/docs/en/api/faststream/confluent/testing/FakeProducer.md deleted file mode 100644 index aeaee2a2d7..0000000000 --- a/docs/docs/en/api/faststream/confluent/testing/FakeProducer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.testing.FakeProducer diff --git a/docs/docs/en/api/faststream/confluent/testing/MockConfluentMessage.md b/docs/docs/en/api/faststream/confluent/testing/MockConfluentMessage.md deleted file mode 100644 index 78791486ab..0000000000 --- a/docs/docs/en/api/faststream/confluent/testing/MockConfluentMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.testing.MockConfluentMessage diff --git a/docs/docs/en/api/faststream/confluent/testing/TestKafkaBroker.md b/docs/docs/en/api/faststream/confluent/testing/TestKafkaBroker.md deleted file mode 100644 index 53dfed8f24..0000000000 --- a/docs/docs/en/api/faststream/confluent/testing/TestKafkaBroker.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.testing.TestKafkaBroker diff --git a/docs/docs/en/api/faststream/confluent/testing/build_message.md b/docs/docs/en/api/faststream/confluent/testing/build_message.md deleted file mode 100644 index 75787a13b3..0000000000 --- a/docs/docs/en/api/faststream/confluent/testing/build_message.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.confluent.testing.build_message diff --git a/docs/docs/en/api/faststream/exceptions/AckMessage.md b/docs/docs/en/api/faststream/exceptions/AckMessage.md deleted file mode 100644 index 175efc68ed..0000000000 --- a/docs/docs/en/api/faststream/exceptions/AckMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.exceptions.AckMessage diff --git a/docs/docs/en/api/faststream/exceptions/ContextError.md b/docs/docs/en/api/faststream/exceptions/ContextError.md deleted file mode 100644 index 73b4fcdd21..0000000000 --- a/docs/docs/en/api/faststream/exceptions/ContextError.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.exceptions.ContextError diff --git a/docs/docs/en/api/faststream/exceptions/FastStreamException.md b/docs/docs/en/api/faststream/exceptions/FastStreamException.md deleted file mode 100644 index bd988e9332..0000000000 --- a/docs/docs/en/api/faststream/exceptions/FastStreamException.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.exceptions.FastStreamException diff --git a/docs/docs/en/api/faststream/exceptions/FeatureNotSupportedException.md b/docs/docs/en/api/faststream/exceptions/FeatureNotSupportedException.md deleted file mode 100644 index bbf1f32d2b..0000000000 --- a/docs/docs/en/api/faststream/exceptions/FeatureNotSupportedException.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.exceptions.FeatureNotSupportedException diff --git a/docs/docs/en/api/faststream/exceptions/HandlerException.md b/docs/docs/en/api/faststream/exceptions/HandlerException.md deleted file mode 100644 index 64495519a4..0000000000 --- a/docs/docs/en/api/faststream/exceptions/HandlerException.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.exceptions.HandlerException diff --git a/docs/docs/en/api/faststream/exceptions/IgnoredException.md b/docs/docs/en/api/faststream/exceptions/IgnoredException.md deleted file mode 100644 index 18452057c1..0000000000 --- a/docs/docs/en/api/faststream/exceptions/IgnoredException.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.exceptions.IgnoredException diff --git a/docs/docs/en/api/faststream/exceptions/IncorrectState.md b/docs/docs/en/api/faststream/exceptions/IncorrectState.md deleted file mode 100644 index 2c890d5358..0000000000 --- a/docs/docs/en/api/faststream/exceptions/IncorrectState.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.exceptions.IncorrectState diff --git a/docs/docs/en/api/faststream/exceptions/NackMessage.md b/docs/docs/en/api/faststream/exceptions/NackMessage.md deleted file mode 100644 index 05502ca14d..0000000000 --- a/docs/docs/en/api/faststream/exceptions/NackMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.exceptions.NackMessage diff --git a/docs/docs/en/api/faststream/exceptions/RejectMessage.md b/docs/docs/en/api/faststream/exceptions/RejectMessage.md deleted file mode 100644 index be491d89c1..0000000000 --- a/docs/docs/en/api/faststream/exceptions/RejectMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.exceptions.RejectMessage diff --git a/docs/docs/en/api/faststream/exceptions/SetupError.md b/docs/docs/en/api/faststream/exceptions/SetupError.md deleted file mode 100644 index 588e66557f..0000000000 --- a/docs/docs/en/api/faststream/exceptions/SetupError.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.exceptions.SetupError diff --git a/docs/docs/en/api/faststream/exceptions/SkipMessage.md b/docs/docs/en/api/faststream/exceptions/SkipMessage.md deleted file mode 100644 index e2a6ac135e..0000000000 --- a/docs/docs/en/api/faststream/exceptions/SkipMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.exceptions.SkipMessage diff --git a/docs/docs/en/api/faststream/exceptions/StartupValidationError.md b/docs/docs/en/api/faststream/exceptions/StartupValidationError.md deleted file mode 100644 index 05b8e7b74d..0000000000 --- a/docs/docs/en/api/faststream/exceptions/StartupValidationError.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.exceptions.StartupValidationError diff --git a/docs/docs/en/api/faststream/exceptions/StopApplication.md b/docs/docs/en/api/faststream/exceptions/StopApplication.md deleted file mode 100644 index 12059837a4..0000000000 --- a/docs/docs/en/api/faststream/exceptions/StopApplication.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.exceptions.StopApplication diff --git a/docs/docs/en/api/faststream/exceptions/StopConsume.md b/docs/docs/en/api/faststream/exceptions/StopConsume.md deleted file mode 100644 index 9733dcc2e9..0000000000 --- a/docs/docs/en/api/faststream/exceptions/StopConsume.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.exceptions.StopConsume diff --git a/docs/docs/en/api/faststream/exceptions/SubscriberNotFound.md b/docs/docs/en/api/faststream/exceptions/SubscriberNotFound.md deleted file mode 100644 index 89428f8251..0000000000 --- a/docs/docs/en/api/faststream/exceptions/SubscriberNotFound.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.exceptions.SubscriberNotFound diff --git a/docs/docs/en/api/faststream/kafka/KafkaBroker.md b/docs/docs/en/api/faststream/kafka/KafkaBroker.md deleted file mode 100644 index 7ee56a5e01..0000000000 --- a/docs/docs/en/api/faststream/kafka/KafkaBroker.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.KafkaBroker diff --git a/docs/docs/en/api/faststream/kafka/KafkaPublisher.md b/docs/docs/en/api/faststream/kafka/KafkaPublisher.md deleted file mode 100644 index c379528109..0000000000 --- a/docs/docs/en/api/faststream/kafka/KafkaPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.KafkaPublisher diff --git a/docs/docs/en/api/faststream/kafka/KafkaResponse.md b/docs/docs/en/api/faststream/kafka/KafkaResponse.md deleted file mode 100644 index 4aab0b965d..0000000000 --- a/docs/docs/en/api/faststream/kafka/KafkaResponse.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.KafkaResponse diff --git a/docs/docs/en/api/faststream/kafka/KafkaRoute.md b/docs/docs/en/api/faststream/kafka/KafkaRoute.md deleted file mode 100644 index 89a8d8cca1..0000000000 --- a/docs/docs/en/api/faststream/kafka/KafkaRoute.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.KafkaRoute diff --git a/docs/docs/en/api/faststream/kafka/KafkaRouter.md b/docs/docs/en/api/faststream/kafka/KafkaRouter.md deleted file mode 100644 index c60f3ca6f4..0000000000 --- a/docs/docs/en/api/faststream/kafka/KafkaRouter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.KafkaRouter diff --git a/docs/docs/en/api/faststream/kafka/TestApp.md b/docs/docs/en/api/faststream/kafka/TestApp.md deleted file mode 100644 index ad101303af..0000000000 --- a/docs/docs/en/api/faststream/kafka/TestApp.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream._internal.testing.app.TestApp diff --git a/docs/docs/en/api/faststream/kafka/TestKafkaBroker.md b/docs/docs/en/api/faststream/kafka/TestKafkaBroker.md deleted file mode 100644 index 096df3b1d1..0000000000 --- a/docs/docs/en/api/faststream/kafka/TestKafkaBroker.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.TestKafkaBroker diff --git a/docs/docs/en/api/faststream/kafka/TopicPartition.md b/docs/docs/en/api/faststream/kafka/TopicPartition.md deleted file mode 100644 index 41fbd7f624..0000000000 --- a/docs/docs/en/api/faststream/kafka/TopicPartition.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: aiokafka.structs.TopicPartition diff --git a/docs/docs/en/api/faststream/kafka/broker/KafkaBroker.md b/docs/docs/en/api/faststream/kafka/broker/KafkaBroker.md deleted file mode 100644 index 2cee711d14..0000000000 --- a/docs/docs/en/api/faststream/kafka/broker/KafkaBroker.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.broker.KafkaBroker diff --git a/docs/docs/en/api/faststream/kafka/broker/broker/KafkaBroker.md b/docs/docs/en/api/faststream/kafka/broker/broker/KafkaBroker.md deleted file mode 100644 index ca32dd3865..0000000000 --- a/docs/docs/en/api/faststream/kafka/broker/broker/KafkaBroker.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.broker.broker.KafkaBroker diff --git a/docs/docs/en/api/faststream/kafka/broker/logging/KafkaParamsStorage.md b/docs/docs/en/api/faststream/kafka/broker/logging/KafkaParamsStorage.md deleted file mode 100644 index f7c8136115..0000000000 --- a/docs/docs/en/api/faststream/kafka/broker/logging/KafkaParamsStorage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.broker.logging.KafkaParamsStorage diff --git a/docs/docs/en/api/faststream/kafka/broker/registrator/KafkaRegistrator.md b/docs/docs/en/api/faststream/kafka/broker/registrator/KafkaRegistrator.md deleted file mode 100644 index aa06d38f65..0000000000 --- a/docs/docs/en/api/faststream/kafka/broker/registrator/KafkaRegistrator.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.broker.registrator.KafkaRegistrator diff --git a/docs/docs/en/api/faststream/kafka/fastapi/Context.md b/docs/docs/en/api/faststream/kafka/fastapi/Context.md deleted file mode 100644 index 99bf141f5c..0000000000 --- a/docs/docs/en/api/faststream/kafka/fastapi/Context.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream._internal.fastapi.context.Context diff --git a/docs/docs/en/api/faststream/kafka/fastapi/KafkaRouter.md b/docs/docs/en/api/faststream/kafka/fastapi/KafkaRouter.md deleted file mode 100644 index 2ab7254e79..0000000000 --- a/docs/docs/en/api/faststream/kafka/fastapi/KafkaRouter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.fastapi.KafkaRouter diff --git a/docs/docs/en/api/faststream/kafka/fastapi/fastapi/KafkaRouter.md b/docs/docs/en/api/faststream/kafka/fastapi/fastapi/KafkaRouter.md deleted file mode 100644 index 80fc17dd4a..0000000000 --- a/docs/docs/en/api/faststream/kafka/fastapi/fastapi/KafkaRouter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.fastapi.fastapi.KafkaRouter diff --git a/docs/docs/en/api/faststream/kafka/message/ConsumerProtocol.md b/docs/docs/en/api/faststream/kafka/message/ConsumerProtocol.md deleted file mode 100644 index c9fd16a983..0000000000 --- a/docs/docs/en/api/faststream/kafka/message/ConsumerProtocol.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.message.ConsumerProtocol diff --git a/docs/docs/en/api/faststream/kafka/message/FakeConsumer.md b/docs/docs/en/api/faststream/kafka/message/FakeConsumer.md deleted file mode 100644 index d41724b288..0000000000 --- a/docs/docs/en/api/faststream/kafka/message/FakeConsumer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.message.FakeConsumer diff --git a/docs/docs/en/api/faststream/kafka/message/KafkaAckableMessage.md b/docs/docs/en/api/faststream/kafka/message/KafkaAckableMessage.md deleted file mode 100644 index 16461be675..0000000000 --- a/docs/docs/en/api/faststream/kafka/message/KafkaAckableMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.message.KafkaAckableMessage diff --git a/docs/docs/en/api/faststream/kafka/message/KafkaMessage.md b/docs/docs/en/api/faststream/kafka/message/KafkaMessage.md deleted file mode 100644 index 7a7a30bae3..0000000000 --- a/docs/docs/en/api/faststream/kafka/message/KafkaMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.message.KafkaMessage diff --git a/docs/docs/en/api/faststream/kafka/opentelemetry/KafkaTelemetryMiddleware.md b/docs/docs/en/api/faststream/kafka/opentelemetry/KafkaTelemetryMiddleware.md deleted file mode 100644 index 02fb4805ac..0000000000 --- a/docs/docs/en/api/faststream/kafka/opentelemetry/KafkaTelemetryMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.opentelemetry.KafkaTelemetryMiddleware diff --git a/docs/docs/en/api/faststream/kafka/opentelemetry/middleware/KafkaTelemetryMiddleware.md b/docs/docs/en/api/faststream/kafka/opentelemetry/middleware/KafkaTelemetryMiddleware.md deleted file mode 100644 index aba78378f2..0000000000 --- a/docs/docs/en/api/faststream/kafka/opentelemetry/middleware/KafkaTelemetryMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.opentelemetry.middleware.KafkaTelemetryMiddleware diff --git a/docs/docs/en/api/faststream/kafka/opentelemetry/provider/BaseKafkaTelemetrySettingsProvider.md b/docs/docs/en/api/faststream/kafka/opentelemetry/provider/BaseKafkaTelemetrySettingsProvider.md deleted file mode 100644 index 5cb13be947..0000000000 --- a/docs/docs/en/api/faststream/kafka/opentelemetry/provider/BaseKafkaTelemetrySettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.opentelemetry.provider.BaseKafkaTelemetrySettingsProvider diff --git a/docs/docs/en/api/faststream/kafka/opentelemetry/provider/BatchKafkaTelemetrySettingsProvider.md b/docs/docs/en/api/faststream/kafka/opentelemetry/provider/BatchKafkaTelemetrySettingsProvider.md deleted file mode 100644 index d3d7080509..0000000000 --- a/docs/docs/en/api/faststream/kafka/opentelemetry/provider/BatchKafkaTelemetrySettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.opentelemetry.provider.BatchKafkaTelemetrySettingsProvider diff --git a/docs/docs/en/api/faststream/kafka/opentelemetry/provider/KafkaTelemetrySettingsProvider.md b/docs/docs/en/api/faststream/kafka/opentelemetry/provider/KafkaTelemetrySettingsProvider.md deleted file mode 100644 index 0859c0df3d..0000000000 --- a/docs/docs/en/api/faststream/kafka/opentelemetry/provider/KafkaTelemetrySettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.opentelemetry.provider.KafkaTelemetrySettingsProvider diff --git a/docs/docs/en/api/faststream/kafka/opentelemetry/provider/telemetry_attributes_provider_factory.md b/docs/docs/en/api/faststream/kafka/opentelemetry/provider/telemetry_attributes_provider_factory.md deleted file mode 100644 index 3b2a1ad394..0000000000 --- a/docs/docs/en/api/faststream/kafka/opentelemetry/provider/telemetry_attributes_provider_factory.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.opentelemetry.provider.telemetry_attributes_provider_factory diff --git a/docs/docs/en/api/faststream/kafka/parser/AioKafkaBatchParser.md b/docs/docs/en/api/faststream/kafka/parser/AioKafkaBatchParser.md deleted file mode 100644 index 25df2532c6..0000000000 --- a/docs/docs/en/api/faststream/kafka/parser/AioKafkaBatchParser.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.parser.AioKafkaBatchParser diff --git a/docs/docs/en/api/faststream/kafka/parser/AioKafkaParser.md b/docs/docs/en/api/faststream/kafka/parser/AioKafkaParser.md deleted file mode 100644 index e7e37cce97..0000000000 --- a/docs/docs/en/api/faststream/kafka/parser/AioKafkaParser.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.parser.AioKafkaParser diff --git a/docs/docs/en/api/faststream/kafka/prometheus/KafkaPrometheusMiddleware.md b/docs/docs/en/api/faststream/kafka/prometheus/KafkaPrometheusMiddleware.md deleted file mode 100644 index c2ffd5356a..0000000000 --- a/docs/docs/en/api/faststream/kafka/prometheus/KafkaPrometheusMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.prometheus.KafkaPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/kafka/prometheus/middleware/KafkaPrometheusMiddleware.md b/docs/docs/en/api/faststream/kafka/prometheus/middleware/KafkaPrometheusMiddleware.md deleted file mode 100644 index 451b7080c0..0000000000 --- a/docs/docs/en/api/faststream/kafka/prometheus/middleware/KafkaPrometheusMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.prometheus.middleware.KafkaPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/kafka/prometheus/provider/BaseKafkaMetricsSettingsProvider.md b/docs/docs/en/api/faststream/kafka/prometheus/provider/BaseKafkaMetricsSettingsProvider.md deleted file mode 100644 index 0fd044f694..0000000000 --- a/docs/docs/en/api/faststream/kafka/prometheus/provider/BaseKafkaMetricsSettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.prometheus.provider.BaseKafkaMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/kafka/prometheus/provider/BatchKafkaMetricsSettingsProvider.md b/docs/docs/en/api/faststream/kafka/prometheus/provider/BatchKafkaMetricsSettingsProvider.md deleted file mode 100644 index 9bd01d5e71..0000000000 --- a/docs/docs/en/api/faststream/kafka/prometheus/provider/BatchKafkaMetricsSettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.prometheus.provider.BatchKafkaMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/kafka/prometheus/provider/KafkaMetricsSettingsProvider.md b/docs/docs/en/api/faststream/kafka/prometheus/provider/KafkaMetricsSettingsProvider.md deleted file mode 100644 index ae7c490da8..0000000000 --- a/docs/docs/en/api/faststream/kafka/prometheus/provider/KafkaMetricsSettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.prometheus.provider.KafkaMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/kafka/prometheus/provider/settings_provider_factory.md b/docs/docs/en/api/faststream/kafka/prometheus/provider/settings_provider_factory.md deleted file mode 100644 index 1393fd9065..0000000000 --- a/docs/docs/en/api/faststream/kafka/prometheus/provider/settings_provider_factory.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.prometheus.provider.settings_provider_factory diff --git a/docs/docs/en/api/faststream/kafka/publisher/factory/create_publisher.md b/docs/docs/en/api/faststream/kafka/publisher/factory/create_publisher.md deleted file mode 100644 index 7ec33758af..0000000000 --- a/docs/docs/en/api/faststream/kafka/publisher/factory/create_publisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.publisher.factory.create_publisher diff --git a/docs/docs/en/api/faststream/kafka/publisher/fake/KafkaFakePublisher.md b/docs/docs/en/api/faststream/kafka/publisher/fake/KafkaFakePublisher.md deleted file mode 100644 index 6bacca904e..0000000000 --- a/docs/docs/en/api/faststream/kafka/publisher/fake/KafkaFakePublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.publisher.fake.KafkaFakePublisher diff --git a/docs/docs/en/api/faststream/kafka/publisher/producer/AioKafkaFastProducer.md b/docs/docs/en/api/faststream/kafka/publisher/producer/AioKafkaFastProducer.md deleted file mode 100644 index 83b116989b..0000000000 --- a/docs/docs/en/api/faststream/kafka/publisher/producer/AioKafkaFastProducer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.publisher.producer.AioKafkaFastProducer diff --git a/docs/docs/en/api/faststream/kafka/publisher/specified/SpecificationBatchPublisher.md b/docs/docs/en/api/faststream/kafka/publisher/specified/SpecificationBatchPublisher.md deleted file mode 100644 index 795766b030..0000000000 --- a/docs/docs/en/api/faststream/kafka/publisher/specified/SpecificationBatchPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.publisher.specified.SpecificationBatchPublisher diff --git a/docs/docs/en/api/faststream/kafka/publisher/specified/SpecificationDefaultPublisher.md b/docs/docs/en/api/faststream/kafka/publisher/specified/SpecificationDefaultPublisher.md deleted file mode 100644 index e191045545..0000000000 --- a/docs/docs/en/api/faststream/kafka/publisher/specified/SpecificationDefaultPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.publisher.specified.SpecificationDefaultPublisher diff --git a/docs/docs/en/api/faststream/kafka/publisher/specified/SpecificationPublisher.md b/docs/docs/en/api/faststream/kafka/publisher/specified/SpecificationPublisher.md deleted file mode 100644 index ed687d7e08..0000000000 --- a/docs/docs/en/api/faststream/kafka/publisher/specified/SpecificationPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.publisher.specified.SpecificationPublisher diff --git a/docs/docs/en/api/faststream/kafka/publisher/state/EmptyProducerState.md b/docs/docs/en/api/faststream/kafka/publisher/state/EmptyProducerState.md deleted file mode 100644 index 0152ee7c2f..0000000000 --- a/docs/docs/en/api/faststream/kafka/publisher/state/EmptyProducerState.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.publisher.state.EmptyProducerState diff --git a/docs/docs/en/api/faststream/kafka/publisher/state/ProducerState.md b/docs/docs/en/api/faststream/kafka/publisher/state/ProducerState.md deleted file mode 100644 index c937179471..0000000000 --- a/docs/docs/en/api/faststream/kafka/publisher/state/ProducerState.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.publisher.state.ProducerState diff --git a/docs/docs/en/api/faststream/kafka/publisher/state/RealProducer.md b/docs/docs/en/api/faststream/kafka/publisher/state/RealProducer.md deleted file mode 100644 index a576226b3c..0000000000 --- a/docs/docs/en/api/faststream/kafka/publisher/state/RealProducer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.publisher.state.RealProducer diff --git a/docs/docs/en/api/faststream/kafka/publisher/usecase/BatchPublisher.md b/docs/docs/en/api/faststream/kafka/publisher/usecase/BatchPublisher.md deleted file mode 100644 index 045cfbf45f..0000000000 --- a/docs/docs/en/api/faststream/kafka/publisher/usecase/BatchPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.publisher.usecase.BatchPublisher diff --git a/docs/docs/en/api/faststream/kafka/publisher/usecase/DefaultPublisher.md b/docs/docs/en/api/faststream/kafka/publisher/usecase/DefaultPublisher.md deleted file mode 100644 index 07518c75b3..0000000000 --- a/docs/docs/en/api/faststream/kafka/publisher/usecase/DefaultPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.publisher.usecase.DefaultPublisher diff --git a/docs/docs/en/api/faststream/kafka/publisher/usecase/LogicPublisher.md b/docs/docs/en/api/faststream/kafka/publisher/usecase/LogicPublisher.md deleted file mode 100644 index 615da58f90..0000000000 --- a/docs/docs/en/api/faststream/kafka/publisher/usecase/LogicPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.publisher.usecase.LogicPublisher diff --git a/docs/docs/en/api/faststream/kafka/response/KafkaPublishCommand.md b/docs/docs/en/api/faststream/kafka/response/KafkaPublishCommand.md deleted file mode 100644 index 4852098fcc..0000000000 --- a/docs/docs/en/api/faststream/kafka/response/KafkaPublishCommand.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.response.KafkaPublishCommand diff --git a/docs/docs/en/api/faststream/kafka/response/KafkaResponse.md b/docs/docs/en/api/faststream/kafka/response/KafkaResponse.md deleted file mode 100644 index 05ecd69c2d..0000000000 --- a/docs/docs/en/api/faststream/kafka/response/KafkaResponse.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.response.KafkaResponse diff --git a/docs/docs/en/api/faststream/kafka/router/KafkaPublisher.md b/docs/docs/en/api/faststream/kafka/router/KafkaPublisher.md deleted file mode 100644 index 5027c18f20..0000000000 --- a/docs/docs/en/api/faststream/kafka/router/KafkaPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.router.KafkaPublisher diff --git a/docs/docs/en/api/faststream/kafka/router/KafkaRoute.md b/docs/docs/en/api/faststream/kafka/router/KafkaRoute.md deleted file mode 100644 index e7e6184deb..0000000000 --- a/docs/docs/en/api/faststream/kafka/router/KafkaRoute.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.router.KafkaRoute diff --git a/docs/docs/en/api/faststream/kafka/router/KafkaRouter.md b/docs/docs/en/api/faststream/kafka/router/KafkaRouter.md deleted file mode 100644 index 5d7578bbfc..0000000000 --- a/docs/docs/en/api/faststream/kafka/router/KafkaRouter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.router.KafkaRouter diff --git a/docs/docs/en/api/faststream/kafka/schemas/params/ConsumerConnectionParams.md b/docs/docs/en/api/faststream/kafka/schemas/params/ConsumerConnectionParams.md deleted file mode 100644 index b289e61e5a..0000000000 --- a/docs/docs/en/api/faststream/kafka/schemas/params/ConsumerConnectionParams.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.schemas.params.ConsumerConnectionParams diff --git a/docs/docs/en/api/faststream/kafka/security/parse_security.md b/docs/docs/en/api/faststream/kafka/security/parse_security.md deleted file mode 100644 index e325a99ad8..0000000000 --- a/docs/docs/en/api/faststream/kafka/security/parse_security.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.security.parse_security diff --git a/docs/docs/en/api/faststream/kafka/subscriber/factory/create_subscriber.md b/docs/docs/en/api/faststream/kafka/subscriber/factory/create_subscriber.md deleted file mode 100644 index d9e5fcb4a4..0000000000 --- a/docs/docs/en/api/faststream/kafka/subscriber/factory/create_subscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.subscriber.factory.create_subscriber diff --git a/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationBatchSubscriber.md b/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationBatchSubscriber.md deleted file mode 100644 index 9e0ce90401..0000000000 --- a/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationBatchSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.subscriber.specified.SpecificationBatchSubscriber diff --git a/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationConcurrentDefaultSubscriber.md b/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationConcurrentDefaultSubscriber.md deleted file mode 100644 index 16f0f81d14..0000000000 --- a/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationConcurrentDefaultSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.subscriber.specified.SpecificationConcurrentDefaultSubscriber diff --git a/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationDefaultSubscriber.md b/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationDefaultSubscriber.md deleted file mode 100644 index fe8ac61ac2..0000000000 --- a/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationDefaultSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.subscriber.specified.SpecificationDefaultSubscriber diff --git a/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationSubscriber.md b/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationSubscriber.md deleted file mode 100644 index 79dca87d97..0000000000 --- a/docs/docs/en/api/faststream/kafka/subscriber/specified/SpecificationSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.subscriber.specified.SpecificationSubscriber diff --git a/docs/docs/en/api/faststream/kafka/subscriber/usecase/BatchSubscriber.md b/docs/docs/en/api/faststream/kafka/subscriber/usecase/BatchSubscriber.md deleted file mode 100644 index 6f8978f38b..0000000000 --- a/docs/docs/en/api/faststream/kafka/subscriber/usecase/BatchSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.subscriber.usecase.BatchSubscriber diff --git a/docs/docs/en/api/faststream/kafka/subscriber/usecase/ConcurrentDefaultSubscriber.md b/docs/docs/en/api/faststream/kafka/subscriber/usecase/ConcurrentDefaultSubscriber.md deleted file mode 100644 index 16f09d9334..0000000000 --- a/docs/docs/en/api/faststream/kafka/subscriber/usecase/ConcurrentDefaultSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.subscriber.usecase.ConcurrentDefaultSubscriber diff --git a/docs/docs/en/api/faststream/kafka/subscriber/usecase/DefaultSubscriber.md b/docs/docs/en/api/faststream/kafka/subscriber/usecase/DefaultSubscriber.md deleted file mode 100644 index 78949c27dd..0000000000 --- a/docs/docs/en/api/faststream/kafka/subscriber/usecase/DefaultSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.subscriber.usecase.DefaultSubscriber diff --git a/docs/docs/en/api/faststream/kafka/subscriber/usecase/LogicSubscriber.md b/docs/docs/en/api/faststream/kafka/subscriber/usecase/LogicSubscriber.md deleted file mode 100644 index 297013e037..0000000000 --- a/docs/docs/en/api/faststream/kafka/subscriber/usecase/LogicSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.subscriber.usecase.LogicSubscriber diff --git a/docs/docs/en/api/faststream/kafka/testing/FakeProducer.md b/docs/docs/en/api/faststream/kafka/testing/FakeProducer.md deleted file mode 100644 index 63eb94c3ca..0000000000 --- a/docs/docs/en/api/faststream/kafka/testing/FakeProducer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.testing.FakeProducer diff --git a/docs/docs/en/api/faststream/kafka/testing/TestKafkaBroker.md b/docs/docs/en/api/faststream/kafka/testing/TestKafkaBroker.md deleted file mode 100644 index 96f257a15f..0000000000 --- a/docs/docs/en/api/faststream/kafka/testing/TestKafkaBroker.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.testing.TestKafkaBroker diff --git a/docs/docs/en/api/faststream/kafka/testing/build_message.md b/docs/docs/en/api/faststream/kafka/testing/build_message.md deleted file mode 100644 index 354d7a82f3..0000000000 --- a/docs/docs/en/api/faststream/kafka/testing/build_message.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.kafka.testing.build_message diff --git a/docs/docs/en/api/faststream/message/AckStatus.md b/docs/docs/en/api/faststream/message/AckStatus.md deleted file mode 100644 index b8d3d6c6c8..0000000000 --- a/docs/docs/en/api/faststream/message/AckStatus.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.message.AckStatus diff --git a/docs/docs/en/api/faststream/message/SourceType.md b/docs/docs/en/api/faststream/message/SourceType.md deleted file mode 100644 index 7df391eac3..0000000000 --- a/docs/docs/en/api/faststream/message/SourceType.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.message.SourceType diff --git a/docs/docs/en/api/faststream/message/StreamMessage.md b/docs/docs/en/api/faststream/message/StreamMessage.md deleted file mode 100644 index 5f072b2410..0000000000 --- a/docs/docs/en/api/faststream/message/StreamMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.message.StreamMessage diff --git a/docs/docs/en/api/faststream/message/decode_message.md b/docs/docs/en/api/faststream/message/decode_message.md deleted file mode 100644 index c0dce11670..0000000000 --- a/docs/docs/en/api/faststream/message/decode_message.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.message.decode_message diff --git a/docs/docs/en/api/faststream/message/encode_message.md b/docs/docs/en/api/faststream/message/encode_message.md deleted file mode 100644 index 7d33d8d904..0000000000 --- a/docs/docs/en/api/faststream/message/encode_message.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.message.encode_message diff --git a/docs/docs/en/api/faststream/message/gen_cor_id.md b/docs/docs/en/api/faststream/message/gen_cor_id.md deleted file mode 100644 index 0abdf298b9..0000000000 --- a/docs/docs/en/api/faststream/message/gen_cor_id.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.message.gen_cor_id diff --git a/docs/docs/en/api/faststream/message/message/AckStatus.md b/docs/docs/en/api/faststream/message/message/AckStatus.md deleted file mode 100644 index 80940a8ba7..0000000000 --- a/docs/docs/en/api/faststream/message/message/AckStatus.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.message.message.AckStatus diff --git a/docs/docs/en/api/faststream/message/message/StreamMessage.md b/docs/docs/en/api/faststream/message/message/StreamMessage.md deleted file mode 100644 index a41232b74c..0000000000 --- a/docs/docs/en/api/faststream/message/message/StreamMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.message.message.StreamMessage diff --git a/docs/docs/en/api/faststream/message/source_type/SourceType.md b/docs/docs/en/api/faststream/message/source_type/SourceType.md deleted file mode 100644 index 8a6fc990e4..0000000000 --- a/docs/docs/en/api/faststream/message/source_type/SourceType.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.message.source_type.SourceType diff --git a/docs/docs/en/api/faststream/message/utils/decode_message.md b/docs/docs/en/api/faststream/message/utils/decode_message.md deleted file mode 100644 index b2ec48dac0..0000000000 --- a/docs/docs/en/api/faststream/message/utils/decode_message.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.message.utils.decode_message diff --git a/docs/docs/en/api/faststream/message/utils/encode_message.md b/docs/docs/en/api/faststream/message/utils/encode_message.md deleted file mode 100644 index 7401e07da5..0000000000 --- a/docs/docs/en/api/faststream/message/utils/encode_message.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.message.utils.encode_message diff --git a/docs/docs/en/api/faststream/message/utils/gen_cor_id.md b/docs/docs/en/api/faststream/message/utils/gen_cor_id.md deleted file mode 100644 index 74b49c30d2..0000000000 --- a/docs/docs/en/api/faststream/message/utils/gen_cor_id.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.message.utils.gen_cor_id diff --git a/docs/docs/en/api/faststream/middlewares/AckPolicy.md b/docs/docs/en/api/faststream/middlewares/AckPolicy.md deleted file mode 100644 index 82d0033dfb..0000000000 --- a/docs/docs/en/api/faststream/middlewares/AckPolicy.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.middlewares.AckPolicy diff --git a/docs/docs/en/api/faststream/middlewares/AcknowledgementMiddleware.md b/docs/docs/en/api/faststream/middlewares/AcknowledgementMiddleware.md deleted file mode 100644 index d3e7d6a763..0000000000 --- a/docs/docs/en/api/faststream/middlewares/AcknowledgementMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.middlewares.AcknowledgementMiddleware diff --git a/docs/docs/en/api/faststream/middlewares/BaseMiddleware.md b/docs/docs/en/api/faststream/middlewares/BaseMiddleware.md deleted file mode 100644 index 30f98187a1..0000000000 --- a/docs/docs/en/api/faststream/middlewares/BaseMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.middlewares.BaseMiddleware diff --git a/docs/docs/en/api/faststream/middlewares/ExceptionMiddleware.md b/docs/docs/en/api/faststream/middlewares/ExceptionMiddleware.md deleted file mode 100644 index c1d21850c8..0000000000 --- a/docs/docs/en/api/faststream/middlewares/ExceptionMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.middlewares.ExceptionMiddleware diff --git a/docs/docs/en/api/faststream/middlewares/acknowledgement/conf/AckPolicy.md b/docs/docs/en/api/faststream/middlewares/acknowledgement/conf/AckPolicy.md deleted file mode 100644 index 8a92ec0a54..0000000000 --- a/docs/docs/en/api/faststream/middlewares/acknowledgement/conf/AckPolicy.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.middlewares.acknowledgement.conf.AckPolicy diff --git a/docs/docs/en/api/faststream/middlewares/acknowledgement/middleware/AcknowledgementMiddleware.md b/docs/docs/en/api/faststream/middlewares/acknowledgement/middleware/AcknowledgementMiddleware.md deleted file mode 100644 index 79b2956eb4..0000000000 --- a/docs/docs/en/api/faststream/middlewares/acknowledgement/middleware/AcknowledgementMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.middlewares.acknowledgement.middleware.AcknowledgementMiddleware diff --git a/docs/docs/en/api/faststream/middlewares/base/BaseMiddleware.md b/docs/docs/en/api/faststream/middlewares/base/BaseMiddleware.md deleted file mode 100644 index d3319e7441..0000000000 --- a/docs/docs/en/api/faststream/middlewares/base/BaseMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.middlewares.base.BaseMiddleware diff --git a/docs/docs/en/api/faststream/middlewares/exception/ExceptionMiddleware.md b/docs/docs/en/api/faststream/middlewares/exception/ExceptionMiddleware.md deleted file mode 100644 index da1693a722..0000000000 --- a/docs/docs/en/api/faststream/middlewares/exception/ExceptionMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.middlewares.exception.ExceptionMiddleware diff --git a/docs/docs/en/api/faststream/middlewares/exception/ignore_handler.md b/docs/docs/en/api/faststream/middlewares/exception/ignore_handler.md deleted file mode 100644 index 1eea49ddbe..0000000000 --- a/docs/docs/en/api/faststream/middlewares/exception/ignore_handler.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.middlewares.exception.ignore_handler diff --git a/docs/docs/en/api/faststream/middlewares/logging/CriticalLogMiddleware.md b/docs/docs/en/api/faststream/middlewares/logging/CriticalLogMiddleware.md deleted file mode 100644 index 58be3830e6..0000000000 --- a/docs/docs/en/api/faststream/middlewares/logging/CriticalLogMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.middlewares.logging.CriticalLogMiddleware diff --git a/docs/docs/en/api/faststream/nats/AckPolicy.md b/docs/docs/en/api/faststream/nats/AckPolicy.md deleted file mode 100644 index 308d12ac63..0000000000 --- a/docs/docs/en/api/faststream/nats/AckPolicy.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: nats.js.api.AckPolicy diff --git a/docs/docs/en/api/faststream/nats/ConsumerConfig.md b/docs/docs/en/api/faststream/nats/ConsumerConfig.md deleted file mode 100644 index 56c357cc07..0000000000 --- a/docs/docs/en/api/faststream/nats/ConsumerConfig.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: nats.js.api.ConsumerConfig diff --git a/docs/docs/en/api/faststream/nats/DeliverPolicy.md b/docs/docs/en/api/faststream/nats/DeliverPolicy.md deleted file mode 100644 index ebb664d0d9..0000000000 --- a/docs/docs/en/api/faststream/nats/DeliverPolicy.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: nats.js.api.DeliverPolicy diff --git a/docs/docs/en/api/faststream/nats/DiscardPolicy.md b/docs/docs/en/api/faststream/nats/DiscardPolicy.md deleted file mode 100644 index 9eacd12198..0000000000 --- a/docs/docs/en/api/faststream/nats/DiscardPolicy.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: nats.js.api.DiscardPolicy diff --git a/docs/docs/en/api/faststream/nats/ExternalStream.md b/docs/docs/en/api/faststream/nats/ExternalStream.md deleted file mode 100644 index 5ea0eacbbc..0000000000 --- a/docs/docs/en/api/faststream/nats/ExternalStream.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: nats.js.api.ExternalStream diff --git a/docs/docs/en/api/faststream/nats/JStream.md b/docs/docs/en/api/faststream/nats/JStream.md deleted file mode 100644 index 70ca7cab69..0000000000 --- a/docs/docs/en/api/faststream/nats/JStream.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.JStream diff --git a/docs/docs/en/api/faststream/nats/KvWatch.md b/docs/docs/en/api/faststream/nats/KvWatch.md deleted file mode 100644 index 1527be51fd..0000000000 --- a/docs/docs/en/api/faststream/nats/KvWatch.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.KvWatch diff --git a/docs/docs/en/api/faststream/nats/NatsBroker.md b/docs/docs/en/api/faststream/nats/NatsBroker.md deleted file mode 100644 index 376231c4cd..0000000000 --- a/docs/docs/en/api/faststream/nats/NatsBroker.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.NatsBroker diff --git a/docs/docs/en/api/faststream/nats/NatsPublisher.md b/docs/docs/en/api/faststream/nats/NatsPublisher.md deleted file mode 100644 index 1f1ffbca2a..0000000000 --- a/docs/docs/en/api/faststream/nats/NatsPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.NatsPublisher diff --git a/docs/docs/en/api/faststream/nats/NatsResponse.md b/docs/docs/en/api/faststream/nats/NatsResponse.md deleted file mode 100644 index 6b967b527a..0000000000 --- a/docs/docs/en/api/faststream/nats/NatsResponse.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.NatsResponse diff --git a/docs/docs/en/api/faststream/nats/NatsRoute.md b/docs/docs/en/api/faststream/nats/NatsRoute.md deleted file mode 100644 index b76a8481dc..0000000000 --- a/docs/docs/en/api/faststream/nats/NatsRoute.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.NatsRoute diff --git a/docs/docs/en/api/faststream/nats/NatsRouter.md b/docs/docs/en/api/faststream/nats/NatsRouter.md deleted file mode 100644 index 89e975235b..0000000000 --- a/docs/docs/en/api/faststream/nats/NatsRouter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.NatsRouter diff --git a/docs/docs/en/api/faststream/nats/ObjWatch.md b/docs/docs/en/api/faststream/nats/ObjWatch.md deleted file mode 100644 index 50102ecf31..0000000000 --- a/docs/docs/en/api/faststream/nats/ObjWatch.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.ObjWatch diff --git a/docs/docs/en/api/faststream/nats/Placement.md b/docs/docs/en/api/faststream/nats/Placement.md deleted file mode 100644 index bff8b3d4b8..0000000000 --- a/docs/docs/en/api/faststream/nats/Placement.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: nats.js.api.Placement diff --git a/docs/docs/en/api/faststream/nats/PubAck.md b/docs/docs/en/api/faststream/nats/PubAck.md deleted file mode 100644 index 697f22abe6..0000000000 --- a/docs/docs/en/api/faststream/nats/PubAck.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: nats.js.api.PubAck diff --git a/docs/docs/en/api/faststream/nats/PullSub.md b/docs/docs/en/api/faststream/nats/PullSub.md deleted file mode 100644 index dbfaf68f54..0000000000 --- a/docs/docs/en/api/faststream/nats/PullSub.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.PullSub diff --git a/docs/docs/en/api/faststream/nats/RePublish.md b/docs/docs/en/api/faststream/nats/RePublish.md deleted file mode 100644 index 35ad498def..0000000000 --- a/docs/docs/en/api/faststream/nats/RePublish.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: nats.js.api.RePublish diff --git a/docs/docs/en/api/faststream/nats/ReplayPolicy.md b/docs/docs/en/api/faststream/nats/ReplayPolicy.md deleted file mode 100644 index 6430f0a22f..0000000000 --- a/docs/docs/en/api/faststream/nats/ReplayPolicy.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: nats.js.api.ReplayPolicy diff --git a/docs/docs/en/api/faststream/nats/RetentionPolicy.md b/docs/docs/en/api/faststream/nats/RetentionPolicy.md deleted file mode 100644 index 919b818c9e..0000000000 --- a/docs/docs/en/api/faststream/nats/RetentionPolicy.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: nats.js.api.RetentionPolicy diff --git a/docs/docs/en/api/faststream/nats/StorageType.md b/docs/docs/en/api/faststream/nats/StorageType.md deleted file mode 100644 index 78a6bc4d8f..0000000000 --- a/docs/docs/en/api/faststream/nats/StorageType.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: nats.js.api.StorageType diff --git a/docs/docs/en/api/faststream/nats/StreamConfig.md b/docs/docs/en/api/faststream/nats/StreamConfig.md deleted file mode 100644 index 3bce18f7de..0000000000 --- a/docs/docs/en/api/faststream/nats/StreamConfig.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: nats.js.api.StreamConfig diff --git a/docs/docs/en/api/faststream/nats/StreamSource.md b/docs/docs/en/api/faststream/nats/StreamSource.md deleted file mode 100644 index 4d85db37e5..0000000000 --- a/docs/docs/en/api/faststream/nats/StreamSource.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: nats.js.api.StreamSource diff --git a/docs/docs/en/api/faststream/nats/TestApp.md b/docs/docs/en/api/faststream/nats/TestApp.md deleted file mode 100644 index ad101303af..0000000000 --- a/docs/docs/en/api/faststream/nats/TestApp.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream._internal.testing.app.TestApp diff --git a/docs/docs/en/api/faststream/nats/TestNatsBroker.md b/docs/docs/en/api/faststream/nats/TestNatsBroker.md deleted file mode 100644 index 8557295619..0000000000 --- a/docs/docs/en/api/faststream/nats/TestNatsBroker.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.TestNatsBroker diff --git a/docs/docs/en/api/faststream/nats/broker/NatsBroker.md b/docs/docs/en/api/faststream/nats/broker/NatsBroker.md deleted file mode 100644 index eeea31372b..0000000000 --- a/docs/docs/en/api/faststream/nats/broker/NatsBroker.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.broker.NatsBroker diff --git a/docs/docs/en/api/faststream/nats/broker/broker/NatsBroker.md b/docs/docs/en/api/faststream/nats/broker/broker/NatsBroker.md deleted file mode 100644 index 7aed0de1ec..0000000000 --- a/docs/docs/en/api/faststream/nats/broker/broker/NatsBroker.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.broker.broker.NatsBroker diff --git a/docs/docs/en/api/faststream/nats/broker/logging/NatsParamsStorage.md b/docs/docs/en/api/faststream/nats/broker/logging/NatsParamsStorage.md deleted file mode 100644 index 25b77d4331..0000000000 --- a/docs/docs/en/api/faststream/nats/broker/logging/NatsParamsStorage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.broker.logging.NatsParamsStorage diff --git a/docs/docs/en/api/faststream/nats/broker/registrator/NatsRegistrator.md b/docs/docs/en/api/faststream/nats/broker/registrator/NatsRegistrator.md deleted file mode 100644 index f7f313746a..0000000000 --- a/docs/docs/en/api/faststream/nats/broker/registrator/NatsRegistrator.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.broker.registrator.NatsRegistrator diff --git a/docs/docs/en/api/faststream/nats/broker/state/BrokerState.md b/docs/docs/en/api/faststream/nats/broker/state/BrokerState.md deleted file mode 100644 index ed5dc00c35..0000000000 --- a/docs/docs/en/api/faststream/nats/broker/state/BrokerState.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.broker.state.BrokerState diff --git a/docs/docs/en/api/faststream/nats/broker/state/ConnectedState.md b/docs/docs/en/api/faststream/nats/broker/state/ConnectedState.md deleted file mode 100644 index b7bb106798..0000000000 --- a/docs/docs/en/api/faststream/nats/broker/state/ConnectedState.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.broker.state.ConnectedState diff --git a/docs/docs/en/api/faststream/nats/broker/state/ConnectionBrokenState.md b/docs/docs/en/api/faststream/nats/broker/state/ConnectionBrokenState.md deleted file mode 100644 index 66df604330..0000000000 --- a/docs/docs/en/api/faststream/nats/broker/state/ConnectionBrokenState.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.broker.state.ConnectionBrokenState diff --git a/docs/docs/en/api/faststream/nats/broker/state/EmptyBrokerState.md b/docs/docs/en/api/faststream/nats/broker/state/EmptyBrokerState.md deleted file mode 100644 index 88bf83710d..0000000000 --- a/docs/docs/en/api/faststream/nats/broker/state/EmptyBrokerState.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.broker.state.EmptyBrokerState diff --git a/docs/docs/en/api/faststream/nats/fastapi/Context.md b/docs/docs/en/api/faststream/nats/fastapi/Context.md deleted file mode 100644 index 99bf141f5c..0000000000 --- a/docs/docs/en/api/faststream/nats/fastapi/Context.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream._internal.fastapi.context.Context diff --git a/docs/docs/en/api/faststream/nats/fastapi/NatsRouter.md b/docs/docs/en/api/faststream/nats/fastapi/NatsRouter.md deleted file mode 100644 index 53123192c2..0000000000 --- a/docs/docs/en/api/faststream/nats/fastapi/NatsRouter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.fastapi.NatsRouter diff --git a/docs/docs/en/api/faststream/nats/fastapi/fastapi/NatsRouter.md b/docs/docs/en/api/faststream/nats/fastapi/fastapi/NatsRouter.md deleted file mode 100644 index 015f730b4f..0000000000 --- a/docs/docs/en/api/faststream/nats/fastapi/fastapi/NatsRouter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.fastapi.fastapi.NatsRouter diff --git a/docs/docs/en/api/faststream/nats/helpers/KVBucketDeclarer.md b/docs/docs/en/api/faststream/nats/helpers/KVBucketDeclarer.md deleted file mode 100644 index b24feaada6..0000000000 --- a/docs/docs/en/api/faststream/nats/helpers/KVBucketDeclarer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.helpers.KVBucketDeclarer diff --git a/docs/docs/en/api/faststream/nats/helpers/OSBucketDeclarer.md b/docs/docs/en/api/faststream/nats/helpers/OSBucketDeclarer.md deleted file mode 100644 index 3ee16a3f24..0000000000 --- a/docs/docs/en/api/faststream/nats/helpers/OSBucketDeclarer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.helpers.OSBucketDeclarer diff --git a/docs/docs/en/api/faststream/nats/helpers/StreamBuilder.md b/docs/docs/en/api/faststream/nats/helpers/StreamBuilder.md deleted file mode 100644 index 3b2a318598..0000000000 --- a/docs/docs/en/api/faststream/nats/helpers/StreamBuilder.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.helpers.StreamBuilder diff --git a/docs/docs/en/api/faststream/nats/helpers/bucket_declarer/KVBucketDeclarer.md b/docs/docs/en/api/faststream/nats/helpers/bucket_declarer/KVBucketDeclarer.md deleted file mode 100644 index fe0eaec17f..0000000000 --- a/docs/docs/en/api/faststream/nats/helpers/bucket_declarer/KVBucketDeclarer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.helpers.bucket_declarer.KVBucketDeclarer diff --git a/docs/docs/en/api/faststream/nats/helpers/obj_storage_declarer/OSBucketDeclarer.md b/docs/docs/en/api/faststream/nats/helpers/obj_storage_declarer/OSBucketDeclarer.md deleted file mode 100644 index b7663051c8..0000000000 --- a/docs/docs/en/api/faststream/nats/helpers/obj_storage_declarer/OSBucketDeclarer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.helpers.obj_storage_declarer.OSBucketDeclarer diff --git a/docs/docs/en/api/faststream/nats/helpers/object_builder/StreamBuilder.md b/docs/docs/en/api/faststream/nats/helpers/object_builder/StreamBuilder.md deleted file mode 100644 index 024daf2d14..0000000000 --- a/docs/docs/en/api/faststream/nats/helpers/object_builder/StreamBuilder.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.helpers.object_builder.StreamBuilder diff --git a/docs/docs/en/api/faststream/nats/helpers/state/ConnectedState.md b/docs/docs/en/api/faststream/nats/helpers/state/ConnectedState.md deleted file mode 100644 index 888302338b..0000000000 --- a/docs/docs/en/api/faststream/nats/helpers/state/ConnectedState.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.helpers.state.ConnectedState diff --git a/docs/docs/en/api/faststream/nats/helpers/state/ConnectionState.md b/docs/docs/en/api/faststream/nats/helpers/state/ConnectionState.md deleted file mode 100644 index 0d99fb56ed..0000000000 --- a/docs/docs/en/api/faststream/nats/helpers/state/ConnectionState.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.helpers.state.ConnectionState diff --git a/docs/docs/en/api/faststream/nats/helpers/state/EmptyConnectionState.md b/docs/docs/en/api/faststream/nats/helpers/state/EmptyConnectionState.md deleted file mode 100644 index 31a062d4ad..0000000000 --- a/docs/docs/en/api/faststream/nats/helpers/state/EmptyConnectionState.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.helpers.state.EmptyConnectionState diff --git a/docs/docs/en/api/faststream/nats/message/NatsBatchMessage.md b/docs/docs/en/api/faststream/nats/message/NatsBatchMessage.md deleted file mode 100644 index 83017107ff..0000000000 --- a/docs/docs/en/api/faststream/nats/message/NatsBatchMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.message.NatsBatchMessage diff --git a/docs/docs/en/api/faststream/nats/message/NatsKvMessage.md b/docs/docs/en/api/faststream/nats/message/NatsKvMessage.md deleted file mode 100644 index 5ac6ed9f41..0000000000 --- a/docs/docs/en/api/faststream/nats/message/NatsKvMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.message.NatsKvMessage diff --git a/docs/docs/en/api/faststream/nats/message/NatsMessage.md b/docs/docs/en/api/faststream/nats/message/NatsMessage.md deleted file mode 100644 index 22d17ceb56..0000000000 --- a/docs/docs/en/api/faststream/nats/message/NatsMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.message.NatsMessage diff --git a/docs/docs/en/api/faststream/nats/message/NatsObjMessage.md b/docs/docs/en/api/faststream/nats/message/NatsObjMessage.md deleted file mode 100644 index 3671628da4..0000000000 --- a/docs/docs/en/api/faststream/nats/message/NatsObjMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.message.NatsObjMessage diff --git a/docs/docs/en/api/faststream/nats/opentelemetry/NatsTelemetryMiddleware.md b/docs/docs/en/api/faststream/nats/opentelemetry/NatsTelemetryMiddleware.md deleted file mode 100644 index e72f2de8ab..0000000000 --- a/docs/docs/en/api/faststream/nats/opentelemetry/NatsTelemetryMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.opentelemetry.NatsTelemetryMiddleware diff --git a/docs/docs/en/api/faststream/nats/opentelemetry/middleware/NatsTelemetryMiddleware.md b/docs/docs/en/api/faststream/nats/opentelemetry/middleware/NatsTelemetryMiddleware.md deleted file mode 100644 index b2bb226585..0000000000 --- a/docs/docs/en/api/faststream/nats/opentelemetry/middleware/NatsTelemetryMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.opentelemetry.middleware.NatsTelemetryMiddleware diff --git a/docs/docs/en/api/faststream/nats/opentelemetry/provider/BaseNatsTelemetrySettingsProvider.md b/docs/docs/en/api/faststream/nats/opentelemetry/provider/BaseNatsTelemetrySettingsProvider.md deleted file mode 100644 index d6626c537d..0000000000 --- a/docs/docs/en/api/faststream/nats/opentelemetry/provider/BaseNatsTelemetrySettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.opentelemetry.provider.BaseNatsTelemetrySettingsProvider diff --git a/docs/docs/en/api/faststream/nats/opentelemetry/provider/NatsBatchTelemetrySettingsProvider.md b/docs/docs/en/api/faststream/nats/opentelemetry/provider/NatsBatchTelemetrySettingsProvider.md deleted file mode 100644 index 045996125a..0000000000 --- a/docs/docs/en/api/faststream/nats/opentelemetry/provider/NatsBatchTelemetrySettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.opentelemetry.provider.NatsBatchTelemetrySettingsProvider diff --git a/docs/docs/en/api/faststream/nats/opentelemetry/provider/NatsTelemetrySettingsProvider.md b/docs/docs/en/api/faststream/nats/opentelemetry/provider/NatsTelemetrySettingsProvider.md deleted file mode 100644 index b58590c4fa..0000000000 --- a/docs/docs/en/api/faststream/nats/opentelemetry/provider/NatsTelemetrySettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.opentelemetry.provider.NatsTelemetrySettingsProvider diff --git a/docs/docs/en/api/faststream/nats/opentelemetry/provider/telemetry_attributes_provider_factory.md b/docs/docs/en/api/faststream/nats/opentelemetry/provider/telemetry_attributes_provider_factory.md deleted file mode 100644 index 200d333e0b..0000000000 --- a/docs/docs/en/api/faststream/nats/opentelemetry/provider/telemetry_attributes_provider_factory.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.opentelemetry.provider.telemetry_attributes_provider_factory diff --git a/docs/docs/en/api/faststream/nats/parser/BatchParser.md b/docs/docs/en/api/faststream/nats/parser/BatchParser.md deleted file mode 100644 index 03ad25f549..0000000000 --- a/docs/docs/en/api/faststream/nats/parser/BatchParser.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.parser.BatchParser diff --git a/docs/docs/en/api/faststream/nats/parser/JsParser.md b/docs/docs/en/api/faststream/nats/parser/JsParser.md deleted file mode 100644 index 0cd283d36e..0000000000 --- a/docs/docs/en/api/faststream/nats/parser/JsParser.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.parser.JsParser diff --git a/docs/docs/en/api/faststream/nats/parser/KvParser.md b/docs/docs/en/api/faststream/nats/parser/KvParser.md deleted file mode 100644 index acba65e133..0000000000 --- a/docs/docs/en/api/faststream/nats/parser/KvParser.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.parser.KvParser diff --git a/docs/docs/en/api/faststream/nats/parser/NatsBaseParser.md b/docs/docs/en/api/faststream/nats/parser/NatsBaseParser.md deleted file mode 100644 index 00b038738d..0000000000 --- a/docs/docs/en/api/faststream/nats/parser/NatsBaseParser.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.parser.NatsBaseParser diff --git a/docs/docs/en/api/faststream/nats/parser/NatsParser.md b/docs/docs/en/api/faststream/nats/parser/NatsParser.md deleted file mode 100644 index ceed3d0bdf..0000000000 --- a/docs/docs/en/api/faststream/nats/parser/NatsParser.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.parser.NatsParser diff --git a/docs/docs/en/api/faststream/nats/parser/ObjParser.md b/docs/docs/en/api/faststream/nats/parser/ObjParser.md deleted file mode 100644 index 50ff5d0e18..0000000000 --- a/docs/docs/en/api/faststream/nats/parser/ObjParser.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.parser.ObjParser diff --git a/docs/docs/en/api/faststream/nats/prometheus/NatsPrometheusMiddleware.md b/docs/docs/en/api/faststream/nats/prometheus/NatsPrometheusMiddleware.md deleted file mode 100644 index d9b179b0c4..0000000000 --- a/docs/docs/en/api/faststream/nats/prometheus/NatsPrometheusMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.prometheus.NatsPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/nats/prometheus/middleware/NatsPrometheusMiddleware.md b/docs/docs/en/api/faststream/nats/prometheus/middleware/NatsPrometheusMiddleware.md deleted file mode 100644 index 7202731048..0000000000 --- a/docs/docs/en/api/faststream/nats/prometheus/middleware/NatsPrometheusMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.prometheus.middleware.NatsPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/nats/prometheus/provider/BaseNatsMetricsSettingsProvider.md b/docs/docs/en/api/faststream/nats/prometheus/provider/BaseNatsMetricsSettingsProvider.md deleted file mode 100644 index 80742833bc..0000000000 --- a/docs/docs/en/api/faststream/nats/prometheus/provider/BaseNatsMetricsSettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.prometheus.provider.BaseNatsMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/nats/prometheus/provider/BatchNatsMetricsSettingsProvider.md b/docs/docs/en/api/faststream/nats/prometheus/provider/BatchNatsMetricsSettingsProvider.md deleted file mode 100644 index 163ebb7bc6..0000000000 --- a/docs/docs/en/api/faststream/nats/prometheus/provider/BatchNatsMetricsSettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.prometheus.provider.BatchNatsMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/nats/prometheus/provider/NatsMetricsSettingsProvider.md b/docs/docs/en/api/faststream/nats/prometheus/provider/NatsMetricsSettingsProvider.md deleted file mode 100644 index e5515a4cc5..0000000000 --- a/docs/docs/en/api/faststream/nats/prometheus/provider/NatsMetricsSettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.prometheus.provider.NatsMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/nats/prometheus/provider/settings_provider_factory.md b/docs/docs/en/api/faststream/nats/prometheus/provider/settings_provider_factory.md deleted file mode 100644 index aeaa7b26e0..0000000000 --- a/docs/docs/en/api/faststream/nats/prometheus/provider/settings_provider_factory.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.prometheus.provider.settings_provider_factory diff --git a/docs/docs/en/api/faststream/nats/publisher/factory/create_publisher.md b/docs/docs/en/api/faststream/nats/publisher/factory/create_publisher.md deleted file mode 100644 index 19b23b99a5..0000000000 --- a/docs/docs/en/api/faststream/nats/publisher/factory/create_publisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.publisher.factory.create_publisher diff --git a/docs/docs/en/api/faststream/nats/publisher/fake/NatsFakePublisher.md b/docs/docs/en/api/faststream/nats/publisher/fake/NatsFakePublisher.md deleted file mode 100644 index df23cc8045..0000000000 --- a/docs/docs/en/api/faststream/nats/publisher/fake/NatsFakePublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.publisher.fake.NatsFakePublisher diff --git a/docs/docs/en/api/faststream/nats/publisher/producer/NatsFastProducer.md b/docs/docs/en/api/faststream/nats/publisher/producer/NatsFastProducer.md deleted file mode 100644 index 82ff491f16..0000000000 --- a/docs/docs/en/api/faststream/nats/publisher/producer/NatsFastProducer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.publisher.producer.NatsFastProducer diff --git a/docs/docs/en/api/faststream/nats/publisher/producer/NatsJSFastProducer.md b/docs/docs/en/api/faststream/nats/publisher/producer/NatsJSFastProducer.md deleted file mode 100644 index 9c0e046e61..0000000000 --- a/docs/docs/en/api/faststream/nats/publisher/producer/NatsJSFastProducer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.publisher.producer.NatsJSFastProducer diff --git a/docs/docs/en/api/faststream/nats/publisher/specified/SpecificationPublisher.md b/docs/docs/en/api/faststream/nats/publisher/specified/SpecificationPublisher.md deleted file mode 100644 index 3f5eec9e22..0000000000 --- a/docs/docs/en/api/faststream/nats/publisher/specified/SpecificationPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.publisher.specified.SpecificationPublisher diff --git a/docs/docs/en/api/faststream/nats/publisher/usecase/LogicPublisher.md b/docs/docs/en/api/faststream/nats/publisher/usecase/LogicPublisher.md deleted file mode 100644 index 08c7794545..0000000000 --- a/docs/docs/en/api/faststream/nats/publisher/usecase/LogicPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.publisher.usecase.LogicPublisher diff --git a/docs/docs/en/api/faststream/nats/response/NatsPublishCommand.md b/docs/docs/en/api/faststream/nats/response/NatsPublishCommand.md deleted file mode 100644 index 148119ba8a..0000000000 --- a/docs/docs/en/api/faststream/nats/response/NatsPublishCommand.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.response.NatsPublishCommand diff --git a/docs/docs/en/api/faststream/nats/response/NatsResponse.md b/docs/docs/en/api/faststream/nats/response/NatsResponse.md deleted file mode 100644 index 8a7da66982..0000000000 --- a/docs/docs/en/api/faststream/nats/response/NatsResponse.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.response.NatsResponse diff --git a/docs/docs/en/api/faststream/nats/router/NatsPublisher.md b/docs/docs/en/api/faststream/nats/router/NatsPublisher.md deleted file mode 100644 index b025495e44..0000000000 --- a/docs/docs/en/api/faststream/nats/router/NatsPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.router.NatsPublisher diff --git a/docs/docs/en/api/faststream/nats/router/NatsRoute.md b/docs/docs/en/api/faststream/nats/router/NatsRoute.md deleted file mode 100644 index 36df33c45e..0000000000 --- a/docs/docs/en/api/faststream/nats/router/NatsRoute.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.router.NatsRoute diff --git a/docs/docs/en/api/faststream/nats/router/NatsRouter.md b/docs/docs/en/api/faststream/nats/router/NatsRouter.md deleted file mode 100644 index 4b6dfaaf7d..0000000000 --- a/docs/docs/en/api/faststream/nats/router/NatsRouter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.router.NatsRouter diff --git a/docs/docs/en/api/faststream/nats/schemas/JStream.md b/docs/docs/en/api/faststream/nats/schemas/JStream.md deleted file mode 100644 index 51df9a02cc..0000000000 --- a/docs/docs/en/api/faststream/nats/schemas/JStream.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.schemas.JStream diff --git a/docs/docs/en/api/faststream/nats/schemas/KvWatch.md b/docs/docs/en/api/faststream/nats/schemas/KvWatch.md deleted file mode 100644 index ce99738043..0000000000 --- a/docs/docs/en/api/faststream/nats/schemas/KvWatch.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.schemas.KvWatch diff --git a/docs/docs/en/api/faststream/nats/schemas/ObjWatch.md b/docs/docs/en/api/faststream/nats/schemas/ObjWatch.md deleted file mode 100644 index 51c3628e5e..0000000000 --- a/docs/docs/en/api/faststream/nats/schemas/ObjWatch.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.schemas.ObjWatch diff --git a/docs/docs/en/api/faststream/nats/schemas/PubAck.md b/docs/docs/en/api/faststream/nats/schemas/PubAck.md deleted file mode 100644 index 697f22abe6..0000000000 --- a/docs/docs/en/api/faststream/nats/schemas/PubAck.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: nats.js.api.PubAck diff --git a/docs/docs/en/api/faststream/nats/schemas/PullSub.md b/docs/docs/en/api/faststream/nats/schemas/PullSub.md deleted file mode 100644 index cb7341340c..0000000000 --- a/docs/docs/en/api/faststream/nats/schemas/PullSub.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.schemas.PullSub diff --git a/docs/docs/en/api/faststream/nats/schemas/js_stream/JStream.md b/docs/docs/en/api/faststream/nats/schemas/js_stream/JStream.md deleted file mode 100644 index af375c116a..0000000000 --- a/docs/docs/en/api/faststream/nats/schemas/js_stream/JStream.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.schemas.js_stream.JStream diff --git a/docs/docs/en/api/faststream/nats/schemas/js_stream/compile_nats_wildcard.md b/docs/docs/en/api/faststream/nats/schemas/js_stream/compile_nats_wildcard.md deleted file mode 100644 index 910f034eff..0000000000 --- a/docs/docs/en/api/faststream/nats/schemas/js_stream/compile_nats_wildcard.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.schemas.js_stream.compile_nats_wildcard diff --git a/docs/docs/en/api/faststream/nats/schemas/js_stream/is_subject_match_wildcard.md b/docs/docs/en/api/faststream/nats/schemas/js_stream/is_subject_match_wildcard.md deleted file mode 100644 index f9305b94e8..0000000000 --- a/docs/docs/en/api/faststream/nats/schemas/js_stream/is_subject_match_wildcard.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.schemas.js_stream.is_subject_match_wildcard diff --git a/docs/docs/en/api/faststream/nats/schemas/kv_watch/KvWatch.md b/docs/docs/en/api/faststream/nats/schemas/kv_watch/KvWatch.md deleted file mode 100644 index ce07fa305d..0000000000 --- a/docs/docs/en/api/faststream/nats/schemas/kv_watch/KvWatch.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.schemas.kv_watch.KvWatch diff --git a/docs/docs/en/api/faststream/nats/schemas/obj_watch/ObjWatch.md b/docs/docs/en/api/faststream/nats/schemas/obj_watch/ObjWatch.md deleted file mode 100644 index 55831b8a6a..0000000000 --- a/docs/docs/en/api/faststream/nats/schemas/obj_watch/ObjWatch.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.schemas.obj_watch.ObjWatch diff --git a/docs/docs/en/api/faststream/nats/schemas/pull_sub/PullSub.md b/docs/docs/en/api/faststream/nats/schemas/pull_sub/PullSub.md deleted file mode 100644 index 673a1e8ff6..0000000000 --- a/docs/docs/en/api/faststream/nats/schemas/pull_sub/PullSub.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.schemas.pull_sub.PullSub diff --git a/docs/docs/en/api/faststream/nats/security/parse_security.md b/docs/docs/en/api/faststream/nats/security/parse_security.md deleted file mode 100644 index d2fe5dd0c3..0000000000 --- a/docs/docs/en/api/faststream/nats/security/parse_security.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.security.parse_security diff --git a/docs/docs/en/api/faststream/nats/subscriber/adapters/UnsubscribeAdapter.md b/docs/docs/en/api/faststream/nats/subscriber/adapters/UnsubscribeAdapter.md deleted file mode 100644 index 9b00a89428..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/adapters/UnsubscribeAdapter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.adapters.UnsubscribeAdapter diff --git a/docs/docs/en/api/faststream/nats/subscriber/adapters/Unsubscriptable.md b/docs/docs/en/api/faststream/nats/subscriber/adapters/Unsubscriptable.md deleted file mode 100644 index 4c6c6b0abe..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/adapters/Unsubscriptable.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.adapters.Unsubscriptable diff --git a/docs/docs/en/api/faststream/nats/subscriber/adapters/Watchable.md b/docs/docs/en/api/faststream/nats/subscriber/adapters/Watchable.md deleted file mode 100644 index 00dde78565..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/adapters/Watchable.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.adapters.Watchable diff --git a/docs/docs/en/api/faststream/nats/subscriber/factory/create_subscriber.md b/docs/docs/en/api/faststream/nats/subscriber/factory/create_subscriber.md deleted file mode 100644 index 0e132c3394..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/factory/create_subscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.factory.create_subscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationBatchPullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationBatchPullStreamSubscriber.md deleted file mode 100644 index d663201213..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationBatchPullStreamSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.specified.SpecificationBatchPullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationConcurrentCoreSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationConcurrentCoreSubscriber.md deleted file mode 100644 index 24f1a256ce..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationConcurrentCoreSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.specified.SpecificationConcurrentCoreSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationConcurrentPullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationConcurrentPullStreamSubscriber.md deleted file mode 100644 index 45d7106b98..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationConcurrentPullStreamSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.specified.SpecificationConcurrentPullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationConcurrentPushStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationConcurrentPushStreamSubscriber.md deleted file mode 100644 index 4a5bebd382..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationConcurrentPushStreamSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.specified.SpecificationConcurrentPushStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationCoreSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationCoreSubscriber.md deleted file mode 100644 index 5415ec6203..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationCoreSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.specified.SpecificationCoreSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationKeyValueWatchSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationKeyValueWatchSubscriber.md deleted file mode 100644 index bd9e10e9d2..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationKeyValueWatchSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.specified.SpecificationKeyValueWatchSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationObjStoreWatchSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationObjStoreWatchSubscriber.md deleted file mode 100644 index d2b5bfa27f..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationObjStoreWatchSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.specified.SpecificationObjStoreWatchSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationPullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationPullStreamSubscriber.md deleted file mode 100644 index c0867b195f..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationPullStreamSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.specified.SpecificationPullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationPushStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationPushStreamSubscriber.md deleted file mode 100644 index ef20892652..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationPushStreamSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.specified.SpecificationPushStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationSubscriber.md deleted file mode 100644 index 613fdecd8a..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/specified/SpecificationSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.specified.SpecificationSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/state/ConnectedSubscriberState.md b/docs/docs/en/api/faststream/nats/subscriber/state/ConnectedSubscriberState.md deleted file mode 100644 index 3398403cb2..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/state/ConnectedSubscriberState.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.state.ConnectedSubscriberState diff --git a/docs/docs/en/api/faststream/nats/subscriber/state/EmptySubscriberState.md b/docs/docs/en/api/faststream/nats/subscriber/state/EmptySubscriberState.md deleted file mode 100644 index de80057014..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/state/EmptySubscriberState.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.state.EmptySubscriberState diff --git a/docs/docs/en/api/faststream/nats/subscriber/state/SubscriberState.md b/docs/docs/en/api/faststream/nats/subscriber/state/SubscriberState.md deleted file mode 100644 index a61839436a..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/state/SubscriberState.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.state.SubscriberState diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/BatchPullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/BatchPullStreamSubscriber.md deleted file mode 100644 index 667ff42587..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/usecases/BatchPullStreamSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.usecases.BatchPullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentCoreSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentCoreSubscriber.md deleted file mode 100644 index bbd0895a8c..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentCoreSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.usecases.ConcurrentCoreSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentPullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentPullStreamSubscriber.md deleted file mode 100644 index 7bb13db682..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentPullStreamSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.usecases.ConcurrentPullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentPushStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentPushStreamSubscriber.md deleted file mode 100644 index c694d41369..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/usecases/ConcurrentPushStreamSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.usecases.ConcurrentPushStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/CoreSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/CoreSubscriber.md deleted file mode 100644 index e35ebd3f9d..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/usecases/CoreSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.usecases.CoreSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/KeyValueWatchSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/KeyValueWatchSubscriber.md deleted file mode 100644 index 507c7a33c4..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/usecases/KeyValueWatchSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.usecases.KeyValueWatchSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/LogicSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/LogicSubscriber.md deleted file mode 100644 index e97348563d..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/usecases/LogicSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.usecases.LogicSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/ObjStoreWatchSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/ObjStoreWatchSubscriber.md deleted file mode 100644 index 25d1434968..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/usecases/ObjStoreWatchSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.usecases.ObjStoreWatchSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/PullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/PullStreamSubscriber.md deleted file mode 100644 index ddc3731c6e..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/usecases/PullStreamSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.usecases.PullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/PushStreamSubscription.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/PushStreamSubscription.md deleted file mode 100644 index 9ea5735afb..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/usecases/PushStreamSubscription.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.usecases.PushStreamSubscription diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/basic/DefaultSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/basic/DefaultSubscriber.md deleted file mode 100644 index f0bd5e52aa..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/usecases/basic/DefaultSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.usecases.basic.DefaultSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/basic/LogicSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/basic/LogicSubscriber.md deleted file mode 100644 index 9dfc93aa9b..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/usecases/basic/LogicSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.usecases.basic.LogicSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/core_subscriber/ConcurrentCoreSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/core_subscriber/ConcurrentCoreSubscriber.md deleted file mode 100644 index a684452aa1..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/usecases/core_subscriber/ConcurrentCoreSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.usecases.core_subscriber.ConcurrentCoreSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/core_subscriber/CoreSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/core_subscriber/CoreSubscriber.md deleted file mode 100644 index cc1905f58e..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/usecases/core_subscriber/CoreSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.usecases.core_subscriber.CoreSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/key_value_subscriber/KeyValueWatchSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/key_value_subscriber/KeyValueWatchSubscriber.md deleted file mode 100644 index 26e1b670d0..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/usecases/key_value_subscriber/KeyValueWatchSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.usecases.key_value_subscriber.KeyValueWatchSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/object_storage_subscriber/ObjStoreWatchSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/object_storage_subscriber/ObjStoreWatchSubscriber.md deleted file mode 100644 index b1722e57ec..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/usecases/object_storage_subscriber/ObjStoreWatchSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.usecases.object_storage_subscriber.ObjStoreWatchSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_basic/StreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_basic/StreamSubscriber.md deleted file mode 100644 index b08fd2abff..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_basic/StreamSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.usecases.stream_basic.StreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/BatchPullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/BatchPullStreamSubscriber.md deleted file mode 100644 index 9e4973cf67..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/BatchPullStreamSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.usecases.stream_pull_subscriber.BatchPullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/ConcurrentPullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/ConcurrentPullStreamSubscriber.md deleted file mode 100644 index 6c31f93a20..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/ConcurrentPullStreamSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.usecases.stream_pull_subscriber.ConcurrentPullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/PullStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/PullStreamSubscriber.md deleted file mode 100644 index 35e7de26de..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_pull_subscriber/PullStreamSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.usecases.stream_pull_subscriber.PullStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_push_subscriber/ConcurrentPushStreamSubscriber.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_push_subscriber/ConcurrentPushStreamSubscriber.md deleted file mode 100644 index 78cffa0a9f..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_push_subscriber/ConcurrentPushStreamSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.usecases.stream_push_subscriber.ConcurrentPushStreamSubscriber diff --git a/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_push_subscriber/PushStreamSubscription.md b/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_push_subscriber/PushStreamSubscription.md deleted file mode 100644 index eee1f7aeb7..0000000000 --- a/docs/docs/en/api/faststream/nats/subscriber/usecases/stream_push_subscriber/PushStreamSubscription.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.subscriber.usecases.stream_push_subscriber.PushStreamSubscription diff --git a/docs/docs/en/api/faststream/nats/testing/FakeProducer.md b/docs/docs/en/api/faststream/nats/testing/FakeProducer.md deleted file mode 100644 index f2615aeb36..0000000000 --- a/docs/docs/en/api/faststream/nats/testing/FakeProducer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.testing.FakeProducer diff --git a/docs/docs/en/api/faststream/nats/testing/PatchedMessage.md b/docs/docs/en/api/faststream/nats/testing/PatchedMessage.md deleted file mode 100644 index e32802d4dd..0000000000 --- a/docs/docs/en/api/faststream/nats/testing/PatchedMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.testing.PatchedMessage diff --git a/docs/docs/en/api/faststream/nats/testing/TestNatsBroker.md b/docs/docs/en/api/faststream/nats/testing/TestNatsBroker.md deleted file mode 100644 index 2abcf7f06d..0000000000 --- a/docs/docs/en/api/faststream/nats/testing/TestNatsBroker.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.testing.TestNatsBroker diff --git a/docs/docs/en/api/faststream/nats/testing/build_message.md b/docs/docs/en/api/faststream/nats/testing/build_message.md deleted file mode 100644 index 160977893d..0000000000 --- a/docs/docs/en/api/faststream/nats/testing/build_message.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.nats.testing.build_message diff --git a/docs/docs/en/api/faststream/opentelemetry/Baggage.md b/docs/docs/en/api/faststream/opentelemetry/Baggage.md deleted file mode 100644 index a61cb56d97..0000000000 --- a/docs/docs/en/api/faststream/opentelemetry/Baggage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.opentelemetry.Baggage diff --git a/docs/docs/en/api/faststream/opentelemetry/TelemetryMiddleware.md b/docs/docs/en/api/faststream/opentelemetry/TelemetryMiddleware.md deleted file mode 100644 index 914f134e60..0000000000 --- a/docs/docs/en/api/faststream/opentelemetry/TelemetryMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.opentelemetry.TelemetryMiddleware diff --git a/docs/docs/en/api/faststream/opentelemetry/TelemetrySettingsProvider.md b/docs/docs/en/api/faststream/opentelemetry/TelemetrySettingsProvider.md deleted file mode 100644 index 7ca8b2cb6d..0000000000 --- a/docs/docs/en/api/faststream/opentelemetry/TelemetrySettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.opentelemetry.TelemetrySettingsProvider diff --git a/docs/docs/en/api/faststream/opentelemetry/baggage/Baggage.md b/docs/docs/en/api/faststream/opentelemetry/baggage/Baggage.md deleted file mode 100644 index c1c6e4efec..0000000000 --- a/docs/docs/en/api/faststream/opentelemetry/baggage/Baggage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.opentelemetry.baggage.Baggage diff --git a/docs/docs/en/api/faststream/opentelemetry/consts/MessageAction.md b/docs/docs/en/api/faststream/opentelemetry/consts/MessageAction.md deleted file mode 100644 index cd58706774..0000000000 --- a/docs/docs/en/api/faststream/opentelemetry/consts/MessageAction.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.opentelemetry.consts.MessageAction diff --git a/docs/docs/en/api/faststream/opentelemetry/middleware/BaseTelemetryMiddleware.md b/docs/docs/en/api/faststream/opentelemetry/middleware/BaseTelemetryMiddleware.md deleted file mode 100644 index 64a7b4a501..0000000000 --- a/docs/docs/en/api/faststream/opentelemetry/middleware/BaseTelemetryMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.opentelemetry.middleware.BaseTelemetryMiddleware diff --git a/docs/docs/en/api/faststream/opentelemetry/middleware/TelemetryMiddleware.md b/docs/docs/en/api/faststream/opentelemetry/middleware/TelemetryMiddleware.md deleted file mode 100644 index f019b3ad61..0000000000 --- a/docs/docs/en/api/faststream/opentelemetry/middleware/TelemetryMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.opentelemetry.middleware.TelemetryMiddleware diff --git a/docs/docs/en/api/faststream/opentelemetry/provider/TelemetrySettingsProvider.md b/docs/docs/en/api/faststream/opentelemetry/provider/TelemetrySettingsProvider.md deleted file mode 100644 index 0fefe1c0ef..0000000000 --- a/docs/docs/en/api/faststream/opentelemetry/provider/TelemetrySettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.opentelemetry.provider.TelemetrySettingsProvider diff --git a/docs/docs/en/api/faststream/params/Context.md b/docs/docs/en/api/faststream/params/Context.md deleted file mode 100644 index 8eb7fc249a..0000000000 --- a/docs/docs/en/api/faststream/params/Context.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.params.Context diff --git a/docs/docs/en/api/faststream/params/Depends.md b/docs/docs/en/api/faststream/params/Depends.md deleted file mode 100644 index c0704687e8..0000000000 --- a/docs/docs/en/api/faststream/params/Depends.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: fast_depends.use.Depends diff --git a/docs/docs/en/api/faststream/params/Header.md b/docs/docs/en/api/faststream/params/Header.md deleted file mode 100644 index f3dd71365c..0000000000 --- a/docs/docs/en/api/faststream/params/Header.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.params.Header diff --git a/docs/docs/en/api/faststream/params/Path.md b/docs/docs/en/api/faststream/params/Path.md deleted file mode 100644 index ad04fdff6e..0000000000 --- a/docs/docs/en/api/faststream/params/Path.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.params.Path diff --git a/docs/docs/en/api/faststream/params/no_cast/NoCastField.md b/docs/docs/en/api/faststream/params/no_cast/NoCastField.md deleted file mode 100644 index 56821cae8a..0000000000 --- a/docs/docs/en/api/faststream/params/no_cast/NoCastField.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.params.no_cast.NoCastField diff --git a/docs/docs/en/api/faststream/params/params/Context.md b/docs/docs/en/api/faststream/params/params/Context.md deleted file mode 100644 index 4c3ec6b4dd..0000000000 --- a/docs/docs/en/api/faststream/params/params/Context.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.params.params.Context diff --git a/docs/docs/en/api/faststream/params/params/Header.md b/docs/docs/en/api/faststream/params/params/Header.md deleted file mode 100644 index 6b15bd1ec1..0000000000 --- a/docs/docs/en/api/faststream/params/params/Header.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.params.params.Header diff --git a/docs/docs/en/api/faststream/params/params/Path.md b/docs/docs/en/api/faststream/params/params/Path.md deleted file mode 100644 index 0903f40023..0000000000 --- a/docs/docs/en/api/faststream/params/params/Path.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.params.params.Path diff --git a/docs/docs/en/api/faststream/prometheus/ConsumeAttrs.md b/docs/docs/en/api/faststream/prometheus/ConsumeAttrs.md deleted file mode 100644 index ad8e536b7a..0000000000 --- a/docs/docs/en/api/faststream/prometheus/ConsumeAttrs.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.prometheus.ConsumeAttrs diff --git a/docs/docs/en/api/faststream/prometheus/MetricsSettingsProvider.md b/docs/docs/en/api/faststream/prometheus/MetricsSettingsProvider.md deleted file mode 100644 index 0f7405e44d..0000000000 --- a/docs/docs/en/api/faststream/prometheus/MetricsSettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.prometheus.MetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/prometheus/PrometheusMiddleware.md b/docs/docs/en/api/faststream/prometheus/PrometheusMiddleware.md deleted file mode 100644 index c340a0cb23..0000000000 --- a/docs/docs/en/api/faststream/prometheus/PrometheusMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.prometheus.PrometheusMiddleware diff --git a/docs/docs/en/api/faststream/prometheus/container/MetricsContainer.md b/docs/docs/en/api/faststream/prometheus/container/MetricsContainer.md deleted file mode 100644 index 009d88d263..0000000000 --- a/docs/docs/en/api/faststream/prometheus/container/MetricsContainer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.prometheus.container.MetricsContainer diff --git a/docs/docs/en/api/faststream/prometheus/manager/MetricsManager.md b/docs/docs/en/api/faststream/prometheus/manager/MetricsManager.md deleted file mode 100644 index b1a897c717..0000000000 --- a/docs/docs/en/api/faststream/prometheus/manager/MetricsManager.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.prometheus.manager.MetricsManager diff --git a/docs/docs/en/api/faststream/prometheus/middleware/BasePrometheusMiddleware.md b/docs/docs/en/api/faststream/prometheus/middleware/BasePrometheusMiddleware.md deleted file mode 100644 index 62bbd031ac..0000000000 --- a/docs/docs/en/api/faststream/prometheus/middleware/BasePrometheusMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.prometheus.middleware.BasePrometheusMiddleware diff --git a/docs/docs/en/api/faststream/prometheus/middleware/PrometheusMiddleware.md b/docs/docs/en/api/faststream/prometheus/middleware/PrometheusMiddleware.md deleted file mode 100644 index 2902586e38..0000000000 --- a/docs/docs/en/api/faststream/prometheus/middleware/PrometheusMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.prometheus.middleware.PrometheusMiddleware diff --git a/docs/docs/en/api/faststream/prometheus/provider/MetricsSettingsProvider.md b/docs/docs/en/api/faststream/prometheus/provider/MetricsSettingsProvider.md deleted file mode 100644 index 3511a21a5b..0000000000 --- a/docs/docs/en/api/faststream/prometheus/provider/MetricsSettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.prometheus.provider.MetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/prometheus/types/ConsumeAttrs.md b/docs/docs/en/api/faststream/prometheus/types/ConsumeAttrs.md deleted file mode 100644 index d9196cab8d..0000000000 --- a/docs/docs/en/api/faststream/prometheus/types/ConsumeAttrs.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.prometheus.types.ConsumeAttrs diff --git a/docs/docs/en/api/faststream/prometheus/types/ProcessingStatus.md b/docs/docs/en/api/faststream/prometheus/types/ProcessingStatus.md deleted file mode 100644 index 98b6710bcd..0000000000 --- a/docs/docs/en/api/faststream/prometheus/types/ProcessingStatus.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.prometheus.types.ProcessingStatus diff --git a/docs/docs/en/api/faststream/prometheus/types/PublishingStatus.md b/docs/docs/en/api/faststream/prometheus/types/PublishingStatus.md deleted file mode 100644 index 4e7435fbea..0000000000 --- a/docs/docs/en/api/faststream/prometheus/types/PublishingStatus.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.prometheus.types.PublishingStatus diff --git a/docs/docs/en/api/faststream/rabbit/ExchangeType.md b/docs/docs/en/api/faststream/rabbit/ExchangeType.md deleted file mode 100644 index 9b299b951d..0000000000 --- a/docs/docs/en/api/faststream/rabbit/ExchangeType.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.ExchangeType diff --git a/docs/docs/en/api/faststream/rabbit/RabbitBroker.md b/docs/docs/en/api/faststream/rabbit/RabbitBroker.md deleted file mode 100644 index f48b2b5e78..0000000000 --- a/docs/docs/en/api/faststream/rabbit/RabbitBroker.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.RabbitBroker diff --git a/docs/docs/en/api/faststream/rabbit/RabbitExchange.md b/docs/docs/en/api/faststream/rabbit/RabbitExchange.md deleted file mode 100644 index bbf9676e72..0000000000 --- a/docs/docs/en/api/faststream/rabbit/RabbitExchange.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.RabbitExchange diff --git a/docs/docs/en/api/faststream/rabbit/RabbitPublisher.md b/docs/docs/en/api/faststream/rabbit/RabbitPublisher.md deleted file mode 100644 index 7e0d3f674b..0000000000 --- a/docs/docs/en/api/faststream/rabbit/RabbitPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.RabbitPublisher diff --git a/docs/docs/en/api/faststream/rabbit/RabbitQueue.md b/docs/docs/en/api/faststream/rabbit/RabbitQueue.md deleted file mode 100644 index 97945b6408..0000000000 --- a/docs/docs/en/api/faststream/rabbit/RabbitQueue.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.RabbitQueue diff --git a/docs/docs/en/api/faststream/rabbit/RabbitResponse.md b/docs/docs/en/api/faststream/rabbit/RabbitResponse.md deleted file mode 100644 index 4d20d82b0e..0000000000 --- a/docs/docs/en/api/faststream/rabbit/RabbitResponse.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.RabbitResponse diff --git a/docs/docs/en/api/faststream/rabbit/RabbitRoute.md b/docs/docs/en/api/faststream/rabbit/RabbitRoute.md deleted file mode 100644 index e11a9f058d..0000000000 --- a/docs/docs/en/api/faststream/rabbit/RabbitRoute.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.RabbitRoute diff --git a/docs/docs/en/api/faststream/rabbit/RabbitRouter.md b/docs/docs/en/api/faststream/rabbit/RabbitRouter.md deleted file mode 100644 index 133880fc50..0000000000 --- a/docs/docs/en/api/faststream/rabbit/RabbitRouter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.RabbitRouter diff --git a/docs/docs/en/api/faststream/rabbit/TestApp.md b/docs/docs/en/api/faststream/rabbit/TestApp.md deleted file mode 100644 index ad101303af..0000000000 --- a/docs/docs/en/api/faststream/rabbit/TestApp.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream._internal.testing.app.TestApp diff --git a/docs/docs/en/api/faststream/rabbit/TestRabbitBroker.md b/docs/docs/en/api/faststream/rabbit/TestRabbitBroker.md deleted file mode 100644 index c4519d58b8..0000000000 --- a/docs/docs/en/api/faststream/rabbit/TestRabbitBroker.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.TestRabbitBroker diff --git a/docs/docs/en/api/faststream/rabbit/broker/RabbitBroker.md b/docs/docs/en/api/faststream/rabbit/broker/RabbitBroker.md deleted file mode 100644 index ac72ec0ae9..0000000000 --- a/docs/docs/en/api/faststream/rabbit/broker/RabbitBroker.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.broker.RabbitBroker diff --git a/docs/docs/en/api/faststream/rabbit/broker/broker/RabbitBroker.md b/docs/docs/en/api/faststream/rabbit/broker/broker/RabbitBroker.md deleted file mode 100644 index 9ed9170ead..0000000000 --- a/docs/docs/en/api/faststream/rabbit/broker/broker/RabbitBroker.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.broker.broker.RabbitBroker diff --git a/docs/docs/en/api/faststream/rabbit/broker/logging/RabbitParamsStorage.md b/docs/docs/en/api/faststream/rabbit/broker/logging/RabbitParamsStorage.md deleted file mode 100644 index e9e46da6af..0000000000 --- a/docs/docs/en/api/faststream/rabbit/broker/logging/RabbitParamsStorage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.broker.logging.RabbitParamsStorage diff --git a/docs/docs/en/api/faststream/rabbit/broker/registrator/RabbitRegistrator.md b/docs/docs/en/api/faststream/rabbit/broker/registrator/RabbitRegistrator.md deleted file mode 100644 index f22385f512..0000000000 --- a/docs/docs/en/api/faststream/rabbit/broker/registrator/RabbitRegistrator.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.broker.registrator.RabbitRegistrator diff --git a/docs/docs/en/api/faststream/rabbit/fastapi/Context.md b/docs/docs/en/api/faststream/rabbit/fastapi/Context.md deleted file mode 100644 index 99bf141f5c..0000000000 --- a/docs/docs/en/api/faststream/rabbit/fastapi/Context.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream._internal.fastapi.context.Context diff --git a/docs/docs/en/api/faststream/rabbit/fastapi/RabbitRouter.md b/docs/docs/en/api/faststream/rabbit/fastapi/RabbitRouter.md deleted file mode 100644 index 72f0a90072..0000000000 --- a/docs/docs/en/api/faststream/rabbit/fastapi/RabbitRouter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.fastapi.RabbitRouter diff --git a/docs/docs/en/api/faststream/rabbit/fastapi/fastapi/RabbitRouter.md b/docs/docs/en/api/faststream/rabbit/fastapi/fastapi/RabbitRouter.md deleted file mode 100644 index d70c558254..0000000000 --- a/docs/docs/en/api/faststream/rabbit/fastapi/fastapi/RabbitRouter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.fastapi.fastapi.RabbitRouter diff --git a/docs/docs/en/api/faststream/rabbit/helpers/declarer/RabbitDeclarer.md b/docs/docs/en/api/faststream/rabbit/helpers/declarer/RabbitDeclarer.md deleted file mode 100644 index b8fc8a0ebd..0000000000 --- a/docs/docs/en/api/faststream/rabbit/helpers/declarer/RabbitDeclarer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.helpers.declarer.RabbitDeclarer diff --git a/docs/docs/en/api/faststream/rabbit/helpers/state/ConnectedState.md b/docs/docs/en/api/faststream/rabbit/helpers/state/ConnectedState.md deleted file mode 100644 index db97303aa3..0000000000 --- a/docs/docs/en/api/faststream/rabbit/helpers/state/ConnectedState.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.helpers.state.ConnectedState diff --git a/docs/docs/en/api/faststream/rabbit/helpers/state/ConnectionState.md b/docs/docs/en/api/faststream/rabbit/helpers/state/ConnectionState.md deleted file mode 100644 index 36b3d4d4d1..0000000000 --- a/docs/docs/en/api/faststream/rabbit/helpers/state/ConnectionState.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.helpers.state.ConnectionState diff --git a/docs/docs/en/api/faststream/rabbit/helpers/state/EmptyConnectionState.md b/docs/docs/en/api/faststream/rabbit/helpers/state/EmptyConnectionState.md deleted file mode 100644 index 7b0af42897..0000000000 --- a/docs/docs/en/api/faststream/rabbit/helpers/state/EmptyConnectionState.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.helpers.state.EmptyConnectionState diff --git a/docs/docs/en/api/faststream/rabbit/message/RabbitMessage.md b/docs/docs/en/api/faststream/rabbit/message/RabbitMessage.md deleted file mode 100644 index 598d43f818..0000000000 --- a/docs/docs/en/api/faststream/rabbit/message/RabbitMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.message.RabbitMessage diff --git a/docs/docs/en/api/faststream/rabbit/opentelemetry/RabbitTelemetryMiddleware.md b/docs/docs/en/api/faststream/rabbit/opentelemetry/RabbitTelemetryMiddleware.md deleted file mode 100644 index 7d5ef3de27..0000000000 --- a/docs/docs/en/api/faststream/rabbit/opentelemetry/RabbitTelemetryMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.opentelemetry.RabbitTelemetryMiddleware diff --git a/docs/docs/en/api/faststream/rabbit/opentelemetry/middleware/RabbitTelemetryMiddleware.md b/docs/docs/en/api/faststream/rabbit/opentelemetry/middleware/RabbitTelemetryMiddleware.md deleted file mode 100644 index e86771a8ba..0000000000 --- a/docs/docs/en/api/faststream/rabbit/opentelemetry/middleware/RabbitTelemetryMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.opentelemetry.middleware.RabbitTelemetryMiddleware diff --git a/docs/docs/en/api/faststream/rabbit/opentelemetry/provider/RabbitTelemetrySettingsProvider.md b/docs/docs/en/api/faststream/rabbit/opentelemetry/provider/RabbitTelemetrySettingsProvider.md deleted file mode 100644 index ba6742ac90..0000000000 --- a/docs/docs/en/api/faststream/rabbit/opentelemetry/provider/RabbitTelemetrySettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.opentelemetry.provider.RabbitTelemetrySettingsProvider diff --git a/docs/docs/en/api/faststream/rabbit/parser/AioPikaParser.md b/docs/docs/en/api/faststream/rabbit/parser/AioPikaParser.md deleted file mode 100644 index 0a02d90270..0000000000 --- a/docs/docs/en/api/faststream/rabbit/parser/AioPikaParser.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.parser.AioPikaParser diff --git a/docs/docs/en/api/faststream/rabbit/prometheus/RabbitPrometheusMiddleware.md b/docs/docs/en/api/faststream/rabbit/prometheus/RabbitPrometheusMiddleware.md deleted file mode 100644 index 2c4308fabd..0000000000 --- a/docs/docs/en/api/faststream/rabbit/prometheus/RabbitPrometheusMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.prometheus.RabbitPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/rabbit/prometheus/middleware/RabbitPrometheusMiddleware.md b/docs/docs/en/api/faststream/rabbit/prometheus/middleware/RabbitPrometheusMiddleware.md deleted file mode 100644 index 45163c998a..0000000000 --- a/docs/docs/en/api/faststream/rabbit/prometheus/middleware/RabbitPrometheusMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.prometheus.middleware.RabbitPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/rabbit/prometheus/provider/RabbitMetricsSettingsProvider.md b/docs/docs/en/api/faststream/rabbit/prometheus/provider/RabbitMetricsSettingsProvider.md deleted file mode 100644 index 6d63301b34..0000000000 --- a/docs/docs/en/api/faststream/rabbit/prometheus/provider/RabbitMetricsSettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.prometheus.provider.RabbitMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/rabbit/publisher/factory/create_publisher.md b/docs/docs/en/api/faststream/rabbit/publisher/factory/create_publisher.md deleted file mode 100644 index bac090fa43..0000000000 --- a/docs/docs/en/api/faststream/rabbit/publisher/factory/create_publisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.publisher.factory.create_publisher diff --git a/docs/docs/en/api/faststream/rabbit/publisher/fake/RabbitFakePublisher.md b/docs/docs/en/api/faststream/rabbit/publisher/fake/RabbitFakePublisher.md deleted file mode 100644 index 60879c8e3a..0000000000 --- a/docs/docs/en/api/faststream/rabbit/publisher/fake/RabbitFakePublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.publisher.fake.RabbitFakePublisher diff --git a/docs/docs/en/api/faststream/rabbit/publisher/options/MessageOptions.md b/docs/docs/en/api/faststream/rabbit/publisher/options/MessageOptions.md deleted file mode 100644 index eaa454588a..0000000000 --- a/docs/docs/en/api/faststream/rabbit/publisher/options/MessageOptions.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.publisher.options.MessageOptions diff --git a/docs/docs/en/api/faststream/rabbit/publisher/options/PublishOptions.md b/docs/docs/en/api/faststream/rabbit/publisher/options/PublishOptions.md deleted file mode 100644 index c80cc9e937..0000000000 --- a/docs/docs/en/api/faststream/rabbit/publisher/options/PublishOptions.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.publisher.options.PublishOptions diff --git a/docs/docs/en/api/faststream/rabbit/publisher/producer/AioPikaFastProducer.md b/docs/docs/en/api/faststream/rabbit/publisher/producer/AioPikaFastProducer.md deleted file mode 100644 index 527cc5604c..0000000000 --- a/docs/docs/en/api/faststream/rabbit/publisher/producer/AioPikaFastProducer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.publisher.producer.AioPikaFastProducer diff --git a/docs/docs/en/api/faststream/rabbit/publisher/producer/LockState.md b/docs/docs/en/api/faststream/rabbit/publisher/producer/LockState.md deleted file mode 100644 index 4d7b37ba46..0000000000 --- a/docs/docs/en/api/faststream/rabbit/publisher/producer/LockState.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.publisher.producer.LockState diff --git a/docs/docs/en/api/faststream/rabbit/publisher/producer/LockUnset.md b/docs/docs/en/api/faststream/rabbit/publisher/producer/LockUnset.md deleted file mode 100644 index 95df1a10e7..0000000000 --- a/docs/docs/en/api/faststream/rabbit/publisher/producer/LockUnset.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.publisher.producer.LockUnset diff --git a/docs/docs/en/api/faststream/rabbit/publisher/producer/RealLock.md b/docs/docs/en/api/faststream/rabbit/publisher/producer/RealLock.md deleted file mode 100644 index 570a279a0a..0000000000 --- a/docs/docs/en/api/faststream/rabbit/publisher/producer/RealLock.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.publisher.producer.RealLock diff --git a/docs/docs/en/api/faststream/rabbit/publisher/specified/SpecificationPublisher.md b/docs/docs/en/api/faststream/rabbit/publisher/specified/SpecificationPublisher.md deleted file mode 100644 index 0001c99fb7..0000000000 --- a/docs/docs/en/api/faststream/rabbit/publisher/specified/SpecificationPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.publisher.specified.SpecificationPublisher diff --git a/docs/docs/en/api/faststream/rabbit/publisher/usecase/LogicPublisher.md b/docs/docs/en/api/faststream/rabbit/publisher/usecase/LogicPublisher.md deleted file mode 100644 index 1ef927866e..0000000000 --- a/docs/docs/en/api/faststream/rabbit/publisher/usecase/LogicPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.publisher.usecase.LogicPublisher diff --git a/docs/docs/en/api/faststream/rabbit/publisher/usecase/PublishKwargs.md b/docs/docs/en/api/faststream/rabbit/publisher/usecase/PublishKwargs.md deleted file mode 100644 index 3d917891cd..0000000000 --- a/docs/docs/en/api/faststream/rabbit/publisher/usecase/PublishKwargs.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.publisher.usecase.PublishKwargs diff --git a/docs/docs/en/api/faststream/rabbit/publisher/usecase/RequestPublishKwargs.md b/docs/docs/en/api/faststream/rabbit/publisher/usecase/RequestPublishKwargs.md deleted file mode 100644 index 5668633016..0000000000 --- a/docs/docs/en/api/faststream/rabbit/publisher/usecase/RequestPublishKwargs.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.publisher.usecase.RequestPublishKwargs diff --git a/docs/docs/en/api/faststream/rabbit/response/RabbitPublishCommand.md b/docs/docs/en/api/faststream/rabbit/response/RabbitPublishCommand.md deleted file mode 100644 index 4c4bb224b6..0000000000 --- a/docs/docs/en/api/faststream/rabbit/response/RabbitPublishCommand.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.response.RabbitPublishCommand diff --git a/docs/docs/en/api/faststream/rabbit/response/RabbitResponse.md b/docs/docs/en/api/faststream/rabbit/response/RabbitResponse.md deleted file mode 100644 index 477cfb9861..0000000000 --- a/docs/docs/en/api/faststream/rabbit/response/RabbitResponse.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.response.RabbitResponse diff --git a/docs/docs/en/api/faststream/rabbit/router/RabbitPublisher.md b/docs/docs/en/api/faststream/rabbit/router/RabbitPublisher.md deleted file mode 100644 index befbec9103..0000000000 --- a/docs/docs/en/api/faststream/rabbit/router/RabbitPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.router.RabbitPublisher diff --git a/docs/docs/en/api/faststream/rabbit/router/RabbitRoute.md b/docs/docs/en/api/faststream/rabbit/router/RabbitRoute.md deleted file mode 100644 index 8e8b0fbb6c..0000000000 --- a/docs/docs/en/api/faststream/rabbit/router/RabbitRoute.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.router.RabbitRoute diff --git a/docs/docs/en/api/faststream/rabbit/router/RabbitRouter.md b/docs/docs/en/api/faststream/rabbit/router/RabbitRouter.md deleted file mode 100644 index eff5f6169a..0000000000 --- a/docs/docs/en/api/faststream/rabbit/router/RabbitRouter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.router.RabbitRouter diff --git a/docs/docs/en/api/faststream/rabbit/schemas/BaseRMQInformation.md b/docs/docs/en/api/faststream/rabbit/schemas/BaseRMQInformation.md deleted file mode 100644 index 7ff32d2cd2..0000000000 --- a/docs/docs/en/api/faststream/rabbit/schemas/BaseRMQInformation.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.schemas.BaseRMQInformation diff --git a/docs/docs/en/api/faststream/rabbit/schemas/ExchangeType.md b/docs/docs/en/api/faststream/rabbit/schemas/ExchangeType.md deleted file mode 100644 index c6c2ef8a28..0000000000 --- a/docs/docs/en/api/faststream/rabbit/schemas/ExchangeType.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.schemas.ExchangeType diff --git a/docs/docs/en/api/faststream/rabbit/schemas/RabbitExchange.md b/docs/docs/en/api/faststream/rabbit/schemas/RabbitExchange.md deleted file mode 100644 index 4e60ed96f5..0000000000 --- a/docs/docs/en/api/faststream/rabbit/schemas/RabbitExchange.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.schemas.RabbitExchange diff --git a/docs/docs/en/api/faststream/rabbit/schemas/RabbitQueue.md b/docs/docs/en/api/faststream/rabbit/schemas/RabbitQueue.md deleted file mode 100644 index 947238b788..0000000000 --- a/docs/docs/en/api/faststream/rabbit/schemas/RabbitQueue.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.schemas.RabbitQueue diff --git a/docs/docs/en/api/faststream/rabbit/schemas/constants/ExchangeType.md b/docs/docs/en/api/faststream/rabbit/schemas/constants/ExchangeType.md deleted file mode 100644 index 11705f35ac..0000000000 --- a/docs/docs/en/api/faststream/rabbit/schemas/constants/ExchangeType.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.schemas.constants.ExchangeType diff --git a/docs/docs/en/api/faststream/rabbit/schemas/exchange/RabbitExchange.md b/docs/docs/en/api/faststream/rabbit/schemas/exchange/RabbitExchange.md deleted file mode 100644 index ebcb211714..0000000000 --- a/docs/docs/en/api/faststream/rabbit/schemas/exchange/RabbitExchange.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.schemas.exchange.RabbitExchange diff --git a/docs/docs/en/api/faststream/rabbit/schemas/proto/BaseRMQInformation.md b/docs/docs/en/api/faststream/rabbit/schemas/proto/BaseRMQInformation.md deleted file mode 100644 index 1eca00071b..0000000000 --- a/docs/docs/en/api/faststream/rabbit/schemas/proto/BaseRMQInformation.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.schemas.proto.BaseRMQInformation diff --git a/docs/docs/en/api/faststream/rabbit/schemas/queue/RabbitQueue.md b/docs/docs/en/api/faststream/rabbit/schemas/queue/RabbitQueue.md deleted file mode 100644 index 83bc15e02f..0000000000 --- a/docs/docs/en/api/faststream/rabbit/schemas/queue/RabbitQueue.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.schemas.queue.RabbitQueue diff --git a/docs/docs/en/api/faststream/rabbit/security/parse_security.md b/docs/docs/en/api/faststream/rabbit/security/parse_security.md deleted file mode 100644 index 0b19ee5ee2..0000000000 --- a/docs/docs/en/api/faststream/rabbit/security/parse_security.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.security.parse_security diff --git a/docs/docs/en/api/faststream/rabbit/subscriber/factory/create_subscriber.md b/docs/docs/en/api/faststream/rabbit/subscriber/factory/create_subscriber.md deleted file mode 100644 index 79c7082931..0000000000 --- a/docs/docs/en/api/faststream/rabbit/subscriber/factory/create_subscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.subscriber.factory.create_subscriber diff --git a/docs/docs/en/api/faststream/rabbit/subscriber/specified/SpecificationSubscriber.md b/docs/docs/en/api/faststream/rabbit/subscriber/specified/SpecificationSubscriber.md deleted file mode 100644 index 928876011d..0000000000 --- a/docs/docs/en/api/faststream/rabbit/subscriber/specified/SpecificationSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.subscriber.specified.SpecificationSubscriber diff --git a/docs/docs/en/api/faststream/rabbit/subscriber/usecase/LogicSubscriber.md b/docs/docs/en/api/faststream/rabbit/subscriber/usecase/LogicSubscriber.md deleted file mode 100644 index 56ef70dd0d..0000000000 --- a/docs/docs/en/api/faststream/rabbit/subscriber/usecase/LogicSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.subscriber.usecase.LogicSubscriber diff --git a/docs/docs/en/api/faststream/rabbit/testing/FakeProducer.md b/docs/docs/en/api/faststream/rabbit/testing/FakeProducer.md deleted file mode 100644 index 7fa3603f60..0000000000 --- a/docs/docs/en/api/faststream/rabbit/testing/FakeProducer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.testing.FakeProducer diff --git a/docs/docs/en/api/faststream/rabbit/testing/PatchedMessage.md b/docs/docs/en/api/faststream/rabbit/testing/PatchedMessage.md deleted file mode 100644 index f58c1140c2..0000000000 --- a/docs/docs/en/api/faststream/rabbit/testing/PatchedMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.testing.PatchedMessage diff --git a/docs/docs/en/api/faststream/rabbit/testing/TestRabbitBroker.md b/docs/docs/en/api/faststream/rabbit/testing/TestRabbitBroker.md deleted file mode 100644 index ab2c088b39..0000000000 --- a/docs/docs/en/api/faststream/rabbit/testing/TestRabbitBroker.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.testing.TestRabbitBroker diff --git a/docs/docs/en/api/faststream/rabbit/testing/apply_pattern.md b/docs/docs/en/api/faststream/rabbit/testing/apply_pattern.md deleted file mode 100644 index 02ffd305ef..0000000000 --- a/docs/docs/en/api/faststream/rabbit/testing/apply_pattern.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.testing.apply_pattern diff --git a/docs/docs/en/api/faststream/rabbit/testing/build_message.md b/docs/docs/en/api/faststream/rabbit/testing/build_message.md deleted file mode 100644 index 296715e46a..0000000000 --- a/docs/docs/en/api/faststream/rabbit/testing/build_message.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.testing.build_message diff --git a/docs/docs/en/api/faststream/rabbit/utils/build_url.md b/docs/docs/en/api/faststream/rabbit/utils/build_url.md deleted file mode 100644 index ffb6555837..0000000000 --- a/docs/docs/en/api/faststream/rabbit/utils/build_url.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.utils.build_url diff --git a/docs/docs/en/api/faststream/rabbit/utils/is_routing_exchange.md b/docs/docs/en/api/faststream/rabbit/utils/is_routing_exchange.md deleted file mode 100644 index 4ef1481a69..0000000000 --- a/docs/docs/en/api/faststream/rabbit/utils/is_routing_exchange.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.rabbit.utils.is_routing_exchange diff --git a/docs/docs/en/api/faststream/redis/ListSub.md b/docs/docs/en/api/faststream/redis/ListSub.md deleted file mode 100644 index 9c97a0afcd..0000000000 --- a/docs/docs/en/api/faststream/redis/ListSub.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.ListSub diff --git a/docs/docs/en/api/faststream/redis/PubSub.md b/docs/docs/en/api/faststream/redis/PubSub.md deleted file mode 100644 index d2fba00014..0000000000 --- a/docs/docs/en/api/faststream/redis/PubSub.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.PubSub diff --git a/docs/docs/en/api/faststream/redis/RedisBroker.md b/docs/docs/en/api/faststream/redis/RedisBroker.md deleted file mode 100644 index 7275bfb60a..0000000000 --- a/docs/docs/en/api/faststream/redis/RedisBroker.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.RedisBroker diff --git a/docs/docs/en/api/faststream/redis/RedisPublisher.md b/docs/docs/en/api/faststream/redis/RedisPublisher.md deleted file mode 100644 index 565d857810..0000000000 --- a/docs/docs/en/api/faststream/redis/RedisPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.RedisPublisher diff --git a/docs/docs/en/api/faststream/redis/RedisResponse.md b/docs/docs/en/api/faststream/redis/RedisResponse.md deleted file mode 100644 index eedecf1ea3..0000000000 --- a/docs/docs/en/api/faststream/redis/RedisResponse.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.RedisResponse diff --git a/docs/docs/en/api/faststream/redis/RedisRoute.md b/docs/docs/en/api/faststream/redis/RedisRoute.md deleted file mode 100644 index 14b4416ed4..0000000000 --- a/docs/docs/en/api/faststream/redis/RedisRoute.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.RedisRoute diff --git a/docs/docs/en/api/faststream/redis/RedisRouter.md b/docs/docs/en/api/faststream/redis/RedisRouter.md deleted file mode 100644 index 9b7292e703..0000000000 --- a/docs/docs/en/api/faststream/redis/RedisRouter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.RedisRouter diff --git a/docs/docs/en/api/faststream/redis/StreamSub.md b/docs/docs/en/api/faststream/redis/StreamSub.md deleted file mode 100644 index d1244238b6..0000000000 --- a/docs/docs/en/api/faststream/redis/StreamSub.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.StreamSub diff --git a/docs/docs/en/api/faststream/redis/TestApp.md b/docs/docs/en/api/faststream/redis/TestApp.md deleted file mode 100644 index ad101303af..0000000000 --- a/docs/docs/en/api/faststream/redis/TestApp.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream._internal.testing.app.TestApp diff --git a/docs/docs/en/api/faststream/redis/TestRedisBroker.md b/docs/docs/en/api/faststream/redis/TestRedisBroker.md deleted file mode 100644 index 703490c302..0000000000 --- a/docs/docs/en/api/faststream/redis/TestRedisBroker.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.TestRedisBroker diff --git a/docs/docs/en/api/faststream/redis/broker/broker/RedisBroker.md b/docs/docs/en/api/faststream/redis/broker/broker/RedisBroker.md deleted file mode 100644 index fdc177e868..0000000000 --- a/docs/docs/en/api/faststream/redis/broker/broker/RedisBroker.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.broker.broker.RedisBroker diff --git a/docs/docs/en/api/faststream/redis/broker/logging/RedisParamsStorage.md b/docs/docs/en/api/faststream/redis/broker/logging/RedisParamsStorage.md deleted file mode 100644 index b7d1bb680a..0000000000 --- a/docs/docs/en/api/faststream/redis/broker/logging/RedisParamsStorage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.broker.logging.RedisParamsStorage diff --git a/docs/docs/en/api/faststream/redis/broker/registrator/RedisRegistrator.md b/docs/docs/en/api/faststream/redis/broker/registrator/RedisRegistrator.md deleted file mode 100644 index 8d040533d7..0000000000 --- a/docs/docs/en/api/faststream/redis/broker/registrator/RedisRegistrator.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.broker.registrator.RedisRegistrator diff --git a/docs/docs/en/api/faststream/redis/fastapi/Context.md b/docs/docs/en/api/faststream/redis/fastapi/Context.md deleted file mode 100644 index 99bf141f5c..0000000000 --- a/docs/docs/en/api/faststream/redis/fastapi/Context.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream._internal.fastapi.context.Context diff --git a/docs/docs/en/api/faststream/redis/fastapi/RedisRouter.md b/docs/docs/en/api/faststream/redis/fastapi/RedisRouter.md deleted file mode 100644 index 7894f88728..0000000000 --- a/docs/docs/en/api/faststream/redis/fastapi/RedisRouter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.fastapi.RedisRouter diff --git a/docs/docs/en/api/faststream/redis/fastapi/fastapi/RedisRouter.md b/docs/docs/en/api/faststream/redis/fastapi/fastapi/RedisRouter.md deleted file mode 100644 index 858c951f61..0000000000 --- a/docs/docs/en/api/faststream/redis/fastapi/fastapi/RedisRouter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.fastapi.fastapi.RedisRouter diff --git a/docs/docs/en/api/faststream/redis/helpers/state/ConnectedState.md b/docs/docs/en/api/faststream/redis/helpers/state/ConnectedState.md deleted file mode 100644 index 793fdb055e..0000000000 --- a/docs/docs/en/api/faststream/redis/helpers/state/ConnectedState.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.helpers.state.ConnectedState diff --git a/docs/docs/en/api/faststream/redis/helpers/state/ConnectionState.md b/docs/docs/en/api/faststream/redis/helpers/state/ConnectionState.md deleted file mode 100644 index 0a27d849dc..0000000000 --- a/docs/docs/en/api/faststream/redis/helpers/state/ConnectionState.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.helpers.state.ConnectionState diff --git a/docs/docs/en/api/faststream/redis/helpers/state/EmptyConnectionState.md b/docs/docs/en/api/faststream/redis/helpers/state/EmptyConnectionState.md deleted file mode 100644 index 70273722e0..0000000000 --- a/docs/docs/en/api/faststream/redis/helpers/state/EmptyConnectionState.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.helpers.state.EmptyConnectionState diff --git a/docs/docs/en/api/faststream/redis/message/BatchListMessage.md b/docs/docs/en/api/faststream/redis/message/BatchListMessage.md deleted file mode 100644 index c510fa09b9..0000000000 --- a/docs/docs/en/api/faststream/redis/message/BatchListMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.message.BatchListMessage diff --git a/docs/docs/en/api/faststream/redis/message/BatchStreamMessage.md b/docs/docs/en/api/faststream/redis/message/BatchStreamMessage.md deleted file mode 100644 index 16885fd028..0000000000 --- a/docs/docs/en/api/faststream/redis/message/BatchStreamMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.message.BatchStreamMessage diff --git a/docs/docs/en/api/faststream/redis/message/DefaultListMessage.md b/docs/docs/en/api/faststream/redis/message/DefaultListMessage.md deleted file mode 100644 index 8f38b34cae..0000000000 --- a/docs/docs/en/api/faststream/redis/message/DefaultListMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.message.DefaultListMessage diff --git a/docs/docs/en/api/faststream/redis/message/DefaultStreamMessage.md b/docs/docs/en/api/faststream/redis/message/DefaultStreamMessage.md deleted file mode 100644 index 6016bb624e..0000000000 --- a/docs/docs/en/api/faststream/redis/message/DefaultStreamMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.message.DefaultStreamMessage diff --git a/docs/docs/en/api/faststream/redis/message/PubSubMessage.md b/docs/docs/en/api/faststream/redis/message/PubSubMessage.md deleted file mode 100644 index 795cecb12e..0000000000 --- a/docs/docs/en/api/faststream/redis/message/PubSubMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.message.PubSubMessage diff --git a/docs/docs/en/api/faststream/redis/message/RedisBatchListMessage.md b/docs/docs/en/api/faststream/redis/message/RedisBatchListMessage.md deleted file mode 100644 index ec7d3983bd..0000000000 --- a/docs/docs/en/api/faststream/redis/message/RedisBatchListMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.message.RedisBatchListMessage diff --git a/docs/docs/en/api/faststream/redis/message/RedisBatchStreamMessage.md b/docs/docs/en/api/faststream/redis/message/RedisBatchStreamMessage.md deleted file mode 100644 index 2c66613eb7..0000000000 --- a/docs/docs/en/api/faststream/redis/message/RedisBatchStreamMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.message.RedisBatchStreamMessage diff --git a/docs/docs/en/api/faststream/redis/message/RedisListMessage.md b/docs/docs/en/api/faststream/redis/message/RedisListMessage.md deleted file mode 100644 index 8c996cb7f0..0000000000 --- a/docs/docs/en/api/faststream/redis/message/RedisListMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.message.RedisListMessage diff --git a/docs/docs/en/api/faststream/redis/message/RedisMessage.md b/docs/docs/en/api/faststream/redis/message/RedisMessage.md deleted file mode 100644 index 1b0654e7ce..0000000000 --- a/docs/docs/en/api/faststream/redis/message/RedisMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.message.RedisMessage diff --git a/docs/docs/en/api/faststream/redis/message/RedisStreamMessage.md b/docs/docs/en/api/faststream/redis/message/RedisStreamMessage.md deleted file mode 100644 index c36385a141..0000000000 --- a/docs/docs/en/api/faststream/redis/message/RedisStreamMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.message.RedisStreamMessage diff --git a/docs/docs/en/api/faststream/redis/message/UnifyRedisDict.md b/docs/docs/en/api/faststream/redis/message/UnifyRedisDict.md deleted file mode 100644 index 9485ca2848..0000000000 --- a/docs/docs/en/api/faststream/redis/message/UnifyRedisDict.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.message.UnifyRedisDict diff --git a/docs/docs/en/api/faststream/redis/message/UnifyRedisMessage.md b/docs/docs/en/api/faststream/redis/message/UnifyRedisMessage.md deleted file mode 100644 index dee09d1657..0000000000 --- a/docs/docs/en/api/faststream/redis/message/UnifyRedisMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.message.UnifyRedisMessage diff --git a/docs/docs/en/api/faststream/redis/opentelemetry/RedisTelemetryMiddleware.md b/docs/docs/en/api/faststream/redis/opentelemetry/RedisTelemetryMiddleware.md deleted file mode 100644 index 537a2dc7b9..0000000000 --- a/docs/docs/en/api/faststream/redis/opentelemetry/RedisTelemetryMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.opentelemetry.RedisTelemetryMiddleware diff --git a/docs/docs/en/api/faststream/redis/opentelemetry/middleware/RedisTelemetryMiddleware.md b/docs/docs/en/api/faststream/redis/opentelemetry/middleware/RedisTelemetryMiddleware.md deleted file mode 100644 index 4c0febf261..0000000000 --- a/docs/docs/en/api/faststream/redis/opentelemetry/middleware/RedisTelemetryMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.opentelemetry.middleware.RedisTelemetryMiddleware diff --git a/docs/docs/en/api/faststream/redis/opentelemetry/provider/RedisTelemetrySettingsProvider.md b/docs/docs/en/api/faststream/redis/opentelemetry/provider/RedisTelemetrySettingsProvider.md deleted file mode 100644 index 26e7859c34..0000000000 --- a/docs/docs/en/api/faststream/redis/opentelemetry/provider/RedisTelemetrySettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.opentelemetry.provider.RedisTelemetrySettingsProvider diff --git a/docs/docs/en/api/faststream/redis/parser/RawMessage.md b/docs/docs/en/api/faststream/redis/parser/RawMessage.md deleted file mode 100644 index 4add7b37fd..0000000000 --- a/docs/docs/en/api/faststream/redis/parser/RawMessage.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.parser.RawMessage diff --git a/docs/docs/en/api/faststream/redis/parser/RedisBatchListParser.md b/docs/docs/en/api/faststream/redis/parser/RedisBatchListParser.md deleted file mode 100644 index e3a583eee8..0000000000 --- a/docs/docs/en/api/faststream/redis/parser/RedisBatchListParser.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.parser.RedisBatchListParser diff --git a/docs/docs/en/api/faststream/redis/parser/RedisBatchStreamParser.md b/docs/docs/en/api/faststream/redis/parser/RedisBatchStreamParser.md deleted file mode 100644 index 28ed437573..0000000000 --- a/docs/docs/en/api/faststream/redis/parser/RedisBatchStreamParser.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.parser.RedisBatchStreamParser diff --git a/docs/docs/en/api/faststream/redis/parser/RedisListParser.md b/docs/docs/en/api/faststream/redis/parser/RedisListParser.md deleted file mode 100644 index fd0cf87991..0000000000 --- a/docs/docs/en/api/faststream/redis/parser/RedisListParser.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.parser.RedisListParser diff --git a/docs/docs/en/api/faststream/redis/parser/RedisPubSubParser.md b/docs/docs/en/api/faststream/redis/parser/RedisPubSubParser.md deleted file mode 100644 index 93ab92cfdb..0000000000 --- a/docs/docs/en/api/faststream/redis/parser/RedisPubSubParser.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.parser.RedisPubSubParser diff --git a/docs/docs/en/api/faststream/redis/parser/RedisStreamParser.md b/docs/docs/en/api/faststream/redis/parser/RedisStreamParser.md deleted file mode 100644 index 79633d06ad..0000000000 --- a/docs/docs/en/api/faststream/redis/parser/RedisStreamParser.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.parser.RedisStreamParser diff --git a/docs/docs/en/api/faststream/redis/parser/SimpleParser.md b/docs/docs/en/api/faststream/redis/parser/SimpleParser.md deleted file mode 100644 index 239d3fda25..0000000000 --- a/docs/docs/en/api/faststream/redis/parser/SimpleParser.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.parser.SimpleParser diff --git a/docs/docs/en/api/faststream/redis/prometheus/RedisPrometheusMiddleware.md b/docs/docs/en/api/faststream/redis/prometheus/RedisPrometheusMiddleware.md deleted file mode 100644 index 01b23fe4f1..0000000000 --- a/docs/docs/en/api/faststream/redis/prometheus/RedisPrometheusMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.prometheus.RedisPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/redis/prometheus/middleware/RedisPrometheusMiddleware.md b/docs/docs/en/api/faststream/redis/prometheus/middleware/RedisPrometheusMiddleware.md deleted file mode 100644 index c29cc91130..0000000000 --- a/docs/docs/en/api/faststream/redis/prometheus/middleware/RedisPrometheusMiddleware.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.prometheus.middleware.RedisPrometheusMiddleware diff --git a/docs/docs/en/api/faststream/redis/prometheus/provider/BaseRedisMetricsSettingsProvider.md b/docs/docs/en/api/faststream/redis/prometheus/provider/BaseRedisMetricsSettingsProvider.md deleted file mode 100644 index 243414331b..0000000000 --- a/docs/docs/en/api/faststream/redis/prometheus/provider/BaseRedisMetricsSettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.prometheus.provider.BaseRedisMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/redis/prometheus/provider/BatchRedisMetricsSettingsProvider.md b/docs/docs/en/api/faststream/redis/prometheus/provider/BatchRedisMetricsSettingsProvider.md deleted file mode 100644 index 33d1d2d3a1..0000000000 --- a/docs/docs/en/api/faststream/redis/prometheus/provider/BatchRedisMetricsSettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.prometheus.provider.BatchRedisMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/redis/prometheus/provider/RedisMetricsSettingsProvider.md b/docs/docs/en/api/faststream/redis/prometheus/provider/RedisMetricsSettingsProvider.md deleted file mode 100644 index a7f5f3abe8..0000000000 --- a/docs/docs/en/api/faststream/redis/prometheus/provider/RedisMetricsSettingsProvider.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.prometheus.provider.RedisMetricsSettingsProvider diff --git a/docs/docs/en/api/faststream/redis/prometheus/provider/settings_provider_factory.md b/docs/docs/en/api/faststream/redis/prometheus/provider/settings_provider_factory.md deleted file mode 100644 index aa4812f1e2..0000000000 --- a/docs/docs/en/api/faststream/redis/prometheus/provider/settings_provider_factory.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.prometheus.provider.settings_provider_factory diff --git a/docs/docs/en/api/faststream/redis/publisher/factory/create_publisher.md b/docs/docs/en/api/faststream/redis/publisher/factory/create_publisher.md deleted file mode 100644 index e568f4120a..0000000000 --- a/docs/docs/en/api/faststream/redis/publisher/factory/create_publisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.publisher.factory.create_publisher diff --git a/docs/docs/en/api/faststream/redis/publisher/fake/RedisFakePublisher.md b/docs/docs/en/api/faststream/redis/publisher/fake/RedisFakePublisher.md deleted file mode 100644 index eb00559657..0000000000 --- a/docs/docs/en/api/faststream/redis/publisher/fake/RedisFakePublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.publisher.fake.RedisFakePublisher diff --git a/docs/docs/en/api/faststream/redis/publisher/producer/RedisFastProducer.md b/docs/docs/en/api/faststream/redis/publisher/producer/RedisFastProducer.md deleted file mode 100644 index 3bc630cc42..0000000000 --- a/docs/docs/en/api/faststream/redis/publisher/producer/RedisFastProducer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.publisher.producer.RedisFastProducer diff --git a/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationChannelPublisher.md b/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationChannelPublisher.md deleted file mode 100644 index 93b88342e4..0000000000 --- a/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationChannelPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.publisher.specified.SpecificationChannelPublisher diff --git a/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationListBatchPublisher.md b/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationListBatchPublisher.md deleted file mode 100644 index c3f9769199..0000000000 --- a/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationListBatchPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.publisher.specified.SpecificationListBatchPublisher diff --git a/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationListPublisher.md b/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationListPublisher.md deleted file mode 100644 index a7ed630a72..0000000000 --- a/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationListPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.publisher.specified.SpecificationListPublisher diff --git a/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationPublisher.md b/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationPublisher.md deleted file mode 100644 index ceb47b19f6..0000000000 --- a/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.publisher.specified.SpecificationPublisher diff --git a/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationStreamPublisher.md b/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationStreamPublisher.md deleted file mode 100644 index 5800dc96da..0000000000 --- a/docs/docs/en/api/faststream/redis/publisher/specified/SpecificationStreamPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.publisher.specified.SpecificationStreamPublisher diff --git a/docs/docs/en/api/faststream/redis/publisher/usecase/ChannelPublisher.md b/docs/docs/en/api/faststream/redis/publisher/usecase/ChannelPublisher.md deleted file mode 100644 index 8aad760800..0000000000 --- a/docs/docs/en/api/faststream/redis/publisher/usecase/ChannelPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.publisher.usecase.ChannelPublisher diff --git a/docs/docs/en/api/faststream/redis/publisher/usecase/ListBatchPublisher.md b/docs/docs/en/api/faststream/redis/publisher/usecase/ListBatchPublisher.md deleted file mode 100644 index d7a1be63e4..0000000000 --- a/docs/docs/en/api/faststream/redis/publisher/usecase/ListBatchPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.publisher.usecase.ListBatchPublisher diff --git a/docs/docs/en/api/faststream/redis/publisher/usecase/ListPublisher.md b/docs/docs/en/api/faststream/redis/publisher/usecase/ListPublisher.md deleted file mode 100644 index 59895dc001..0000000000 --- a/docs/docs/en/api/faststream/redis/publisher/usecase/ListPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.publisher.usecase.ListPublisher diff --git a/docs/docs/en/api/faststream/redis/publisher/usecase/LogicPublisher.md b/docs/docs/en/api/faststream/redis/publisher/usecase/LogicPublisher.md deleted file mode 100644 index c441bcc461..0000000000 --- a/docs/docs/en/api/faststream/redis/publisher/usecase/LogicPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.publisher.usecase.LogicPublisher diff --git a/docs/docs/en/api/faststream/redis/publisher/usecase/StreamPublisher.md b/docs/docs/en/api/faststream/redis/publisher/usecase/StreamPublisher.md deleted file mode 100644 index ea56c9d699..0000000000 --- a/docs/docs/en/api/faststream/redis/publisher/usecase/StreamPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.publisher.usecase.StreamPublisher diff --git a/docs/docs/en/api/faststream/redis/response/DestinationType.md b/docs/docs/en/api/faststream/redis/response/DestinationType.md deleted file mode 100644 index 4eda1ad154..0000000000 --- a/docs/docs/en/api/faststream/redis/response/DestinationType.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.response.DestinationType diff --git a/docs/docs/en/api/faststream/redis/response/RedisPublishCommand.md b/docs/docs/en/api/faststream/redis/response/RedisPublishCommand.md deleted file mode 100644 index 14e21c799e..0000000000 --- a/docs/docs/en/api/faststream/redis/response/RedisPublishCommand.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.response.RedisPublishCommand diff --git a/docs/docs/en/api/faststream/redis/response/RedisResponse.md b/docs/docs/en/api/faststream/redis/response/RedisResponse.md deleted file mode 100644 index dd7fbe72eb..0000000000 --- a/docs/docs/en/api/faststream/redis/response/RedisResponse.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.response.RedisResponse diff --git a/docs/docs/en/api/faststream/redis/router/RedisPublisher.md b/docs/docs/en/api/faststream/redis/router/RedisPublisher.md deleted file mode 100644 index fd1cad4d37..0000000000 --- a/docs/docs/en/api/faststream/redis/router/RedisPublisher.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.router.RedisPublisher diff --git a/docs/docs/en/api/faststream/redis/router/RedisRoute.md b/docs/docs/en/api/faststream/redis/router/RedisRoute.md deleted file mode 100644 index d6e1f525a7..0000000000 --- a/docs/docs/en/api/faststream/redis/router/RedisRoute.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.router.RedisRoute diff --git a/docs/docs/en/api/faststream/redis/router/RedisRouter.md b/docs/docs/en/api/faststream/redis/router/RedisRouter.md deleted file mode 100644 index 373ceea5a8..0000000000 --- a/docs/docs/en/api/faststream/redis/router/RedisRouter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.router.RedisRouter diff --git a/docs/docs/en/api/faststream/redis/schemas/ListSub.md b/docs/docs/en/api/faststream/redis/schemas/ListSub.md deleted file mode 100644 index 3e0b448229..0000000000 --- a/docs/docs/en/api/faststream/redis/schemas/ListSub.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.schemas.ListSub diff --git a/docs/docs/en/api/faststream/redis/schemas/PubSub.md b/docs/docs/en/api/faststream/redis/schemas/PubSub.md deleted file mode 100644 index 078a8e2d8e..0000000000 --- a/docs/docs/en/api/faststream/redis/schemas/PubSub.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.schemas.PubSub diff --git a/docs/docs/en/api/faststream/redis/schemas/StreamSub.md b/docs/docs/en/api/faststream/redis/schemas/StreamSub.md deleted file mode 100644 index 396e594c0b..0000000000 --- a/docs/docs/en/api/faststream/redis/schemas/StreamSub.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.schemas.StreamSub diff --git a/docs/docs/en/api/faststream/redis/schemas/list_sub/ListSub.md b/docs/docs/en/api/faststream/redis/schemas/list_sub/ListSub.md deleted file mode 100644 index f4b58ff4fb..0000000000 --- a/docs/docs/en/api/faststream/redis/schemas/list_sub/ListSub.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.schemas.list_sub.ListSub diff --git a/docs/docs/en/api/faststream/redis/schemas/proto/RedisSpecificationProtocol.md b/docs/docs/en/api/faststream/redis/schemas/proto/RedisSpecificationProtocol.md deleted file mode 100644 index de3ab92ace..0000000000 --- a/docs/docs/en/api/faststream/redis/schemas/proto/RedisSpecificationProtocol.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.schemas.proto.RedisSpecificationProtocol diff --git a/docs/docs/en/api/faststream/redis/schemas/proto/validate_options.md b/docs/docs/en/api/faststream/redis/schemas/proto/validate_options.md deleted file mode 100644 index 7a5381120e..0000000000 --- a/docs/docs/en/api/faststream/redis/schemas/proto/validate_options.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.schemas.proto.validate_options diff --git a/docs/docs/en/api/faststream/redis/schemas/pub_sub/PubSub.md b/docs/docs/en/api/faststream/redis/schemas/pub_sub/PubSub.md deleted file mode 100644 index 08552c7b8c..0000000000 --- a/docs/docs/en/api/faststream/redis/schemas/pub_sub/PubSub.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.schemas.pub_sub.PubSub diff --git a/docs/docs/en/api/faststream/redis/schemas/stream_sub/StreamSub.md b/docs/docs/en/api/faststream/redis/schemas/stream_sub/StreamSub.md deleted file mode 100644 index e1a8d44d4e..0000000000 --- a/docs/docs/en/api/faststream/redis/schemas/stream_sub/StreamSub.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.schemas.stream_sub.StreamSub diff --git a/docs/docs/en/api/faststream/redis/security/parse_security.md b/docs/docs/en/api/faststream/redis/security/parse_security.md deleted file mode 100644 index d3673649db..0000000000 --- a/docs/docs/en/api/faststream/redis/security/parse_security.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.security.parse_security diff --git a/docs/docs/en/api/faststream/redis/subscriber/factory/create_subscriber.md b/docs/docs/en/api/faststream/redis/subscriber/factory/create_subscriber.md deleted file mode 100644 index d5cf7eadc8..0000000000 --- a/docs/docs/en/api/faststream/redis/subscriber/factory/create_subscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.subscriber.factory.create_subscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationChannelSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationChannelSubscriber.md deleted file mode 100644 index 538babd05f..0000000000 --- a/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationChannelSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.subscriber.specified.SpecificationChannelSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationListBatchSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationListBatchSubscriber.md deleted file mode 100644 index 60e7fa385d..0000000000 --- a/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationListBatchSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.subscriber.specified.SpecificationListBatchSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationListSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationListSubscriber.md deleted file mode 100644 index 988ffccb3c..0000000000 --- a/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationListSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.subscriber.specified.SpecificationListSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationStreamBatchSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationStreamBatchSubscriber.md deleted file mode 100644 index 76a6aff457..0000000000 --- a/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationStreamBatchSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.subscriber.specified.SpecificationStreamBatchSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationStreamSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationStreamSubscriber.md deleted file mode 100644 index f1bfe8a520..0000000000 --- a/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationStreamSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.subscriber.specified.SpecificationStreamSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationSubscriber.md deleted file mode 100644 index 90a2845dc9..0000000000 --- a/docs/docs/en/api/faststream/redis/subscriber/specified/SpecificationSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.subscriber.specified.SpecificationSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/usecase/BatchListSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/usecase/BatchListSubscriber.md deleted file mode 100644 index aee1b8aa9b..0000000000 --- a/docs/docs/en/api/faststream/redis/subscriber/usecase/BatchListSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.subscriber.usecase.BatchListSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/usecase/ChannelSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/usecase/ChannelSubscriber.md deleted file mode 100644 index 3ab1fc045a..0000000000 --- a/docs/docs/en/api/faststream/redis/subscriber/usecase/ChannelSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.subscriber.usecase.ChannelSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/usecase/ListSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/usecase/ListSubscriber.md deleted file mode 100644 index f7c44e8be5..0000000000 --- a/docs/docs/en/api/faststream/redis/subscriber/usecase/ListSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.subscriber.usecase.ListSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/usecase/LogicSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/usecase/LogicSubscriber.md deleted file mode 100644 index e3531e7dcc..0000000000 --- a/docs/docs/en/api/faststream/redis/subscriber/usecase/LogicSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.subscriber.usecase.LogicSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/usecase/StreamBatchSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/usecase/StreamBatchSubscriber.md deleted file mode 100644 index 3500cc21e2..0000000000 --- a/docs/docs/en/api/faststream/redis/subscriber/usecase/StreamBatchSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.subscriber.usecase.StreamBatchSubscriber diff --git a/docs/docs/en/api/faststream/redis/subscriber/usecase/StreamSubscriber.md b/docs/docs/en/api/faststream/redis/subscriber/usecase/StreamSubscriber.md deleted file mode 100644 index 6e2ac31d7f..0000000000 --- a/docs/docs/en/api/faststream/redis/subscriber/usecase/StreamSubscriber.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.subscriber.usecase.StreamSubscriber diff --git a/docs/docs/en/api/faststream/redis/testing/ChannelVisitor.md b/docs/docs/en/api/faststream/redis/testing/ChannelVisitor.md deleted file mode 100644 index f916be2ae8..0000000000 --- a/docs/docs/en/api/faststream/redis/testing/ChannelVisitor.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.testing.ChannelVisitor diff --git a/docs/docs/en/api/faststream/redis/testing/FakeProducer.md b/docs/docs/en/api/faststream/redis/testing/FakeProducer.md deleted file mode 100644 index e05efb6448..0000000000 --- a/docs/docs/en/api/faststream/redis/testing/FakeProducer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.testing.FakeProducer diff --git a/docs/docs/en/api/faststream/redis/testing/ListVisitor.md b/docs/docs/en/api/faststream/redis/testing/ListVisitor.md deleted file mode 100644 index 414b8a0400..0000000000 --- a/docs/docs/en/api/faststream/redis/testing/ListVisitor.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.testing.ListVisitor diff --git a/docs/docs/en/api/faststream/redis/testing/StreamVisitor.md b/docs/docs/en/api/faststream/redis/testing/StreamVisitor.md deleted file mode 100644 index 0b72d99109..0000000000 --- a/docs/docs/en/api/faststream/redis/testing/StreamVisitor.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.testing.StreamVisitor diff --git a/docs/docs/en/api/faststream/redis/testing/TestRedisBroker.md b/docs/docs/en/api/faststream/redis/testing/TestRedisBroker.md deleted file mode 100644 index 22946e09f8..0000000000 --- a/docs/docs/en/api/faststream/redis/testing/TestRedisBroker.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.testing.TestRedisBroker diff --git a/docs/docs/en/api/faststream/redis/testing/Visitor.md b/docs/docs/en/api/faststream/redis/testing/Visitor.md deleted file mode 100644 index 746688710f..0000000000 --- a/docs/docs/en/api/faststream/redis/testing/Visitor.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.testing.Visitor diff --git a/docs/docs/en/api/faststream/redis/testing/build_message.md b/docs/docs/en/api/faststream/redis/testing/build_message.md deleted file mode 100644 index b2265905c6..0000000000 --- a/docs/docs/en/api/faststream/redis/testing/build_message.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.redis.testing.build_message diff --git a/docs/docs/en/api/faststream/response/PublishCommand.md b/docs/docs/en/api/faststream/response/PublishCommand.md deleted file mode 100644 index 8ca17ac376..0000000000 --- a/docs/docs/en/api/faststream/response/PublishCommand.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.response.PublishCommand diff --git a/docs/docs/en/api/faststream/response/PublishType.md b/docs/docs/en/api/faststream/response/PublishType.md deleted file mode 100644 index 57d3cbddd7..0000000000 --- a/docs/docs/en/api/faststream/response/PublishType.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.response.PublishType diff --git a/docs/docs/en/api/faststream/response/Response.md b/docs/docs/en/api/faststream/response/Response.md deleted file mode 100644 index e96fe35896..0000000000 --- a/docs/docs/en/api/faststream/response/Response.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.response.Response diff --git a/docs/docs/en/api/faststream/response/ensure_response.md b/docs/docs/en/api/faststream/response/ensure_response.md deleted file mode 100644 index e55d638acf..0000000000 --- a/docs/docs/en/api/faststream/response/ensure_response.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.response.ensure_response diff --git a/docs/docs/en/api/faststream/response/publish_type/PublishType.md b/docs/docs/en/api/faststream/response/publish_type/PublishType.md deleted file mode 100644 index 2ac2fcd51c..0000000000 --- a/docs/docs/en/api/faststream/response/publish_type/PublishType.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.response.publish_type.PublishType diff --git a/docs/docs/en/api/faststream/response/response/PublishCommand.md b/docs/docs/en/api/faststream/response/response/PublishCommand.md deleted file mode 100644 index b247a7e5d8..0000000000 --- a/docs/docs/en/api/faststream/response/response/PublishCommand.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.response.response.PublishCommand diff --git a/docs/docs/en/api/faststream/response/response/Response.md b/docs/docs/en/api/faststream/response/response/Response.md deleted file mode 100644 index 01a68bb486..0000000000 --- a/docs/docs/en/api/faststream/response/response/Response.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.response.response.Response diff --git a/docs/docs/en/api/faststream/response/utils/ensure_response.md b/docs/docs/en/api/faststream/response/utils/ensure_response.md deleted file mode 100644 index 327b9ce951..0000000000 --- a/docs/docs/en/api/faststream/response/utils/ensure_response.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.response.utils.ensure_response diff --git a/docs/docs/en/api/faststream/security/BaseSecurity.md b/docs/docs/en/api/faststream/security/BaseSecurity.md deleted file mode 100644 index 0e5abb09ae..0000000000 --- a/docs/docs/en/api/faststream/security/BaseSecurity.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.security.BaseSecurity diff --git a/docs/docs/en/api/faststream/security/SASLGSSAPI.md b/docs/docs/en/api/faststream/security/SASLGSSAPI.md deleted file mode 100644 index 8b6eec2741..0000000000 --- a/docs/docs/en/api/faststream/security/SASLGSSAPI.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.security.SASLGSSAPI diff --git a/docs/docs/en/api/faststream/security/SASLOAuthBearer.md b/docs/docs/en/api/faststream/security/SASLOAuthBearer.md deleted file mode 100644 index 9652a58840..0000000000 --- a/docs/docs/en/api/faststream/security/SASLOAuthBearer.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.security.SASLOAuthBearer diff --git a/docs/docs/en/api/faststream/security/SASLPlaintext.md b/docs/docs/en/api/faststream/security/SASLPlaintext.md deleted file mode 100644 index b4b5165f27..0000000000 --- a/docs/docs/en/api/faststream/security/SASLPlaintext.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.security.SASLPlaintext diff --git a/docs/docs/en/api/faststream/security/SASLScram256.md b/docs/docs/en/api/faststream/security/SASLScram256.md deleted file mode 100644 index 4d50681fa9..0000000000 --- a/docs/docs/en/api/faststream/security/SASLScram256.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.security.SASLScram256 diff --git a/docs/docs/en/api/faststream/security/SASLScram512.md b/docs/docs/en/api/faststream/security/SASLScram512.md deleted file mode 100644 index 115645cc8c..0000000000 --- a/docs/docs/en/api/faststream/security/SASLScram512.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.security.SASLScram512 diff --git a/docs/docs/en/api/faststream/specification/AsyncAPI.md b/docs/docs/en/api/faststream/specification/AsyncAPI.md deleted file mode 100644 index 4b23e3fa4a..0000000000 --- a/docs/docs/en/api/faststream/specification/AsyncAPI.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.AsyncAPI diff --git a/docs/docs/en/api/faststream/specification/Contact.md b/docs/docs/en/api/faststream/specification/Contact.md deleted file mode 100644 index aa8ac012ea..0000000000 --- a/docs/docs/en/api/faststream/specification/Contact.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.Contact diff --git a/docs/docs/en/api/faststream/specification/ExternalDocs.md b/docs/docs/en/api/faststream/specification/ExternalDocs.md deleted file mode 100644 index 52e0432c94..0000000000 --- a/docs/docs/en/api/faststream/specification/ExternalDocs.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.ExternalDocs diff --git a/docs/docs/en/api/faststream/specification/License.md b/docs/docs/en/api/faststream/specification/License.md deleted file mode 100644 index ac2365f82b..0000000000 --- a/docs/docs/en/api/faststream/specification/License.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.License diff --git a/docs/docs/en/api/faststream/specification/Tag.md b/docs/docs/en/api/faststream/specification/Tag.md deleted file mode 100644 index ae4f1202a1..0000000000 --- a/docs/docs/en/api/faststream/specification/Tag.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.Tag diff --git a/docs/docs/en/api/faststream/specification/asyncapi/AsyncAPI.md b/docs/docs/en/api/faststream/specification/asyncapi/AsyncAPI.md deleted file mode 100644 index f6c0b2de09..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/AsyncAPI.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.AsyncAPI diff --git a/docs/docs/en/api/faststream/specification/asyncapi/factory/AsyncAPI.md b/docs/docs/en/api/faststream/specification/asyncapi/factory/AsyncAPI.md deleted file mode 100644 index 9e68cc1f6c..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/factory/AsyncAPI.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.factory.AsyncAPI diff --git a/docs/docs/en/api/faststream/specification/asyncapi/get_asyncapi_html.md b/docs/docs/en/api/faststream/specification/asyncapi/get_asyncapi_html.md deleted file mode 100644 index 02a5bf12cb..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/get_asyncapi_html.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.get_asyncapi_html diff --git a/docs/docs/en/api/faststream/specification/asyncapi/message/get_model_schema.md b/docs/docs/en/api/faststream/specification/asyncapi/message/get_model_schema.md deleted file mode 100644 index 83b5c9026e..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/message/get_model_schema.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.message.get_model_schema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/message/get_response_schema.md b/docs/docs/en/api/faststream/specification/asyncapi/message/get_response_schema.md deleted file mode 100644 index d283b28902..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/message/get_response_schema.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.message.get_response_schema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/message/parse_handler_params.md b/docs/docs/en/api/faststream/specification/asyncapi/message/parse_handler_params.md deleted file mode 100644 index cb6c4416f8..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/message/parse_handler_params.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.message.parse_handler_params diff --git a/docs/docs/en/api/faststream/specification/asyncapi/site/get_asyncapi_html.md b/docs/docs/en/api/faststream/specification/asyncapi/site/get_asyncapi_html.md deleted file mode 100644 index 837b931af7..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/site/get_asyncapi_html.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.site.get_asyncapi_html diff --git a/docs/docs/en/api/faststream/specification/asyncapi/site/serve_app.md b/docs/docs/en/api/faststream/specification/asyncapi/site/serve_app.md deleted file mode 100644 index 279e9eb8e0..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/site/serve_app.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.site.serve_app diff --git a/docs/docs/en/api/faststream/specification/asyncapi/utils/clear_key.md b/docs/docs/en/api/faststream/specification/asyncapi/utils/clear_key.md deleted file mode 100644 index cf6103d19a..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/utils/clear_key.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.utils.clear_key diff --git a/docs/docs/en/api/faststream/specification/asyncapi/utils/move_pydantic_refs.md b/docs/docs/en/api/faststream/specification/asyncapi/utils/move_pydantic_refs.md deleted file mode 100644 index 445472f96d..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/utils/move_pydantic_refs.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.utils.move_pydantic_refs diff --git a/docs/docs/en/api/faststream/specification/asyncapi/utils/resolve_payloads.md b/docs/docs/en/api/faststream/specification/asyncapi/utils/resolve_payloads.md deleted file mode 100644 index d92d1850f3..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/utils/resolve_payloads.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.utils.resolve_payloads diff --git a/docs/docs/en/api/faststream/specification/asyncapi/utils/to_camelcase.md b/docs/docs/en/api/faststream/specification/asyncapi/utils/to_camelcase.md deleted file mode 100644 index 5a260c9cca..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/utils/to_camelcase.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.utils.to_camelcase diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/AsyncAPI2.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/AsyncAPI2.md deleted file mode 100644 index b6ca4b870a..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/AsyncAPI2.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.AsyncAPI2 diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/facade/AsyncAPI2.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/facade/AsyncAPI2.md deleted file mode 100644 index 1807a92056..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/facade/AsyncAPI2.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.facade.AsyncAPI2 diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_app_schema.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_app_schema.md deleted file mode 100644 index ef0e191d3d..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_app_schema.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.generate.get_app_schema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_channels.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_channels.md deleted file mode 100644 index 03fc069dc1..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_channels.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.generate.get_broker_channels diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_server.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_server.md deleted file mode 100644 index c7b9007c14..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/get_broker_server.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.generate.get_broker_server diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/resolve_channel_messages.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/resolve_channel_messages.md deleted file mode 100644 index 91abb99b8b..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/generate/resolve_channel_messages.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.generate.resolve_channel_messages diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/get_app_schema.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/get_app_schema.md deleted file mode 100644 index 234b4b8bda..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/get_app_schema.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.get_app_schema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ApplicationInfo.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ApplicationInfo.md deleted file mode 100644 index b7aaf16515..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ApplicationInfo.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.ApplicationInfo diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ApplicationSchema.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ApplicationSchema.md deleted file mode 100644 index 614fed94e1..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ApplicationSchema.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.ApplicationSchema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Channel.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Channel.md deleted file mode 100644 index 76da65a973..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Channel.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.Channel diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Components.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Components.md deleted file mode 100644 index 12ba1a0a30..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Components.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.Components diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Contact.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Contact.md deleted file mode 100644 index 7eba14d8b1..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Contact.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.Contact diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/CorrelationId.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/CorrelationId.md deleted file mode 100644 index 3173309f51..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/CorrelationId.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.CorrelationId diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ExternalDocs.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ExternalDocs.md deleted file mode 100644 index 2df43d1016..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ExternalDocs.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.ExternalDocs diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/License.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/License.md deleted file mode 100644 index 3f17b11448..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/License.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.License diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Message.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Message.md deleted file mode 100644 index f6247931d4..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Message.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.Message diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Operation.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Operation.md deleted file mode 100644 index e25d0e8ff2..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Operation.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.Operation diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Parameter.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Parameter.md deleted file mode 100644 index fac8aa5ee7..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Parameter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.Parameter diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Reference.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Reference.md deleted file mode 100644 index c469faf891..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Reference.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.Reference diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Server.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Server.md deleted file mode 100644 index 82bc1ddb32..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Server.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.Server diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ServerVariable.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ServerVariable.md deleted file mode 100644 index 06639f3ec5..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/ServerVariable.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.ServerVariable diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Tag.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Tag.md deleted file mode 100644 index 35baa89db7..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/Tag.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.Tag diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/ChannelBinding.md deleted file mode 100644 index 36874fc37c..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/OperationBinding.md deleted file mode 100644 index eb11d6b550..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/ChannelBinding.md deleted file mode 100644 index 263e89f51b..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/OperationBinding.md deleted file mode 100644 index 350a96b413..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/ChannelBinding.md deleted file mode 100644 index 6b4f8d6d93..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Exchange.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Exchange.md deleted file mode 100644 index dbd3288b64..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Exchange.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.channel.Exchange diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Queue.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Queue.md deleted file mode 100644 index 31de312529..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/channel/Queue.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.channel.Queue diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/OperationBinding.md deleted file mode 100644 index 937cda8820..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/amqp/operation/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/ChannelBinding.md deleted file mode 100644 index 7792a2bef7..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/OperationBinding.md deleted file mode 100644 index 21c35af99f..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel/ChannelBinding.md deleted file mode 100644 index 82b2556711..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/channel/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/OperationBinding.md deleted file mode 100644 index 49e28f86ef..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/kafka/operation/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/ChannelBinding.md deleted file mode 100644 index a044af926c..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.main.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/OperationBinding.md deleted file mode 100644 index 9cf2d46f59..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.main.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/ChannelBinding.md deleted file mode 100644 index c7d4ecef03..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/channel/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.main.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/OperationBinding.md deleted file mode 100644 index b464bbb356..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/main/operation/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.main.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/ChannelBinding.md deleted file mode 100644 index 8380c4571d..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.nats.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/OperationBinding.md deleted file mode 100644 index c48ff3bad7..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.nats.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel/ChannelBinding.md deleted file mode 100644 index ebc06a51b8..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/channel/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.nats.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/OperationBinding.md deleted file mode 100644 index 10ebc684ce..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/nats/operation/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.nats.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/ChannelBinding.md deleted file mode 100644 index 49402a3533..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.redis.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/OperationBinding.md deleted file mode 100644 index 4a41fede12..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.redis.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel/ChannelBinding.md deleted file mode 100644 index 4c859b133e..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/channel/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.redis.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/OperationBinding.md deleted file mode 100644 index 5e7ef90817..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/redis/operation/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.redis.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/ChannelBinding.md deleted file mode 100644 index efd54e587e..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/OperationBinding.md deleted file mode 100644 index 4f3babf6a5..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/ChannelBinding.md deleted file mode 100644 index 274f800ea8..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/from_spec.md deleted file mode 100644 index 6890ca0373..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel/from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.channel.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/OperationBinding.md deleted file mode 100644 index 931067bfef..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/from_spec.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/from_spec.md deleted file mode 100644 index b8a69ffcc0..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation/from_spec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.operation.from_spec diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channels/Channel.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channels/Channel.md deleted file mode 100644 index 520d156b96..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/channels/Channel.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.channels.Channel diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/components/Components.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/components/Components.md deleted file mode 100644 index 215edc3e69..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/components/Components.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.components.Components diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact/Contact.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact/Contact.md deleted file mode 100644 index 14b7574d92..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/contact/Contact.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.contact.Contact diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs/ExternalDocs.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs/ExternalDocs.md deleted file mode 100644 index 8b66a2c5f3..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/docs/ExternalDocs.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.docs.ExternalDocs diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/info/ApplicationInfo.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/info/ApplicationInfo.md deleted file mode 100644 index db377ddd61..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/info/ApplicationInfo.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.info.ApplicationInfo diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license/License.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license/License.md deleted file mode 100644 index d9d4102522..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/license/License.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.license.License diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/CorrelationId.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/CorrelationId.md deleted file mode 100644 index bbfc2f40d8..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/CorrelationId.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.message.CorrelationId diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/Message.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/Message.md deleted file mode 100644 index 9667e77e8e..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/message/Message.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.message.Message diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operations/Operation.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operations/Operation.md deleted file mode 100644 index 3d750e5f3e..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/operations/Operation.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.operations.Operation diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/schema/ApplicationSchema.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/schema/ApplicationSchema.md deleted file mode 100644 index 2a380a8e4d..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/schema/ApplicationSchema.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.schema.ApplicationSchema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/servers/Server.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/servers/Server.md deleted file mode 100644 index a50c1a5cf1..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/servers/Server.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.servers.Server diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/servers/ServerVariable.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/servers/ServerVariable.md deleted file mode 100644 index 8606288a32..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/servers/ServerVariable.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.servers.ServerVariable diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag/Tag.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag/Tag.md deleted file mode 100644 index c3d9025966..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/tag/Tag.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.tag.Tag diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/utils/Parameter.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/utils/Parameter.md deleted file mode 100644 index c2971d5485..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/utils/Parameter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.utils.Parameter diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/utils/Reference.md b/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/utils/Reference.md deleted file mode 100644 index 2737907b0e..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v2_6_0/schema/utils/Reference.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.utils.Reference diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/AsyncAPI3.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/AsyncAPI3.md deleted file mode 100644 index 4eb400a450..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/AsyncAPI3.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.AsyncAPI3 diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/facade/AsyncAPI3.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/facade/AsyncAPI3.md deleted file mode 100644 index 5216f86a02..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/facade/AsyncAPI3.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.facade.AsyncAPI3 diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_app_schema.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_app_schema.md deleted file mode 100644 index 0faa97ba94..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_app_schema.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.generate.get_app_schema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_channels.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_channels.md deleted file mode 100644 index d43691125d..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_channels.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.generate.get_broker_channels diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_server.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_server.md deleted file mode 100644 index 1c71db1292..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/generate/get_broker_server.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.generate.get_broker_server diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/get_app_schema.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/get_app_schema.md deleted file mode 100644 index 977c46289d..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/get_app_schema.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.get_app_schema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationInfo.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationInfo.md deleted file mode 100644 index be7a85513c..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationInfo.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.ApplicationInfo diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationSchema.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationSchema.md deleted file mode 100644 index 0f3fa28a38..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ApplicationSchema.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.ApplicationSchema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Channel.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Channel.md deleted file mode 100644 index f213110586..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Channel.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.Channel diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Components.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Components.md deleted file mode 100644 index bce8d6e93e..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Components.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.Components diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Contact.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Contact.md deleted file mode 100644 index 14b7574d92..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Contact.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.contact.Contact diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/CorrelationId.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/CorrelationId.md deleted file mode 100644 index bbfc2f40d8..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/CorrelationId.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.message.CorrelationId diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ExternalDocs.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ExternalDocs.md deleted file mode 100644 index 8b66a2c5f3..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ExternalDocs.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.docs.ExternalDocs diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/License.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/License.md deleted file mode 100644 index d9d4102522..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/License.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.license.License diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Message.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Message.md deleted file mode 100644 index 9667e77e8e..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Message.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.message.Message diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Operation.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Operation.md deleted file mode 100644 index a46ecefb8d..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Operation.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.Operation diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Parameter.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Parameter.md deleted file mode 100644 index c2971d5485..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Parameter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.utils.Parameter diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Reference.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Reference.md deleted file mode 100644 index 2737907b0e..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Reference.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.utils.Reference diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Server.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Server.md deleted file mode 100644 index d41ebe84c3..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Server.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.Server diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ServerVariable.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ServerVariable.md deleted file mode 100644 index 8606288a32..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/ServerVariable.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.servers.ServerVariable diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Tag.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Tag.md deleted file mode 100644 index c3d9025966..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/Tag.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.tag.Tag diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/ChannelBinding.md deleted file mode 100644 index ca8431218b..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.bindings.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/OperationBinding.md deleted file mode 100644 index 876f866f35..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.bindings.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/ChannelBinding.md deleted file mode 100644 index 2777001c4d..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.bindings.amqp.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/OperationBinding.md deleted file mode 100644 index 325bba3f9e..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.bindings.amqp.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel/ChannelBinding.md deleted file mode 100644 index 74c10098ac..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/channel/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.bindings.amqp.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation/OperationBinding.md deleted file mode 100644 index 51c5024cc7..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.bindings.amqp.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka/ChannelBinding.md deleted file mode 100644 index 82b2556711..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka/OperationBinding.md deleted file mode 100644 index 49e28f86ef..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/kafka/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.kafka.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/ChannelBinding.md deleted file mode 100644 index 07977ed15f..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.bindings.main.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/OperationBinding.md deleted file mode 100644 index c897790951..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.bindings.main.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel/ChannelBinding.md deleted file mode 100644 index 409e449a27..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/channel/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.bindings.main.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation/OperationBinding.md deleted file mode 100644 index 4e85a7f5e4..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/main/operation/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.bindings.main.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats/ChannelBinding.md deleted file mode 100644 index ebc06a51b8..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.nats.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats/OperationBinding.md deleted file mode 100644 index 10ebc684ce..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/nats/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.nats.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis/ChannelBinding.md deleted file mode 100644 index 4c859b133e..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.redis.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis/OperationBinding.md deleted file mode 100644 index 5e7ef90817..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/redis/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.redis.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs/ChannelBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs/ChannelBinding.md deleted file mode 100644 index 274f800ea8..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.channel.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs/OperationBinding.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs/OperationBinding.md deleted file mode 100644 index 931067bfef..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/bindings/sqs/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.bindings.sqs.operation.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channels/Channel.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channels/Channel.md deleted file mode 100644 index b3b425a350..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/channels/Channel.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.channels.Channel diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/components/Components.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/components/Components.md deleted file mode 100644 index db5c489f43..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/components/Components.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.components.Components diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/contact/Contact.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/contact/Contact.md deleted file mode 100644 index 14b7574d92..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/contact/Contact.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.contact.Contact diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/docs/ExternalDocs.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/docs/ExternalDocs.md deleted file mode 100644 index 8b66a2c5f3..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/docs/ExternalDocs.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.docs.ExternalDocs diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/info/ApplicationInfo.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/info/ApplicationInfo.md deleted file mode 100644 index f0c2b0f95d..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/info/ApplicationInfo.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.info.ApplicationInfo diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/license/License.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/license/License.md deleted file mode 100644 index d9d4102522..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/license/License.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.license.License diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/message/CorrelationId.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/message/CorrelationId.md deleted file mode 100644 index bbfc2f40d8..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/message/CorrelationId.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.message.CorrelationId diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/message/Message.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/message/Message.md deleted file mode 100644 index 9667e77e8e..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/message/Message.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.message.Message diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/Action.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/Action.md deleted file mode 100644 index c5a9956348..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/Action.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.operations.Action diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/Operation.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/Operation.md deleted file mode 100644 index 1ac73f73da..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/operations/Operation.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.operations.Operation diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/schema/ApplicationSchema.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/schema/ApplicationSchema.md deleted file mode 100644 index 57fc00568a..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/schema/ApplicationSchema.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.schema.ApplicationSchema diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/servers/Server.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/servers/Server.md deleted file mode 100644 index 1d9f1168d9..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/servers/Server.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v3_0_0.schema.servers.Server diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/tag/Tag.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/tag/Tag.md deleted file mode 100644 index c3d9025966..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/tag/Tag.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.tag.Tag diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/utils/Parameter.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/utils/Parameter.md deleted file mode 100644 index c2971d5485..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/utils/Parameter.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.utils.Parameter diff --git a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/utils/Reference.md b/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/utils/Reference.md deleted file mode 100644 index 2737907b0e..0000000000 --- a/docs/docs/en/api/faststream/specification/asyncapi/v3_0_0/schema/utils/Reference.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.asyncapi.v2_6_0.schema.utils.Reference diff --git a/docs/docs/en/api/faststream/specification/base/info/BaseApplicationInfo.md b/docs/docs/en/api/faststream/specification/base/info/BaseApplicationInfo.md deleted file mode 100644 index 324bbbcec9..0000000000 --- a/docs/docs/en/api/faststream/specification/base/info/BaseApplicationInfo.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.base.info.BaseApplicationInfo diff --git a/docs/docs/en/api/faststream/specification/base/schema/BaseApplicationSchema.md b/docs/docs/en/api/faststream/specification/base/schema/BaseApplicationSchema.md deleted file mode 100644 index 8d9291322c..0000000000 --- a/docs/docs/en/api/faststream/specification/base/schema/BaseApplicationSchema.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.base.schema.BaseApplicationSchema diff --git a/docs/docs/en/api/faststream/specification/base/specification/Specification.md b/docs/docs/en/api/faststream/specification/base/specification/Specification.md deleted file mode 100644 index 0b3f07b9f7..0000000000 --- a/docs/docs/en/api/faststream/specification/base/specification/Specification.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.base.specification.Specification diff --git a/docs/docs/en/api/faststream/specification/proto/EndpointSpecification.md b/docs/docs/en/api/faststream/specification/proto/EndpointSpecification.md deleted file mode 100644 index 3d6dcee882..0000000000 --- a/docs/docs/en/api/faststream/specification/proto/EndpointSpecification.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.proto.EndpointSpecification diff --git a/docs/docs/en/api/faststream/specification/proto/ServerSpecification.md b/docs/docs/en/api/faststream/specification/proto/ServerSpecification.md deleted file mode 100644 index d49b60e512..0000000000 --- a/docs/docs/en/api/faststream/specification/proto/ServerSpecification.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.proto.ServerSpecification diff --git a/docs/docs/en/api/faststream/specification/proto/broker/ServerSpecification.md b/docs/docs/en/api/faststream/specification/proto/broker/ServerSpecification.md deleted file mode 100644 index 6bb667f707..0000000000 --- a/docs/docs/en/api/faststream/specification/proto/broker/ServerSpecification.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.proto.broker.ServerSpecification diff --git a/docs/docs/en/api/faststream/specification/proto/endpoint/EndpointSpecification.md b/docs/docs/en/api/faststream/specification/proto/endpoint/EndpointSpecification.md deleted file mode 100644 index 491c5e3e87..0000000000 --- a/docs/docs/en/api/faststream/specification/proto/endpoint/EndpointSpecification.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.proto.endpoint.EndpointSpecification diff --git a/docs/docs/en/api/faststream/specification/schema/Contact.md b/docs/docs/en/api/faststream/specification/schema/Contact.md deleted file mode 100644 index 5c95b1d99b..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/Contact.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.Contact diff --git a/docs/docs/en/api/faststream/specification/schema/ContactDict.md b/docs/docs/en/api/faststream/specification/schema/ContactDict.md deleted file mode 100644 index 79d9ca5fb2..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/ContactDict.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.ContactDict diff --git a/docs/docs/en/api/faststream/specification/schema/ExternalDocs.md b/docs/docs/en/api/faststream/specification/schema/ExternalDocs.md deleted file mode 100644 index 242418f578..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/ExternalDocs.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.ExternalDocs diff --git a/docs/docs/en/api/faststream/specification/schema/ExternalDocsDict.md b/docs/docs/en/api/faststream/specification/schema/ExternalDocsDict.md deleted file mode 100644 index 788848b13a..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/ExternalDocsDict.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.ExternalDocsDict diff --git a/docs/docs/en/api/faststream/specification/schema/License.md b/docs/docs/en/api/faststream/specification/schema/License.md deleted file mode 100644 index 4e321c7aab..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/License.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.License diff --git a/docs/docs/en/api/faststream/specification/schema/LicenseDict.md b/docs/docs/en/api/faststream/specification/schema/LicenseDict.md deleted file mode 100644 index 16204a3fc8..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/LicenseDict.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.LicenseDict diff --git a/docs/docs/en/api/faststream/specification/schema/Message.md b/docs/docs/en/api/faststream/specification/schema/Message.md deleted file mode 100644 index d1baee52f5..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/Message.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.Message diff --git a/docs/docs/en/api/faststream/specification/schema/Operation.md b/docs/docs/en/api/faststream/specification/schema/Operation.md deleted file mode 100644 index cde09d402f..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/Operation.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.Operation diff --git a/docs/docs/en/api/faststream/specification/schema/PublisherSpec.md b/docs/docs/en/api/faststream/specification/schema/PublisherSpec.md deleted file mode 100644 index 5b3e7f23e5..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/PublisherSpec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.PublisherSpec diff --git a/docs/docs/en/api/faststream/specification/schema/SubscriberSpec.md b/docs/docs/en/api/faststream/specification/schema/SubscriberSpec.md deleted file mode 100644 index 7ec1f6964b..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/SubscriberSpec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.SubscriberSpec diff --git a/docs/docs/en/api/faststream/specification/schema/Tag.md b/docs/docs/en/api/faststream/specification/schema/Tag.md deleted file mode 100644 index 03071c314f..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/Tag.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.Tag diff --git a/docs/docs/en/api/faststream/specification/schema/TagDict.md b/docs/docs/en/api/faststream/specification/schema/TagDict.md deleted file mode 100644 index 02f4de9c05..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/TagDict.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.TagDict diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/ChannelBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/ChannelBinding.md deleted file mode 100644 index cb7f566dc1..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/bindings/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.bindings.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/OperationBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/OperationBinding.md deleted file mode 100644 index 6fcad5ea7e..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/bindings/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.bindings.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/amqp/ChannelBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/amqp/ChannelBinding.md deleted file mode 100644 index 194c68f536..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/bindings/amqp/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.bindings.amqp.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/amqp/Exchange.md b/docs/docs/en/api/faststream/specification/schema/bindings/amqp/Exchange.md deleted file mode 100644 index 355222c2bb..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/bindings/amqp/Exchange.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.bindings.amqp.Exchange diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/amqp/OperationBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/amqp/OperationBinding.md deleted file mode 100644 index 6bb90ca8ae..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/bindings/amqp/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.bindings.amqp.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/amqp/Queue.md b/docs/docs/en/api/faststream/specification/schema/bindings/amqp/Queue.md deleted file mode 100644 index 54c9493d0e..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/bindings/amqp/Queue.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.bindings.amqp.Queue diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/kafka/ChannelBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/kafka/ChannelBinding.md deleted file mode 100644 index 2561bf2e72..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/bindings/kafka/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.bindings.kafka.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/kafka/OperationBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/kafka/OperationBinding.md deleted file mode 100644 index 0746cedd33..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/bindings/kafka/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.bindings.kafka.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/main/ChannelBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/main/ChannelBinding.md deleted file mode 100644 index 73bfc4bb40..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/bindings/main/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.bindings.main.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/main/OperationBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/main/OperationBinding.md deleted file mode 100644 index f4ebb70b9c..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/bindings/main/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.bindings.main.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/nats/ChannelBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/nats/ChannelBinding.md deleted file mode 100644 index 4495e21ac2..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/bindings/nats/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.bindings.nats.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/nats/OperationBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/nats/OperationBinding.md deleted file mode 100644 index fde8061b86..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/bindings/nats/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.bindings.nats.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/redis/ChannelBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/redis/ChannelBinding.md deleted file mode 100644 index 0f991824da..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/bindings/redis/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.bindings.redis.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/redis/OperationBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/redis/OperationBinding.md deleted file mode 100644 index 95e3ca446a..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/bindings/redis/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.bindings.redis.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/sqs/ChannelBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/sqs/ChannelBinding.md deleted file mode 100644 index 521a6f5560..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/bindings/sqs/ChannelBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.bindings.sqs.ChannelBinding diff --git a/docs/docs/en/api/faststream/specification/schema/bindings/sqs/OperationBinding.md b/docs/docs/en/api/faststream/specification/schema/bindings/sqs/OperationBinding.md deleted file mode 100644 index a70995cb7f..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/bindings/sqs/OperationBinding.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.bindings.sqs.OperationBinding diff --git a/docs/docs/en/api/faststream/specification/schema/extra/Contact.md b/docs/docs/en/api/faststream/specification/schema/extra/Contact.md deleted file mode 100644 index f89be2dc65..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/extra/Contact.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.extra.Contact diff --git a/docs/docs/en/api/faststream/specification/schema/extra/ContactDict.md b/docs/docs/en/api/faststream/specification/schema/extra/ContactDict.md deleted file mode 100644 index 8f20fd396d..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/extra/ContactDict.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.extra.ContactDict diff --git a/docs/docs/en/api/faststream/specification/schema/extra/ExternalDocs.md b/docs/docs/en/api/faststream/specification/schema/extra/ExternalDocs.md deleted file mode 100644 index a745e15910..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/extra/ExternalDocs.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.extra.ExternalDocs diff --git a/docs/docs/en/api/faststream/specification/schema/extra/ExternalDocsDict.md b/docs/docs/en/api/faststream/specification/schema/extra/ExternalDocsDict.md deleted file mode 100644 index 1110d88070..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/extra/ExternalDocsDict.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.extra.ExternalDocsDict diff --git a/docs/docs/en/api/faststream/specification/schema/extra/License.md b/docs/docs/en/api/faststream/specification/schema/extra/License.md deleted file mode 100644 index 033374ed25..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/extra/License.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.extra.License diff --git a/docs/docs/en/api/faststream/specification/schema/extra/LicenseDict.md b/docs/docs/en/api/faststream/specification/schema/extra/LicenseDict.md deleted file mode 100644 index e2994e1d88..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/extra/LicenseDict.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.extra.LicenseDict diff --git a/docs/docs/en/api/faststream/specification/schema/extra/Tag.md b/docs/docs/en/api/faststream/specification/schema/extra/Tag.md deleted file mode 100644 index cc373f1528..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/extra/Tag.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.extra.Tag diff --git a/docs/docs/en/api/faststream/specification/schema/extra/TagDict.md b/docs/docs/en/api/faststream/specification/schema/extra/TagDict.md deleted file mode 100644 index c2455e5c4f..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/extra/TagDict.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.extra.TagDict diff --git a/docs/docs/en/api/faststream/specification/schema/extra/contact/Contact.md b/docs/docs/en/api/faststream/specification/schema/extra/contact/Contact.md deleted file mode 100644 index f34ea777d3..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/extra/contact/Contact.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.extra.contact.Contact diff --git a/docs/docs/en/api/faststream/specification/schema/extra/contact/ContactDict.md b/docs/docs/en/api/faststream/specification/schema/extra/contact/ContactDict.md deleted file mode 100644 index 17d0d774eb..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/extra/contact/ContactDict.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.extra.contact.ContactDict diff --git a/docs/docs/en/api/faststream/specification/schema/extra/external_docs/ExternalDocs.md b/docs/docs/en/api/faststream/specification/schema/extra/external_docs/ExternalDocs.md deleted file mode 100644 index bf06e4b97c..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/extra/external_docs/ExternalDocs.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.extra.external_docs.ExternalDocs diff --git a/docs/docs/en/api/faststream/specification/schema/extra/external_docs/ExternalDocsDict.md b/docs/docs/en/api/faststream/specification/schema/extra/external_docs/ExternalDocsDict.md deleted file mode 100644 index cf1c76bc2b..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/extra/external_docs/ExternalDocsDict.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.extra.external_docs.ExternalDocsDict diff --git a/docs/docs/en/api/faststream/specification/schema/extra/license/License.md b/docs/docs/en/api/faststream/specification/schema/extra/license/License.md deleted file mode 100644 index 58cb3821e7..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/extra/license/License.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.extra.license.License diff --git a/docs/docs/en/api/faststream/specification/schema/extra/license/LicenseDict.md b/docs/docs/en/api/faststream/specification/schema/extra/license/LicenseDict.md deleted file mode 100644 index fb8779aa39..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/extra/license/LicenseDict.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.extra.license.LicenseDict diff --git a/docs/docs/en/api/faststream/specification/schema/extra/tag/Tag.md b/docs/docs/en/api/faststream/specification/schema/extra/tag/Tag.md deleted file mode 100644 index b25a4d5cb1..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/extra/tag/Tag.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.extra.tag.Tag diff --git a/docs/docs/en/api/faststream/specification/schema/extra/tag/TagDict.md b/docs/docs/en/api/faststream/specification/schema/extra/tag/TagDict.md deleted file mode 100644 index 92500cc5b2..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/extra/tag/TagDict.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.extra.tag.TagDict diff --git a/docs/docs/en/api/faststream/specification/schema/message/Message.md b/docs/docs/en/api/faststream/specification/schema/message/Message.md deleted file mode 100644 index 1c2fd0ceb8..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/message/Message.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.message.Message diff --git a/docs/docs/en/api/faststream/specification/schema/message/model/Message.md b/docs/docs/en/api/faststream/specification/schema/message/model/Message.md deleted file mode 100644 index f057a4e898..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/message/model/Message.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.message.model.Message diff --git a/docs/docs/en/api/faststream/specification/schema/operation/Operation.md b/docs/docs/en/api/faststream/specification/schema/operation/Operation.md deleted file mode 100644 index 23088a80f0..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/operation/Operation.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.operation.Operation diff --git a/docs/docs/en/api/faststream/specification/schema/operation/model/Operation.md b/docs/docs/en/api/faststream/specification/schema/operation/model/Operation.md deleted file mode 100644 index 17c306a8ab..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/operation/model/Operation.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.operation.model.Operation diff --git a/docs/docs/en/api/faststream/specification/schema/publisher/PublisherSpec.md b/docs/docs/en/api/faststream/specification/schema/publisher/PublisherSpec.md deleted file mode 100644 index 002bc1ecb8..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/publisher/PublisherSpec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.publisher.PublisherSpec diff --git a/docs/docs/en/api/faststream/specification/schema/subscriber/SubscriberSpec.md b/docs/docs/en/api/faststream/specification/schema/subscriber/SubscriberSpec.md deleted file mode 100644 index 5a4e4515e2..0000000000 --- a/docs/docs/en/api/faststream/specification/schema/subscriber/SubscriberSpec.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -# 0.5 - API -# 2 - Release -# 3 - Contributing -# 5 - Template Page -# 10 - Default -search: - boost: 0.5 ---- - -::: faststream.specification.schema.subscriber.SubscriberSpec diff --git a/docs/docs/en/release.md b/docs/docs/en/release.md index cfe5149109..02d814d290 100644 --- a/docs/docs/en/release.md +++ b/docs/docs/en/release.md @@ -55,7 +55,7 @@ Also, thanks to [@Sehat1137](https://github.com/Sehat1137){.external-link target Well, you (community) made a new breathtaken release for us! Thanks to all of this release contributors. -Special thanks to [@Flosckow](https://github.com/Flosckow){.external-link target="_blank"}. He promores a new perfect feature - concurrent Kafka subscriber (with autocommit mode) +Special thanks to [@Flosckow](https://github.com/Flosckow){.external-link target="_blank"} . He promotes a new perfect feature - concurrent Kafka subscriber (with autocommit mode) ```python from faststream.kafka import KafkaBroker diff --git a/faststream/kafka/broker/broker.py b/faststream/kafka/broker/broker.py index 752ca5c52d..0052ab41b5 100644 --- a/faststream/kafka/broker/broker.py +++ b/faststream/kafka/broker/broker.py @@ -10,6 +10,7 @@ Optional, TypeVar, Union, + overload, ) import aiokafka @@ -41,6 +42,7 @@ from aiokafka import ConsumerRecord from aiokafka.abc import AbstractTokenProvider + from aiokafka.structs import RecordMetadata from fast_depends.dependencies import Dependant from fast_depends.library.serializer import SerializerProto from typing_extensions import TypedDict, Unpack @@ -663,76 +665,91 @@ def _subscriber_setup_extra(self) -> "AnyDict": "builder": self._connection, } + @overload + async def publish( + self, + message: "SendableMessage", + topic: str = "", + *, + key: Union[bytes, Any, None] = None, + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + correlation_id: Optional[str] = None, + reply_to: str = "", + no_confirm: Literal[True] = False, + ) -> "asyncio.Future[RecordMetadata]": + ... + + @overload + async def publish( + self, + message: "SendableMessage", + topic: str = "", + *, + key: Union[bytes, Any, None] = None, + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + correlation_id: Optional[str] = None, + reply_to: str = "", + no_confirm: Literal[False] = False, + ) -> "RecordMetadata": + ... + @override - async def publish( # type: ignore[override] - self, - message: Annotated[ - "SendableMessage", - Doc("Message body to send."), - ], - topic: Annotated[ - str, - Doc("Topic where the message will be published."), - ], - *, - key: Annotated[ - Union[bytes, Any, None], - Doc( - """ - A key to associate with the message. Can be used to - determine which partition to send the message to. If partition - is `None` (and producer's partitioner config is left as default), - then messages with the same key will be delivered to the same - partition (but if key is `None`, partition is chosen randomly). - Must be type `bytes`, or be serializable to bytes via configured - `key_serializer`. - """, - ), - ] = None, - partition: Annotated[ - Optional[int], - Doc( - """ - Specify a partition. If not set, the partition will be - selected using the configured `partitioner`. - """, - ), - ] = None, - timestamp_ms: Annotated[ - Optional[int], - Doc( - """ - Epoch milliseconds (from Jan 1 1970 UTC) to use as - the message timestamp. Defaults to current time. - """, - ), - ] = None, - headers: Annotated[ - Optional[dict[str, str]], - Doc("Message headers to store metainformation."), - ] = None, - correlation_id: Annotated[ - Optional[str], - Doc( - "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages.", - ), - ] = None, - reply_to: Annotated[ - str, - Doc("Reply message topic name to send response."), - ] = "", - no_confirm: Annotated[ - bool, - Doc("Do not wait for Kafka publish confirmation."), - ] = False, - ) -> "asyncio.Future": + async def publish( + self, + message: "SendableMessage", + topic: str = "", + *, + key: Union[bytes, Any, None] = None, + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + correlation_id: Optional[str] = None, + reply_to: str = "", + no_confirm: bool = False, + ) -> Union["asyncio.Future[RecordMetadata]", "RecordMetadata"]: """Publish message directly. This method allows you to publish message in not AsyncAPI-documented way. You can use it in another frameworks applications or to publish messages from time to time. Please, use `@broker.publisher(...)` or `broker.publisher(...).publish(...)` instead in a regular way. + + Args: + message: + Message body to send. + topic: + Topic where the message will be published. + key: + A key to associate with the message. Can be used to + determine which partition to send the message to. If partition + is `None` (and producer's partitioner config is left as default), + then messages with the same key will be delivered to the same + partition (but if key is `None`, partition is chosen randomly). + Must be type `bytes`, or be serializable to bytes via configured + `key_serializer` + partition: + Specify a partition. If not set, the partition will be + selected using the configured `partitioner` + timestamp_ms: + Epoch milliseconds (from Jan 1 1970 UTC) to use as + the message timestamp. Defaults to current time. + headers: + Message headers to store metainformation. + correlation_id: + Manual message **correlation_id** setter. + **correlation_id** is a useful option to trace messages. + reply_to: + Reply message topic name to send response. + no_confirm: + Do not wait for Kafka publish confirmation. + + Returns: + `asyncio.Future[RecordMetadata]` if no_confirm = True. + `RecordMetadata` if no_confirm = False. """ cmd = KafkaPublishCommand( message, @@ -823,54 +840,68 @@ async def request( # type: ignore[override] msg: KafkaMessage = await super()._basic_request(cmd, producer=self._producer) return msg + @overload async def publish_batch( - self, - *messages: Annotated[ - "SendableMessage", - Doc("Messages bodies to send."), - ], - topic: Annotated[ - str, - Doc("Topic where the message will be published."), - ] = "", - partition: Annotated[ - Optional[int], - Doc( - """ - Specify a partition. If not set, the partition will be - selected using the configured `partitioner`. - """, - ), - ] = None, - timestamp_ms: Annotated[ - Optional[int], - Doc( - """ - Epoch milliseconds (from Jan 1 1970 UTC) to use as - the message timestamp. Defaults to current time. - """, - ), - ] = None, - headers: Annotated[ - Optional[dict[str, str]], - Doc("Messages headers to store metainformation."), - ] = None, - reply_to: Annotated[ - str, - Doc("Reply message topic name to send response."), - ] = "", - correlation_id: Annotated[ - Optional[str], - Doc( - "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages.", - ), - ] = None, - no_confirm: Annotated[ - bool, - Doc("Do not wait for Kafka publish confirmation."), - ] = False, - ) -> "asyncio.Future": + self, + *messages: "SendableMessage", + topic: str = "", + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + reply_to: str = "", + correlation_id: Optional[str] = None, + no_confirm: Literal[True] = False, + ) -> "asyncio.Future[RecordMetadata]": ... + + @overload + async def publish_batch( + self, + *messages: "SendableMessage", + topic: str = "", + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + reply_to: str = "", + correlation_id: Optional[str] = None, + no_confirm: Literal[False] = False, + ) -> "RecordMetadata": ... + + async def publish_batch( + self, + *messages: "SendableMessage", + topic: str = "", + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + reply_to: str = "", + correlation_id: Optional[str] = None, + no_confirm: bool = False, + ) -> Union["asyncio.Future[RecordMetadata]", "RecordMetadata"]: + """Args: + *messages: + Messages bodies to send. + topic: + Topic where the message will be published. + partition: + Specify a partition. If not set, the partition will be + selected using the configured `partitioner` + timestamp_ms: + Epoch milliseconds (from Jan 1 1970 UTC) to use as + the message timestamp. Defaults to current time. + headers: + Message headers to store metainformation. + reply_to: + Reply message topic name to send response. + correlation_id: + Manual message **correlation_id** setter. + **correlation_id** is a useful option to trace messages. + no_confirm: + Do not wait for Kafka publish confirmation. + + Returns: + `asyncio.Future[RecordMetadata]` if no_confirm = True. + `RecordMetadata` if no_confirm = False. + """ assert self._producer, NOT_CONNECTED_YET # nosec B101 cmd = KafkaPublishCommand( diff --git a/faststream/kafka/publisher/producer.py b/faststream/kafka/publisher/producer.py index a6574e104d..86591617e8 100644 --- a/faststream/kafka/publisher/producer.py +++ b/faststream/kafka/publisher/producer.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Any, Optional +from typing import TYPE_CHECKING, Any, Optional, Union from typing_extensions import override @@ -15,6 +15,7 @@ import asyncio from aiokafka import AIOKafkaProducer + from aiokafka.structs import RecordMetadata from faststream._internal.types import CustomCallable from faststream.kafka.response import KafkaPublishCommand @@ -58,7 +59,7 @@ def closed(self) -> bool: async def publish( # type: ignore[override] self, cmd: "KafkaPublishCommand", - ) -> "asyncio.Future": + ) -> Union["asyncio.Future[RecordMetadata]", "RecordMetadata"]: """Publish a message to a topic.""" message, content_type = encode_message(cmd.body) @@ -77,13 +78,13 @@ async def publish( # type: ignore[override] ) if not cmd.no_confirm: - await send_future + return await send_future return send_future async def publish_batch( self, cmd: "KafkaPublishCommand", - ) -> "asyncio.Future": + ) -> Union["asyncio.Future[RecordMetadata]", "RecordMetadata"]: """Publish a batch of messages to a topic.""" batch = self._producer.producer.create_batch() @@ -113,7 +114,7 @@ async def publish_batch( partition=cmd.partition, ) if not cmd.no_confirm: - await send_future + return await send_future return send_future @override diff --git a/faststream/kafka/publisher/usecase.py b/faststream/kafka/publisher/usecase.py index bedf73a6aa..3ae0f93136 100644 --- a/faststream/kafka/publisher/usecase.py +++ b/faststream/kafka/publisher/usecase.py @@ -1,5 +1,5 @@ from collections.abc import Iterable, Sequence -from typing import TYPE_CHECKING, Annotated, Any, Optional, Union +from typing import TYPE_CHECKING, Annotated, Any, Literal, Optional, Union, overload from aiokafka import ConsumerRecord from typing_extensions import Doc, override @@ -14,6 +14,8 @@ if TYPE_CHECKING: import asyncio + from aiokafka.structs import RecordMetadata + from faststream._internal.basic_types import SendableMessage from faststream._internal.types import BrokerMiddleware, PublisherMiddleware from faststream.kafka.message import KafkaMessage @@ -151,70 +153,83 @@ def __init__( self.key = key + @overload + async def publish( + self, + message: "SendableMessage", + topic: str = "", + *, + key: Union[bytes, Any, None] = None, + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + correlation_id: Optional[str] = None, + reply_to: str = "", + no_confirm: Literal[True] = False, + ) -> "asyncio.Future[RecordMetadata]": ... + + @overload + async def publish( + self, + message: "SendableMessage", + topic: str = "", + *, + key: Union[bytes, Any, None] = None, + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + correlation_id: Optional[str] = None, + reply_to: str = "", + no_confirm: Literal[False] = False, + ) -> "RecordMetadata": ... + @override async def publish( self, - message: Annotated[ - "SendableMessage", - Doc("Message body to send."), - ], - topic: Annotated[ - str, - Doc("Topic where the message will be published."), - ] = "", + message: "SendableMessage", + topic: str = "", *, - key: Annotated[ - Union[bytes, Any, None], - Doc( - """ - A key to associate with the message. Can be used to - determine which partition to send the message to. If partition - is `None` (and producer's partitioner config is left as default), - then messages with the same key will be delivered to the same - partition (but if key is `None`, partition is chosen randomly). - Must be type `bytes`, or be serializable to bytes via configured - `key_serializer`. - """, - ), - ] = None, - partition: Annotated[ - Optional[int], - Doc( - """ - Specify a partition. If not set, the partition will be - selected using the configured `partitioner`. - """, - ), - ] = None, - timestamp_ms: Annotated[ - Optional[int], - Doc( - """ - Epoch milliseconds (from Jan 1 1970 UTC) to use as - the message timestamp. Defaults to current time. - """, - ), - ] = None, - headers: Annotated[ - Optional[dict[str, str]], - Doc("Message headers to store metainformation."), - ] = None, - correlation_id: Annotated[ - Optional[str], - Doc( - "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages.", - ), - ] = None, - reply_to: Annotated[ - str, - Doc("Reply message topic name to send response."), - ] = "", - no_confirm: Annotated[ - bool, - Doc("Do not wait for Kafka publish confirmation."), - ] = False, - ) -> "asyncio.Future": + key: Union[bytes, Any, None] = None, + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + correlation_id: Optional[str] = None, + reply_to: str = "", + no_confirm: bool = False, + ) -> Union["asyncio.Future[RecordMetadata]", "RecordMetadata"]: + """Args: + message: + Message body to send. + topic: + Topic where the message will be published. + key: + A key to associate with the message. Can be used to + determine which partition to send the message to. If partition + is `None` (and producer's partitioner config is left as default), + then messages with the same key will be delivered to the same + partition (but if key is `None`, partition is chosen randomly). + Must be type `bytes`, or be serializable to bytes via configured + `key_serializer` + partition: + Specify a partition. If not set, the partition will be + selected using the configured `partitioner` + timestamp_ms: + Epoch milliseconds (from Jan 1 1970 UTC) to use as + the message timestamp. Defaults to current time. + headers: + Message headers to store metainformation. + correlation_id: + Manual message **correlation_id** setter. + **correlation_id** is a useful option to trace messages. + reply_to: + Reply message topic name to send response. + no_confirm: + Do not wait for Kafka publish confirmation. + + Returns: + `asyncio.Future[RecordMetadata]` if no_confirm = True. + `RecordMetadata` if no_confirm = False. + """ cmd = KafkaPublishCommand( message, topic=topic or self.topic, @@ -321,55 +336,70 @@ async def request( class BatchPublisher(LogicPublisher[tuple["ConsumerRecord", ...]]): + + @overload + async def publish( + self, + *messages: "SendableMessage", + topic: str = "", + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + reply_to: str = "", + correlation_id: Optional[str] = None, + no_confirm: Literal[True] = False, + ) -> "asyncio.Future[RecordMetadata]": ... + + @overload + async def publish( + self, + *messages: "SendableMessage", + topic: str = "", + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + reply_to: str = "", + correlation_id: Optional[str] = None, + no_confirm: Literal[False] = False, + ) -> "RecordMetadata": ... + @override async def publish( self, - *messages: Annotated[ - "SendableMessage", - Doc("Messages bodies to send."), - ], - topic: Annotated[ - str, - Doc("Topic where the message will be published."), - ] = "", - partition: Annotated[ - Optional[int], - Doc( - """ - Specify a partition. If not set, the partition will be - selected using the configured `partitioner`. - """, - ), - ] = None, - timestamp_ms: Annotated[ - Optional[int], - Doc( - """ - Epoch milliseconds (from Jan 1 1970 UTC) to use as - the message timestamp. Defaults to current time. - """, - ), - ] = None, - headers: Annotated[ - Optional[dict[str, str]], - Doc("Messages headers to store metainformation."), - ] = None, - reply_to: Annotated[ - str, - Doc("Reply message topic name to send response."), - ] = "", - correlation_id: Annotated[ - Optional[str], - Doc( - "Manual message **correlation_id** setter. " - "**correlation_id** is a useful option to trace messages.", - ), - ] = None, - no_confirm: Annotated[ - bool, - Doc("Do not wait for Kafka publish confirmation."), - ] = False, - ) -> "asyncio.Future": + *messages: "SendableMessage", + topic: str = "", + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + reply_to: str = "", + correlation_id: Optional[str] = None, + no_confirm: bool = False, + ) -> Union["asyncio.Future[RecordMetadata]", "RecordMetadata"]: + """Args: + *messages: + Messages bodies to send. + topic: + Topic where the message will be published. + partition: + Specify a partition. If not set, the partition will be + selected using the configured `partitioner` + timestamp_ms: + Epoch milliseconds (from Jan 1 1970 UTC) to use as + the message timestamp. Defaults to current time. + headers: + Message headers to store metainformation. + reply_to: + Reply message topic name to send response. + correlation_id: + Manual message **correlation_id** setter. + **correlation_id** is a useful option to trace messages. + no_confirm: + Do not wait for Kafka publish confirmation. + + Returns: + `asyncio.Future[RecordMetadata]` if no_confirm = True. + `RecordMetadata` if no_confirm = False. + """ cmd = KafkaPublishCommand( *messages, key=None, diff --git a/tests/brokers/kafka/test_publish.py b/tests/brokers/kafka/test_publish.py index bb884c450a..e35730547f 100644 --- a/tests/brokers/kafka/test_publish.py +++ b/tests/brokers/kafka/test_publish.py @@ -2,6 +2,7 @@ from unittest.mock import Mock import pytest +from aiokafka.structs import RecordMetadata from faststream import Context from faststream.kafka import KafkaResponse @@ -25,8 +26,7 @@ async def handler(msg) -> None: async with self.patch_broker(pub_broker) as br: await br.start() - await br.publish_batch(1, "hi", topic=queue) - + record_metadata = await br.publish_batch(1, "hi", topic=queue) result, _ = await asyncio.wait( ( asyncio.create_task(msgs_queue.get()), @@ -34,6 +34,7 @@ async def handler(msg) -> None: ), timeout=3, ) + assert isinstance(record_metadata, RecordMetadata) assert {1, "hi"} == {r.result() for r in result} @@ -82,7 +83,7 @@ async def pub(m): async with self.patch_broker(pub_broker) as br: await br.start() - await br.publish("", queue + "1") + record_metadata = await br.publish("", queue + "1") result, _ = await asyncio.wait( ( @@ -91,6 +92,7 @@ async def pub(m): ), timeout=3, ) + assert isinstance(record_metadata, RecordMetadata) assert {1, "hi"} == {r.result() for r in result} @@ -133,3 +135,23 @@ async def handle_next(msg=Context("message")) -> None: body=b"1", key=b"1", ) + + @pytest.mark.asyncio() + async def test_return_future( + self, + queue: str, + mock: Mock, + ) -> None: + pub_broker = self.get_broker() + + @pub_broker.subscriber(queue) + async def handler(m) -> None: + pass + + async with self.patch_broker(pub_broker) as br: + await br.start() + + batch_record_metadata_future = await br.publish_batch(1, "hi", topic=queue, no_confirm=True) + record_metadata_future = await br.publish("", topic=queue, no_confirm=True) + assert isinstance(batch_record_metadata_future, asyncio.Future) + assert isinstance(record_metadata_future, asyncio.Future) From d1a23763e31f31868d718fccf24d00dccb2e1283 Mon Sep 17 00:00:00 2001 From: Ivan Kirpichnikov Date: Sun, 15 Dec 2024 18:54:38 +0300 Subject: [PATCH 230/245] fix type hins in faststream/specification (#1985) --- faststream/specification/asyncapi/factory.py | 4 ++-- faststream/specification/asyncapi/message.py | 2 +- .../specification/asyncapi/v2_6_0/facade.py | 4 ++-- .../v2_6_0/schema/bindings/sqs/channel.py | 11 +++++++---- .../v2_6_0/schema/bindings/sqs/operation.py | 11 +++++++---- .../asyncapi/v2_6_0/schema/contact.py | 3 ++- .../asyncapi/v2_6_0/schema/docs.py | 3 ++- .../asyncapi/v2_6_0/schema/license.py | 3 ++- .../asyncapi/v2_6_0/schema/tag.py | 3 ++- .../specification/asyncapi/v3_0_0/facade.py | 4 ++-- .../specification/asyncapi/v3_0_0/generate.py | 18 +++++++++--------- .../asyncapi/v3_0_0/schema/__init__.py | 4 +++- .../v3_0_0/schema/bindings/amqp/operation.py | 12 ++++++++---- 13 files changed, 49 insertions(+), 33 deletions(-) diff --git a/faststream/specification/asyncapi/factory.py b/faststream/specification/asyncapi/factory.py index dc263a6b52..cb3657e6fd 100644 --- a/faststream/specification/asyncapi/factory.py +++ b/faststream/specification/asyncapi/factory.py @@ -1,4 +1,4 @@ -from collections.abc import Iterable +from collections.abc import Sequence from typing import TYPE_CHECKING, Any, Literal, Optional, Union from faststream.specification.base.specification import Specification @@ -28,7 +28,7 @@ def AsyncAPI( # noqa: N802 terms_of_service: Optional["AnyHttpUrl"] = None, license: Optional[Union["License", "LicenseDict", "AnyDict"]] = None, contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] = None, - tags: Iterable[Union["Tag", "TagDict", "AnyDict"]] = (), + tags: Sequence[Union["Tag", "TagDict", "AnyDict"]] = (), external_docs: Optional[ Union["ExternalDocs", "ExternalDocsDict", "AnyDict"] ] = None, diff --git a/faststream/specification/asyncapi/message.py b/faststream/specification/asyncapi/message.py index 187cc70af0..9c4e30d1e2 100644 --- a/faststream/specification/asyncapi/message.py +++ b/faststream/specification/asyncapi/message.py @@ -18,7 +18,7 @@ def parse_handler_params(call: "CallModel", prefix: str = "") -> AnyDict: """Parses the handler parameters.""" - model = getattr(call, "serializer", call).model + model = getattr(call, "serializer", call).model # type: ignore[union-attr] assert model # nosec B101 body = get_model_schema( diff --git a/faststream/specification/asyncapi/v2_6_0/facade.py b/faststream/specification/asyncapi/v2_6_0/facade.py index d8c4b5618b..f70f071c37 100644 --- a/faststream/specification/asyncapi/v2_6_0/facade.py +++ b/faststream/specification/asyncapi/v2_6_0/facade.py @@ -1,4 +1,4 @@ -from collections.abc import Iterable +from collections.abc import Sequence from typing import TYPE_CHECKING, Any, Optional, Union from faststream.specification.base.specification import Specification @@ -34,7 +34,7 @@ def __init__( contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] = None, license: Optional[Union["License", "LicenseDict", "AnyDict"]] = None, identifier: Optional[str] = None, - tags: Iterable[Union["Tag", "TagDict", "AnyDict"]] = (), + tags: Sequence[Union["Tag", "TagDict", "AnyDict"]] = (), external_docs: Optional[ Union["ExternalDocs", "ExternalDocsDict", "AnyDict"] ] = None, diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel.py index 93a1c5ac80..3145805c65 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/channel.py @@ -22,12 +22,15 @@ class ChannelBinding(BaseModel): bindingVersion: str = "custom" @classmethod - def from_spec(cls, binding: sqs.ChannelBinding) -> Self: + def from_pub(cls, binding: sqs.ChannelBinding) -> Self: return cls( queue=binding.queue, bindingVersion=binding.bindingVersion, ) - -def from_spec(binding: sqs.ChannelBinding) -> ChannelBinding: - return ChannelBinding.from_spec(binding) + @classmethod + def from_sub(cls, binding: sqs.ChannelBinding) -> Self: + return cls( + queue=binding.queue, + bindingVersion=binding.bindingVersion, + ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation.py b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation.py index 35aa598d20..dca688bf95 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/bindings/sqs/operation.py @@ -24,12 +24,15 @@ class OperationBinding(BaseModel): bindingVersion: str = "custom" @classmethod - def from_spec(cls, binding: sqs.OperationBinding) -> Self: + def from_pub(cls, binding: sqs.OperationBinding) -> Self: return cls( replyTo=binding.replyTo, bindingVersion=binding.bindingVersion, ) - -def from_spec(binding: sqs.OperationBinding) -> OperationBinding: - return OperationBinding.from_spec(binding) + @classmethod + def from_sub(cls, binding: sqs.OperationBinding) -> Self: + return cls( + replyTo=binding.replyTo, + bindingVersion=binding.bindingVersion, + ) diff --git a/faststream/specification/asyncapi/v2_6_0/schema/contact.py b/faststream/specification/asyncapi/v2_6_0/schema/contact.py index 9456d7dd61..da07f90910 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/contact.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/contact.py @@ -1,4 +1,4 @@ -from typing import Optional, Union, overload +from typing import Optional, Union, cast, overload from pydantic import AnyHttpUrl, BaseModel from typing_extensions import Self @@ -64,6 +64,7 @@ def from_spec( email=contact.email, ) + contact = cast(AnyDict, contact) contact_data, custom_data = filter_by_dict(ContactDict, contact) if custom_data: diff --git a/faststream/specification/asyncapi/v2_6_0/schema/docs.py b/faststream/specification/asyncapi/v2_6_0/schema/docs.py index 6ad8d6a252..5bf8ebb458 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/docs.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/docs.py @@ -1,4 +1,4 @@ -from typing import Optional, Union, overload +from typing import Optional, Union, cast, overload from pydantic import AnyHttpUrl, BaseModel from typing_extensions import Self @@ -58,6 +58,7 @@ def from_spec( if isinstance(docs, SpecDocs): return cls(url=docs.url, description=docs.description) + docs = cast(AnyDict, docs) docs_data, custom_data = filter_by_dict(ExternalDocsDict, docs) if custom_data: diff --git a/faststream/specification/asyncapi/v2_6_0/schema/license.py b/faststream/specification/asyncapi/v2_6_0/schema/license.py index 1d3b778d8e..a713b75fe4 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/license.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/license.py @@ -1,4 +1,4 @@ -from typing import Optional, Union, overload +from typing import Optional, Union, cast, overload from pydantic import AnyHttpUrl, BaseModel from typing_extensions import Self @@ -64,6 +64,7 @@ def from_spec( url=license.url, ) + license = cast(AnyDict, license) license_data, custom_data = filter_by_dict(LicenseDict, license) if custom_data: diff --git a/faststream/specification/asyncapi/v2_6_0/schema/tag.py b/faststream/specification/asyncapi/v2_6_0/schema/tag.py index a4fdae8d8d..ba2ac8e17f 100644 --- a/faststream/specification/asyncapi/v2_6_0/schema/tag.py +++ b/faststream/specification/asyncapi/v2_6_0/schema/tag.py @@ -1,4 +1,4 @@ -from typing import Optional, Union, overload +from typing import Optional, Union, cast, overload from pydantic import BaseModel from typing_extensions import Self @@ -56,6 +56,7 @@ def from_spec(cls, tag: Union[SpecTag, TagDict, AnyDict]) -> Union[Self, AnyDict externalDocs=ExternalDocs.from_spec(tag.external_docs), ) + tag = cast(AnyDict, tag) tag_data, custom_data = filter_by_dict(TagDict, tag) if custom_data: diff --git a/faststream/specification/asyncapi/v3_0_0/facade.py b/faststream/specification/asyncapi/v3_0_0/facade.py index 4ce47b6f90..36276e5327 100644 --- a/faststream/specification/asyncapi/v3_0_0/facade.py +++ b/faststream/specification/asyncapi/v3_0_0/facade.py @@ -1,4 +1,4 @@ -from collections.abc import Iterable +from collections.abc import Sequence from typing import TYPE_CHECKING, Any, Optional, Union from faststream.specification.base.specification import Specification @@ -34,7 +34,7 @@ def __init__( contact: Optional[Union["Contact", "ContactDict", "AnyDict"]] = None, license: Optional[Union["License", "LicenseDict", "AnyDict"]] = None, identifier: Optional[str] = None, - tags: Iterable[Union["Tag", "TagDict", "AnyDict"]] = (), + tags: Sequence[Union["Tag", "TagDict", "AnyDict"]] = (), external_docs: Optional[ Union["ExternalDocs", "ExternalDocsDict", "AnyDict"] ] = None, diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index 1efc8c4fdc..ddd2026e3b 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -87,7 +87,7 @@ def get_app_schema( termsOfService=terms_of_service, contact=Contact.from_spec(contact), license=License.from_spec(license), - tags=[Tag.from_spec(tag) for tag in tags] or None, + tags=[Tag.from_spec(tag) for tag in tags] or None if tags else None, externalDocs=ExternalDocs.from_spec(external_docs), ), asyncapi=schema_version, @@ -153,10 +153,10 @@ def get_broker_channels( operations = {} for sub in broker._subscribers: - for key, channel in sub.schema().items(): - channel_obj = Channel.from_sub(key, channel) + for sub_key, sub_channel in sub.schema().items(): + channel_obj = Channel.from_sub(sub_key, sub_channel) - channel_key = clear_key(key) + channel_key = clear_key(sub_key) # TODO: add duplication key warning channels[channel_key] = channel_obj @@ -168,14 +168,14 @@ def get_broker_channels( for msg_name in channel_obj.messages ], channel=Reference(**{"$ref": f"#/channels/{channel_key}"}), - operation=channel.operation, + operation=sub_channel.operation, ) for pub in broker._publishers: - for key, channel in pub.schema().items(): - channel_obj = Channel.from_pub(key, channel) + for pub_key, pub_channel in pub.schema().items(): + channel_obj = Channel.from_pub(pub_key, pub_channel) - channel_key = clear_key(key) + channel_key = clear_key(pub_key) # TODO: add duplication key warning channels[channel_key] = channel_obj @@ -187,7 +187,7 @@ def get_broker_channels( for msg_name in channel_obj.messages ], channel=Reference(**{"$ref": f"#/channels/{channel_key}"}), - operation=channel.operation, + operation=pub_channel.operation, ) return channels, operations diff --git a/faststream/specification/asyncapi/v3_0_0/schema/__init__.py b/faststream/specification/asyncapi/v3_0_0/schema/__init__.py index e0cbcbd7b2..7b5c98ae62 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/__init__.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/__init__.py @@ -1,3 +1,5 @@ +from faststream.specification.asyncapi.v2_6_0.schema import ServerVariable + from .channels import Channel from .components import Components from .contact import Contact @@ -7,7 +9,7 @@ from .message import CorrelationId, Message from .operations import Operation from .schema import ApplicationSchema -from .servers import Server, ServerVariable +from .servers import Server from .tag import Tag from .utils import Parameter, Reference diff --git a/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation.py b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation.py index 77ba8356a0..d6f95b68e8 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/bindings/amqp/operation.py @@ -5,16 +5,20 @@ from typing import Optional +from pydantic import BaseModel, PositiveInt from typing_extensions import Self -from faststream.specification.asyncapi.v2_6_0.schema.bindings.amqp import ( - OperationBinding as V2Binding, -) from faststream.specification.schema.bindings import amqp -class OperationBinding(V2Binding): +class OperationBinding(BaseModel): cc: Optional[list[str]] = None + ack: bool + replyTo: Optional[str] = None + deliveryMode: Optional[int] = None + mandatory: Optional[bool] = None + priority: Optional[PositiveInt] = None + bindingVersion: str = "0.3.0" @classmethod From d9586553d48062d903e54ca0628b14e16e3aa249 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Sun, 15 Dec 2024 19:04:19 +0300 Subject: [PATCH 231/245] chore: polish types --- faststream/kafka/broker/broker.py | 130 +++++++++--------- faststream/kafka/publisher/producer.py | 2 +- faststream/kafka/publisher/state.py | 6 +- faststream/kafka/publisher/usecase.py | 89 ++++++------ faststream/specification/asyncapi/message.py | 4 +- .../specification/asyncapi/v2_6_0/facade.py | 2 +- .../specification/asyncapi/v3_0_0/facade.py | 2 +- .../asyncapi/v3_0_0/schema/__init__.py | 4 +- .../asyncapi/v3_0_0/schema/servers.py | 6 + .../specification/base/specification.py | 5 +- tests/brokers/kafka/test_publish.py | 4 +- 11 files changed, 135 insertions(+), 119 deletions(-) diff --git a/faststream/kafka/broker/broker.py b/faststream/kafka/broker/broker.py index 0052ab41b5..0ba6b7d75a 100644 --- a/faststream/kafka/broker/broker.py +++ b/faststream/kafka/broker/broker.py @@ -667,49 +667,47 @@ def _subscriber_setup_extra(self) -> "AnyDict": @overload async def publish( - self, - message: "SendableMessage", - topic: str = "", - *, - key: Union[bytes, Any, None] = None, - partition: Optional[int] = None, - timestamp_ms: Optional[int] = None, - headers: Optional[dict[str, str]] = None, - correlation_id: Optional[str] = None, - reply_to: str = "", - no_confirm: Literal[True] = False, - ) -> "asyncio.Future[RecordMetadata]": - ... + self, + message: "SendableMessage", + topic: str = "", + *, + key: Union[bytes, Any, None] = None, + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + correlation_id: Optional[str] = None, + reply_to: str = "", + no_confirm: Literal[True], + ) -> "asyncio.Future[RecordMetadata]": ... @overload async def publish( - self, - message: "SendableMessage", - topic: str = "", - *, - key: Union[bytes, Any, None] = None, - partition: Optional[int] = None, - timestamp_ms: Optional[int] = None, - headers: Optional[dict[str, str]] = None, - correlation_id: Optional[str] = None, - reply_to: str = "", - no_confirm: Literal[False] = False, - ) -> "RecordMetadata": - ... + self, + message: "SendableMessage", + topic: str = "", + *, + key: Union[bytes, Any, None] = None, + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + correlation_id: Optional[str] = None, + reply_to: str = "", + no_confirm: Literal[False] = False, + ) -> "RecordMetadata": ... @override async def publish( - self, - message: "SendableMessage", - topic: str = "", - *, - key: Union[bytes, Any, None] = None, - partition: Optional[int] = None, - timestamp_ms: Optional[int] = None, - headers: Optional[dict[str, str]] = None, - correlation_id: Optional[str] = None, - reply_to: str = "", - no_confirm: bool = False, + self, + message: "SendableMessage", + topic: str = "", + *, + key: Union[bytes, Any, None] = None, + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + correlation_id: Optional[str] = None, + reply_to: str = "", + no_confirm: bool = False, ) -> Union["asyncio.Future[RecordMetadata]", "RecordMetadata"]: """Publish message directly. @@ -842,42 +840,44 @@ async def request( # type: ignore[override] @overload async def publish_batch( - self, - *messages: "SendableMessage", - topic: str = "", - partition: Optional[int] = None, - timestamp_ms: Optional[int] = None, - headers: Optional[dict[str, str]] = None, - reply_to: str = "", - correlation_id: Optional[str] = None, - no_confirm: Literal[True] = False, + self, + *messages: "SendableMessage", + topic: str = "", + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + reply_to: str = "", + correlation_id: Optional[str] = None, + no_confirm: Literal[True], ) -> "asyncio.Future[RecordMetadata]": ... @overload async def publish_batch( - self, - *messages: "SendableMessage", - topic: str = "", - partition: Optional[int] = None, - timestamp_ms: Optional[int] = None, - headers: Optional[dict[str, str]] = None, - reply_to: str = "", - correlation_id: Optional[str] = None, - no_confirm: Literal[False] = False, + self, + *messages: "SendableMessage", + topic: str = "", + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + reply_to: str = "", + correlation_id: Optional[str] = None, + no_confirm: Literal[False] = False, ) -> "RecordMetadata": ... async def publish_batch( - self, - *messages: "SendableMessage", - topic: str = "", - partition: Optional[int] = None, - timestamp_ms: Optional[int] = None, - headers: Optional[dict[str, str]] = None, - reply_to: str = "", - correlation_id: Optional[str] = None, - no_confirm: bool = False, + self, + *messages: "SendableMessage", + topic: str = "", + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + reply_to: str = "", + correlation_id: Optional[str] = None, + no_confirm: bool = False, ) -> Union["asyncio.Future[RecordMetadata]", "RecordMetadata"]: - """Args: + """Publish a message batch as a single request to broker. + + Args: *messages: Messages bodies to send. topic: diff --git a/faststream/kafka/publisher/producer.py b/faststream/kafka/publisher/producer.py index 86591617e8..bdd8d3677c 100644 --- a/faststream/kafka/publisher/producer.py +++ b/faststream/kafka/publisher/producer.py @@ -48,7 +48,7 @@ async def disconnect(self) -> None: await self._producer.stop() self._producer = EmptyProducerState() - def __bool__(self) -> None: + def __bool__(self) -> bool: return bool(self._producer) @property diff --git a/faststream/kafka/publisher/state.py b/faststream/kafka/publisher/state.py index 3094cf02c1..397967c696 100644 --- a/faststream/kafka/publisher/state.py +++ b/faststream/kafka/publisher/state.py @@ -1,3 +1,4 @@ +from abc import abstractmethod from typing import TYPE_CHECKING, Protocol from faststream.exceptions import IncorrectState @@ -8,7 +9,10 @@ class ProducerState(Protocol): producer: "AIOKafkaProducer" - closed: bool + + @property + @abstractmethod + def closed(self) -> bool: ... def __bool__(self) -> bool: ... diff --git a/faststream/kafka/publisher/usecase.py b/faststream/kafka/publisher/usecase.py index 3ae0f93136..a715342e9d 100644 --- a/faststream/kafka/publisher/usecase.py +++ b/faststream/kafka/publisher/usecase.py @@ -155,32 +155,32 @@ def __init__( @overload async def publish( - self, - message: "SendableMessage", - topic: str = "", - *, - key: Union[bytes, Any, None] = None, - partition: Optional[int] = None, - timestamp_ms: Optional[int] = None, - headers: Optional[dict[str, str]] = None, - correlation_id: Optional[str] = None, - reply_to: str = "", - no_confirm: Literal[True] = False, + self, + message: "SendableMessage", + topic: str = "", + *, + key: Union[bytes, Any, None] = None, + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + correlation_id: Optional[str] = None, + reply_to: str = "", + no_confirm: Literal[True], ) -> "asyncio.Future[RecordMetadata]": ... @overload async def publish( - self, - message: "SendableMessage", - topic: str = "", - *, - key: Union[bytes, Any, None] = None, - partition: Optional[int] = None, - timestamp_ms: Optional[int] = None, - headers: Optional[dict[str, str]] = None, - correlation_id: Optional[str] = None, - reply_to: str = "", - no_confirm: Literal[False] = False, + self, + message: "SendableMessage", + topic: str = "", + *, + key: Union[bytes, Any, None] = None, + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + correlation_id: Optional[str] = None, + reply_to: str = "", + no_confirm: Literal[False] = False, ) -> "RecordMetadata": ... @override @@ -197,7 +197,9 @@ async def publish( reply_to: str = "", no_confirm: bool = False, ) -> Union["asyncio.Future[RecordMetadata]", "RecordMetadata"]: - """Args: + """Publishes a message to Kafka. + + Args: message: Message body to send. topic: @@ -336,31 +338,30 @@ async def request( class BatchPublisher(LogicPublisher[tuple["ConsumerRecord", ...]]): - @overload async def publish( - self, - *messages: "SendableMessage", - topic: str = "", - partition: Optional[int] = None, - timestamp_ms: Optional[int] = None, - headers: Optional[dict[str, str]] = None, - reply_to: str = "", - correlation_id: Optional[str] = None, - no_confirm: Literal[True] = False, + self, + *messages: "SendableMessage", + topic: str = "", + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + reply_to: str = "", + correlation_id: Optional[str] = None, + no_confirm: Literal[True], ) -> "asyncio.Future[RecordMetadata]": ... @overload async def publish( - self, - *messages: "SendableMessage", - topic: str = "", - partition: Optional[int] = None, - timestamp_ms: Optional[int] = None, - headers: Optional[dict[str, str]] = None, - reply_to: str = "", - correlation_id: Optional[str] = None, - no_confirm: Literal[False] = False, + self, + *messages: "SendableMessage", + topic: str = "", + partition: Optional[int] = None, + timestamp_ms: Optional[int] = None, + headers: Optional[dict[str, str]] = None, + reply_to: str = "", + correlation_id: Optional[str] = None, + no_confirm: Literal[False] = False, ) -> "RecordMetadata": ... @override @@ -375,7 +376,9 @@ async def publish( correlation_id: Optional[str] = None, no_confirm: bool = False, ) -> Union["asyncio.Future[RecordMetadata]", "RecordMetadata"]: - """Args: + """Publish a message batch as a single request to broker. + + Args: *messages: Messages bodies to send. topic: diff --git a/faststream/specification/asyncapi/message.py b/faststream/specification/asyncapi/message.py index 9c4e30d1e2..fe692d7085 100644 --- a/faststream/specification/asyncapi/message.py +++ b/faststream/specification/asyncapi/message.py @@ -18,11 +18,11 @@ def parse_handler_params(call: "CallModel", prefix: str = "") -> AnyDict: """Parses the handler parameters.""" - model = getattr(call, "serializer", call).model # type: ignore[union-attr] + model = getattr(call, "serializer", call).model assert model # nosec B101 body = get_model_schema( - create_model( # type: ignore[call-overload] + create_model( model.__name__, **{p.field_name: (p.field_type, p.default_value) for p in call.flat_params}, ), diff --git a/faststream/specification/asyncapi/v2_6_0/facade.py b/faststream/specification/asyncapi/v2_6_0/facade.py index f70f071c37..fcb3f66f38 100644 --- a/faststream/specification/asyncapi/v2_6_0/facade.py +++ b/faststream/specification/asyncapi/v2_6_0/facade.py @@ -61,7 +61,7 @@ def to_yaml(self) -> str: return self.schema.to_yaml() @property - def schema(self) -> ApplicationSchema: # type: ignore[override] + def schema(self) -> ApplicationSchema: return get_app_schema( self.broker, title=self.title, diff --git a/faststream/specification/asyncapi/v3_0_0/facade.py b/faststream/specification/asyncapi/v3_0_0/facade.py index 36276e5327..31542ab11b 100644 --- a/faststream/specification/asyncapi/v3_0_0/facade.py +++ b/faststream/specification/asyncapi/v3_0_0/facade.py @@ -61,7 +61,7 @@ def to_yaml(self) -> str: return self.schema.to_yaml() @property - def schema(self) -> ApplicationSchema: # type: ignore[override] + def schema(self) -> ApplicationSchema: return get_app_schema( self.broker, title=self.title, diff --git a/faststream/specification/asyncapi/v3_0_0/schema/__init__.py b/faststream/specification/asyncapi/v3_0_0/schema/__init__.py index 7b5c98ae62..e0cbcbd7b2 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/__init__.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/__init__.py @@ -1,5 +1,3 @@ -from faststream.specification.asyncapi.v2_6_0.schema import ServerVariable - from .channels import Channel from .components import Components from .contact import Contact @@ -9,7 +7,7 @@ from .message import CorrelationId, Message from .operations import Operation from .schema import ApplicationSchema -from .servers import Server +from .servers import Server, ServerVariable from .tag import Tag from .utils import Parameter, Reference diff --git a/faststream/specification/asyncapi/v3_0_0/schema/servers.py b/faststream/specification/asyncapi/v3_0_0/schema/servers.py index 5951d7935b..902ebc8f9f 100644 --- a/faststream/specification/asyncapi/v3_0_0/schema/servers.py +++ b/faststream/specification/asyncapi/v3_0_0/schema/servers.py @@ -10,6 +10,12 @@ SecurityRequirement = list[dict[str, list[str]]] +__all__ = ( + "Server", + "ServerVariable", +) + + class Server(BaseModel): """A class to represent a server. diff --git a/faststream/specification/base/specification.py b/faststream/specification/base/specification.py index 0c3946e76f..e8e674b25e 100644 --- a/faststream/specification/base/specification.py +++ b/faststream/specification/base/specification.py @@ -1,3 +1,4 @@ +from abc import abstractmethod from typing import Any, Protocol, runtime_checkable from .schema import BaseApplicationSchema @@ -5,7 +6,9 @@ @runtime_checkable class Specification(Protocol): - schema: BaseApplicationSchema + @property + @abstractmethod + def schema(self) -> BaseApplicationSchema: ... def to_json(self) -> str: return self.schema.to_json() diff --git a/tests/brokers/kafka/test_publish.py b/tests/brokers/kafka/test_publish.py index e35730547f..2ad86210ee 100644 --- a/tests/brokers/kafka/test_publish.py +++ b/tests/brokers/kafka/test_publish.py @@ -151,7 +151,9 @@ async def handler(m) -> None: async with self.patch_broker(pub_broker) as br: await br.start() - batch_record_metadata_future = await br.publish_batch(1, "hi", topic=queue, no_confirm=True) + batch_record_metadata_future = await br.publish_batch( + 1, "hi", topic=queue, no_confirm=True + ) record_metadata_future = await br.publish("", topic=queue, no_confirm=True) assert isinstance(batch_record_metadata_future, asyncio.Future) assert isinstance(record_metadata_future, asyncio.Future) From 2bb82c249d7637493347271581d576f60e6687d3 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Sun, 15 Dec 2024 21:01:49 +0300 Subject: [PATCH 232/245] lint: fix top-level mypy --- faststream/asgi/app.py | 2 +- faststream/message/message.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/faststream/asgi/app.py b/faststream/asgi/app.py index 4cbaae0e64..33ffec16d7 100644 --- a/faststream/asgi/app.py +++ b/faststream/asgi/app.py @@ -172,7 +172,7 @@ async def run( config = uvicorn.Config( app=self, log_level=log_level, - **{ + **{ # type: ignore[arg-type] key: v for key, v in run_extra_options.items() if key in uvicorn_config_params diff --git a/faststream/message/message.py b/faststream/message/message.py index a7db6f895d..2037e7dc98 100644 --- a/faststream/message/message.py +++ b/faststream/message/message.py @@ -12,7 +12,7 @@ from .source_type import SourceType if TYPE_CHECKING: - from faststream._internal.basic_types import AnyDict, DecodedMessage + from faststream._internal.basic_types import AnyDict from faststream._internal.types import AsyncCallable # prevent circular imports @@ -74,7 +74,7 @@ def __repr__(self) -> str: filter( bool, ( - f"body={self.body}", + f"body={self.body!r}", f"content_type={self.content_type}", f"message_id={self.message_id}", f"correlation_id={self.correlation_id}", @@ -89,7 +89,7 @@ def __repr__(self) -> str: return f"{self.__class__.__name__}({inner})" - async def decode(self) -> Optional["DecodedMessage"]: + async def decode(self) -> Optional["Any"]: """Serialize the message by lazy decoder. Returns a cache after first usage. To prevent such behavior, please call From c7f4bc38e66a560a3b2052d76e497139ed6df6d6 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Sun, 15 Dec 2024 22:00:51 +0300 Subject: [PATCH 233/245] lint: fix rabbit otel & prometheus mypy --- faststream/_internal/types.py | 14 +++++++++++-- faststream/middlewares/base.py | 22 +++++++-------------- faststream/opentelemetry/middleware.py | 18 ++++++++--------- faststream/opentelemetry/provider.py | 18 +++++++++++++---- faststream/prometheus/middleware.py | 21 +++++++++++--------- faststream/prometheus/provider.py | 16 ++++++++++++--- faststream/rabbit/opentelemetry/provider.py | 6 ++++-- faststream/rabbit/prometheus/provider.py | 8 +++++--- 8 files changed, 76 insertions(+), 47 deletions(-) diff --git a/faststream/_internal/types.py b/faststream/_internal/types.py index b90aad9cd1..5aa5c1d63a 100644 --- a/faststream/_internal/types.py +++ b/faststream/_internal/types.py @@ -8,7 +8,11 @@ Union, ) -from typing_extensions import ParamSpec, TypeAlias +from typing_extensions import ( + ParamSpec, + TypeAlias, + TypeVar as TypeVar313, +) from faststream._internal.basic_types import AsyncFuncAny from faststream._internal.context.repository import ContextRepo @@ -21,7 +25,6 @@ StreamMsg = TypeVar("StreamMsg", bound=StreamMessage[Any]) ConnectionType = TypeVar("ConnectionType") - SyncFilter: TypeAlias = Callable[[StreamMsg], bool] AsyncFilter: TypeAlias = Callable[[StreamMsg], Awaitable[bool]] Filter: TypeAlias = Union[ @@ -82,6 +85,13 @@ def __call__( ] +PublishCommandType = TypeVar313( + "PublishCommandType", + bound=PublishCommand, + default=PublishCommand, +) + + class PublisherMiddleware(Protocol): """Publisher middleware interface.""" diff --git a/faststream/middlewares/base.py b/faststream/middlewares/base.py index 9604d7b5da..ca78b03ad1 100644 --- a/faststream/middlewares/base.py +++ b/faststream/middlewares/base.py @@ -1,10 +1,9 @@ from collections.abc import Awaitable from typing import TYPE_CHECKING, Any, Callable, Generic, Optional -# We should use typing_extensions.TypeVar until python3.13 due default -from typing_extensions import Self, TypeVar +from typing_extensions import Self -from faststream.response.response import PublishCommand +from faststream._internal.types import PublishCommandType if TYPE_CHECKING: from types import TracebackType @@ -14,14 +13,7 @@ from faststream.message import StreamMessage -PublishCommand_T = TypeVar( - "PublishCommand_T", - bound=PublishCommand, - default=PublishCommand, -) - - -class BaseMiddleware(Generic[PublishCommand_T]): +class BaseMiddleware(Generic[PublishCommandType]): """A base middleware class.""" def __init__( @@ -92,8 +84,8 @@ async def consume_scope( async def on_publish( self, - msg: PublishCommand_T, - ) -> PublishCommand_T: + msg: PublishCommandType, + ) -> PublishCommandType: """This option was deprecated and will be removed in 0.6.10. Please, use `publish_scope` instead.""" return msg @@ -107,8 +99,8 @@ async def after_publish( async def publish_scope( self, - call_next: Callable[[PublishCommand_T], Awaitable[Any]], - cmd: PublishCommand_T, + call_next: Callable[[PublishCommandType], Awaitable[Any]], + cmd: PublishCommandType, ) -> Any: """Publish a message and return an async iterator.""" err: Optional[Exception] = None diff --git a/faststream/opentelemetry/middleware.py b/faststream/opentelemetry/middleware.py index 247bd4ff75..42e323c85a 100644 --- a/faststream/opentelemetry/middleware.py +++ b/faststream/opentelemetry/middleware.py @@ -10,7 +10,8 @@ from opentelemetry.trace import Link, Span from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator -from faststream.middlewares.base import BaseMiddleware, PublishCommand_T +from faststream._internal.types import PublishCommandType +from faststream.middlewares.base import BaseMiddleware from faststream.opentelemetry.baggage import Baggage from faststream.opentelemetry.consts import ( ERROR_TYPE, @@ -32,14 +33,13 @@ from faststream._internal.context.repository import ContextRepo from faststream.message import StreamMessage from faststream.opentelemetry.provider import TelemetrySettingsProvider - from faststream.response.response import PublishCommand _BAGGAGE_PROPAGATOR = W3CBaggagePropagator() _TRACE_PROPAGATOR = TraceContextTextMapPropagator() -class TelemetryMiddleware(Generic[PublishCommand_T]): +class TelemetryMiddleware(Generic[PublishCommandType]): __slots__ = ( "_meter", "_metrics", @@ -52,7 +52,7 @@ def __init__( *, settings_provider_factory: Callable[ [Any], - Optional["TelemetrySettingsProvider[Any]"], + Optional["TelemetrySettingsProvider[Any, PublishCommandType]"], ], tracer_provider: Optional["TracerProvider"] = None, meter_provider: Optional["MeterProvider"] = None, @@ -70,8 +70,8 @@ def __call__( /, *, context: "ContextRepo", - ) -> "BaseTelemetryMiddleware[PublishCommand_T]": - return BaseTelemetryMiddleware[PublishCommand_T]( + ) -> "BaseTelemetryMiddleware[PublishCommandType]": + return BaseTelemetryMiddleware[PublishCommandType]( msg, tracer=self._tracer, metrics_container=self._metrics, @@ -152,7 +152,7 @@ def observe_consume( ) -class BaseTelemetryMiddleware(BaseMiddleware[PublishCommand_T]): +class BaseTelemetryMiddleware(BaseMiddleware[PublishCommandType]): def __init__( self, msg: Optional[Any], @@ -161,7 +161,7 @@ def __init__( tracer: "Tracer", settings_provider_factory: Callable[ [Any], - Optional["TelemetrySettingsProvider[Any]"], + Optional["TelemetrySettingsProvider[Any, PublishCommandType]"], ], metrics_container: _MetricsContainer, context: "ContextRepo", @@ -178,7 +178,7 @@ def __init__( async def publish_scope( self, call_next: "AsyncFunc", - msg: "PublishCommand", + msg: "PublishCommandType", ) -> Any: if (provider := self.__settings_provider) is None: return await call_next(msg) diff --git a/faststream/opentelemetry/provider.py b/faststream/opentelemetry/provider.py index 6e2aaa90b6..0cedf1bd8c 100644 --- a/faststream/opentelemetry/provider.py +++ b/faststream/opentelemetry/provider.py @@ -1,14 +1,24 @@ from typing import TYPE_CHECKING, Protocol +from typing_extensions import TypeVar as TypeVar313 + from faststream._internal.types import MsgType +from faststream.response import PublishCommand if TYPE_CHECKING: from faststream._internal.basic_types import AnyDict from faststream.message import StreamMessage - from faststream.response.response import PublishCommand -class TelemetrySettingsProvider(Protocol[MsgType]): +PublishCommandType_contra = TypeVar313( + "PublishCommandType_contra", + bound=PublishCommand, + default=PublishCommand, + contravariant=True, +) + + +class TelemetrySettingsProvider(Protocol[MsgType, PublishCommandType_contra]): messaging_system: str def get_consume_attrs_from_message( @@ -23,10 +33,10 @@ def get_consume_destination_name( def get_publish_attrs_from_cmd( self, - cmd: "PublishCommand", + cmd: PublishCommandType_contra, ) -> "AnyDict": ... def get_publish_destination_name( self, - cmd: "PublishCommand", + cmd: PublishCommandType_contra, ) -> str: ... diff --git a/faststream/prometheus/middleware.py b/faststream/prometheus/middleware.py index 91b4df6382..33d4950e62 100644 --- a/faststream/prometheus/middleware.py +++ b/faststream/prometheus/middleware.py @@ -3,9 +3,10 @@ from typing import TYPE_CHECKING, Any, Callable, Generic, Optional from faststream._internal.constants import EMPTY +from faststream._internal.types import PublishCommandType from faststream.exceptions import IgnoredException from faststream.message import SourceType -from faststream.middlewares.base import BaseMiddleware, PublishCommand_T +from faststream.middlewares.base import BaseMiddleware from faststream.prometheus.consts import ( PROCESSING_STATUS_BY_ACK_STATUS, PROCESSING_STATUS_BY_HANDLER_EXCEPTION_MAP, @@ -24,14 +25,15 @@ from faststream.message.message import StreamMessage -class PrometheusMiddleware(Generic[PublishCommand_T]): +class PrometheusMiddleware(Generic[PublishCommandType]): __slots__ = ("_metrics_container", "_metrics_manager", "_settings_provider_factory") def __init__( self, *, settings_provider_factory: Callable[ - [Any], Optional[MetricsSettingsProvider[Any]] + [Any], + Optional[MetricsSettingsProvider[Any, PublishCommandType]], ], registry: "CollectorRegistry", app_name: str = EMPTY, @@ -58,8 +60,8 @@ def __call__( /, *, context: "ContextRepo", - ) -> "BasePrometheusMiddleware[PublishCommand_T]": - return BasePrometheusMiddleware[PublishCommand_T]( + ) -> "BasePrometheusMiddleware[PublishCommandType]": + return BasePrometheusMiddleware[PublishCommandType]( msg, metrics_manager=self._metrics_manager, settings_provider_factory=self._settings_provider_factory, @@ -67,14 +69,15 @@ def __call__( ) -class BasePrometheusMiddleware(BaseMiddleware[PublishCommand_T]): +class BasePrometheusMiddleware(BaseMiddleware[PublishCommandType]): def __init__( self, msg: Optional[Any], /, *, settings_provider_factory: Callable[ - [Any], Optional[MetricsSettingsProvider[Any]] + [Any], + Optional[MetricsSettingsProvider[Any, PublishCommandType]], ], metrics_manager: MetricsManager, context: "ContextRepo", @@ -164,8 +167,8 @@ async def consume_scope( async def publish_scope( self, - call_next: Callable[[PublishCommand_T], Awaitable[Any]], - cmd: PublishCommand_T, + call_next: Callable[[PublishCommandType], Awaitable[Any]], + cmd: PublishCommandType, ) -> Any: if self._settings_provider is None or cmd.publish_type is PublishType.REPLY: return await call_next(cmd) diff --git a/faststream/prometheus/provider.py b/faststream/prometheus/provider.py index acbf68702f..d8de081a1f 100644 --- a/faststream/prometheus/provider.py +++ b/faststream/prometheus/provider.py @@ -1,13 +1,23 @@ from typing import TYPE_CHECKING, Protocol +from typing_extensions import TypeVar as TypeVar313 + from faststream.message.message import MsgType, StreamMessage +from faststream.response.response import PublishCommand if TYPE_CHECKING: from faststream.prometheus import ConsumeAttrs - from faststream.response.response import PublishCommand -class MetricsSettingsProvider(Protocol[MsgType]): +PublishCommandType_contra = TypeVar313( + "PublishCommandType_contra", + bound=PublishCommand, + default=PublishCommand, + contravariant=True, +) + + +class MetricsSettingsProvider(Protocol[MsgType, PublishCommandType_contra]): messaging_system: str def get_consume_attrs_from_message( @@ -17,5 +27,5 @@ def get_consume_attrs_from_message( def get_publish_destination_name_from_cmd( self, - cmd: "PublishCommand", + cmd: PublishCommandType_contra, ) -> str: ... diff --git a/faststream/rabbit/opentelemetry/provider.py b/faststream/rabbit/opentelemetry/provider.py index e9bd12c7fd..374285d932 100644 --- a/faststream/rabbit/opentelemetry/provider.py +++ b/faststream/rabbit/opentelemetry/provider.py @@ -4,16 +4,18 @@ from faststream.opentelemetry import TelemetrySettingsProvider from faststream.opentelemetry.consts import MESSAGING_DESTINATION_PUBLISH_NAME +from faststream.rabbit.response import RabbitPublishCommand if TYPE_CHECKING: from aio_pika import IncomingMessage from faststream._internal.basic_types import AnyDict from faststream.message import StreamMessage - from faststream.rabbit.response import RabbitPublishCommand -class RabbitTelemetrySettingsProvider(TelemetrySettingsProvider["IncomingMessage"]): +class RabbitTelemetrySettingsProvider( + TelemetrySettingsProvider["IncomingMessage", RabbitPublishCommand], +): __slots__ = ("messaging_system",) def __init__(self) -> None: diff --git a/faststream/rabbit/prometheus/provider.py b/faststream/rabbit/prometheus/provider.py index f4fa0d977f..14427f977d 100644 --- a/faststream/rabbit/prometheus/provider.py +++ b/faststream/rabbit/prometheus/provider.py @@ -4,15 +4,17 @@ ConsumeAttrs, MetricsSettingsProvider, ) +from faststream.rabbit.response import RabbitPublishCommand if TYPE_CHECKING: from aio_pika import IncomingMessage from faststream.message.message import StreamMessage - from faststream.rabbit.response import RabbitPublishCommand -class RabbitMetricsSettingsProvider(MetricsSettingsProvider["IncomingMessage"]): +class RabbitMetricsSettingsProvider( + MetricsSettingsProvider["IncomingMessage", RabbitPublishCommand], +): __slots__ = ("messaging_system",) def __init__(self) -> None: @@ -33,6 +35,6 @@ def get_consume_attrs_from_message( def get_publish_destination_name_from_cmd( self, - cmd: "RabbitPublishCommand", + cmd: RabbitPublishCommand, ) -> str: return f"{cmd.exchange.name or 'default'}.{cmd.destination}" From 195035e6d8eb88323bc4d2ca20448afbdd47c6fb Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Sun, 15 Dec 2024 23:08:23 +0300 Subject: [PATCH 234/245] lint: fix rabbit response types --- faststream/_internal/types.py | 8 -------- faststream/middlewares/base.py | 14 ++++++++++++-- faststream/opentelemetry/middleware.py | 3 +-- faststream/prometheus/middleware.py | 3 +-- faststream/rabbit/response.py | 15 +++++++++++---- faststream/rabbit/schemas/proto.py | 2 +- 6 files changed, 26 insertions(+), 19 deletions(-) diff --git a/faststream/_internal/types.py b/faststream/_internal/types.py index 5aa5c1d63a..489d1b94b3 100644 --- a/faststream/_internal/types.py +++ b/faststream/_internal/types.py @@ -11,7 +11,6 @@ from typing_extensions import ( ParamSpec, TypeAlias, - TypeVar as TypeVar313, ) from faststream._internal.basic_types import AsyncFuncAny @@ -85,13 +84,6 @@ def __call__( ] -PublishCommandType = TypeVar313( - "PublishCommandType", - bound=PublishCommand, - default=PublishCommand, -) - - class PublisherMiddleware(Protocol): """Publisher middleware interface.""" diff --git a/faststream/middlewares/base.py b/faststream/middlewares/base.py index ca78b03ad1..131da032b4 100644 --- a/faststream/middlewares/base.py +++ b/faststream/middlewares/base.py @@ -1,9 +1,12 @@ from collections.abc import Awaitable from typing import TYPE_CHECKING, Any, Callable, Generic, Optional -from typing_extensions import Self +from typing_extensions import ( + Self, + TypeVar as TypeVar313, +) -from faststream._internal.types import PublishCommandType +from faststream.response import PublishCommand if TYPE_CHECKING: from types import TracebackType @@ -13,6 +16,13 @@ from faststream.message import StreamMessage +PublishCommandType = TypeVar313( + "PublishCommandType", + bound=PublishCommand, + default=PublishCommand, +) + + class BaseMiddleware(Generic[PublishCommandType]): """A base middleware class.""" diff --git a/faststream/opentelemetry/middleware.py b/faststream/opentelemetry/middleware.py index 42e323c85a..e1f07b4527 100644 --- a/faststream/opentelemetry/middleware.py +++ b/faststream/opentelemetry/middleware.py @@ -10,8 +10,7 @@ from opentelemetry.trace import Link, Span from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator -from faststream._internal.types import PublishCommandType -from faststream.middlewares.base import BaseMiddleware +from faststream.middlewares.base import BaseMiddleware, PublishCommandType from faststream.opentelemetry.baggage import Baggage from faststream.opentelemetry.consts import ( ERROR_TYPE, diff --git a/faststream/prometheus/middleware.py b/faststream/prometheus/middleware.py index 33d4950e62..db146eb4a1 100644 --- a/faststream/prometheus/middleware.py +++ b/faststream/prometheus/middleware.py @@ -3,10 +3,9 @@ from typing import TYPE_CHECKING, Any, Callable, Generic, Optional from faststream._internal.constants import EMPTY -from faststream._internal.types import PublishCommandType from faststream.exceptions import IgnoredException from faststream.message import SourceType -from faststream.middlewares.base import BaseMiddleware +from faststream.middlewares.base import BaseMiddleware, PublishCommandType from faststream.prometheus.consts import ( PROCESSING_STATUS_BY_ACK_STATUS, PROCESSING_STATUS_BY_HANDLER_EXCEPTION_MAP, diff --git a/faststream/rabbit/response.py b/faststream/rabbit/response.py index 9bac3f6417..f45cbb07ce 100644 --- a/faststream/rabbit/response.py +++ b/faststream/rabbit/response.py @@ -7,11 +7,18 @@ from faststream.response.publish_type import PublishType if TYPE_CHECKING: + from typing import TypedDict + from aio_pika.abc import TimeoutType from faststream.rabbit.publisher.options import MessageOptions from faststream.rabbit.types import AioPikaSendableMessage + class _PublishOptions(TypedDict): + timeout: TimeoutType + mandatory: bool + immediate: bool + class RabbitResponse(Response): def __init__( @@ -33,7 +40,7 @@ def __init__( ) self.message_options = message_options - self.publish_options = { + self.publish_options: _PublishOptions = { "mandatory": mandatory, "immediate": immediate, "timeout": timeout, @@ -41,7 +48,7 @@ def __init__( @override def as_publish_command(self) -> "RabbitPublishCommand": - return RabbitPublishCommand( + return RabbitPublishCommand( # type: ignore[misc] message=self.body, headers=self.headers, correlation_id=self.correlation_id, @@ -65,11 +72,11 @@ def __init__( mandatory: bool = True, immediate: bool = False, timeout: "TimeoutType" = None, - correlation_id: Optional[str] = None, **message_options: Unpack["MessageOptions"], ) -> None: headers = message_options.pop("headers", {}) - reply_to = message_options.pop("reply_to", "") + reply_to = message_options.pop("reply_to") or "" + correlation_id = message_options.pop("correlation_id", None) super().__init__( body=message, diff --git a/faststream/rabbit/schemas/proto.py b/faststream/rabbit/schemas/proto.py index 2109772124..2929ce7c4f 100644 --- a/faststream/rabbit/schemas/proto.py +++ b/faststream/rabbit/schemas/proto.py @@ -37,4 +37,4 @@ def _setup( self.virtual_host = virtual_host # Setup next parent class - super()._setup(**kwargs) + super()._setup(**kwargs) # type: ignore[misc] From a728ba7024b0377f2b7a94748e806376515df9c9 Mon Sep 17 00:00:00 2001 From: Spataphore <93342746+spataphore1337@users.noreply.github.com> Date: Mon, 16 Dec 2024 12:25:54 +0300 Subject: [PATCH 235/245] feat: add raise BatchBufferOverflowException (#1989) * feat: add raise BatchBufferOverflowException * Update producer.py --------- Co-authored-by: Pastukhov Nikita --- faststream/kafka/exceptions.py | 13 +++++++++++++ faststream/kafka/publisher/producer.py | 8 +++++--- 2 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 faststream/kafka/exceptions.py diff --git a/faststream/kafka/exceptions.py b/faststream/kafka/exceptions.py new file mode 100644 index 0000000000..8d398706b9 --- /dev/null +++ b/faststream/kafka/exceptions.py @@ -0,0 +1,13 @@ +from faststream.exceptions import FastStreamException + + +class BatchBufferOverflowException(FastStreamException): + """Exception raised when a buffer overflow occurs when adding a new message to the batches.""" + + def __init__(self, + message_position: int) -> None: + self.message_position = message_position + + def __str__(self) -> str: + return f"The batch buffer is full. The position of the message" \ + f" in the transferred collection at which the overflow occurred: {self.message_position}" diff --git a/faststream/kafka/publisher/producer.py b/faststream/kafka/publisher/producer.py index bdd8d3677c..e0764bf96a 100644 --- a/faststream/kafka/publisher/producer.py +++ b/faststream/kafka/publisher/producer.py @@ -5,12 +5,12 @@ from faststream._internal.publisher.proto import ProducerProto from faststream._internal.subscriber.utils import resolve_custom_func from faststream.exceptions import FeatureNotSupportedException +from faststream.kafka.exceptions import BatchBufferOverflowException from faststream.kafka.message import KafkaMessage from faststream.kafka.parser import AioKafkaParser from faststream.message import encode_message from .state import EmptyProducerState, ProducerState, RealProducer - if TYPE_CHECKING: import asyncio @@ -90,7 +90,7 @@ async def publish_batch( headers_to_send = cmd.headers_to_publish() - for body in cmd.batch_bodies: + for message_position, body in enumerate(cmd.batch_bodies): message, content_type = encode_message(body) if content_type: @@ -101,12 +101,14 @@ async def publish_batch( else: final_headers = headers_to_send.copy() - batch.append( + metadata = batch.append( key=None, value=message, timestamp=cmd.timestamp_ms, headers=[(i, j.encode()) for i, j in final_headers.items()], ) + if metadata is None: + raise BatchBufferOverflowException(message_position=message_position) send_future = await self._producer.producer.send_batch( batch, From 5f9c7b6b22bc29c1d728cacad6e5472d10a63a12 Mon Sep 17 00:00:00 2001 From: Apostol Fet <90645107+ApostolFet@users.noreply.github.com> Date: Fri, 20 Dec 2024 00:31:19 +0300 Subject: [PATCH 236/245] fix: KeyError 'reply_to' in rabbit (#1999) --- faststream/rabbit/publisher/usecase.py | 2 +- faststream/rabbit/response.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/faststream/rabbit/publisher/usecase.py b/faststream/rabbit/publisher/usecase.py index abb48bb1b1..d4b736cfa4 100644 --- a/faststream/rabbit/publisher/usecase.py +++ b/faststream/rabbit/publisher/usecase.py @@ -72,7 +72,7 @@ def __init__( request_options = dict(message_kwargs) self.headers = request_options.pop("headers") or {} - self.reply_to = request_options.pop("reply_to", "") + self.reply_to = request_options.pop("reply_to", None) or "" self.timeout = request_options.pop("timeout", None) message_options, _ = filter_by_dict(MessageOptions, request_options) diff --git a/faststream/rabbit/response.py b/faststream/rabbit/response.py index f45cbb07ce..ffb1ad3b31 100644 --- a/faststream/rabbit/response.py +++ b/faststream/rabbit/response.py @@ -75,7 +75,7 @@ def __init__( **message_options: Unpack["MessageOptions"], ) -> None: headers = message_options.pop("headers", {}) - reply_to = message_options.pop("reply_to") or "" + reply_to = message_options.pop("reply_to", None) or "" correlation_id = message_options.pop("correlation_id", None) super().__init__( From 0b49d76126fd69c768c793e869a887dd3e28ad38 Mon Sep 17 00:00:00 2001 From: Roma Frolov <98967567+roma-frolov@users.noreply.github.com> Date: Fri, 20 Dec 2024 19:35:02 +0300 Subject: [PATCH 237/245] feat: delayed broker setting (#1931) * feat: delayed broker setting * feat: tests for delayed broker setting * feat: addition test * feat: broker -> **brokers * feat: ruff --- faststream/_internal/application.py | 32 ++++++++++++++++---- faststream/_internal/cli/utils/logs.py | 3 +- faststream/asgi/app.py | 2 +- tests/application/__init__.py | 0 tests/application/test_delayed_broker.py | 38 ++++++++++++++++++++++++ 5 files changed, 67 insertions(+), 8 deletions(-) create mode 100644 tests/application/__init__.py create mode 100644 tests/application/test_delayed_broker.py diff --git a/faststream/_internal/application.py b/faststream/_internal/application.py index 4f670ffd85..185dcf0878 100644 --- a/faststream/_internal/application.py +++ b/faststream/_internal/application.py @@ -29,6 +29,7 @@ fake_context, to_async, ) +from faststream.exceptions import SetupError if TYPE_CHECKING: from fast_depends.library.serializer import SerializerProto @@ -78,7 +79,7 @@ async def catch_startup_validation_error() -> AsyncIterator[None]: class StartAbleApplication: def __init__( self, - broker: "BrokerUsecase[Any, Any]", + broker: Optional["BrokerUsecase[Any, Any]"] = None, /, provider: Optional["Provider"] = None, serializer: Optional["SerializerProto"] = EMPTY, @@ -91,7 +92,7 @@ def __init__( def _init_setupable_( # noqa: PLW3201 self, - broker: "BrokerUsecase[Any, Any]", + broker: Optional["BrokerUsecase[Any, Any]"] = None, /, provider: Optional["Provider"] = None, serializer: Optional["SerializerProto"] = EMPTY, @@ -115,21 +116,39 @@ def _init_setupable_( # noqa: PLW3201 ) ) - self.broker = broker + self.brokers = [broker] if broker else [] self._setup() def _setup(self) -> None: - self.broker._setup(OuterBrokerState(di_state=self._state.di_state)) + for broker in self.brokers: + broker._setup(OuterBrokerState(di_state=self._state.di_state)) async def _start_broker(self) -> None: + assert self.broker, "You should setup a broker" await self.broker.start() + @property + def broker(self) -> Optional["BrokerUsecase[Any, Any]"]: + return self.brokers[0] if self.brokers else None + + def set_broker(self, broker: "BrokerUsecase[Any, Any]") -> None: + """Set already existed App object broker. + + Useful then you create/init broker in `on_startup` hook. + """ + if self.brokers: + msg = f"`{self}` already has a broker. You can't use multiple brokers until 1.0.0 release." + raise SetupError(msg) + + self.brokers.append(broker) + self._setup() + class Application(StartAbleApplication): def __init__( self, - broker: "BrokerUsecase[Any, Any]", + broker: Optional["BrokerUsecase[Any, Any]"] = None, /, logger: Optional["LoggerProto"] = logger, provider: Optional["Provider"] = None, @@ -253,7 +272,8 @@ async def _shutdown(self, log_level: int = logging.INFO) -> None: async def stop(self) -> None: """Executes shutdown hooks and stop broker.""" async with self._shutdown_hooks_context(): - await self.broker.close() + for broker in self.brokers: + await broker.close() @asynccontextmanager async def _shutdown_hooks_context(self) -> AsyncIterator[None]: diff --git a/faststream/_internal/cli/utils/logs.py b/faststream/_internal/cli/utils/logs.py index 1c1f98936c..7233378201 100644 --- a/faststream/_internal/cli/utils/logs.py +++ b/faststream/_internal/cli/utils/logs.py @@ -68,4 +68,5 @@ def set_log_level(level: int, app: "Application") -> None: if app.logger and getattr(app.logger, "setLevel", None): app.logger.setLevel(level) # type: ignore[attr-defined] - app.broker._state.get().logger_state.set_level(level) + for broker in app.brokers: + broker._state.get().logger_state.set_level(level) diff --git a/faststream/asgi/app.py b/faststream/asgi/app.py index 33ffec16d7..559e149b0f 100644 --- a/faststream/asgi/app.py +++ b/faststream/asgi/app.py @@ -82,7 +82,7 @@ class AsgiFastStream(Application): def __init__( self, - broker: "BrokerUsecase[Any, Any]", + broker: Optional["BrokerUsecase[Any, Any]"] = None, /, asgi_routes: Sequence[tuple[str, "ASGIApp"]] = (), # regular broker args diff --git a/tests/application/__init__.py b/tests/application/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/application/test_delayed_broker.py b/tests/application/test_delayed_broker.py new file mode 100644 index 0000000000..c2eb32cf57 --- /dev/null +++ b/tests/application/test_delayed_broker.py @@ -0,0 +1,38 @@ +import pytest + +from faststream._internal.application import StartAbleApplication +from faststream.exceptions import SetupError +from faststream.rabbit import RabbitBroker + + +def test_set_broker() -> None: + app = StartAbleApplication() + + assert app.broker is None + + broker = RabbitBroker() + app.set_broker(broker) + + assert app.broker is broker + + +def test_set_more_than_once_broker() -> None: + app = StartAbleApplication() + broker_1 = RabbitBroker() + broker_2 = RabbitBroker() + + app.set_broker(broker_1) + + with pytest.raises( + SetupError, + match=f"`{app}` already has a broker. You can't use multiple brokers until 1.0.0 release.", + ): + app.set_broker(broker_2) + + +@pytest.mark.asyncio() +async def test_start_not_setup_broker() -> None: + app = StartAbleApplication() + + with pytest.raises(AssertionError, match="You should setup a broker"): + await app._start_broker() From bc8732736481f5905aa9d3141b49a14acb6bedf4 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Fri, 20 Dec 2024 19:39:41 +0300 Subject: [PATCH 238/245] lint: fix rabbit types a bit --- faststream/rabbit/publisher/usecase.py | 2 +- faststream/rabbit/response.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/faststream/rabbit/publisher/usecase.py b/faststream/rabbit/publisher/usecase.py index abb48bb1b1..d4b736cfa4 100644 --- a/faststream/rabbit/publisher/usecase.py +++ b/faststream/rabbit/publisher/usecase.py @@ -72,7 +72,7 @@ def __init__( request_options = dict(message_kwargs) self.headers = request_options.pop("headers") or {} - self.reply_to = request_options.pop("reply_to", "") + self.reply_to = request_options.pop("reply_to", None) or "" self.timeout = request_options.pop("timeout", None) message_options, _ = filter_by_dict(MessageOptions, request_options) diff --git a/faststream/rabbit/response.py b/faststream/rabbit/response.py index f45cbb07ce..ffb1ad3b31 100644 --- a/faststream/rabbit/response.py +++ b/faststream/rabbit/response.py @@ -75,7 +75,7 @@ def __init__( **message_options: Unpack["MessageOptions"], ) -> None: headers = message_options.pop("headers", {}) - reply_to = message_options.pop("reply_to") or "" + reply_to = message_options.pop("reply_to", None) or "" correlation_id = message_options.pop("correlation_id", None) super().__init__( From bbea3655205cdd3394c5b99d42693dbead111160 Mon Sep 17 00:00:00 2001 From: Roma Frolov <98967567+roma-frolov@users.noreply.github.com> Date: Mon, 23 Dec 2024 20:44:00 +0300 Subject: [PATCH 239/245] feat: Pretty prom tests (#2000) * feat: moved the creation of metrics to functions * feat: ruff * feat: pretty prometheus tests * feat: ruff * feat: fix test --- faststream/confluent/response.py | 2 +- faststream/kafka/response.py | 2 +- faststream/redis/response.py | 2 +- faststream/response/response.py | 2 +- .../brokers/confluent/test_publish_command.py | 2 + tests/brokers/kafka/test_publish_command.py | 2 + tests/brokers/redis/test_publish_command.py | 2 + tests/prometheus/basic.py | 249 +++++----- tests/prometheus/confluent/basic.py | 16 +- tests/prometheus/confluent/test_confluent.py | 23 +- tests/prometheus/confluent/test_provider.py | 22 +- tests/prometheus/kafka/basic.py | 16 +- tests/prometheus/kafka/test_kafka.py | 23 +- tests/prometheus/kafka/test_provider.py | 26 +- tests/prometheus/nats/basic.py | 20 +- tests/prometheus/nats/test_nats.py | 31 +- tests/prometheus/nats/test_provider.py | 25 +- tests/prometheus/rabbit/basic.py | 5 + tests/prometheus/rabbit/test_provider.py | 10 +- tests/prometheus/redis/basic.py | 16 +- tests/prometheus/redis/test_provider.py | 27 +- tests/prometheus/redis/test_redis.py | 35 +- tests/prometheus/test_metrics.py | 407 ++++------------- tests/prometheus/utils.py | 426 ++++++++++++++++++ 24 files changed, 834 insertions(+), 557 deletions(-) create mode 100644 tests/prometheus/utils.py diff --git a/faststream/confluent/response.py b/faststream/confluent/response.py index 3473e291bc..8fe706783a 100644 --- a/faststream/confluent/response.py +++ b/faststream/confluent/response.py @@ -109,7 +109,7 @@ def from_cmd( if body is None: body = EMPTY - if isinstance(body, Sequence) and not isinstance(body, str): + if isinstance(body, Sequence) and not isinstance(body, (str, bytes)): if body: body, extra_bodies = body[0], body[1:] else: diff --git a/faststream/kafka/response.py b/faststream/kafka/response.py index 13d3c186bf..8db0ec538b 100644 --- a/faststream/kafka/response.py +++ b/faststream/kafka/response.py @@ -101,7 +101,7 @@ def from_cmd( if body is None: body = EMPTY - if isinstance(body, Sequence) and not isinstance(body, str): + if isinstance(body, Sequence) and not isinstance(body, (str, bytes)): if body: body, extra_bodies = body[0], body[1:] else: diff --git a/faststream/redis/response.py b/faststream/redis/response.py index d48ee0ba1a..fbaece2ff0 100644 --- a/faststream/redis/response.py +++ b/faststream/redis/response.py @@ -130,7 +130,7 @@ def from_cmd( if body is None: body = EMPTY - if isinstance(body, Sequence) and not isinstance(body, str): + if isinstance(body, Sequence) and not isinstance(body, (str, bytes)): if body: body, extra_bodies = body[0], body[1:] else: diff --git a/faststream/response/response.py b/faststream/response/response.py index ff44643f35..eb2edc85a1 100644 --- a/faststream/response/response.py +++ b/faststream/response/response.py @@ -52,7 +52,7 @@ def __init__( @property def batch_bodies(self) -> tuple["Any", ...]: - if self.body: + if self.body or isinstance(self.body, (str, bytes)): return (self.body,) return () diff --git a/tests/brokers/confluent/test_publish_command.py b/tests/brokers/confluent/test_publish_command.py index 43e089afbb..b85d093a82 100644 --- a/tests/brokers/confluent/test_publish_command.py +++ b/tests/brokers/confluent/test_publish_command.py @@ -34,6 +34,8 @@ def test_kafka_response_class(): pytest.param(None, (), id="None Response"), pytest.param((), (), id="Empty Sequence"), pytest.param("123", ("123",), id="String Response"), + pytest.param("", ("",), id="Empty String Response"), + pytest.param(b"", (b"",), id="Empty Bytes Response"), pytest.param([1, 2, 3], (1, 2, 3), id="Sequence Data"), pytest.param([0, 1, 2], (0, 1, 2), id="Sequence Data with False first element"), ), diff --git a/tests/brokers/kafka/test_publish_command.py b/tests/brokers/kafka/test_publish_command.py index 912989aa1c..6de51562ca 100644 --- a/tests/brokers/kafka/test_publish_command.py +++ b/tests/brokers/kafka/test_publish_command.py @@ -34,6 +34,8 @@ def test_kafka_response_class(): pytest.param(None, (), id="None Response"), pytest.param((), (), id="Empty Sequence"), pytest.param("123", ("123",), id="String Response"), + pytest.param("", ("",), id="Empty String Response"), + pytest.param(b"", (b"",), id="Empty Bytes Response"), pytest.param([1, 2, 3], (1, 2, 3), id="Sequence Data"), pytest.param([0, 1, 2], (0, 1, 2), id="Sequence Data with False first element"), ), diff --git a/tests/brokers/redis/test_publish_command.py b/tests/brokers/redis/test_publish_command.py index 3da0619eac..507ff05d24 100644 --- a/tests/brokers/redis/test_publish_command.py +++ b/tests/brokers/redis/test_publish_command.py @@ -34,6 +34,8 @@ def test_kafka_response_class() -> None: pytest.param(None, (), id="None Response"), pytest.param((), (), id="Empty Sequence"), pytest.param("123", ("123",), id="String Response"), + pytest.param("", ("",), id="Empty String Response"), + pytest.param(b"", (b"",), id="Empty Bytes Response"), pytest.param([1, 2, 3], (1, 2, 3), id="Sequence Data"), pytest.param([0, 1, 2], (0, 1, 2), id="Sequence Data with False first element"), ), diff --git a/tests/prometheus/basic.py b/tests/prometheus/basic.py index e7598aa166..9beaa18f43 100644 --- a/tests/prometheus/basic.py +++ b/tests/prometheus/basic.py @@ -1,8 +1,8 @@ import asyncio -from typing import Any, Optional -from unittest.mock import ANY, Mock, call +from typing import Any, Optional, cast import pytest +from dirty_equals import IsList, IsPositiveFloat, IsStr from prometheus_client import CollectorRegistry from faststream import Context @@ -14,27 +14,28 @@ PROCESSING_STATUS_BY_HANDLER_EXCEPTION_MAP, BasePrometheusMiddleware, ) -from faststream.prometheus.types import ProcessingStatus +from faststream.prometheus.types import ProcessingStatus, PublishingStatus from tests.brokers.base.basic import BaseTestcaseConfig +from tests.prometheus.utils import ( + get_published_messages_duration_seconds_metric, + get_published_messages_exceptions_metric, + get_published_messages_metric, + get_received_messages_in_process_metric, + get_received_messages_metric, + get_received_messages_size_bytes_metric, + get_received_processed_messages_duration_seconds_metric, + get_received_processed_messages_exceptions_metric, + get_received_processed_messages_metric, +) @pytest.mark.asyncio() class LocalPrometheusTestcase(BaseTestcaseConfig): - def get_broker(self, apply_types: bool = False, **kwargs: Any): - raise NotImplementedError - def get_middleware(self, **kwargs: Any) -> BasePrometheusMiddleware: raise NotImplementedError - @staticmethod - def consume_destination_name(queue: str) -> str: - return queue - - @property - def settings_provider_factory(self): - return self.get_middleware( - registry=CollectorRegistry() - )._settings_provider_factory + def get_settings_provider(self) -> MetricsSettingsProvider[Any]: + raise NotImplementedError @pytest.mark.parametrize( ( @@ -81,10 +82,8 @@ async def test_metrics( exception_class: Optional[type[Exception]], ) -> None: event = asyncio.Event() - - middleware = self.get_middleware(registry=CollectorRegistry()) - metrics_manager_mock = Mock() - middleware._metrics_manager = metrics_manager_mock + registry = CollectorRegistry() + middleware = self.get_middleware(registry=registry) broker = self.get_broker(apply_types=True, middlewares=(middleware,)) @@ -118,62 +117,69 @@ async def handler(m=Context("message")): await asyncio.wait(tasks, timeout=self.timeout) assert event.is_set() - self.assert_consume_metrics( - metrics_manager=metrics_manager_mock, + self.assert_metrics( + registry=registry, message=message, exception_class=exception_class, ) - self.assert_publish_metrics(metrics_manager=metrics_manager_mock) - def assert_consume_metrics( + def assert_metrics( self, *, - metrics_manager: Any, + registry: CollectorRegistry, message: Any, exception_class: Optional[type[Exception]], ) -> None: - settings_provider = self.settings_provider_factory(message.raw_message) + settings_provider = self.get_settings_provider() consume_attrs = settings_provider.get_consume_attrs_from_message(message) - assert metrics_manager.add_received_message.mock_calls == [ - call( - amount=consume_attrs["messages_count"], - broker=settings_provider.messaging_system, - handler=consume_attrs["destination_name"], - ), - ] - assert metrics_manager.observe_received_messages_size.mock_calls == [ - call( - size=consume_attrs["message_size"], - broker=settings_provider.messaging_system, - handler=consume_attrs["destination_name"], - ), - ] + received_messages_metric = get_received_messages_metric( + metrics_prefix="faststream", + app_name="faststream", + broker=settings_provider.messaging_system, + queue=consume_attrs["destination_name"], + messages_amount=consume_attrs["messages_count"], + ) - assert metrics_manager.add_received_message_in_process.mock_calls == [ - call( - amount=consume_attrs["messages_count"], - broker=settings_provider.messaging_system, - handler=consume_attrs["destination_name"], + received_messages_size_bytes_metric = get_received_messages_size_bytes_metric( + metrics_prefix="faststream", + app_name="faststream", + broker=settings_provider.messaging_system, + queue=consume_attrs["destination_name"], + buckets=( + 2.0**4, + 2.0**6, + 2.0**8, + 2.0**10, + 2.0**12, + 2.0**14, + 2.0**16, + 2.0**18, + 2.0**20, + 2.0**22, + 2.0**24, + float("inf"), ), - ] - assert metrics_manager.remove_received_message_in_process.mock_calls == [ - call( - amount=consume_attrs["messages_count"], + size=consume_attrs["message_size"], + messages_amount=1, + ) + + received_messages_in_process_metric = get_received_messages_in_process_metric( + metrics_prefix="faststream", + app_name="faststream", + broker=settings_provider.messaging_system, + queue=consume_attrs["destination_name"], + messages_amount=0, + ) + + received_processed_messages_duration_seconds_metric = ( + get_received_processed_messages_duration_seconds_metric( + metrics_prefix="faststream", + app_name="faststream", broker=settings_provider.messaging_system, - handler=consume_attrs["destination_name"], + queue=consume_attrs["destination_name"], + duration=cast(float, IsPositiveFloat), ) - ] - - assert ( - metrics_manager.observe_received_processed_message_duration.mock_calls - == [ - call( - duration=ANY, - broker=settings_provider.messaging_system, - handler=consume_attrs["destination_name"], - ), - ] ) status = ProcessingStatus.acked @@ -186,47 +192,73 @@ def assert_consume_metrics( elif message.committed: status = PROCESSING_STATUS_BY_ACK_STATUS[message.committed] - assert metrics_manager.add_received_processed_message.mock_calls == [ - call( - amount=consume_attrs["messages_count"], - broker=settings_provider.messaging_system, - handler=consume_attrs["destination_name"], - status=status.value, - ), - ] + received_processed_messages_metric = get_received_processed_messages_metric( + metrics_prefix="faststream", + app_name="faststream", + broker=settings_provider.messaging_system, + queue=consume_attrs["destination_name"], + messages_amount=consume_attrs["messages_count"], + status=status, + ) + + exception_type: Optional[str] = None if exception_class and not issubclass(exception_class, IgnoredException): - assert ( - metrics_manager.add_received_processed_message_exception.mock_calls - == [ - call( - broker=settings_provider.messaging_system, - handler=consume_attrs["destination_name"], - exception_type=exception_class.__name__, - ), - ] - ) - else: - assert ( - metrics_manager.add_received_processed_message_exception.mock_calls - == [] + exception_type = exception_class.__name__ + + received_processed_messages_exceptions_metric = ( + get_received_processed_messages_exceptions_metric( + metrics_prefix="faststream", + app_name="faststream", + broker=settings_provider.messaging_system, + queue=consume_attrs["destination_name"], + exception_type=exception_type, + exceptions_amount=consume_attrs["messages_count"], ) + ) - def assert_publish_metrics(self, metrics_manager: Any) -> None: - settings_provider = self.settings_provider_factory(None) - assert metrics_manager.observe_published_message_duration.mock_calls == [ - call( - duration=ANY, broker=settings_provider.messaging_system, destination=ANY - ), - ] - assert metrics_manager.add_published_message.mock_calls == [ - call( - amount=ANY, + published_messages_metric = get_published_messages_metric( + metrics_prefix="faststream", + app_name="faststream", + broker=settings_provider.messaging_system, + queue=cast(str, IsStr), + status=PublishingStatus.success, + messages_amount=consume_attrs["messages_count"], + ) + + published_messages_duration_seconds_metric = ( + get_published_messages_duration_seconds_metric( + metrics_prefix="faststream", + app_name="faststream", broker=settings_provider.messaging_system, - destination=ANY, - status="success", - ), - ] + queue=cast(str, IsStr), + duration=cast(float, IsPositiveFloat), + ) + ) + + published_messages_exceptions_metric = get_published_messages_exceptions_metric( + metrics_prefix="faststream", + app_name="faststream", + broker=settings_provider.messaging_system, + queue=cast(str, IsStr), + exception_type=None, + ) + + expected_metrics = IsList( + received_messages_metric, + received_messages_size_bytes_metric, + received_messages_in_process_metric, + received_processed_messages_metric, + received_processed_messages_duration_seconds_metric, + received_processed_messages_exceptions_metric, + published_messages_metric, + published_messages_duration_seconds_metric, + published_messages_exceptions_metric, + check_order=False, + ) + real_metrics = list(registry.collect()) + + assert real_metrics == expected_metrics class LocalRPCPrometheusTestcase: @@ -236,16 +268,21 @@ async def test_rpc_request( queue: str, ) -> None: event = asyncio.Event() + registry = CollectorRegistry() - middleware = self.get_middleware(registry=CollectorRegistry()) - metrics_manager_mock = Mock() - middleware._metrics_manager = metrics_manager_mock + middleware = self.get_middleware(registry=registry) broker = self.get_broker(apply_types=True, middlewares=(middleware,)) + message = None + @broker.subscriber(queue) - async def handle(): + async def handle(m=Context("message")): event.set() + + nonlocal message + message = m + return "" async with self.patch_broker(broker) as br: @@ -257,8 +294,12 @@ async def handle(): ) assert event.is_set() - metrics_manager_mock.add_received_message.assert_called_once() - metrics_manager_mock.add_published_message.assert_called_once() + + self.assert_metrics( + registry=registry, + message=message, + exception_class=None, + ) class LocalMetricsSettingsProviderTestcase: @@ -268,11 +309,11 @@ def get_middleware(self, **kwargs) -> BasePrometheusMiddleware: raise NotImplementedError @staticmethod - def get_provider() -> MetricsSettingsProvider: + def get_settings_provider() -> MetricsSettingsProvider: raise NotImplementedError def test_messaging_system(self) -> None: - provider = self.get_provider() + provider = self.get_settings_provider() assert provider.messaging_system == self.messaging_system def test_one_registry_for_some_middlewares(self) -> None: diff --git a/tests/prometheus/confluent/basic.py b/tests/prometheus/confluent/basic.py index facea2efec..0852877951 100644 --- a/tests/prometheus/confluent/basic.py +++ b/tests/prometheus/confluent/basic.py @@ -2,10 +2,14 @@ from faststream import AckPolicy from faststream.confluent.prometheus import KafkaPrometheusMiddleware +from faststream.confluent.prometheus.provider import ( + BatchConfluentMetricsSettingsProvider, + ConfluentMetricsSettingsProvider, +) from tests.brokers.confluent.basic import ConfluentTestcaseConfig -class KafkaPrometheusSettings(ConfluentTestcaseConfig): +class BaseConfluentPrometheusSettings(ConfluentTestcaseConfig): messaging_system = "kafka" def get_middleware(self, **kwargs: Any) -> KafkaPrometheusMiddleware: @@ -26,3 +30,13 @@ def get_subscriber_params( "ack_policy": AckPolicy.REJECT_ON_ERROR, **kwargs, } + + +class ConfluentPrometheusSettings(BaseConfluentPrometheusSettings): + def get_settings_provider(self) -> ConfluentMetricsSettingsProvider: + return ConfluentMetricsSettingsProvider() + + +class BatchConfluentPrometheusSettings(BaseConfluentPrometheusSettings): + def get_settings_provider(self) -> BatchConfluentMetricsSettingsProvider: + return BatchConfluentMetricsSettingsProvider() diff --git a/tests/prometheus/confluent/test_confluent.py b/tests/prometheus/confluent/test_confluent.py index 1cf625b803..39d629cb9f 100644 --- a/tests/prometheus/confluent/test_confluent.py +++ b/tests/prometheus/confluent/test_confluent.py @@ -1,6 +1,5 @@ import asyncio from typing import Any -from unittest.mock import Mock import pytest from prometheus_client import CollectorRegistry @@ -12,20 +11,19 @@ from tests.brokers.confluent.test_publish import TestPublish from tests.prometheus.basic import LocalPrometheusTestcase -from .basic import KafkaPrometheusSettings +from .basic import BatchConfluentPrometheusSettings, ConfluentPrometheusSettings @pytest.mark.confluent() -class TestPrometheus(KafkaPrometheusSettings, LocalPrometheusTestcase): - async def test_metrics_batch( +class TestBatchPrometheus(BatchConfluentPrometheusSettings, LocalPrometheusTestcase): + async def test_metrics( self, queue: str, ): event = asyncio.Event() - middleware = self.get_middleware(registry=CollectorRegistry()) - metrics_manager_mock = Mock() - middleware._metrics_manager = metrics_manager_mock + registry = CollectorRegistry() + middleware = self.get_middleware(registry=registry) broker = self.get_broker(apply_types=True, middlewares=(middleware,)) @@ -50,10 +48,15 @@ async def handler(m=Context("message")): await asyncio.wait(tasks, timeout=self.timeout) assert event.is_set() - self.assert_consume_metrics( - metrics_manager=metrics_manager_mock, message=message, exception_class=None + self.assert_metrics( + registry=registry, + message=message, + exception_class=None, ) - self.assert_publish_metrics(metrics_manager=metrics_manager_mock) + + +@pytest.mark.confluent() +class TestPrometheus(ConfluentPrometheusSettings, LocalPrometheusTestcase): ... @pytest.mark.confluent() diff --git a/tests/prometheus/confluent/test_provider.py b/tests/prometheus/confluent/test_provider.py index d65c9d6a2a..a1099c3886 100644 --- a/tests/prometheus/confluent/test_provider.py +++ b/tests/prometheus/confluent/test_provider.py @@ -8,19 +8,17 @@ ConfluentMetricsSettingsProvider, settings_provider_factory, ) -from faststream.prometheus import MetricsSettingsProvider from tests.prometheus.basic import LocalMetricsSettingsProviderTestcase -from .basic import KafkaPrometheusSettings +from .basic import BatchConfluentPrometheusSettings, ConfluentPrometheusSettings class LocalBaseConfluentMetricsSettingsProviderTestcase( - KafkaPrometheusSettings, LocalMetricsSettingsProviderTestcase, ): def test_get_publish_destination_name_from_cmd(self, queue: str) -> None: expected_destination_name = queue - provider = self.get_provider() + provider = self.get_settings_provider() command = SimpleNamespace(destination=queue) destination_name = provider.get_publish_destination_name_from_cmd(command) @@ -29,12 +27,8 @@ def test_get_publish_destination_name_from_cmd(self, queue: str) -> None: class TestKafkaMetricsSettingsProvider( - LocalBaseConfluentMetricsSettingsProviderTestcase + ConfluentPrometheusSettings, LocalBaseConfluentMetricsSettingsProviderTestcase ): - @staticmethod - def get_provider() -> MetricsSettingsProvider: - return ConfluentMetricsSettingsProvider() - def test_get_consume_attrs_from_message(self, queue: str) -> None: body = b"Hello" expected_attrs = { @@ -47,19 +41,15 @@ def test_get_consume_attrs_from_message(self, queue: str) -> None: body=body, raw_message=SimpleNamespace(topic=lambda: queue) ) - provider = self.get_provider() + provider = self.get_settings_provider() attrs = provider.get_consume_attrs_from_message(message) assert attrs == expected_attrs class TestBatchConfluentMetricsSettingsProvider( - LocalBaseConfluentMetricsSettingsProviderTestcase + BatchConfluentPrometheusSettings, LocalBaseConfluentMetricsSettingsProviderTestcase ): - @staticmethod - def get_provider() -> MetricsSettingsProvider: - return BatchConfluentMetricsSettingsProvider() - def test_get_consume_attrs_from_message(self, queue: str) -> None: body = [b"Hi ", b"again, ", b"FastStream!"] message = SimpleNamespace( @@ -75,7 +65,7 @@ def test_get_consume_attrs_from_message(self, queue: str) -> None: "messages_count": len(message.raw_message), } - provider = self.get_provider() + provider = self.get_settings_provider() attrs = provider.get_consume_attrs_from_message(message) assert attrs == expected_attrs diff --git a/tests/prometheus/kafka/basic.py b/tests/prometheus/kafka/basic.py index 9fdd8795dc..b4b2661037 100644 --- a/tests/prometheus/kafka/basic.py +++ b/tests/prometheus/kafka/basic.py @@ -2,10 +2,14 @@ from faststream import AckPolicy from faststream.kafka.prometheus import KafkaPrometheusMiddleware +from faststream.kafka.prometheus.provider import ( + BatchKafkaMetricsSettingsProvider, + KafkaMetricsSettingsProvider, +) from tests.brokers.kafka.basic import KafkaTestcaseConfig -class KafkaPrometheusSettings(KafkaTestcaseConfig): +class BaseKafkaPrometheusSettings(KafkaTestcaseConfig): messaging_system = "kafka" def get_middleware(self, **kwargs: Any) -> KafkaPrometheusMiddleware: @@ -25,3 +29,13 @@ def get_subscriber_params( "ack_policy": AckPolicy.REJECT_ON_ERROR, **kwargs, } + + +class KafkaPrometheusSettings(BaseKafkaPrometheusSettings): + def get_settings_provider(self) -> KafkaMetricsSettingsProvider: + return KafkaMetricsSettingsProvider() + + +class BatchKafkaPrometheusSettings(BaseKafkaPrometheusSettings): + def get_settings_provider(self) -> BatchKafkaMetricsSettingsProvider: + return BatchKafkaMetricsSettingsProvider() diff --git a/tests/prometheus/kafka/test_kafka.py b/tests/prometheus/kafka/test_kafka.py index 4384add588..e2e0580b52 100644 --- a/tests/prometheus/kafka/test_kafka.py +++ b/tests/prometheus/kafka/test_kafka.py @@ -1,5 +1,4 @@ import asyncio -from unittest.mock import Mock import pytest from prometheus_client import CollectorRegistry @@ -11,20 +10,19 @@ from tests.brokers.kafka.test_publish import TestPublish from tests.prometheus.basic import LocalPrometheusTestcase -from .basic import KafkaPrometheusSettings +from .basic import BatchKafkaPrometheusSettings, KafkaPrometheusSettings @pytest.mark.kafka() -class TestPrometheus(KafkaPrometheusSettings, LocalPrometheusTestcase): - async def test_metrics_batch( +class TestBatchPrometheus(BatchKafkaPrometheusSettings, LocalPrometheusTestcase): + async def test_metrics( self, queue: str, ): event = asyncio.Event() - middleware = self.get_middleware(registry=CollectorRegistry()) - metrics_manager_mock = Mock() - middleware._metrics_manager = metrics_manager_mock + registry = CollectorRegistry() + middleware = self.get_middleware(registry=registry) broker = self.get_broker(apply_types=True, middlewares=(middleware,)) @@ -49,10 +47,15 @@ async def handler(m=Context("message")): await asyncio.wait(tasks, timeout=self.timeout) assert event.is_set() - self.assert_consume_metrics( - metrics_manager=metrics_manager_mock, message=message, exception_class=None + self.assert_metrics( + registry=registry, + message=message, + exception_class=None, ) - self.assert_publish_metrics(metrics_manager=metrics_manager_mock) + + +@pytest.mark.kafka() +class TestPrometheus(KafkaPrometheusSettings, LocalPrometheusTestcase): ... @pytest.mark.kafka() diff --git a/tests/prometheus/kafka/test_provider.py b/tests/prometheus/kafka/test_provider.py index 2b590712b2..e046737f85 100644 --- a/tests/prometheus/kafka/test_provider.py +++ b/tests/prometheus/kafka/test_provider.py @@ -8,19 +8,17 @@ KafkaMetricsSettingsProvider, settings_provider_factory, ) -from faststream.prometheus import MetricsSettingsProvider from tests.prometheus.basic import LocalMetricsSettingsProviderTestcase -from .basic import KafkaPrometheusSettings +from .basic import BatchKafkaPrometheusSettings, KafkaPrometheusSettings class LocalBaseKafkaMetricsSettingsProviderTestcase( - KafkaPrometheusSettings, LocalMetricsSettingsProviderTestcase, ): def test_get_publish_destination_name_from_cmd(self, queue: str) -> None: expected_destination_name = queue - provider = self.get_provider() + provider = self.get_settings_provider() command = SimpleNamespace(destination=queue) destination_name = provider.get_publish_destination_name_from_cmd(command) @@ -28,11 +26,10 @@ def test_get_publish_destination_name_from_cmd(self, queue: str) -> None: assert destination_name == expected_destination_name -class TestKafkaMetricsSettingsProvider(LocalBaseKafkaMetricsSettingsProviderTestcase): - @staticmethod - def get_provider() -> MetricsSettingsProvider: - return KafkaMetricsSettingsProvider() - +class TestKafkaMetricsSettingsProvider( + KafkaPrometheusSettings, + LocalBaseKafkaMetricsSettingsProviderTestcase, +): def test_get_consume_attrs_from_message(self, queue: str) -> None: body = b"Hello" expected_attrs = { @@ -43,19 +40,16 @@ def test_get_consume_attrs_from_message(self, queue: str) -> None: message = SimpleNamespace(body=body, raw_message=SimpleNamespace(topic=queue)) - provider = self.get_provider() + provider = self.get_settings_provider() attrs = provider.get_consume_attrs_from_message(message) assert attrs == expected_attrs class TestBatchKafkaMetricsSettingsProvider( - LocalBaseKafkaMetricsSettingsProviderTestcase + BatchKafkaPrometheusSettings, + LocalBaseKafkaMetricsSettingsProviderTestcase, ): - @staticmethod - def get_provider() -> MetricsSettingsProvider: - return BatchKafkaMetricsSettingsProvider() - def test_get_consume_attrs_from_message(self, queue: str) -> None: body = [b"Hi ", b"again, ", b"FastStream!"] message = SimpleNamespace( @@ -70,7 +64,7 @@ def test_get_consume_attrs_from_message(self, queue: str) -> None: "messages_count": len(message.raw_message), } - provider = self.get_provider() + provider = self.get_settings_provider() attrs = provider.get_consume_attrs_from_message(message) assert attrs == expected_attrs diff --git a/tests/prometheus/nats/basic.py b/tests/prometheus/nats/basic.py index 5199ee84ef..4fda6435e7 100644 --- a/tests/prometheus/nats/basic.py +++ b/tests/prometheus/nats/basic.py @@ -1,15 +1,25 @@ from typing import Any -from faststream.nats import NatsBroker from faststream.nats.prometheus import NatsPrometheusMiddleware +from faststream.nats.prometheus.provider import ( + BatchNatsMetricsSettingsProvider, + NatsMetricsSettingsProvider, +) from tests.brokers.nats.basic import NatsTestcaseConfig -class NatsPrometheusSettings(NatsTestcaseConfig): +class BaseNatsPrometheusSettings(NatsTestcaseConfig): messaging_system = "nats" - def get_broker(self, apply_types=False, **kwargs: Any) -> NatsBroker: - return NatsBroker(apply_types=apply_types, **kwargs) - def get_middleware(self, **kwargs: Any) -> NatsPrometheusMiddleware: return NatsPrometheusMiddleware(**kwargs) + + +class NatsPrometheusSettings(BaseNatsPrometheusSettings): + def get_settings_provider(self) -> NatsMetricsSettingsProvider: + return NatsMetricsSettingsProvider() + + +class BatchNatsPrometheusSettings(BaseNatsPrometheusSettings): + def get_settings_provider(self) -> BatchNatsMetricsSettingsProvider: + return BatchNatsMetricsSettingsProvider() diff --git a/tests/prometheus/nats/test_nats.py b/tests/prometheus/nats/test_nats.py index edb07ad20b..b9ea9c89a2 100644 --- a/tests/prometheus/nats/test_nats.py +++ b/tests/prometheus/nats/test_nats.py @@ -1,6 +1,5 @@ import asyncio from typing import Any -from unittest.mock import Mock import pytest from prometheus_client import CollectorRegistry @@ -12,7 +11,7 @@ from tests.brokers.nats.test_publish import TestPublish from tests.prometheus.basic import LocalPrometheusTestcase, LocalRPCPrometheusTestcase -from .basic import NatsPrometheusSettings +from .basic import BatchNatsPrometheusSettings, NatsPrometheusSettings @pytest.fixture() @@ -21,21 +20,16 @@ def stream(queue): @pytest.mark.nats() -class TestPrometheus( - NatsPrometheusSettings, - LocalPrometheusTestcase, - LocalRPCPrometheusTestcase, -): - async def test_metrics_batch( +class TestBatchPrometheus(BatchNatsPrometheusSettings, LocalPrometheusTestcase): + async def test_metrics( self, queue: str, stream: JStream, ) -> None: event = asyncio.Event() - middleware = self.get_middleware(registry=CollectorRegistry()) - metrics_manager_mock = Mock() - middleware._metrics_manager = metrics_manager_mock + registry = CollectorRegistry() + middleware = self.get_middleware(registry=registry) broker = self.get_broker(apply_types=True, middlewares=(middleware,)) @@ -62,10 +56,19 @@ async def handler(m=Context("message")): await asyncio.wait(tasks, timeout=self.timeout) assert event.is_set() - self.assert_consume_metrics( - metrics_manager=metrics_manager_mock, message=message, exception_class=None + self.assert_metrics( + registry=registry, + message=message, + exception_class=None, ) - self.assert_publish_metrics(metrics_manager=metrics_manager_mock) + + +@pytest.mark.nats() +class TestPrometheus( + NatsPrometheusSettings, + LocalPrometheusTestcase, + LocalRPCPrometheusTestcase, +): ... @pytest.mark.nats() diff --git a/tests/prometheus/nats/test_provider.py b/tests/prometheus/nats/test_provider.py index 10410b95f8..3c94a7e129 100644 --- a/tests/prometheus/nats/test_provider.py +++ b/tests/prometheus/nats/test_provider.py @@ -9,30 +9,27 @@ NatsMetricsSettingsProvider, settings_provider_factory, ) -from faststream.prometheus import MetricsSettingsProvider from tests.prometheus.basic import LocalMetricsSettingsProviderTestcase -from .basic import NatsPrometheusSettings +from .basic import BatchNatsPrometheusSettings, NatsPrometheusSettings class LocalBaseNatsMetricsSettingsProviderTestcase( - NatsPrometheusSettings, - LocalMetricsSettingsProviderTestcase, + LocalMetricsSettingsProviderTestcase ): def test_get_publish_destination_name_from_cmd(self, queue: str) -> None: expected_destination_name = queue command = SimpleNamespace(destination=queue) - provider = self.get_provider() + provider = self.get_settings_provider() destination_name = provider.get_publish_destination_name_from_cmd(command) assert destination_name == expected_destination_name -class TestNatsMetricsSettingsProvider(LocalBaseNatsMetricsSettingsProviderTestcase): - def get_provider(self) -> MetricsSettingsProvider: - return NatsMetricsSettingsProvider() - +class TestNatsMetricsSettingsProvider( + NatsPrometheusSettings, LocalBaseNatsMetricsSettingsProviderTestcase +): def test_get_consume_attrs_from_message(self, queue: str) -> None: body = b"Hello" expected_attrs = { @@ -42,19 +39,15 @@ def test_get_consume_attrs_from_message(self, queue: str) -> None: } message = SimpleNamespace(body=body, raw_message=SimpleNamespace(subject=queue)) - provider = self.get_provider() + provider = self.get_settings_provider() attrs = provider.get_consume_attrs_from_message(message) assert attrs == expected_attrs class TestBatchNatsMetricsSettingsProvider( - LocalBaseNatsMetricsSettingsProviderTestcase + BatchNatsPrometheusSettings, LocalBaseNatsMetricsSettingsProviderTestcase ): - @staticmethod - def get_provider() -> MetricsSettingsProvider: - return BatchNatsMetricsSettingsProvider() - def test_get_consume_attrs_from_message(self, queue: str) -> None: body = b"Hello" raw_messages = [ @@ -68,7 +61,7 @@ def test_get_consume_attrs_from_message(self, queue: str) -> None: } message = SimpleNamespace(body=body, raw_message=raw_messages) - provider = self.get_provider() + provider = self.get_settings_provider() attrs = provider.get_consume_attrs_from_message(message) assert attrs == expected_attrs diff --git a/tests/prometheus/rabbit/basic.py b/tests/prometheus/rabbit/basic.py index a489fcb2e8..ee8a2d20a9 100644 --- a/tests/prometheus/rabbit/basic.py +++ b/tests/prometheus/rabbit/basic.py @@ -1,6 +1,8 @@ from typing import Any +from faststream.prometheus import MetricsSettingsProvider from faststream.rabbit.prometheus import RabbitPrometheusMiddleware +from faststream.rabbit.prometheus.provider import RabbitMetricsSettingsProvider from tests.brokers.rabbit.basic import RabbitTestcaseConfig @@ -9,3 +11,6 @@ class RabbitPrometheusSettings(RabbitTestcaseConfig): def get_middleware(self, **kwargs: Any) -> RabbitPrometheusMiddleware: return RabbitPrometheusMiddleware(**kwargs) + + def get_settings_provider(self) -> MetricsSettingsProvider[Any]: + return RabbitMetricsSettingsProvider() diff --git a/tests/prometheus/rabbit/test_provider.py b/tests/prometheus/rabbit/test_provider.py index 88f4c506bb..f31ea11a35 100644 --- a/tests/prometheus/rabbit/test_provider.py +++ b/tests/prometheus/rabbit/test_provider.py @@ -3,8 +3,6 @@ import pytest -from faststream.prometheus import MetricsSettingsProvider -from faststream.rabbit.prometheus.provider import RabbitMetricsSettingsProvider from tests.prometheus.basic import LocalMetricsSettingsProviderTestcase from .basic import RabbitPrometheusSettings @@ -14,10 +12,6 @@ class TestRabbitMetricsSettingsProvider( RabbitPrometheusSettings, LocalMetricsSettingsProviderTestcase, ): - @staticmethod - def get_provider() -> MetricsSettingsProvider: - return RabbitMetricsSettingsProvider() - @pytest.mark.parametrize( "exchange", ( @@ -40,7 +34,7 @@ def test_get_consume_attrs_from_message( body=body, raw_message=SimpleNamespace(exchange=exchange, routing_key=queue) ) - provider = self.get_provider() + provider = self.get_settings_provider() attrs = provider.get_consume_attrs_from_message(message) assert attrs == expected_attrs @@ -62,7 +56,7 @@ def test_get_publish_destination_name_from_cmd( exchange=SimpleNamespace(name=exchange), destination=queue ) - provider = self.get_provider() + provider = self.get_settings_provider() destination_name = provider.get_publish_destination_name_from_cmd(command) assert destination_name == expected_destination_name diff --git a/tests/prometheus/redis/basic.py b/tests/prometheus/redis/basic.py index a1f89f3ead..79e3bb477b 100644 --- a/tests/prometheus/redis/basic.py +++ b/tests/prometheus/redis/basic.py @@ -1,11 +1,25 @@ from typing import Any from faststream.redis.prometheus import RedisPrometheusMiddleware +from faststream.redis.prometheus.provider import ( + BatchRedisMetricsSettingsProvider, + RedisMetricsSettingsProvider, +) from tests.brokers.redis.basic import RedisTestcaseConfig -class RedisPrometheusSettings(RedisTestcaseConfig): +class BaseRedisPrometheusSettings(RedisTestcaseConfig): messaging_system = "redis" def get_middleware(self, **kwargs: Any) -> RedisPrometheusMiddleware: return RedisPrometheusMiddleware(**kwargs) + + +class RedisPrometheusSettings(BaseRedisPrometheusSettings): + def get_settings_provider(self) -> RedisMetricsSettingsProvider: + return RedisMetricsSettingsProvider() + + +class BatchRedisPrometheusSettings(BaseRedisPrometheusSettings): + def get_settings_provider(self) -> BatchRedisMetricsSettingsProvider: + return BatchRedisMetricsSettingsProvider() diff --git a/tests/prometheus/redis/test_provider.py b/tests/prometheus/redis/test_provider.py index 58e84cee4d..1e4fef4581 100644 --- a/tests/prometheus/redis/test_provider.py +++ b/tests/prometheus/redis/test_provider.py @@ -2,7 +2,6 @@ import pytest -from faststream.prometheus import MetricsSettingsProvider from faststream.redis.message import ( BatchListMessage, BatchStreamMessage, @@ -17,16 +16,15 @@ ) from tests.prometheus.basic import LocalMetricsSettingsProviderTestcase -from .basic import RedisPrometheusSettings +from .basic import BatchRedisPrometheusSettings, RedisPrometheusSettings class LocalBaseRedisMetricsSettingsProviderTestcase( - RedisPrometheusSettings, - LocalMetricsSettingsProviderTestcase, + LocalMetricsSettingsProviderTestcase ): def test_get_publish_destination_name_from_cmd(self, queue: str) -> None: expected_destination_name = queue - provider = self.get_provider() + provider = self.get_settings_provider() command = SimpleNamespace(destination=queue) destination_name = provider.get_publish_destination_name_from_cmd(command) @@ -34,11 +32,9 @@ def test_get_publish_destination_name_from_cmd(self, queue: str) -> None: assert destination_name == expected_destination_name -class TestRedisMetricsSettingsProvider(LocalBaseRedisMetricsSettingsProviderTestcase): - @staticmethod - def get_provider() -> MetricsSettingsProvider: - return RedisMetricsSettingsProvider() - +class TestRedisMetricsSettingsProvider( + RedisPrometheusSettings, LocalBaseRedisMetricsSettingsProviderTestcase +): @pytest.mark.parametrize( "destination", ( @@ -62,19 +58,16 @@ def test_get_consume_attrs_from_message(self, queue: str, destination: str) -> N message = SimpleNamespace(body=body, raw_message=raw_message) - provider = self.get_provider() + provider = self.get_settings_provider() attrs = provider.get_consume_attrs_from_message(message) assert attrs == expected_attrs class TestBatchRedisMetricsSettingsProvider( - LocalBaseRedisMetricsSettingsProviderTestcase + BatchRedisPrometheusSettings, + LocalBaseRedisMetricsSettingsProviderTestcase, ): - @staticmethod - def get_provider() -> MetricsSettingsProvider: - return BatchRedisMetricsSettingsProvider() - @pytest.mark.parametrize( "destination", ( @@ -104,7 +97,7 @@ def test_get_consume_attrs_from_message(self, queue: str, destination: str) -> N raw_message=raw_message, ) - provider = self.get_provider() + provider = self.get_settings_provider() attrs = provider.get_consume_attrs_from_message(message) assert attrs == expected_attrs diff --git a/tests/prometheus/redis/test_redis.py b/tests/prometheus/redis/test_redis.py index 4f6954116f..01e1e1f62d 100644 --- a/tests/prometheus/redis/test_redis.py +++ b/tests/prometheus/redis/test_redis.py @@ -1,6 +1,5 @@ import asyncio from typing import Any -from unittest.mock import Mock import pytest from prometheus_client import CollectorRegistry @@ -12,24 +11,19 @@ from tests.brokers.redis.test_publish import TestPublish from tests.prometheus.basic import LocalPrometheusTestcase, LocalRPCPrometheusTestcase -from .basic import RedisPrometheusSettings +from .basic import BatchRedisPrometheusSettings, RedisPrometheusSettings @pytest.mark.redis() -class TestPrometheus( - RedisPrometheusSettings, - LocalPrometheusTestcase, - LocalRPCPrometheusTestcase, -): - async def test_metrics_batch( +class TestBatchPrometheus(BatchRedisPrometheusSettings, LocalPrometheusTestcase): + async def test_metrics( self, queue: str, - ): + ) -> None: event = asyncio.Event() - middleware = self.get_middleware(registry=CollectorRegistry()) - metrics_manager_mock = Mock() - middleware._metrics_manager = metrics_manager_mock + registry = CollectorRegistry() + middleware = self.get_middleware(registry=registry) broker = self.get_broker(apply_types=True, middlewares=(middleware,)) @@ -47,16 +41,25 @@ async def handler(m=Context("message")): async with broker: await broker.start() tasks = ( - asyncio.create_task(broker.publish_batch("hello", "world", list=queue)), + asyncio.create_task(broker.publish_batch("hel", "lo", list=queue)), asyncio.create_task(event.wait()), ) await asyncio.wait(tasks, timeout=self.timeout) assert event.is_set() - self.assert_consume_metrics( - metrics_manager=metrics_manager_mock, message=message, exception_class=None + self.assert_metrics( + registry=registry, + message=message, + exception_class=None, ) - self.assert_publish_metrics(metrics_manager=metrics_manager_mock) + + +@pytest.mark.redis() +class TestPrometheus( + RedisPrometheusSettings, + LocalPrometheusTestcase, + LocalRPCPrometheusTestcase, +): ... @pytest.mark.redis() diff --git a/tests/prometheus/test_metrics.py b/tests/prometheus/test_metrics.py index 6be01b42c2..45dc6132fd 100644 --- a/tests/prometheus/test_metrics.py +++ b/tests/prometheus/test_metrics.py @@ -1,22 +1,30 @@ import random -from typing import Optional -from unittest.mock import ANY +from typing import Any, Optional import pytest -from dirty_equals import IsPositiveFloat, IsStr -from prometheus_client import CollectorRegistry, Histogram, Metric -from prometheus_client.samples import Sample +from prometheus_client import CollectorRegistry from faststream.prometheus.container import MetricsContainer from faststream.prometheus.manager import MetricsManager from faststream.prometheus.types import ProcessingStatus, PublishingStatus +from tests.prometheus.utils import ( + get_published_messages_duration_seconds_metric, + get_published_messages_exceptions_metric, + get_published_messages_metric, + get_received_messages_in_process_metric, + get_received_messages_metric, + get_received_messages_size_bytes_metric, + get_received_processed_messages_duration_seconds_metric, + get_received_processed_messages_exceptions_metric, + get_received_processed_messages_metric, +) class TestCaseMetrics: @staticmethod def create_metrics_manager( - app_name: Optional[str] = None, - metrics_prefix: Optional[str] = None, + app_name: str, + metrics_prefix: str, received_messages_size_buckets: Optional[list[float]] = None, ) -> MetricsManager: registry = CollectorRegistry() @@ -64,28 +72,13 @@ def test_add_received_message( metrics_prefix=metrics_prefix, ) - expected = Metric( - name=f"{metrics_prefix}_received_messages", - documentation="Count of received messages by broker and handler", - unit="", - typ="counter", - ) - expected.samples = [ - Sample( - name=f"{metrics_prefix}_received_messages_total", - labels={"app_name": app_name, "broker": broker, "handler": queue}, - value=float(messages_amount), - timestamp=None, - exemplar=None, - ), - Sample( - name=f"{metrics_prefix}_received_messages_created", - labels={"app_name": app_name, "broker": broker, "handler": queue}, - value=IsPositiveFloat, - timestamp=None, - exemplar=None, - ), - ] + expected = get_received_messages_metric( + app_name=app_name, + metrics_prefix=metrics_prefix, + queue=queue, + broker=broker, + messages_amount=messages_amount, + ) manager.add_received_message( amount=messages_amount, broker=broker, handler=queue @@ -110,7 +103,7 @@ def test_observe_received_messages_size( broker: str, is_default_buckets: bool, ) -> None: - manager_kwargs = { + manager_kwargs: dict[str, Any] = { "app_name": app_name, "metrics_prefix": metrics_prefix, } @@ -129,50 +122,15 @@ def test_observe_received_messages_size( else custom_buckets ) - expected = Metric( - name=f"{metrics_prefix}_received_messages_size_bytes", - documentation="Histogram of received messages size in bytes by broker and handler", - unit="", - typ="histogram", - ) - expected.samples = [ - *[ - Sample( - name=f"{metrics_prefix}_received_messages_size_bytes_bucket", - labels={ - "app_name": app_name, - "broker": broker, - "handler": queue, - "le": IsStr, - }, - value=1.0, - timestamp=None, - exemplar=None, - ) - for _ in buckets - ], - Sample( - name=f"{metrics_prefix}_received_messages_size_bytes_count", - labels={"app_name": app_name, "broker": broker, "handler": queue}, - value=1.0, - timestamp=None, - exemplar=None, - ), - Sample( - name=f"{metrics_prefix}_received_messages_size_bytes_sum", - labels={"app_name": app_name, "broker": broker, "handler": queue}, - value=size, - timestamp=None, - exemplar=None, - ), - Sample( - name=f"{metrics_prefix}_received_messages_size_bytes_created", - labels={"app_name": app_name, "broker": broker, "handler": queue}, - value=ANY, - timestamp=None, - exemplar=None, - ), - ] + expected = get_received_messages_size_bytes_metric( + metrics_prefix=metrics_prefix, + app_name=app_name, + broker=broker, + queue=queue, + buckets=buckets, + size=size, + messages_amount=1, + ) manager.observe_received_messages_size(size=size, broker=broker, handler=queue) @@ -193,21 +151,13 @@ def test_add_received_message_in_process( metrics_prefix=metrics_prefix, ) - expected = Metric( - name=f"{metrics_prefix}_received_messages_in_process", - documentation="Gauge of received messages in process by broker and handler", - unit="", - typ="gauge", + expected = get_received_messages_in_process_metric( + metrics_prefix=metrics_prefix, + app_name=app_name, + broker=broker, + queue=queue, + messages_amount=messages_amount, ) - expected.samples = [ - Sample( - name=f"{metrics_prefix}_received_messages_in_process", - labels={"app_name": app_name, "broker": broker, "handler": queue}, - value=float(messages_amount), - timestamp=None, - exemplar=None, - ), - ] manager.add_received_message_in_process( amount=messages_amount, broker=broker, handler=queue @@ -230,21 +180,13 @@ def test_remove_received_message_in_process( metrics_prefix=metrics_prefix, ) - expected = Metric( - name=f"{metrics_prefix}_received_messages_in_process", - documentation="Gauge of received messages in process by broker and handler", - unit="", - typ="gauge", + expected = get_received_messages_in_process_metric( + metrics_prefix=metrics_prefix, + app_name=app_name, + broker=broker, + queue=queue, + messages_amount=messages_amount - 1, ) - expected.samples = [ - Sample( - name=f"{metrics_prefix}_received_messages_in_process", - labels={"app_name": app_name, "broker": broker, "handler": queue}, - value=float(messages_amount - 1), - timestamp=None, - exemplar=None, - ), - ] manager.add_received_message_in_process( amount=messages_amount, broker=broker, handler=queue @@ -281,38 +223,14 @@ def test_add_received_processed_message( metrics_prefix=metrics_prefix, ) - expected = Metric( - name=f"{metrics_prefix}_received_processed_messages", - documentation="Count of received processed messages by broker, handler and status", - unit="", - typ="counter", - ) - expected.samples = [ - Sample( - name=f"{metrics_prefix}_received_processed_messages_total", - labels={ - "app_name": app_name, - "broker": broker, - "handler": queue, - "status": status.value, - }, - value=float(messages_amount), - timestamp=None, - exemplar=None, - ), - Sample( - name=f"{metrics_prefix}_received_processed_messages_created", - labels={ - "app_name": app_name, - "broker": broker, - "handler": queue, - "status": status.value, - }, - value=IsPositiveFloat, - timestamp=None, - exemplar=None, - ), - ] + expected = get_received_processed_messages_metric( + metrics_prefix=metrics_prefix, + app_name=app_name, + broker=broker, + queue=queue, + messages_amount=messages_amount, + status=status, + ) manager.add_received_processed_message( amount=messages_amount, @@ -339,50 +257,13 @@ def test_observe_received_processed_message_duration( duration = 0.001 - expected = Metric( - name=f"{metrics_prefix}_received_processed_messages_duration_seconds", - documentation="Histogram of received processed messages duration in seconds by broker and handler", - unit="", - typ="histogram", - ) - expected.samples = [ - *[ - Sample( - name=f"{metrics_prefix}_received_processed_messages_duration_seconds_bucket", - labels={ - "app_name": app_name, - "broker": broker, - "handler": queue, - "le": IsStr, - }, - value=1.0, - timestamp=None, - exemplar=None, - ) - for _ in Histogram.DEFAULT_BUCKETS - ], - Sample( - name=f"{metrics_prefix}_received_processed_messages_duration_seconds_count", - labels={"app_name": app_name, "broker": broker, "handler": queue}, - value=1.0, - timestamp=None, - exemplar=None, - ), - Sample( - name=f"{metrics_prefix}_received_processed_messages_duration_seconds_sum", - labels={"app_name": app_name, "broker": broker, "handler": queue}, - value=duration, - timestamp=None, - exemplar=None, - ), - Sample( - name=f"{metrics_prefix}_received_processed_messages_duration_seconds_created", - labels={"app_name": app_name, "broker": broker, "handler": queue}, - value=ANY, - timestamp=None, - exemplar=None, - ), - ] + expected = get_received_processed_messages_duration_seconds_metric( + metrics_prefix=metrics_prefix, + app_name=app_name, + broker=broker, + queue=queue, + duration=duration, + ) manager.observe_received_processed_message_duration( duration=duration, @@ -409,38 +290,14 @@ def test_add_received_processed_message_exception( metrics_prefix=metrics_prefix, ) - expected = Metric( - name=f"{metrics_prefix}_received_processed_messages_exceptions", - documentation="Count of received processed messages exceptions by broker, handler and exception_type", - unit="", - typ="counter", - ) - expected.samples = [ - Sample( - name=f"{metrics_prefix}_received_processed_messages_exceptions_total", - labels={ - "app_name": app_name, - "broker": broker, - "handler": queue, - "exception_type": exception_type, - }, - value=1.0, - timestamp=None, - exemplar=None, - ), - Sample( - name=f"{metrics_prefix}_received_processed_messages_exceptions_created", - labels={ - "app_name": app_name, - "broker": broker, - "handler": queue, - "exception_type": exception_type, - }, - value=IsPositiveFloat, - timestamp=None, - exemplar=None, - ), - ] + expected = get_received_processed_messages_exceptions_metric( + metrics_prefix=metrics_prefix, + app_name=app_name, + broker=broker, + queue=queue, + exception_type=exception_type, + exceptions_amount=1, + ) manager.add_received_processed_message_exception( exception_type=exception_type, @@ -475,38 +332,14 @@ def test_add_published_message( metrics_prefix=metrics_prefix, ) - expected = Metric( - name=f"{metrics_prefix}_published_messages", - documentation="Count of published messages by destination and status", - unit="", - typ="counter", - ) - expected.samples = [ - Sample( - name=f"{metrics_prefix}_published_messages_total", - labels={ - "app_name": app_name, - "broker": broker, - "destination": queue, - "status": status.value, - }, - value=1.0, - timestamp=None, - exemplar=None, - ), - Sample( - name=f"{metrics_prefix}_published_messages_created", - labels={ - "app_name": app_name, - "broker": broker, - "destination": queue, - "status": status.value, - }, - value=IsPositiveFloat, - timestamp=None, - exemplar=None, - ), - ] + expected = get_published_messages_metric( + metrics_prefix=metrics_prefix, + app_name=app_name, + broker=broker, + queue=queue, + status=status, + messages_amount=1, + ) manager.add_published_message( status=status, @@ -532,50 +365,13 @@ def test_observe_published_message_duration( duration = 0.001 - expected = Metric( - name=f"{metrics_prefix}_published_messages_duration_seconds", - documentation="Histogram of published messages duration in seconds by broker and destination", - unit="", - typ="histogram", - ) - expected.samples = [ - *[ - Sample( - name=f"{metrics_prefix}_published_messages_duration_seconds_bucket", - labels={ - "app_name": app_name, - "broker": broker, - "destination": queue, - "le": IsStr, - }, - value=1.0, - timestamp=None, - exemplar=None, - ) - for _ in Histogram.DEFAULT_BUCKETS - ], - Sample( - name=f"{metrics_prefix}_published_messages_duration_seconds_count", - labels={"app_name": app_name, "broker": broker, "destination": queue}, - value=1.0, - timestamp=None, - exemplar=None, - ), - Sample( - name=f"{metrics_prefix}_published_messages_duration_seconds_sum", - labels={"app_name": app_name, "broker": broker, "destination": queue}, - value=duration, - timestamp=None, - exemplar=None, - ), - Sample( - name=f"{metrics_prefix}_published_messages_duration_seconds_created", - labels={"app_name": app_name, "broker": broker, "destination": queue}, - value=IsPositiveFloat, - timestamp=None, - exemplar=None, - ), - ] + expected = get_published_messages_duration_seconds_metric( + metrics_prefix=metrics_prefix, + app_name=app_name, + broker=broker, + queue=queue, + duration=duration, + ) manager.observe_published_message_duration( duration=duration, @@ -600,38 +396,13 @@ def test_add_published_message_exception( metrics_prefix=metrics_prefix, ) - expected = Metric( - name=f"{metrics_prefix}_published_messages_exceptions", - documentation="Count of published messages exceptions by broker, destination and exception_type", - unit="", - typ="counter", - ) - expected.samples = [ - Sample( - name=f"{metrics_prefix}_published_messages_exceptions_total", - labels={ - "app_name": app_name, - "broker": broker, - "destination": queue, - "exception_type": exception_type, - }, - value=1.0, - timestamp=None, - exemplar=None, - ), - Sample( - name=f"{metrics_prefix}_published_messages_exceptions_created", - labels={ - "app_name": app_name, - "broker": broker, - "destination": queue, - "exception_type": exception_type, - }, - value=IsPositiveFloat, - timestamp=None, - exemplar=None, - ), - ] + expected = get_published_messages_exceptions_metric( + metrics_prefix=metrics_prefix, + app_name=app_name, + broker=broker, + queue=queue, + exception_type=exception_type, + ) manager.add_published_message_exception( exception_type=exception_type, diff --git a/tests/prometheus/utils.py b/tests/prometheus/utils.py new file mode 100644 index 0000000000..cb1e0738c0 --- /dev/null +++ b/tests/prometheus/utils.py @@ -0,0 +1,426 @@ +from collections.abc import Sequence +from typing import Optional, cast + +from dirty_equals import IsFloat, IsPositiveFloat, IsStr +from prometheus_client import Histogram, Metric +from prometheus_client.samples import Sample + +from faststream.prometheus.types import ProcessingStatus, PublishingStatus + + +def get_received_messages_metric( + *, + metrics_prefix: str, + app_name: str, + broker: str, + queue: str, + messages_amount: int, +) -> Metric: + metric = Metric( + name=f"{metrics_prefix}_received_messages", + documentation="Count of received messages by broker and handler", + unit="", + typ="counter", + ) + metric.samples = [ + Sample( + name=f"{metrics_prefix}_received_messages_total", + labels={"app_name": app_name, "broker": broker, "handler": queue}, + value=float(messages_amount), + timestamp=None, + exemplar=None, + ), + Sample( + name=f"{metrics_prefix}_received_messages_created", + labels={"app_name": app_name, "broker": broker, "handler": queue}, + value=cast(float, IsPositiveFloat), + timestamp=None, + exemplar=None, + ), + ] + + return metric + + +def get_received_messages_size_bytes_metric( + *, + metrics_prefix: str, + app_name: str, + broker: str, + queue: str, + buckets: Sequence[float], + size: int, + messages_amount: int, +) -> Metric: + metric = Metric( + name=f"{metrics_prefix}_received_messages_size_bytes", + documentation="Histogram of received messages size in bytes by broker and handler", + unit="", + typ="histogram", + ) + metric.samples = [ + *[ + Sample( + name=f"{metrics_prefix}_received_messages_size_bytes_bucket", + labels={ + "app_name": app_name, + "broker": broker, + "handler": queue, + "le": cast(str, IsStr), + }, + value=float(messages_amount), + timestamp=None, + exemplar=None, + ) + for _ in buckets + ], + Sample( + name=f"{metrics_prefix}_received_messages_size_bytes_count", + labels={"app_name": app_name, "broker": broker, "handler": queue}, + value=float(messages_amount), + timestamp=None, + exemplar=None, + ), + Sample( + name=f"{metrics_prefix}_received_messages_size_bytes_sum", + labels={"app_name": app_name, "broker": broker, "handler": queue}, + value=size, + timestamp=None, + exemplar=None, + ), + Sample( + name=f"{metrics_prefix}_received_messages_size_bytes_created", + labels={"app_name": app_name, "broker": broker, "handler": queue}, + value=cast(float, IsPositiveFloat), + timestamp=None, + exemplar=None, + ), + ] + + return metric + + +def get_received_messages_in_process_metric( + *, + metrics_prefix: str, + app_name: str, + broker: str, + queue: str, + messages_amount: int, +) -> Metric: + metric = Metric( + name=f"{metrics_prefix}_received_messages_in_process", + documentation="Gauge of received messages in process by broker and handler", + unit="", + typ="gauge", + ) + metric.samples = [ + Sample( + name=f"{metrics_prefix}_received_messages_in_process", + labels={"app_name": app_name, "broker": broker, "handler": queue}, + value=float(messages_amount), + timestamp=None, + exemplar=None, + ), + ] + + return metric + + +def get_received_processed_messages_metric( + *, + metrics_prefix: str, + app_name: str, + broker: str, + queue: str, + messages_amount: int, + status: ProcessingStatus, +) -> Metric: + metric = Metric( + name=f"{metrics_prefix}_received_processed_messages", + documentation="Count of received processed messages by broker, handler and status", + unit="", + typ="counter", + ) + metric.samples = [ + Sample( + name=f"{metrics_prefix}_received_processed_messages_total", + labels={ + "app_name": app_name, + "broker": broker, + "handler": queue, + "status": status.value, + }, + value=float(messages_amount), + timestamp=None, + exemplar=None, + ), + Sample( + name=f"{metrics_prefix}_received_processed_messages_created", + labels={ + "app_name": app_name, + "broker": broker, + "handler": queue, + "status": status.value, + }, + value=cast(float, IsPositiveFloat), + timestamp=None, + exemplar=None, + ), + ] + + return metric + + +def get_received_processed_messages_duration_seconds_metric( + *, + metrics_prefix: str, + app_name: str, + broker: str, + queue: str, + duration: float, +) -> Metric: + metric = Metric( + name=f"{metrics_prefix}_received_processed_messages_duration_seconds", + documentation="Histogram of received processed messages duration in seconds by broker and handler", + unit="", + typ="histogram", + ) + metric.samples = [ + *[ + Sample( + name=f"{metrics_prefix}_received_processed_messages_duration_seconds_bucket", + labels={ + "app_name": app_name, + "broker": broker, + "handler": queue, + "le": cast(str, IsStr), + }, + value=cast(float, IsFloat), + timestamp=None, + exemplar=None, + ) + for _ in Histogram.DEFAULT_BUCKETS + ], + Sample( + name=f"{metrics_prefix}_received_processed_messages_duration_seconds_count", + labels={"app_name": app_name, "broker": broker, "handler": queue}, + value=cast(float, IsPositiveFloat), + timestamp=None, + exemplar=None, + ), + Sample( + name=f"{metrics_prefix}_received_processed_messages_duration_seconds_sum", + labels={"app_name": app_name, "broker": broker, "handler": queue}, + value=duration, + timestamp=None, + exemplar=None, + ), + Sample( + name=f"{metrics_prefix}_received_processed_messages_duration_seconds_created", + labels={"app_name": app_name, "broker": broker, "handler": queue}, + value=cast(float, IsPositiveFloat), + timestamp=None, + exemplar=None, + ), + ] + + return metric + + +def get_received_processed_messages_exceptions_metric( + *, + metrics_prefix: str, + app_name: str, + broker: str, + queue: str, + exception_type: Optional[str], + exceptions_amount: int, +) -> Metric: + metric = Metric( + name=f"{metrics_prefix}_received_processed_messages_exceptions", + documentation="Count of received processed messages exceptions by broker, handler and exception_type", + unit="", + typ="counter", + ) + metric.samples = ( + [ + Sample( + name=f"{metrics_prefix}_received_processed_messages_exceptions_total", + labels={ + "app_name": app_name, + "broker": broker, + "handler": queue, + "exception_type": exception_type, + }, + value=float(exceptions_amount), + timestamp=None, + exemplar=None, + ), + Sample( + name=f"{metrics_prefix}_received_processed_messages_exceptions_created", + labels={ + "app_name": app_name, + "broker": broker, + "handler": queue, + "exception_type": exception_type, + }, + value=cast(float, IsPositiveFloat), + timestamp=None, + exemplar=None, + ), + ] + if exception_type is not None + else [] + ) + + return metric + + +def get_published_messages_metric( + *, + metrics_prefix: str, + app_name: str, + broker: str, + queue: str, + messages_amount: int, + status: PublishingStatus, +) -> Metric: + metric = Metric( + name=f"{metrics_prefix}_published_messages", + documentation="Count of published messages by destination and status", + unit="", + typ="counter", + ) + metric.samples = [ + Sample( + name=f"{metrics_prefix}_published_messages_total", + labels={ + "app_name": app_name, + "broker": broker, + "destination": queue, + "status": status.value, + }, + value=messages_amount, + timestamp=None, + exemplar=None, + ), + Sample( + name=f"{metrics_prefix}_published_messages_created", + labels={ + "app_name": app_name, + "broker": broker, + "destination": queue, + "status": status.value, + }, + value=cast(float, IsPositiveFloat), + timestamp=None, + exemplar=None, + ), + ] + + return metric + + +def get_published_messages_duration_seconds_metric( + *, + metrics_prefix: str, + app_name: str, + broker: str, + queue: str, + duration: float, +) -> Metric: + metric = Metric( + name=f"{metrics_prefix}_published_messages_duration_seconds", + documentation="Histogram of published messages duration in seconds by broker and destination", + unit="", + typ="histogram", + ) + metric.samples = [ + *[ + Sample( + name=f"{metrics_prefix}_published_messages_duration_seconds_bucket", + labels={ + "app_name": app_name, + "broker": broker, + "destination": queue, + "le": cast(str, IsStr), + }, + value=cast(float, IsFloat), + timestamp=None, + exemplar=None, + ) + for _ in Histogram.DEFAULT_BUCKETS + ], + Sample( + name=f"{metrics_prefix}_published_messages_duration_seconds_count", + labels={"app_name": app_name, "broker": broker, "destination": queue}, + value=cast(float, IsPositiveFloat), + timestamp=None, + exemplar=None, + ), + Sample( + name=f"{metrics_prefix}_published_messages_duration_seconds_sum", + labels={"app_name": app_name, "broker": broker, "destination": queue}, + value=duration, + timestamp=None, + exemplar=None, + ), + Sample( + name=f"{metrics_prefix}_published_messages_duration_seconds_created", + labels={"app_name": app_name, "broker": broker, "destination": queue}, + value=cast(float, IsPositiveFloat), + timestamp=None, + exemplar=None, + ), + ] + + return metric + + +def get_published_messages_exceptions_metric( + *, + metrics_prefix: str, + app_name: str, + broker: str, + queue: str, + exception_type: Optional[str], +) -> Metric: + metric = Metric( + name=f"{metrics_prefix}_published_messages_exceptions", + documentation="Count of published messages exceptions by broker, destination and exception_type", + unit="", + typ="counter", + ) + metric.samples = ( + [ + Sample( + name=f"{metrics_prefix}_published_messages_exceptions_total", + labels={ + "app_name": app_name, + "broker": broker, + "destination": queue, + "exception_type": exception_type, + }, + value=1.0, + timestamp=None, + exemplar=None, + ), + Sample( + name=f"{metrics_prefix}_published_messages_exceptions_created", + labels={ + "app_name": app_name, + "broker": broker, + "destination": queue, + "exception_type": exception_type, + }, + value=cast(float, IsPositiveFloat), + timestamp=None, + exemplar=None, + ), + ] + if exception_type is not None + else [] + ) + + return metric From ae50f1ef62ece599cd421189a013c10c8c698145 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Wed, 25 Dec 2024 10:20:24 +0300 Subject: [PATCH 240/245] fix: correct PublishType for publisher decorator --- faststream/_internal/publisher/fake.py | 4 +++- faststream/confluent/publisher/fake.py | 1 + faststream/confluent/response.py | 2 +- faststream/kafka/exceptions.py | 9 +++++---- faststream/kafka/publisher/fake.py | 1 + faststream/kafka/publisher/producer.py | 1 + faststream/kafka/response.py | 2 +- faststream/nats/publisher/fake.py | 1 + faststream/nats/response.py | 2 +- faststream/rabbit/publisher/fake.py | 6 ++++-- faststream/rabbit/response.py | 2 +- faststream/redis/publisher/fake.py | 1 + faststream/redis/response.py | 2 +- faststream/response/response.py | 3 ++- 14 files changed, 24 insertions(+), 13 deletions(-) diff --git a/faststream/_internal/publisher/fake.py b/faststream/_internal/publisher/fake.py index e1d498d86c..fc69628816 100644 --- a/faststream/_internal/publisher/fake.py +++ b/faststream/_internal/publisher/fake.py @@ -5,6 +5,7 @@ from faststream._internal.basic_types import SendableMessage from faststream._internal.publisher.proto import BasePublisherProto +from faststream.response.publish_type import PublishType if TYPE_CHECKING: from faststream._internal.basic_types import AsyncFunc @@ -26,7 +27,8 @@ def __init__( @abstractmethod def patch_command(self, cmd: "PublishCommand") -> "PublishCommand": - raise NotImplementedError + cmd.publish_type = PublishType.REPLY + return cmd async def _publish( self, diff --git a/faststream/confluent/publisher/fake.py b/faststream/confluent/publisher/fake.py index 82d97ab682..6e302ccb51 100644 --- a/faststream/confluent/publisher/fake.py +++ b/faststream/confluent/publisher/fake.py @@ -22,6 +22,7 @@ def __init__( def patch_command( self, cmd: Union["PublishCommand", "KafkaPublishCommand"] ) -> "KafkaPublishCommand": + cmd = super().patch_command(cmd) real_cmd = KafkaPublishCommand.from_cmd(cmd) real_cmd.destination = self.topic return real_cmd diff --git a/faststream/confluent/response.py b/faststream/confluent/response.py index 3473e291bc..004578638a 100644 --- a/faststream/confluent/response.py +++ b/faststream/confluent/response.py @@ -44,7 +44,7 @@ def as_publish_command(self) -> "KafkaPublishCommand": self.body, headers=self.headers, correlation_id=self.correlation_id, - _publish_type=PublishType.REPLY, + _publish_type=PublishType.PUBLISH, # Kafka specific topic="", key=self.key, diff --git a/faststream/kafka/exceptions.py b/faststream/kafka/exceptions.py index 8d398706b9..443d2cfdc6 100644 --- a/faststream/kafka/exceptions.py +++ b/faststream/kafka/exceptions.py @@ -4,10 +4,11 @@ class BatchBufferOverflowException(FastStreamException): """Exception raised when a buffer overflow occurs when adding a new message to the batches.""" - def __init__(self, - message_position: int) -> None: + def __init__(self, message_position: int) -> None: self.message_position = message_position def __str__(self) -> str: - return f"The batch buffer is full. The position of the message" \ - f" in the transferred collection at which the overflow occurred: {self.message_position}" + return ( + "The batch buffer is full. The position of the message" + f" in the transferred collection at which the overflow occurred: {self.message_position}" + ) diff --git a/faststream/kafka/publisher/fake.py b/faststream/kafka/publisher/fake.py index 92ecbabcb8..ea9a321816 100644 --- a/faststream/kafka/publisher/fake.py +++ b/faststream/kafka/publisher/fake.py @@ -22,6 +22,7 @@ def __init__( def patch_command( self, cmd: Union["PublishCommand", "KafkaPublishCommand"] ) -> "KafkaPublishCommand": + cmd = super().patch_command(cmd) real_cmd = KafkaPublishCommand.from_cmd(cmd) real_cmd.destination = self.topic return real_cmd diff --git a/faststream/kafka/publisher/producer.py b/faststream/kafka/publisher/producer.py index e0764bf96a..5569ab9877 100644 --- a/faststream/kafka/publisher/producer.py +++ b/faststream/kafka/publisher/producer.py @@ -11,6 +11,7 @@ from faststream.message import encode_message from .state import EmptyProducerState, ProducerState, RealProducer + if TYPE_CHECKING: import asyncio diff --git a/faststream/kafka/response.py b/faststream/kafka/response.py index 13d3c186bf..a0dbd61ce5 100644 --- a/faststream/kafka/response.py +++ b/faststream/kafka/response.py @@ -36,7 +36,7 @@ def as_publish_command(self) -> "KafkaPublishCommand": self.body, headers=self.headers, correlation_id=self.correlation_id, - _publish_type=PublishType.REPLY, + _publish_type=PublishType.PUBLISH, # Kafka specific topic="", key=self.key, diff --git a/faststream/nats/publisher/fake.py b/faststream/nats/publisher/fake.py index 7c70536e34..1a0a95f18f 100644 --- a/faststream/nats/publisher/fake.py +++ b/faststream/nats/publisher/fake.py @@ -22,6 +22,7 @@ def __init__( def patch_command( self, cmd: Union["PublishCommand", "NatsPublishCommand"] ) -> "NatsPublishCommand": + cmd = super().patch_command(cmd) real_cmd = NatsPublishCommand.from_cmd(cmd) real_cmd.destination = self.subject return real_cmd diff --git a/faststream/nats/response.py b/faststream/nats/response.py index f8121bf883..f66b1c6ef4 100644 --- a/faststream/nats/response.py +++ b/faststream/nats/response.py @@ -31,7 +31,7 @@ def as_publish_command(self) -> "NatsPublishCommand": message=self.body, headers=self.headers, correlation_id=self.correlation_id, - _publish_type=PublishType.REPLY, + _publish_type=PublishType.PUBLISH, # Nats specific subject="", stream=self.stream, diff --git a/faststream/rabbit/publisher/fake.py b/faststream/rabbit/publisher/fake.py index e5c67848e6..30ff04c425 100644 --- a/faststream/rabbit/publisher/fake.py +++ b/faststream/rabbit/publisher/fake.py @@ -19,12 +19,14 @@ def __init__( ) -> None: super().__init__(producer=producer) self.routing_key = routing_key - self.app_id = str + self.app_id = app_id def patch_command( self, cmd: Union["PublishCommand", "RabbitPublishCommand"] ) -> "RabbitPublishCommand": + cmd = super().patch_command(cmd) real_cmd = RabbitPublishCommand.from_cmd(cmd) real_cmd.destination = self.routing_key - real_cmd.app_id = self.app_id + if self.app_id: + real_cmd.message_options["app_id"] = self.app_id return real_cmd diff --git a/faststream/rabbit/response.py b/faststream/rabbit/response.py index ffb1ad3b31..7b261f47f9 100644 --- a/faststream/rabbit/response.py +++ b/faststream/rabbit/response.py @@ -52,7 +52,7 @@ def as_publish_command(self) -> "RabbitPublishCommand": message=self.body, headers=self.headers, correlation_id=self.correlation_id, - _publish_type=PublishType.REPLY, + _publish_type=PublishType.PUBLISH, # RMQ specific routing_key="", **self.publish_options, diff --git a/faststream/redis/publisher/fake.py b/faststream/redis/publisher/fake.py index 2fd055e6f2..b7efa2b0d5 100644 --- a/faststream/redis/publisher/fake.py +++ b/faststream/redis/publisher/fake.py @@ -22,6 +22,7 @@ def __init__( def patch_command( self, cmd: Union["PublishCommand", "RedisPublishCommand"] ) -> "RedisPublishCommand": + cmd = super().patch_command(cmd) real_cmd = RedisPublishCommand.from_cmd(cmd) real_cmd.destination = self.channel return real_cmd diff --git a/faststream/redis/response.py b/faststream/redis/response.py index d48ee0ba1a..6b3296c7f5 100644 --- a/faststream/redis/response.py +++ b/faststream/redis/response.py @@ -42,7 +42,7 @@ def as_publish_command(self) -> "RedisPublishCommand": self.body, headers=self.headers, correlation_id=self.correlation_id, - _publish_type=PublishType.REPLY, + _publish_type=PublishType.PUBLISH, # Kafka specific channel="fake-channel", # it will be replaced by reply-sender maxlen=self.maxlen, diff --git a/faststream/response/response.py b/faststream/response/response.py index ff44643f35..72ac990df4 100644 --- a/faststream/response/response.py +++ b/faststream/response/response.py @@ -20,11 +20,12 @@ def __init__( self.correlation_id = correlation_id def as_publish_command(self) -> "PublishCommand": + """Method to transform handlers' Response result to DTO for publishers.""" return PublishCommand( body=self.body, headers=self.headers, correlation_id=self.correlation_id, - _publish_type=PublishType.REPLY, + _publish_type=PublishType.PUBLISH, ) From 873734720d1f200d733cdf311fa73d57a7041187 Mon Sep 17 00:00:00 2001 From: Apostol Fet <90645107+ApostolFet@users.noreply.github.com> Date: Wed, 25 Dec 2024 23:56:51 +0300 Subject: [PATCH 241/245] Overwrite message schema (#2007) * fix: use of overwritten message scheme and warning * test: overwrite schema and warning * test: deleted the loop and made a length check --- .../specification/asyncapi/v2_6_0/generate.py | 11 ++++- .../specification/asyncapi/v3_0_0/generate.py | 9 +++++ tests/asyncapi/base/v2_6_0/arguments.py | 40 +++++++++++++++++++ tests/asyncapi/base/v3_0_0/arguments.py | 40 +++++++++++++++++++ 4 files changed, 98 insertions(+), 2 deletions(-) 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", + } From 0694ef406f98ec7625464e7b77b6cbbbc00f8d1f Mon Sep 17 00:00:00 2001 From: doublehomixide Date: Sat, 28 Dec 2024 21:55:28 +0300 Subject: [PATCH 242/245] new test: in_memory_routing (#2010) Co-authored-by: Nikita Pastukhov Co-authored-by: Pastukhov Nikita --- faststream/rabbit/testing.py | 7 +- tests/asyncapi/base/v2_6_0/arguments.py | 9 +- tests/asyncapi/base/v3_0_0/arguments.py | 9 +- tests/brokers/rabbit/test_test_client.py | 291 ++++++++++++----------- 4 files changed, 167 insertions(+), 149 deletions(-) diff --git a/faststream/rabbit/testing.py b/faststream/rabbit/testing.py index 97b5619184..919cc2aec7 100644 --- a/faststream/rabbit/testing.py +++ b/faststream/rabbit/testing.py @@ -270,9 +270,12 @@ async def _execute_handler( def _is_handler_matches( handler: "LogicSubscriber", routing_key: str, - headers: "Mapping[Any, Any]", - exchange: "RabbitExchange", + headers: Optional["Mapping[Any, Any]"] = None, + exchange: Optional["RabbitExchange"] = None, ) -> bool: + headers = headers or {} + exchange = RabbitExchange.validate(exchange) + if handler.exchange != exchange: return False diff --git a/tests/asyncapi/base/v2_6_0/arguments.py b/tests/asyncapi/base/v2_6_0/arguments.py index a7aa9984e9..69d9f676f9 100644 --- a/tests/asyncapi/base/v2_6_0/arguments.py +++ b/tests/asyncapi/base/v2_6_0/arguments.py @@ -718,8 +718,13 @@ class User: @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() + 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"] diff --git a/tests/asyncapi/base/v3_0_0/arguments.py b/tests/asyncapi/base/v3_0_0/arguments.py index d93833a85d..a3afe8a6fb 100644 --- a/tests/asyncapi/base/v3_0_0/arguments.py +++ b/tests/asyncapi/base/v3_0_0/arguments.py @@ -702,8 +702,13 @@ class User: @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() + 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"] diff --git a/tests/brokers/rabbit/test_test_client.py b/tests/brokers/rabbit/test_test_client.py index 0ddaf24b58..1d14978dd5 100644 --- a/tests/brokers/rabbit/test_test_client.py +++ b/tests/brokers/rabbit/test_test_client.py @@ -1,4 +1,5 @@ import asyncio +from typing import Any import pytest @@ -6,11 +7,12 @@ from faststream.exceptions import SubscriberNotFound from faststream.rabbit import ( ExchangeType, + RabbitBroker, RabbitExchange, RabbitQueue, ) from faststream.rabbit.annotations import RabbitMessage -from faststream.rabbit.testing import FakeProducer, apply_pattern +from faststream.rabbit.testing import FakeProducer, _is_handler_matches, apply_pattern from tests.brokers.base.testclient import BrokerTestclientTestcase from .basic import RabbitMemoryTestcaseConfig @@ -42,151 +44,15 @@ def subscriber(m) -> None: assert event.is_set() - async def test_respect_routing_key(self) -> None: - broker = self.get_broker() - - publisher = broker.publisher( - exchange=RabbitExchange("test", type=ExchangeType.TOPIC), - routing_key="up", - ) - - async with self.patch_broker(broker): - await publisher.publish("Hi!") - - publisher.mock.assert_called_once_with("Hi!") - - async def test_direct( + async def test_direct_not_found( self, queue: str, ) -> None: broker = self.get_broker() - @broker.subscriber(queue) - async def handler(m) -> int: - return 1 - - @broker.subscriber(queue + "1", exchange="test") - async def handler2(m) -> int: - return 2 - async with self.patch_broker(broker) as br: - await br.start() - - assert await (await br.request("", queue)).decode() == 1 - assert ( - await (await br.request("", queue + "1", exchange="test")).decode() == 2 - ) - with pytest.raises(SubscriberNotFound): - await br.request("", exchange="test2") - - async def test_fanout( - self, - queue: str, - mock, - ) -> None: - broker = self.get_broker() - - exch = RabbitExchange("test", type=ExchangeType.FANOUT) - - @broker.subscriber(queue, exchange=exch) - async def handler(m) -> None: - mock() - - async with self.patch_broker(broker) as br: - await br.request("", exchange=exch) - - with pytest.raises(SubscriberNotFound): - await br.request("", exchange="test2") - - assert mock.call_count == 1 - - async def test_any_topic_routing(self) -> None: - broker = self.get_broker() - - exch = RabbitExchange("test", type=ExchangeType.TOPIC) - - @broker.subscriber( - RabbitQueue("test", routing_key="test.*.subj.*"), - exchange=exch, - ) - def subscriber(msg) -> None: ... - - async with self.patch_broker(broker) as br: - await br.publish("hello", "test.a.subj.b", exchange=exch) - subscriber.mock.assert_called_once_with("hello") - - async def test_ending_topic_routing(self) -> None: - broker = self.get_broker() - - exch = RabbitExchange("test", type=ExchangeType.TOPIC) - - @broker.subscriber( - RabbitQueue("test", routing_key="test.#"), - exchange=exch, - ) - def subscriber(msg) -> None: ... - - async with self.patch_broker(broker) as br: - await br.publish("hello", "test.a.subj.b", exchange=exch) - subscriber.mock.assert_called_once_with("hello") - - async def test_mixed_topic_routing(self) -> None: - broker = self.get_broker() - - exch = RabbitExchange("test", type=ExchangeType.TOPIC) - - @broker.subscriber( - RabbitQueue("test", routing_key="*.*.subj.#"), - exchange=exch, - ) - def subscriber(msg) -> None: ... - - async with self.patch_broker(broker) as br: - await br.publish("hello", "test.a.subj.b.c", exchange=exch) - subscriber.mock.assert_called_once_with("hello") - - async def test_header(self) -> None: - broker = self.get_broker() - - q1 = RabbitQueue( - "test-queue-2", - bind_arguments={"key": 2, "key2": 2, "x-match": "any"}, - ) - q2 = RabbitQueue( - "test-queue-3", - bind_arguments={"key": 2, "key2": 2, "x-match": "all"}, - ) - q3 = RabbitQueue( - "test-queue-4", - bind_arguments={}, - ) - exch = RabbitExchange("exchange", type=ExchangeType.HEADERS) - - @broker.subscriber(q2, exch) - async def handler2(msg) -> int: - return 2 - - @broker.subscriber(q1, exch) - async def handler(msg) -> int: - return 1 - - @broker.subscriber(q3, exch) - async def handler3(msg) -> int: - return 3 - - async with self.patch_broker(broker) as br: - assert ( - await ( - await br.request(exchange=exch, headers={"key": 2, "key2": 2}) - ).decode() - == 2 - ) - assert ( - await (await br.request(exchange=exch, headers={"key": 2})).decode() - == 1 - ) - assert await (await br.request(exchange=exch, headers={})).decode() == 3 + await br.request("", "") async def test_consume_manual_ack( self, @@ -205,13 +71,13 @@ async def handler(msg: RabbitMessage) -> None: consume.set() @broker.subscriber(queue=queue + "1", exchange=exchange) - async def handler2(msg: RabbitMessage): + async def handler2(msg: RabbitMessage) -> None: await msg.raw_message.nack() consume2.set() raise ValueError @broker.subscriber(queue=queue + "2", exchange=exchange) - async def handler3(msg: RabbitMessage): + async def handler3(msg: RabbitMessage) -> None: await msg.raw_message.reject() consume3.set() raise ValueError @@ -239,7 +105,7 @@ async def handler3(msg: RabbitMessage): assert consume2.is_set() assert consume3.is_set() - async def test_respect_middleware(self, queue) -> None: + async def test_respect_middleware(self, queue: str) -> None: routes = [] class Middleware(BaseMiddleware): @@ -262,7 +128,7 @@ async def h2(msg) -> None: ... assert len(routes) == 2 @pytest.mark.rabbit() - async def test_real_respect_middleware(self, queue) -> None: + async def test_real_respect_middleware(self, queue: str) -> None: routes = [] class Middleware(BaseMiddleware): @@ -329,3 +195,142 @@ async def test_broker_with_real_patches_publishers_and_subscribers( ) def test(pattern: str, current: str, result: bool) -> None: assert apply_pattern(pattern, current) == result + + +exch_direct = RabbitExchange("exchange", auto_delete=True, type=ExchangeType.DIRECT) +exch_fanout = RabbitExchange("exchange", auto_delete=True, type=ExchangeType.FANOUT) +exch_topic = RabbitExchange("exchange", auto_delete=True, type=ExchangeType.TOPIC) +exch_headers = RabbitExchange("exchange", auto_delete=True, type=ExchangeType.HEADERS) +reqular_queue = RabbitQueue("test-reqular-queue", auto_delete=True) + +routing_key_queue = RabbitQueue( + "test-routing-key-queue", auto_delete=True, routing_key="*.info" +) +one_key_queue = RabbitQueue( + "test-one-key-queue", auto_delete=True, bind_arguments={"key": 1} +) +any_keys_queue = RabbitQueue( + "test-any-keys-queue", + auto_delete=True, + bind_arguments={"key": 2, "key2": 2, "x-match": "any"}, +) +all_keys_queue = RabbitQueue( + "test-all-keys-queue", + auto_delete=True, + bind_arguments={"key": 2, "key2": 2, "x-match": "all"}, +) + +broker = RabbitBroker() + + +@pytest.mark.parametrize( + ( + "queue", + "exchange", + "routing_key", + "headers", + "expected_result", + ), + ( + pytest.param( + reqular_queue, + exch_direct, + reqular_queue.routing, + {}, + True, + id="direct match", + ), + pytest.param( + reqular_queue, + exch_direct, + "wrong key", + {}, + False, + id="direct mismatch", + ), + pytest.param( + reqular_queue, + exch_fanout, + "", + {}, + True, + id="fanout match", + ), + pytest.param( + routing_key_queue, + exch_topic, + "log.info", + {}, + True, + id="topic match", + ), + pytest.param( + routing_key_queue, + exch_topic, + "log.wrong", + {}, + False, + id="topic mismatch", + ), + pytest.param( + one_key_queue, + exch_headers, + "", + {"key": 1}, + True, + id="one header match", + ), + pytest.param( + one_key_queue, + exch_headers, + "", + {"key": "wrong"}, + False, + id="one header mismatch", + ), + pytest.param( + any_keys_queue, + exch_headers, + "", + {"key2": 2}, + True, + id="any headers match", + ), + pytest.param( + any_keys_queue, + exch_headers, + "", + {"key2": "wrong"}, + False, + id="any headers mismatch", + ), + pytest.param( + all_keys_queue, + exch_headers, + "", + {"key": 2, "key2": 2}, + True, + id="all headers match", + ), + pytest.param( + all_keys_queue, + exch_headers, + "", + {"key": "wrong", "key2": 2}, + False, + id="all headers mismatch", + ), + ), +) +def test_in_memory_routing( + queue: str, + exchange: RabbitExchange, + routing_key: str, + headers: dict[str, Any], + expected_result: bool, +) -> None: + subscriber = broker.subscriber(queue, exchange) + assert ( + _is_handler_matches(subscriber, routing_key, headers, exchange) + is expected_result + ) From 18c166fb6eee1f99cb1b194d126dad19174f6419 Mon Sep 17 00:00:00 2001 From: David Grigorenko <69060921+DABND19@users.noreply.github.com> Date: Mon, 30 Dec 2024 14:15:56 +0300 Subject: [PATCH 243/245] Separated thread for confluent kafka consumer client. (#2014) * fix: Disabled excessive throttling for BatchSubscriber. * fix: Use separate thread for confluent kafka consumer. * refactor: Added run_in_executor function. * fix: Stop consumer client after consumer tasks are stopped. --- faststream/_internal/utils/functions.py | 10 ++++- faststream/confluent/client.py | 49 ++++++++++++---------- faststream/confluent/subscriber/usecase.py | 20 ++++----- 3 files changed, 43 insertions(+), 36 deletions(-) diff --git a/faststream/_internal/utils/functions.py b/faststream/_internal/utils/functions.py index e8cb60d696..efea5541d6 100644 --- a/faststream/_internal/utils/functions.py +++ b/faststream/_internal/utils/functions.py @@ -1,9 +1,12 @@ +import asyncio from collections.abc import AsyncIterator, Awaitable, Iterator +from concurrent.futures import Executor from contextlib import asynccontextmanager, contextmanager -from functools import wraps +from functools import partial, wraps from typing import ( Any, Callable, + Optional, TypeVar, Union, cast, @@ -80,3 +83,8 @@ def drop_response_type(model: CallModel) -> CallModel: async def return_input(x: Any) -> Any: return x + + +async def run_in_executor(executor: Optional[Executor], func: Callable[P, T], *args: P.args, **kwargs: P.kwargs) -> T: + loop = asyncio.get_running_loop() + return await loop.run_in_executor(executor, partial(func, *args, **kwargs)) diff --git a/faststream/confluent/client.py b/faststream/confluent/client.py index 385a1b4389..471b71c368 100644 --- a/faststream/confluent/client.py +++ b/faststream/confluent/client.py @@ -1,6 +1,7 @@ import asyncio import logging from collections.abc import Iterable, Sequence +from concurrent.futures import ThreadPoolExecutor from contextlib import suppress from time import time from typing import ( @@ -17,7 +18,7 @@ from faststream._internal.constants import EMPTY from faststream._internal.log import logger as faststream_logger -from faststream._internal.utils.functions import call_or_await +from faststream._internal.utils.functions import call_or_await, run_in_executor from faststream.confluent import config as config_module from faststream.confluent.schemas import TopicPartition from faststream.exceptions import SetupError @@ -314,9 +315,8 @@ def __init__( self.config = final_config self.consumer = Consumer(final_config, logger=self.logger_state.logger.logger) # type: ignore[call-arg] - # We shouldn't read messages and close consumer concurrently - # https://github.com/airtai/faststream/issues/1904#issuecomment-2506990895 - self._lock = anyio.Lock() + # A pool with single thread is used in order to execute the commands of the consumer sequentially: + self._thread_pool = ThreadPoolExecutor(max_workers=1) @property def topics_to_create(self) -> list[str]: @@ -325,11 +325,12 @@ def topics_to_create(self) -> list[str]: async def start(self) -> None: """Starts the Kafka consumer and subscribes to the specified topics.""" if self.allow_auto_create_topics: - await call_or_await( + await run_in_executor( + self._thread_pool, create_topics, - self.topics_to_create, - self.config, - self.logger_state.logger.logger, + topics=self.topics_to_create, + config=self.config, + logger_=self.logger_state.logger.logger, ) else: @@ -339,10 +340,13 @@ async def start(self) -> None: ) if self.topics: - await call_or_await(self.consumer.subscribe, self.topics) + await run_in_executor( + self._thread_pool, self.consumer.subscribe, topics=self.topics + ) elif self.partitions: - await call_or_await( + await run_in_executor( + self._thread_pool, self.consumer.assign, [p.to_confluent() for p in self.partitions], ) @@ -353,7 +357,7 @@ async def start(self) -> None: async def commit(self, asynchronous: bool = True) -> None: """Commits the offsets of all messages returned by the last poll operation.""" - await call_or_await(self.consumer.commit, asynchronous=asynchronous) + await run_in_executor(self._thread_pool, self.consumer.commit, asynchronous=asynchronous) async def stop(self) -> None: """Stops the Kafka consumer and releases all resources.""" @@ -376,13 +380,13 @@ async def stop(self) -> None: ) # Wrap calls to async to make method cancelable by timeout - async with self._lock: - await call_or_await(self.consumer.close) + await run_in_executor(self._thread_pool, self.consumer.close) + + self._thread_pool.shutdown(wait=False) async def getone(self, timeout: float = 0.1) -> Optional[Message]: """Consumes a single message from Kafka.""" - async with self._lock: - msg = await call_or_await(self.consumer.poll, timeout) + msg = await run_in_executor(self._thread_pool, self.consumer.poll, timeout) return check_msg_error(msg) async def getmany( @@ -391,13 +395,12 @@ async def getmany( max_records: Optional[int] = 10, ) -> tuple[Message, ...]: """Consumes a batch of messages from Kafka and groups them by topic and partition.""" - async with self._lock: - raw_messages: list[Optional[Message]] = await call_or_await( - self.consumer.consume, # type: ignore[arg-type] - num_messages=max_records or 10, - timeout=timeout, - ) - + raw_messages: list[Optional[Message]] = await run_in_executor( + self._thread_pool, + self.consumer.consume, # type: ignore[arg-type] + num_messages=max_records or 10, + timeout=timeout, + ) return tuple(x for x in map(check_msg_error, raw_messages) if x is not None) async def seek(self, topic: str, partition: int, offset: int) -> None: @@ -407,7 +410,7 @@ async def seek(self, topic: str, partition: int, offset: int) -> None: partition=partition, offset=offset, ) - await call_or_await(self.consumer.seek, topic_partition.to_confluent()) + await run_in_executor(self._thread_pool, self.consumer.seek, topic_partition.to_confluent()) def check_msg_error(msg: Optional[Message]) -> Optional[Message]: diff --git a/faststream/confluent/subscriber/usecase.py b/faststream/confluent/subscriber/usecase.py index 7f94ec1b7b..a2a0392978 100644 --- a/faststream/confluent/subscriber/usecase.py +++ b/faststream/confluent/subscriber/usecase.py @@ -131,12 +131,12 @@ async def start(self) -> None: self.add_task(self._consume()) async def close(self) -> None: + await super().close() + if self.consumer is not None: await self.consumer.stop() self.consumer = None - await super().close() - @override async def get_one( self, @@ -335,18 +335,14 @@ def __init__( async def get_msg(self) -> Optional[tuple["Message", ...]]: assert self.consumer, "You should setup subscriber at first." # nosec B101 - - messages = await self.consumer.getmany( - timeout=self.polling_interval, - max_records=self.max_records, + return ( + await self.consumer.getmany( + timeout=self.polling_interval, + max_records=self.max_records, + ) + or None ) - if not messages: # TODO: why we are sleeping here? - await anyio.sleep(self.polling_interval) - return None - - return messages - def get_log_context( self, message: Optional["StreamMessage[tuple[Message, ...]]"], From 4f98e59175ff121e01bef1b74db6395e6a3d886f Mon Sep 17 00:00:00 2001 From: Flosckow <66554425+Flosckow@users.noreply.github.com> Date: Mon, 30 Dec 2024 18:31:08 +0700 Subject: [PATCH 244/245] Feat: concurrent redis (#2012) * Feat: add tests * Feat: add concurrent subscriber * Fix: revert ruff * Fix: again ruff * Fix: fastapi init * Fix: inheritance --------- Co-authored-by: Daniil Dumchenko Co-authored-by: Pastukhov Nikita --- faststream/redis/broker/registrator.py | 52 ++++++---- faststream/redis/fastapi/fastapi.py | 63 +++++++----- faststream/redis/router.py | 5 + faststream/redis/subscriber/factory.py | 54 +++++++++- faststream/redis/subscriber/specified.py | 28 ++++++ faststream/redis/subscriber/usecases/basic.py | 49 ++++++++- .../subscriber/usecases/channel_subscriber.py | 41 +++++++- .../subscriber/usecases/list_subscriber.py | 41 +++++++- .../subscriber/usecases/stream_subscriber.py | 45 ++++++++- tests/brokers/redis/test_consume.py | 99 +++++++++++++++++++ 10 files changed, 421 insertions(+), 56 deletions(-) diff --git a/faststream/redis/broker/registrator.py b/faststream/redis/broker/registrator.py index 39567dd835..624fc5a539 100644 --- a/faststream/redis/broker/registrator.py +++ b/faststream/redis/broker/registrator.py @@ -9,7 +9,10 @@ from faststream.redis.message import UnifyRedisDict from faststream.redis.publisher.factory import create_publisher from faststream.redis.subscriber.factory import SubsciberType, create_subscriber -from faststream.redis.subscriber.specified import SpecificationSubscriber +from faststream.redis.subscriber.specified import ( + SpecificationConcurrentSubscriber, + SpecificationSubscriber, +) if TYPE_CHECKING: from fast_depends.dependencies import Dependant @@ -104,28 +107,35 @@ def subscriber( # type: ignore[override] bool, Doc("Whetever to include operation in AsyncAPI schema or not."), ] = True, - ) -> SpecificationSubscriber: - subscriber = cast( - "SpecificationSubscriber", - super().subscriber( - create_subscriber( - channel=channel, - list=list, - stream=stream, - # subscriber args - ack_policy=ack_policy, - no_ack=no_ack, - no_reply=no_reply, - broker_middlewares=self.middlewares, - broker_dependencies=self._dependencies, - # AsyncAPI - title_=title, - description_=description, - include_in_schema=self._solve_include_in_schema(include_in_schema), - ), - ), + max_workers: Annotated[ + int, + Doc("Number of workers to process messages concurrently."), + ] = 1, + ) -> Union[SpecificationSubscriber, SpecificationConcurrentSubscriber]: + subscriber = create_subscriber( + channel=channel, + list=list, + stream=stream, + # subscriber args + max_workers=max_workers, + no_ack=no_ack, + no_reply=no_reply, + ack_policy=ack_policy, + broker_middlewares=self.middlewares, + broker_dependencies=self._dependencies, + # AsyncAPI + title_=title, + description_=description, + include_in_schema=self._solve_include_in_schema(include_in_schema), ) + if max_workers > 1: + subscriber = cast("SpecificationConcurrentSubscriber", subscriber) + else: + subscriber = cast("SpecificationSubscriber", subscriber) + + subscriber = super().subscriber(subscriber) # type: ignore[assignment] + return subscriber.add_call( parser_=parser or self._parser, decoder_=decoder or self._decoder, diff --git a/faststream/redis/fastapi/fastapi.py b/faststream/redis/fastapi/fastapi.py index f05b7987af..547f3b3a6d 100644 --- a/faststream/redis/fastapi/fastapi.py +++ b/faststream/redis/fastapi/fastapi.py @@ -29,7 +29,10 @@ from faststream.redis.broker.broker import RedisBroker as RB from faststream.redis.message import UnifyRedisDict from faststream.redis.schemas import ListSub, PubSub, StreamSub -from faststream.redis.subscriber.specified import SpecificationSubscriber +from faststream.redis.subscriber.specified import ( + SpecificationConcurrentSubscriber, + SpecificationSubscriber, +) if TYPE_CHECKING: from enum import Enum @@ -620,34 +623,40 @@ def subscriber( # type: ignore[override] """, ), ] = False, - ) -> SpecificationSubscriber: - return cast( - "SpecificationSubscriber", - super().subscriber( - channel=channel, - list=list, - stream=stream, - dependencies=dependencies, - parser=parser, - decoder=decoder, - middlewares=middlewares, - ack_policy=ack_policy, - no_ack=no_ack, - no_reply=no_reply, - title=title, - description=description, - include_in_schema=include_in_schema, - # FastAPI args - response_model=response_model, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - ), + max_workers: Annotated[ + int, + Doc("Number of workers to process messages concurrently."), + ] = 1, + ) -> Union[SpecificationSubscriber, SpecificationConcurrentSubscriber]: + subscriber = super().subscriber( + channel=channel, + max_workers=max_workers, + list=list, + stream=stream, + dependencies=dependencies, + parser=parser, + decoder=decoder, + middlewares=middlewares, + ack_policy=ack_policy, + no_ack=no_ack, + no_reply=no_reply, + title=title, + description=description, + include_in_schema=include_in_schema, + # FastAPI args + response_model=response_model, + response_model_include=response_model_include, + response_model_exclude=response_model_exclude, + response_model_by_alias=response_model_by_alias, + response_model_exclude_unset=response_model_exclude_unset, + response_model_exclude_defaults=response_model_exclude_defaults, + response_model_exclude_none=response_model_exclude_none, ) + if max_workers > 1: + return cast("SpecificationConcurrentSubscriber", subscriber) + return cast("SpecificationSubscriber", subscriber) + @override def publisher( self, diff --git a/faststream/redis/router.py b/faststream/redis/router.py index d6d4e67cfe..f9239c023c 100644 --- a/faststream/redis/router.py +++ b/faststream/redis/router.py @@ -189,6 +189,10 @@ def __init__( bool, Doc("Whetever to include operation in AsyncAPI schema or not."), ] = True, + max_workers: Annotated[ + int, + Doc("Number of workers to process messages concurrently."), + ] = 1, ) -> None: super().__init__( call, @@ -197,6 +201,7 @@ def __init__( list=list, stream=stream, dependencies=dependencies, + max_workers=max_workers, parser=parser, decoder=decoder, middlewares=middlewares, diff --git a/faststream/redis/subscriber/factory.py b/faststream/redis/subscriber/factory.py index 1a2a4cc31c..e598fe30cd 100644 --- a/faststream/redis/subscriber/factory.py +++ b/faststream/redis/subscriber/factory.py @@ -10,10 +10,13 @@ from faststream.redis.schemas import INCORRECT_SETUP_MSG, ListSub, PubSub, StreamSub from faststream.redis.schemas.proto import validate_options from faststream.redis.subscriber.specified import ( + SpecificationChannelConcurrentSubscriber, SpecificationChannelSubscriber, SpecificationListBatchSubscriber, + SpecificationListConcurrentSubscriber, SpecificationListSubscriber, SpecificationStreamBatchSubscriber, + SpecificationStreamConcurrentSubscriber, SpecificationStreamSubscriber, ) @@ -29,6 +32,9 @@ "SpecificationStreamSubscriber", "SpecificationListBatchSubscriber", "SpecificationListSubscriber", + "SpecificationChannelConcurrentSubscriber", + "SpecificationListConcurrentSubscriber", + "SpecificationStreamConcurrentSubscriber", ] @@ -47,6 +53,7 @@ def create_subscriber( title_: Optional[str] = None, description_: Optional[str] = None, include_in_schema: bool = True, + max_workers: int = 1, ) -> SubsciberType: _validate_input_for_misconfigure( channel=channel, @@ -54,12 +61,26 @@ def create_subscriber( stream=stream, ack_policy=ack_policy, no_ack=no_ack, + max_workers=max_workers, ) if ack_policy is EMPTY: ack_policy = AckPolicy.DO_NOTHING if no_ack else AckPolicy.REJECT_ON_ERROR if (channel_sub := PubSub.validate(channel)) is not None: + if max_workers > 1: + return SpecificationChannelConcurrentSubscriber( + channel=channel_sub, + # basic args + no_reply=no_reply, + broker_dependencies=broker_dependencies, + broker_middlewares=broker_middlewares, + max_workers=max_workers, + # AsyncAPI args + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + ) return SpecificationChannelSubscriber( channel=channel_sub, # basic args @@ -86,7 +107,20 @@ def create_subscriber( description_=description_, include_in_schema=include_in_schema, ) - + if max_workers > 1: + return SpecificationStreamConcurrentSubscriber( + stream=stream_sub, + # basic args + ack_policy=ack_policy, + no_reply=no_reply, + broker_dependencies=broker_dependencies, + broker_middlewares=broker_middlewares, + max_workers=max_workers, + # AsyncAPI args + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + ) return SpecificationStreamSubscriber( stream=stream_sub, # basic args @@ -113,7 +147,19 @@ def create_subscriber( description_=description_, include_in_schema=include_in_schema, ) - + if max_workers > 1: + return SpecificationListConcurrentSubscriber( + list=list_sub, + # basic args + no_reply=no_reply, + broker_dependencies=broker_dependencies, + broker_middlewares=broker_middlewares, + max_workers=max_workers, + # AsyncAPI args + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + ) return SpecificationListSubscriber( list=list_sub, # basic args @@ -136,6 +182,7 @@ def _validate_input_for_misconfigure( stream: Union["StreamSub", str, None], ack_policy: AckPolicy, no_ack: bool, + max_workers: int, ) -> None: validate_options(channel=channel, list=list, stream=stream) @@ -149,6 +196,9 @@ def _validate_input_for_misconfigure( if ack_policy is not EMPTY: msg = "You can't use deprecated `no_ack` and `ack_policy` simultaneously. Please, use `ack_policy` only." raise SetupError(msg) + if stream and no_ack and max_workers > 1: + msg = "Max workers not work with manual no_ack mode." + raise SetupError(msg) if ack_policy is not EMPTY: if channel: diff --git a/faststream/redis/subscriber/specified.py b/faststream/redis/subscriber/specified.py index 30591233db..4598cfd987 100644 --- a/faststream/redis/subscriber/specified.py +++ b/faststream/redis/subscriber/specified.py @@ -3,14 +3,18 @@ ) from faststream.redis.schemas import ListSub, StreamSub from faststream.redis.schemas.proto import RedisSpecificationProtocol +from faststream.redis.subscriber.usecases.basic import ConcurrentSubscriber from faststream.redis.subscriber.usecases.channel_subscriber import ( ChannelSubscriber, + ConcurrentChannelSubscriber, ) from faststream.redis.subscriber.usecases.list_subscriber import ( BatchListSubscriber, + ConcurrentListSubscriber, ListSubscriber, ) from faststream.redis.subscriber.usecases.stream_subscriber import ( + ConcurrentStreamSubscriber, StreamBatchSubscriber, StreamSubscriber, ) @@ -100,3 +104,27 @@ class SpecificationListSubscriber(_ListSubscriberMixin, ListSubscriber): class SpecificationListBatchSubscriber(_ListSubscriberMixin, BatchListSubscriber): pass + + +class SpecificationConcurrentSubscriber( + ConcurrentSubscriber, RedisSpecificationProtocol[SubscriberSpec] +): + pass + + +class SpecificationStreamConcurrentSubscriber( + ConcurrentStreamSubscriber, SpecificationStreamSubscriber +): + pass + + +class SpecificationChannelConcurrentSubscriber( + ConcurrentChannelSubscriber, SpecificationChannelSubscriber +): + pass + + +class SpecificationListConcurrentSubscriber( + ConcurrentListSubscriber, SpecificationListSubscriber +): + pass diff --git a/faststream/redis/subscriber/usecases/basic.py b/faststream/redis/subscriber/usecases/basic.py index a5592f3730..d4fd993394 100644 --- a/faststream/redis/subscriber/usecases/basic.py +++ b/faststream/redis/subscriber/usecases/basic.py @@ -10,7 +10,7 @@ import anyio from typing_extensions import TypeAlias, override -from faststream._internal.subscriber.mixins import TasksMixin +from faststream._internal.subscriber.mixins import ConcurrentMixin, TasksMixin from faststream._internal.subscriber.usecase import SubscriberUsecase from faststream.redis.message import ( UnifyRedisDict, @@ -153,3 +153,50 @@ def build_log_context( "channel": channel, "message_id": getattr(message, "message_id", ""), } + + async def consume_one(self, msg: "BrokerStreamMessage") -> None: + await self.consume(msg) + + +class ConcurrentSubscriber(ConcurrentMixin["BrokerStreamMessage"], LogicSubscriber): + def __init__( + self, + *, + default_parser: "AsyncCallable", + default_decoder: "AsyncCallable", + # Subscriber args + max_workers: int, + no_ack: bool, + no_reply: bool, + retry: bool, + broker_dependencies: Iterable["Dependant"], + broker_middlewares: Sequence["BrokerMiddleware[UnifyRedisDict]"], + # AsyncAPI args + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, + ) -> None: + super().__init__( + max_workers=max_workers, + default_parser=default_parser, + default_decoder=default_decoder, + # Propagated options + no_ack=no_ack, + no_reply=no_reply, + retry=retry, + broker_middlewares=broker_middlewares, + broker_dependencies=broker_dependencies, + # AsyncAPI + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + ) + + self._client = None + + async def start(self) -> None: + await super().start() + self.start_consume_task() + + async def consume_one(self, msg: "BrokerStreamMessage") -> None: + await self._put_msg(msg) diff --git a/faststream/redis/subscriber/usecases/channel_subscriber.py b/faststream/redis/subscriber/usecases/channel_subscriber.py index e7c261ad07..d7284e47c6 100644 --- a/faststream/redis/subscriber/usecases/channel_subscriber.py +++ b/faststream/redis/subscriber/usecases/channel_subscriber.py @@ -12,6 +12,7 @@ ) from typing_extensions import TypeAlias, override +from faststream._internal.subscriber.mixins import ConcurrentMixin from faststream._internal.subscriber.utils import process_msg from faststream.middlewares import AckPolicy from faststream.redis.message import ( @@ -147,9 +148,47 @@ async def _get_message(self, psub: RPubSub) -> Optional[PubSubMessage]: async def _get_msgs(self, psub: RPubSub) -> None: if msg := await self._get_message(psub): - await self.consume(msg) + await self.consume_one(msg) def add_prefix(self, prefix: str) -> None: new_ch = deepcopy(self.channel) new_ch.name = f"{prefix}{new_ch.name}" self.channel = new_ch + + +class ConcurrentChannelSubscriber( + ConcurrentMixin["BrokerStreamMessage"], ChannelSubscriber +): + def __init__( + self, + *, + channel: "PubSub", + # Subscriber args + no_reply: bool, + broker_dependencies: Iterable["Dependant"], + broker_middlewares: Sequence["BrokerMiddleware[UnifyRedisDict]"], + # AsyncAPI args + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, + max_workers: int, + ) -> None: + super().__init__( + # Propagated options + channel=channel, + no_reply=no_reply, + max_workers=max_workers, + broker_middlewares=broker_middlewares, + broker_dependencies=broker_dependencies, + # AsyncAPI + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + ) + + async def start(self) -> None: + await super().start() + self.start_consume_task() + + async def consume_one(self, msg: "BrokerStreamMessage") -> None: + await self._put_msg(msg) diff --git a/faststream/redis/subscriber/usecases/list_subscriber.py b/faststream/redis/subscriber/usecases/list_subscriber.py index 8c6558398f..c002920002 100644 --- a/faststream/redis/subscriber/usecases/list_subscriber.py +++ b/faststream/redis/subscriber/usecases/list_subscriber.py @@ -9,6 +9,7 @@ import anyio from typing_extensions import TypeAlias, override +from faststream._internal.subscriber.mixins import ConcurrentMixin from faststream._internal.subscriber.utils import process_msg from faststream.middlewares import AckPolicy from faststream.redis.message import ( @@ -177,7 +178,7 @@ async def _get_msgs(self, client: "Redis[bytes]") -> None: channel=self.list_sub.name, ) - await self.consume(msg) + await self.consume_one(msg) class BatchListSubscriber(_ListHandlerMixin): @@ -215,7 +216,43 @@ async def _get_msgs(self, client: "Redis[bytes]") -> None: data=raw_msgs, ) - await self.consume(msg) + await self.consume_one(msg) else: await anyio.sleep(self.list_sub.polling_interval) + + +class ConcurrentListSubscriber(ConcurrentMixin["BrokerStreamMessage"], ListSubscriber): + def __init__( + self, + *, + list: ListSub, + # Subscriber args + no_reply: bool, + broker_dependencies: Iterable["Dependant"], + broker_middlewares: Sequence["BrokerMiddleware[UnifyRedisDict]"], + max_workers: int, + # AsyncAPI args + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, + ) -> None: + super().__init__( + list=list, + # Propagated options + no_reply=no_reply, + broker_middlewares=broker_middlewares, + broker_dependencies=broker_dependencies, + max_workers=max_workers, + # AsyncAPI + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + ) + + async def start(self) -> None: + await super().start() + self.start_consume_task() + + async def consume_one(self, msg: "BrokerStreamMessage") -> None: + await self._put_msg(msg) diff --git a/faststream/redis/subscriber/usecases/stream_subscriber.py b/faststream/redis/subscriber/usecases/stream_subscriber.py index 44c3a0c28b..4037ea7a2d 100644 --- a/faststream/redis/subscriber/usecases/stream_subscriber.py +++ b/faststream/redis/subscriber/usecases/stream_subscriber.py @@ -11,6 +11,7 @@ from redis.exceptions import ResponseError from typing_extensions import TypeAlias, override +from faststream._internal.subscriber.mixins import ConcurrentMixin from faststream._internal.subscriber.utils import process_msg from faststream.redis.message import ( BatchStreamMessage, @@ -281,7 +282,7 @@ async def _get_msgs( data=raw_msg, ) - await self.consume(msg) + await self.consume_one(msg) class StreamBatchSubscriber(_StreamHandlerMixin): @@ -333,4 +334,44 @@ async def _get_msgs( message_ids=ids, ) - await self.consume(msg) + await self.consume_one(msg) + + +class ConcurrentStreamSubscriber( + ConcurrentMixin["BrokerStreamMessage"], StreamSubscriber +): + def __init__( + self, + *, + stream: StreamSub, + # Subscriber args + ack_policy: "AckPolicy", + no_reply: bool, + broker_dependencies: Iterable["Dependant"], + broker_middlewares: Sequence["BrokerMiddleware[UnifyRedisDict]"], + max_workers: int, + # AsyncAPI args + title_: Optional[str], + description_: Optional[str], + include_in_schema: bool, + ) -> None: + super().__init__( + stream=stream, + # Propagated options + ack_policy=ack_policy, + no_reply=no_reply, + broker_middlewares=broker_middlewares, + broker_dependencies=broker_dependencies, + max_workers=max_workers, + # AsyncAPI + title_=title_, + description_=description_, + include_in_schema=include_in_schema, + ) + + async def start(self) -> None: + await super().start() + self.start_consume_task() + + async def consume_one(self, msg: "BrokerStreamMessage") -> None: + await self._put_msg(msg) diff --git a/tests/brokers/redis/test_consume.py b/tests/brokers/redis/test_consume.py index 9aa3b7590b..f0da8be4eb 100644 --- a/tests/brokers/redis/test_consume.py +++ b/tests/brokers/redis/test_consume.py @@ -93,6 +93,39 @@ async def handler(msg) -> None: mock.assert_called_once_with("hello") + async def test_concurrent_consume_channel(self, queue: str, mock: MagicMock): + event = asyncio.Event() + event2 = asyncio.Event() + + consume_broker = self.get_broker() + + @consume_broker.subscriber(channel=PubSub(queue), max_workers=2) + async def handler(msg): + mock() + if event.is_set(): + event2.set() + else: + event.set() + await asyncio.sleep(0.1) + + async with self.patch_broker(consume_broker) as br: + await br.start() + + for i in range(5): + await br.publish(i, queue) + + await asyncio.wait( + ( + asyncio.create_task(event.wait()), + asyncio.create_task(event2.wait()), + ), + timeout=3, + ) + + assert event.is_set() + assert event2.is_set() + assert mock.call_count == 2, mock.call_count + @pytest.mark.redis() @pytest.mark.asyncio() @@ -354,6 +387,39 @@ async def test_get_one_timeout( mock(await subscriber.get_one(timeout=1e-24)) mock.assert_called_once_with(None) + async def test_concurrent_consume_list(self, queue: str, mock: MagicMock): + event = asyncio.Event() + event2 = asyncio.Event() + + consume_broker = self.get_broker() + + @consume_broker.subscriber(list=ListSub(queue), max_workers=2) + async def handler(msg): + mock() + if event.is_set(): + event2.set() + else: + event.set() + await asyncio.sleep(0.1) + + async with self.patch_broker(consume_broker) as br: + await br.start() + + for i in range(5): + await br.publish(i, list=queue) + + await asyncio.wait( + ( + asyncio.create_task(event.wait()), + asyncio.create_task(event2.wait()), + ), + timeout=3, + ) + + assert event.is_set() + assert event2.is_set() + assert mock.call_count == 2, mock.call_count + @pytest.mark.redis() @pytest.mark.asyncio() @@ -681,3 +747,36 @@ async def test_get_one_timeout( mock(await subscriber.get_one(timeout=1e-24)) mock.assert_called_once_with(None) + + async def test_concurrent_consume_stream(self, queue: str, mock: MagicMock): + event = asyncio.Event() + event2 = asyncio.Event() + + consume_broker = self.get_broker() + + @consume_broker.subscriber(stream=StreamSub(queue), max_workers=2) + async def handler(msg): + mock() + if event.is_set(): + event2.set() + else: + event.set() + await asyncio.sleep(0.1) + + async with self.patch_broker(consume_broker) as br: + await br.start() + + for i in range(5): + await br.publish(i, stream=queue) + + await asyncio.wait( + ( + asyncio.create_task(event.wait()), + asyncio.create_task(event2.wait()), + ), + timeout=3, + ) + + assert event.is_set() + assert event2.is_set() + assert mock.call_count == 2, mock.call_count From 5bced11289cddc8e54f94c05e523b89820443fd9 Mon Sep 17 00:00:00 2001 From: Nikita Pastukhov Date: Mon, 30 Dec 2024 16:06:50 +0300 Subject: [PATCH 245/245] chore: add warning comment to confluent client --- faststream/confluent/client.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/faststream/confluent/client.py b/faststream/confluent/client.py index 471b71c368..d6eee25f40 100644 --- a/faststream/confluent/client.py +++ b/faststream/confluent/client.py @@ -380,6 +380,10 @@ async def stop(self) -> None: ) # Wrap calls to async to make method cancelable by timeout + # We shouldn't read messages and close consumer concurrently + # https://github.com/airtai/faststream/issues/1904#issuecomment-2506990895 + # Now it works withouth lock due `ThreadPoolExecutor(max_workers=1)` + # that makes all calls to consumer sequential await run_in_executor(self._thread_pool, self.consumer.close) self._thread_pool.shutdown(wait=False)